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