]> git.zerfleddert.de Git - proxmark3-svn/blob - bootrom/bootrom.c
usb communication (device side) refactoring
[proxmark3-svn] / bootrom / bootrom.c
1 //-----------------------------------------------------------------------------
2 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
3 // at your option, any later version. See the LICENSE.txt file for the text of
4 // the license.
5 //-----------------------------------------------------------------------------
6 // Main code for the bootloader
7 //-----------------------------------------------------------------------------
8
9 #include "proxmark3.h"
10 #include "usb_cdc.h"
11
12 void DbpString(char *str) {
13 uint8_t len = 0;
14 while (str[len] != 0x00) {
15 len++;
16 }
17 cmd_send(CMD_DEBUG_PRINT_STRING,len,0,0,(uint8_t*)str,len);
18 }
19
20 struct common_area common_area __attribute__((section(".commonarea")));
21 unsigned int start_addr, end_addr, bootrom_unlocked;
22 extern char _bootrom_start, _bootrom_end, _flash_start, _flash_end;
23
24 static void ConfigClocks(void)
25 {
26 // we are using a 16 MHz crystal as the basis for everything
27 // slow clock runs at 32Khz typical regardless of crystal
28
29 // enable system clock and USB clock
30 AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_PCK | AT91C_PMC_UDP;
31
32 // enable the clock to the following peripherals
33 AT91C_BASE_PMC->PMC_PCER =
34 (1<<AT91C_ID_PIOA) |
35 (1<<AT91C_ID_ADC) |
36 (1<<AT91C_ID_SPI) |
37 (1<<AT91C_ID_SSC) |
38 (1<<AT91C_ID_PWMC) |
39 (1<<AT91C_ID_UDP);
40
41 // worst case scenario, with MAINCK = 16Mhz xtal, startup delay is 1.4ms
42 // if SLCK slow clock runs at its worst case (max) frequency of 42khz
43 // max startup delay = (1.4ms*42k)/8 = 7.356 so round up to 8
44
45 // enable main oscillator and set startup delay
46 AT91C_BASE_PMC->PMC_MOR =
47 AT91C_CKGR_MOSCEN |
48 PMC_MAIN_OSC_STARTUP_DELAY(8);
49
50 // wait for main oscillator to stabilize
51 while ( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS) )
52 ;
53
54 // PLL output clock frequency in range 80 - 160 MHz needs CKGR_PLL = 00
55 // PLL output clock frequency in range 150 - 180 MHz needs CKGR_PLL = 10
56 // PLL output is MAINCK * multiplier / divisor = 16Mhz * 12 / 2 = 96Mhz
57 AT91C_BASE_PMC->PMC_PLLR =
58 PMC_PLL_DIVISOR(2) |
59 PMC_PLL_COUNT_BEFORE_LOCK(0x50) |
60 PMC_PLL_FREQUENCY_RANGE(0) |
61 PMC_PLL_MULTIPLIER(12) |
62 PMC_PLL_USB_DIVISOR(1);
63
64 // wait for PLL to lock
65 while ( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCK) )
66 ;
67
68 // we want a master clock (MCK) to be PLL clock / 2 = 96Mhz / 2 = 48Mhz
69 // datasheet recommends that this register is programmed in two operations
70 // when changing to PLL, program the prescaler first then the source
71 AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2;
72
73 // wait for main clock ready signal
74 while ( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) )
75 ;
76
77 // set the source to PLL
78 AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2 | AT91C_PMC_CSS_PLL_CLK;
79
80 // wait for main clock ready signal
81 while ( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) )
82 ;
83 }
84
85 static void Fatal(void)
86 {
87 for(;;);
88 }
89
90 void UsbPacketReceived(UsbCommand *c) {
91 int i, dont_ack=0;
92 volatile uint32_t *p;
93
94 uint32_t arg0 = (uint32_t)c->arg[0];
95
96 switch(c->cmd) {
97 case CMD_DEVICE_INFO: {
98 dont_ack = 1;
99 arg0 = DEVICE_INFO_FLAG_BOOTROM_PRESENT | DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM |
100 DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH;
101 if(common_area.flags.osimage_present) {
102 arg0 |= DEVICE_INFO_FLAG_OSIMAGE_PRESENT;
103 }
104 cmd_send(CMD_DEVICE_INFO,arg0,1,2,0,0);
105 } break;
106
107 case CMD_SETUP_WRITE: {
108 /* The temporary write buffer of the embedded flash controller is mapped to the
109 * whole memory region, only the last 8 bits are decoded.
110 */
111 p = (volatile uint32_t *)&_flash_start;
112 for(i = 0; i < 12; i++) {
113 p[i+arg0] = c->d.asDwords[i];
114 }
115 } break;
116
117 case CMD_FINISH_WRITE: {
118 uint32_t* flash_mem = (uint32_t*)(&_flash_start);
119 for (size_t j=0; j<2; j++) {
120 for(i = 0+(64*j); i < 64+(64*j); i++) {
121 flash_mem[i] = c->d.asDwords[i];
122 }
123
124 uint32_t flash_address = arg0 + (0x100*j);
125
126 /* Check that the address that we are supposed to write to is within our allowed region */
127 if( ((flash_address+AT91C_IFLASH_PAGE_SIZE-1) >= end_addr) || (flash_address < start_addr) ) {
128 /* Disallow write */
129 dont_ack = 1;
130 cmd_send(CMD_NACK,0,0,0,0,0);
131 } else {
132 uint32_t page_n = (flash_address - ((uint32_t)flash_mem)) / AT91C_IFLASH_PAGE_SIZE;
133 /* Translate address to flash page and do flash, update here for the 512k part */
134 AT91C_BASE_EFC0->EFC_FCR = MC_FLASH_COMMAND_KEY |
135 MC_FLASH_COMMAND_PAGEN(page_n) |
136 AT91C_MC_FCMD_START_PROG;
137 }
138
139 // Wait until flashing of page finishes
140 uint32_t sr;
141 while(!((sr = AT91C_BASE_EFC0->EFC_FSR) & AT91C_MC_FRDY));
142 if(sr & (AT91C_MC_LOCKE | AT91C_MC_PROGE)) {
143 dont_ack = 1;
144 cmd_send(CMD_NACK,0,0,0,0,0);
145 }
146 }
147 } break;
148
149 case CMD_HARDWARE_RESET: {
150 usb_disable();
151 AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
152 } break;
153
154 case CMD_START_FLASH: {
155 if(c->arg[2] == START_FLASH_MAGIC) bootrom_unlocked = 1;
156 else bootrom_unlocked = 0;
157 {
158 int prot_start = (int)&_bootrom_start;
159 int prot_end = (int)&_bootrom_end;
160 int allow_start = (int)&_flash_start;
161 int allow_end = (int)&_flash_end;
162 int cmd_start = c->arg[0];
163 int cmd_end = c->arg[1];
164
165 /* Only allow command if the bootrom is unlocked, or the parameters are outside of the protected
166 * bootrom area. In any case they must be within the flash area.
167 */
168 if( (bootrom_unlocked || ((cmd_start >= prot_end) || (cmd_end < prot_start)))
169 && (cmd_start >= allow_start) && (cmd_end <= allow_end) ) {
170 start_addr = cmd_start;
171 end_addr = cmd_end;
172 } else {
173 start_addr = end_addr = 0;
174 dont_ack = 1;
175 cmd_send(CMD_NACK,0,0,0,0,0);
176 }
177 }
178 } break;
179
180 default: {
181 Fatal();
182 } break;
183 }
184
185 if(!dont_ack) {
186 cmd_send(CMD_ACK,arg0,0,0,0,0);
187 }
188 }
189
190 static void flash_mode(int externally_entered)
191 {
192 start_addr = 0;
193 end_addr = 0;
194 bootrom_unlocked = 0;
195 UsbCommand rx;
196
197 usb_enable();
198 for (volatile size_t i=0; i<0x100000; i++) {};
199
200 for(;;) {
201 WDT_HIT();
202
203 if (cmd_receive(&rx)) {
204 UsbPacketReceived(&rx);
205 }
206
207 if(!externally_entered && !BUTTON_PRESS()) {
208 /* Perform a reset to leave flash mode */
209 usb_disable();
210 LED_B_ON();
211 AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
212 for(;;);
213 }
214 if(externally_entered && BUTTON_PRESS()) {
215 /* Let the user's button press override the automatic leave */
216 externally_entered = 0;
217 }
218 }
219 }
220
221 extern uint32_t _osimage_entry;
222 void BootROM(void)
223 {
224 //------------
225 // First set up all the I/O pins; GPIOs configured directly, other ones
226 // just need to be assigned to the appropriate peripheral.
227
228 // Kill all the pullups, especially the one on USB D+; leave them for
229 // the unused pins, though.
230 AT91C_BASE_PIOA->PIO_PPUDR =
231 GPIO_USB_PU |
232 GPIO_LED_A |
233 GPIO_LED_B |
234 GPIO_LED_C |
235 GPIO_LED_D |
236 GPIO_FPGA_DIN |
237 GPIO_FPGA_DOUT |
238 GPIO_FPGA_CCLK |
239 GPIO_FPGA_NINIT |
240 GPIO_FPGA_NPROGRAM |
241 GPIO_FPGA_DONE |
242 GPIO_MUXSEL_HIPKD |
243 GPIO_MUXSEL_HIRAW |
244 GPIO_MUXSEL_LOPKD |
245 GPIO_MUXSEL_LORAW |
246 GPIO_RELAY |
247 GPIO_NVDD_ON;
248 // (and add GPIO_FPGA_ON)
249 // These pins are outputs
250 AT91C_BASE_PIOA->PIO_OER =
251 GPIO_LED_A |
252 GPIO_LED_B |
253 GPIO_LED_C |
254 GPIO_LED_D |
255 GPIO_RELAY |
256 GPIO_NVDD_ON;
257 // PIO controls the following pins
258 AT91C_BASE_PIOA->PIO_PER =
259 GPIO_USB_PU |
260 GPIO_LED_A |
261 GPIO_LED_B |
262 GPIO_LED_C |
263 GPIO_LED_D;
264
265 // USB_D_PLUS_PULLUP_OFF();
266 usb_disable();
267 LED_D_OFF();
268 LED_C_ON();
269 LED_B_OFF();
270 LED_A_OFF();
271
272 AT91C_BASE_EFC0->EFC_FMR =
273 AT91C_MC_FWS_1FWS |
274 MC_FLASH_MODE_MASTER_CLK_IN_MHZ(48);
275
276 // Initialize all system clocks
277 ConfigClocks();
278
279 LED_A_ON();
280
281 int common_area_present = 0;
282 switch(AT91C_BASE_RSTC->RSTC_RSR & AT91C_RSTC_RSTTYP) {
283 case AT91C_RSTC_RSTTYP_WATCHDOG:
284 case AT91C_RSTC_RSTTYP_SOFTWARE:
285 case AT91C_RSTC_RSTTYP_USER:
286 /* In these cases the common_area in RAM should be ok, retain it if it's there */
287 if(common_area.magic == COMMON_AREA_MAGIC && common_area.version == 1) {
288 common_area_present = 1;
289 }
290 break;
291 default: /* Otherwise, initialize it from scratch */
292 break;
293 }
294
295 if(!common_area_present){
296 /* Common area not ok, initialize it */
297 int i; for(i=0; i<sizeof(common_area); i++) { /* Makeshift memset, no need to drag util.c into this */
298 ((char*)&common_area)[i] = 0;
299 }
300 common_area.magic = COMMON_AREA_MAGIC;
301 common_area.version = 1;
302 common_area.flags.bootrom_present = 1;
303 }
304
305 common_area.flags.bootrom_present = 1;
306 if(common_area.command == COMMON_AREA_COMMAND_ENTER_FLASH_MODE) {
307 common_area.command = COMMON_AREA_COMMAND_NONE;
308 flash_mode(1);
309 } else if(BUTTON_PRESS()) {
310 flash_mode(0);
311 } else if(_osimage_entry == 0xffffffffU) {
312 flash_mode(1);
313 } else {
314 // jump to Flash address of the osimage entry point (LSBit set for thumb mode)
315 __asm("bx %0\n" : : "r" ( ((int)&_osimage_entry) | 0x1 ) );
316 }
317 }
Impressum, Datenschutz