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