1 #include <alloca.h>
2 #include <stdbool.h>
3 #include <string.h>
4 
5 #include <variant/variant.h>
6 
7 #include <plat/pwr.h>
8 #include <plat/gpio.h>
9 #include <plat/cmsis.h>
10 
11 #include <bl.h>
12 
13 struct StmUdid
14 {
15     volatile uint32_t U_ID[3];
16 };
17 
18 struct StmSpi {
19     volatile uint32_t CR1;
20     volatile uint32_t CR2;
21     volatile uint32_t SR;
22     volatile uint32_t DR;
23     volatile uint32_t CRCPR;
24     volatile uint32_t RXCRCR;
25     volatile uint32_t TXCRCR;
26     volatile uint32_t I2SCFGR;
27     volatile uint32_t I2SPR;
28 };
29 
30 struct StmGpio {
31     volatile uint32_t MODER;
32     volatile uint32_t OTYPER;
33     volatile uint32_t OSPEEDR;
34     volatile uint32_t PUPDR;
35     volatile uint32_t IDR;
36     volatile uint32_t ODR;
37     volatile uint32_t BSRR;
38     volatile uint32_t LCKR;
39     volatile uint32_t AFR[2];
40 };
41 
42 struct StmFlash
43 {
44     volatile uint32_t ACR;
45     volatile uint32_t KEYR;
46     volatile uint32_t OPTKEYR;
47     volatile uint32_t SR;
48     volatile uint32_t CR;
49     volatile uint32_t OPTCR;
50 };
51 
52 struct StmCrc
53 {
54     volatile uint32_t DR;
55     volatile uint32_t IDR;
56     volatile uint32_t CR;
57 };
58 
59 struct StmRcc {
60     volatile uint32_t CR;
61     volatile uint32_t PLLCFGR;
62     volatile uint32_t CFGR;
63     volatile uint32_t CIR;
64     volatile uint32_t AHB1RSTR;
65     volatile uint32_t AHB2RSTR;
66     volatile uint32_t AHB3RSTR;
67     uint8_t unused0[4];
68     volatile uint32_t APB1RSTR;
69     volatile uint32_t APB2RSTR;
70     uint8_t unused1[8];
71     volatile uint32_t AHB1ENR;
72     volatile uint32_t AHB2ENR;
73     volatile uint32_t AHB3ENR;
74     uint8_t unused2[4];
75     volatile uint32_t APB1ENR;
76     volatile uint32_t APB2ENR;
77     uint8_t unused3[8];
78     volatile uint32_t AHB1LPENR;
79     volatile uint32_t AHB2LPENR;
80     volatile uint32_t AHB3LPENR;
81     uint8_t unused4[4];
82     volatile uint32_t APB1LPENR;
83     volatile uint32_t APB2LPENR;
84     uint8_t unused5[8];
85     volatile uint32_t BDCR;
86     volatile uint32_t CSR;
87     uint8_t unused6[8];
88     volatile uint32_t SSCGR;
89     volatile uint32_t PLLI2SCFGR;
90 };
91 
92 typedef void (*FlashEraseF)(volatile uint32_t *, uint32_t, volatile uint32_t *);
93 typedef void (*FlashWriteF)(volatile uint8_t *, uint8_t, volatile uint32_t *);
94 
95 static struct StmSpi *SPI;
96 static struct StmGpio *GPIOA;
97 static struct StmRcc *RCC;
98 static uint32_t mOldApb2State;
99 static uint32_t mOldAhb1State;
100 
101 #define INT_IN_PIN          (SH_INT_WAKEUP - GPIO_PA(0))
102 
103 #define FLASH_ACR_LAT(x)    ((x) & FLASH_ACR_LAT_MASK)
104 #define FLASH_ACR_LAT_MASK  0x0F
105 #define FLASH_ACR_PRFTEN    0x00000100
106 #define FLASH_ACR_ICEN      0x00000200
107 #define FLASH_ACR_DCEN      0x00000400
108 #define FLASH_ACR_ICRST     0x00000800
109 #define FLASH_ACR_DCRST     0x00001000
110 
111 #define FLASH_SR_EOP        0x00000001
112 #define FLASH_SR_OPERR      0x00000002
113 #define FLASH_SR_WRPERR     0x00000010
114 #define FLASH_SR_PGAERR     0x00000020
115 #define FLASH_SR_PGPERR     0x00000040
116 #define FLASH_SR_PGSERR     0x00000080
117 #define FLASH_SR_RDERR      0x00000100
118 #define FLASH_SR_BSY        0x00010000
119 
120 #define FLASH_CR_PG         0x00000001
121 #define FLASH_CR_SER        0x00000002
122 #define FLASH_CR_MER        0x00000004
123 #define FLASH_CR_SNB(x)     (((x) << FLASH_CR_SNB_SHIFT) & FLASH_CR_SNB_MASK)
124 #define FLASH_CR_SNB_MASK   0x00000078
125 #define FLASH_CR_SNB_SHIFT  3
126 #define FLASH_CR_PSIZE(x)   (((x) << FLASH_CR_PSIZE_SHIFT) & FLASH_CR_PSIZE_MASK)
127 #define FLASH_CR_PSIZE_MASK 0x00000300
128 #define FLASH_CR_PSIZE_SHIFT 8
129 #define FLASH_CR_PSIZE_8    0x0
130 #define FLASH_CR_PSIZE_16   0x1
131 #define FLASH_CR_PSIZE_32   0x2
132 #define FLASH_CR_PSIZE_64   0x3
133 #define FLASH_CR_STRT       0x00010000
134 #define FLASH_CR_EOPIE      0x01000000
135 #define FLASH_CR_ERRIE      0x02000000
136 #define FLASH_CR_LOCK       0x80000000
137 
138 //stm defines
139 #define BL_MAX_FLASH_CODE   1024
140 
141 /*
142  * Return the address of the erase code and the length of the code
143  *
144  * This code needs to run out of ram and not flash since accessing flash
145  * while erasing is undefined (best case the processor stalls, worst case
146  * it starts executing garbage)
147  *
148  * This function is used to get a pointer to the actual code that does the
149  * erase and polls for completion (so we can copy it to ram) as well as the
150  * length of the code (so we know how much space to allocate for it)
151  *
152  * void FlashEraseF(volatile uint32_t *addr, uint32_t value, volatile uint32_t *status)
153  * {
154  *     *addr = value;
155  *     while (*status & FLASH_SR_BSY) ;
156  * }
157  */
blGetFlashEraseCode(uint16_t ** addr,uint32_t * size)158 static void __attribute__((naked)) blGetFlashEraseCode(uint16_t **addr, uint32_t *size)
159 {
160     asm volatile (
161         "  push {lr}          \n"
162         "  bl   9f            \n"
163         "  str  r1, [r0, #0]  \n" // *addr = value
164         "1:                   \n"
165         "  ldr  r3, [r2, #0]  \n" // r3 = *status
166         "  lsls r3, #15       \n" // r3 <<= 15
167         "  bmi  1b            \n" // if (r3 < 0) goto 1
168         "  bx   lr            \n" // return
169         "9:                   \n"
170         "  bic  lr, #0x1      \n"
171         "  adr  r3, 9b        \n"
172         "  sub  r3, lr        \n"
173         "  str  lr, [r0]      \n"
174         "  str  r3, [r1]      \n"
175         "  pop {pc}           \n"
176     );
177 }
178 
_blEraseSectors(uint32_t sector_cnt,uint8_t * erase_mask)179 static void _blEraseSectors(uint32_t sector_cnt, uint8_t *erase_mask)
180 {
181     struct StmFlash *flash = (struct StmFlash *)FLASH_BASE;
182     uint16_t *code_src, *code;
183     uint32_t i, code_length;
184     FlashEraseF func;
185 
186     blGetFlashEraseCode(&code_src, &code_length);
187 
188     if (code_length < BL_MAX_FLASH_CODE) {
189         code = (uint16_t *)(((uint32_t)alloca(code_length + 1) + 1) & ~0x1);
190         func = (FlashEraseF)((uint8_t *)code+1);
191 
192         for (i = 0; i < code_length / sizeof(uint16_t); i++)
193             code[i] = code_src[i];
194 
195         for (i = 0; i < sector_cnt; i++) {
196             if (erase_mask[i]) {
197                 flash->CR = (flash->CR & ~(FLASH_CR_SNB_MASK)) |
198                     FLASH_CR_SNB(i) | FLASH_CR_SER;
199                 func(&flash->CR, flash->CR | FLASH_CR_STRT, &flash->SR);
200                 flash->CR &= ~(FLASH_CR_SNB_MASK | FLASH_CR_SER);
201             }
202         }
203     }
204 }
205 
blEraseSectors(uint32_t sector_cnt,uint8_t * erase_mask,uint32_t key1,uint32_t key2)206 bool blEraseSectors(uint32_t sector_cnt, uint8_t *erase_mask, uint32_t key1, uint32_t key2)
207 {
208     struct StmFlash *flash = (struct StmFlash *)FLASH_BASE;
209     uint32_t acr_cache, cr_cache;
210     // disable interrupts
211     // otherwise an interrupt during flash write/erase will stall the processor
212     // until the write/erase completes
213     uint32_t int_state = blDisableInts();
214 
215     // wait for flash to not be busy (should never be set at this point)
216     while (flash->SR & FLASH_SR_BSY);
217 
218     cr_cache = flash->CR;
219 
220     if (flash->CR & FLASH_CR_LOCK) {
221         // unlock flash
222         flash->KEYR = key1;
223         flash->KEYR = key2;
224     }
225 
226     if (!(flash->CR & FLASH_CR_LOCK)) {
227         flash->CR = FLASH_CR_PSIZE(FLASH_CR_PSIZE_8);
228         acr_cache = flash->ACR;
229 
230         // disable and flush data and instruction caches
231         flash->ACR &= ~(FLASH_ACR_DCEN | FLASH_ACR_ICEN);
232         flash->ACR |= (FLASH_ACR_DCRST | FLASH_ACR_ICRST);
233 
234         _blEraseSectors(sector_cnt, erase_mask);
235 
236         flash->ACR = acr_cache;
237         flash->CR = cr_cache;
238 
239         // restore interrupts
240         blRestoreInts(int_state);
241         return true;
242     }
243     return false;
244 }
245 
246 /*
247  * Return the address of the write code and the length of the code
248  *
249  * This code needs to run out of ram and not flash since accessing flash
250  * while writing to flash is undefined (best case the processor stalls, worst
251  * case it starts executing garbage)
252  *
253  * This function is used to get a pointer to the actual code that does the
254  * write and polls for completion (so we can copy it to ram) as well as the
255  * length of the code (so we know how much space to allocate for it)
256  *
257  * void FlashWriteF(volatile uint8_t *addr, uint8_t value, volatile uint32_t *status)
258  * {
259  *     *addr = value;
260  *     while (*status & FLASH_SR_BSY) ;
261  * }
262  */
blGetFlashWriteCode(uint16_t ** addr,uint32_t * size)263 static void __attribute__((naked)) blGetFlashWriteCode(uint16_t **addr, uint32_t *size)
264 {
265     asm volatile (
266         "  push {lr}          \n"
267         "  bl   9f            \n"
268         "  strb r1, [r0, #0]  \n" // *addr = value
269         "1:                   \n"
270         "  ldr  r3, [r2, #0]  \n" // r3 = *status
271         "  lsls r3, #15       \n" // r3 <<= 15
272         "  bmi  1b            \n" // if (r3 < 0) goto 1
273         "  bx   lr            \n" // return
274         "9:                   \n"
275         "  bic  lr, #0x1      \n"
276         "  adr  r3, 9b        \n"
277         "  sub  r3, lr        \n"
278         "  str  lr, [r0]      \n"
279         "  str  r3, [r1]      \n"
280         "  pop {pc}           \n"
281     );
282 }
283 
blWriteBytes(uint8_t * dst,const uint8_t * src,uint32_t length)284 static void blWriteBytes(uint8_t *dst, const uint8_t *src, uint32_t length)
285 {
286     struct StmFlash *flash = (struct StmFlash *)FLASH_BASE;
287     uint16_t *code_src, *code;
288     uint32_t i, code_length;
289     FlashWriteF func;
290 
291     blGetFlashWriteCode(&code_src, &code_length);
292 
293     if (code_length < BL_MAX_FLASH_CODE) {
294         code = (uint16_t *)(((uint32_t)alloca(code_length+1) + 1) & ~0x1);
295         func = (FlashWriteF)((uint8_t *)code+1);
296 
297         for (i = 0; i < code_length / sizeof(uint16_t); i++)
298             code[i] = code_src[i];
299 
300         flash->CR |= FLASH_CR_PG;
301 
302         for (i = 0; i < length; i++) {
303             if (dst[i] != src[i])
304                 func(&dst[i], src[i], &flash->SR);
305         }
306 
307         flash->CR &= ~FLASH_CR_PG;
308     }
309 }
310 
blPlatProgramFlash(uint8_t * dst,const uint8_t * src,uint32_t length,uint32_t key1,uint32_t key2)311 bool blPlatProgramFlash(uint8_t *dst, const uint8_t *src, uint32_t length, uint32_t key1, uint32_t key2)
312 {
313     struct StmFlash *flash = (struct StmFlash *)FLASH_BASE;
314     uint32_t acr_cache, cr_cache;
315     // disable interrupts
316     // otherwise an interrupt during flash write will stall the processor
317     // until the write completes
318     uint32_t int_state = blDisableInts();
319 
320     // wait for flash to not be busy (should never be set at this point)
321     while (flash->SR & FLASH_SR_BSY);
322 
323     cr_cache = flash->CR;
324 
325     if (flash->CR & FLASH_CR_LOCK) {
326         // unlock flash
327         flash->KEYR = key1;
328         flash->KEYR = key2;
329     }
330 
331     if (flash->CR & FLASH_CR_LOCK) {
332         // unlock failed, restore interrupts
333         blRestoreInts(int_state);
334 
335         return false;
336     }
337 
338     flash->CR = FLASH_CR_PSIZE(FLASH_CR_PSIZE_8);
339 
340     acr_cache = flash->ACR;
341 
342     // disable and flush data and instruction caches
343     flash->ACR &= ~(FLASH_ACR_DCEN | FLASH_ACR_ICEN);
344     flash->ACR |= (FLASH_ACR_DCRST | FLASH_ACR_ICRST);
345 
346     blWriteBytes(dst, src, length);
347 
348     flash->ACR = acr_cache;
349     flash->CR = cr_cache;
350 
351     blRestoreInts(int_state);
352     return true;
353 }
354 
blDisableInts(void)355 uint32_t blDisableInts(void)
356 {
357     uint32_t state;
358 
359     asm volatile (
360         "mrs %0, PRIMASK    \n"
361         "cpsid i            \n"
362         :"=r"(state)
363     );
364 
365     return state;
366 }
367 
blRestoreInts(uint32_t state)368 void blRestoreInts(uint32_t state)
369 {
370     asm volatile(
371         "msr PRIMASK, %0   \n"
372         ::"r"((uint32_t)state)
373     );
374 }
375 
blReboot(void)376 void blReboot(void)
377 {
378     SCB->AIRCR = 0x05FA0004;
379     //we never get here
380     while(1);
381 }
382 
blResetRxData()383 void blResetRxData()
384 {
385     (void)SPI->DR;
386     while (!(SPI->SR & 1));
387     (void)SPI->DR;
388 }
389 
blSpiTxRxByte(uint32_t val)390 uint8_t blSpiTxRxByte(uint32_t val)
391 {
392     while (!(SPI->SR & 2));
393     SPI->DR = val;
394     while (!(SPI->SR & 1));
395     return SPI->DR;
396 }
397 
blGetSnum(uint32_t * snum,uint32_t length)398 uint32_t blGetSnum(uint32_t *snum, uint32_t length)
399 {
400     struct StmUdid *reg = (struct StmUdid *)UDID_BASE;
401     uint32_t i;
402 
403     if (length > 3)
404         length = 3;
405 
406     for (i = 0; i < length; i++)
407         snum[i] = reg->U_ID[i];
408 
409     return (length << 2);
410 }
411 
blSetup()412 void blSetup()
413 {
414     SPI = (struct StmSpi*)SPI1_BASE;
415     GPIOA = (struct StmGpio*)GPIOA_BASE;
416     RCC = (struct StmRcc*)RCC_BASE;
417 
418     if (SH_INT_WAKEUP < GPIO_PA(0) || SH_INT_WAKEUP > GPIO_PA(15)) {
419 
420         //link time assert :)
421         extern void ThisIsAnError_BlIntPinNotInGpioA(void);
422         ThisIsAnError_BlIntPinNotInGpioA();
423     }
424 
425     //SPI & GPIOA on
426     mOldApb2State = RCC->APB2ENR;
427     mOldAhb1State = RCC->AHB1ENR;
428     RCC->APB2ENR |= PERIPH_APB2_SPI1;
429     RCC->AHB1ENR |= PERIPH_AHB1_GPIOA;
430 
431     //reset units
432     RCC->APB2RSTR |= PERIPH_APB2_SPI1;
433     RCC->AHB1RSTR |= PERIPH_AHB1_GPIOA;
434     RCC->APB2RSTR &=~ PERIPH_APB2_SPI1;
435     RCC->AHB1RSTR &=~ PERIPH_AHB1_GPIOA;
436 
437     //configure GPIOA for SPI A4..A7 for SPI use (function 5), int pin as not func, high speed, no pullups, not open drain, proper directions
438     GPIOA->AFR[0] = (GPIOA->AFR[0] & 0x0000ffff & ~(0x0f << (INT_IN_PIN * 4))) | 0x55550000;
439     GPIOA->OSPEEDR |= 0x0000ff00 | (3 << (INT_IN_PIN * 2));
440     GPIOA->PUPDR &=~ (0x0000ff00 | (3 << (INT_IN_PIN * 2)));
441     GPIOA->OTYPER &=~ (0x00f0 | (1 << INT_IN_PIN));
442     GPIOA->MODER = (GPIOA->MODER & 0xffff00ff & ~(0x03 << (INT_IN_PIN * 2))) | 0x0000aa00;
443 }
444 
blCleanup()445 void blCleanup()
446 {
447     //reset units & return APB2 & AHB1 to initial state
448     RCC->APB2RSTR |= PERIPH_APB2_SPI1;
449     RCC->AHB1RSTR |= PERIPH_AHB1_GPIOA;
450     RCC->APB2RSTR &=~ PERIPH_APB2_SPI1;
451     RCC->AHB1RSTR &=~ PERIPH_AHB1_GPIOA;
452     RCC->APB2ENR = mOldApb2State;
453     RCC->AHB1ENR = mOldAhb1State;
454 }
455 
blHostActive()456 bool blHostActive()
457 {
458     return !(GPIOA->IDR & (1 << INT_IN_PIN));
459 }
460 
blConfigIo()461 void blConfigIo()
462 {
463     //config SPI
464     SPI->CR1 = 0x00000040; //spi is on, configured same as bootloader would
465     SPI->CR2 = 0x00000000; //spi is on, configured same as bootloader would
466 }
467 
blSyncWait(uint32_t syncCode)468 bool blSyncWait(uint32_t syncCode)
469 {
470     uint32_t nRetries;
471     //wait for sync
472     for (nRetries = 10000; nRetries; nRetries--) {
473         if (SPI->SR & 1) {
474             if (SPI->DR == syncCode)
475                 break;
476             (void)SPI->SR; //re-read to clear overlfow condition (if any)
477         }
478     }
479     return nRetries > 0;
480 }
481 
__blEntry(void)482 static void __blEntry(void)
483 {
484     extern char __code_start[], __bss_end[], __bss_start[], __data_end[], __data_start[], __data_data[];
485     uint32_t appBase = ((uint32_t)&__code_start) & ~1;
486 
487     //make sure we're the vector table and no ints happen (BL does not use them)
488     blDisableInts();
489     SCB->VTOR = (uint32_t)&BL;
490 
491     //init things a little for the higher levels
492     memset(__bss_start, 0, __bss_end - __bss_start);
493     memcpy(__data_start, __data_data, __data_end - __data_start);
494 
495     blMain(appBase);
496 
497     //call OS with ints off
498     blDisableInts();
499     SCB->VTOR = appBase;
500     asm volatile(
501         "LDR SP, [%0, #0]    \n"
502         "LDR PC, [%0, #4]    \n"
503         :
504         :"r"(appBase)
505         :"memory", "cc"
506     );
507 
508     //we should never return here
509     while(1);
510 }
511 
blSpuriousIntHandler(void)512 static void blSpuriousIntHandler(void)
513 {
514     //BAD!
515     blReboot();
516 }
517 
518 extern uint8_t __stack_top[];
519 uint64_t __attribute__ ((section (".stack"))) _STACK[BL_STACK_SIZE / sizeof(uint64_t)];
520 
521 const struct BlVecTable __attribute__((section(".blvec"))) __BL_VEC =
522 {
523     .blStackTop             = (uint32_t)&__stack_top,
524     .blEntry                = &__blEntry,
525     .blNmiHandler           = &blSpuriousIntHandler,
526     .blMmuFaultHandler      = &blSpuriousIntHandler,
527     .blBusFaultHandler      = &blSpuriousIntHandler,
528     .blUsageFaultHandler    = &blSpuriousIntHandler,
529 };
530