FreeCalypso > hg > freecalypso-reveng
comparison frbl/reconst/boot.c @ 315:bc3391aa3d35
frbl/reconst/boot.c: import from TI's FLUID package
with defenestrated line endings
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Wed, 04 Mar 2020 23:17:27 +0000 |
parents | |
children | 2ceb1f263e19 |
comparison
equal
deleted
inserted
replaced
314:147b8c609300 | 315:bc3391aa3d35 |
---|---|
1 /****************************************************************************** | |
2 * FLUID (Flash Loader Utility Independent of Device) | |
3 * | |
4 * (C) Delta Technologies 2001. | |
5 * Cleanup, modifications and extensions by Mads Meisner-Jensen, mmj@ti.com. | |
6 * | |
7 * Target Bootloader | |
8 * | |
9 * $Id: boot.c 1.18 Mon, 28 Apr 2003 08:49:16 +0200 tsj $ | |
10 * | |
11 ******************************************************************************/ | |
12 | |
13 #include "chipset.cfg" | |
14 #include "target.h" | |
15 | |
16 | |
17 #define DEBUG_TRACE 0 | |
18 | |
19 | |
20 // Protocol version of this bootloader | |
21 | |
22 // Version 0: Original, unmodified Delta Technology Bootloader. | |
23 | |
24 // Version 1: First Fluid Bootloader. 'B'audrate command and 'V'ersion | |
25 // command. Backward compatibly with version 0. | |
26 | |
27 // Version 2: 'H'ardware chipset query command. Debug/Trace | |
28 // functionality. Backward compatibly with version 0, 1. Fixed bug where | |
29 // IND$CALL was used to start command interpreter instead of private jump() | |
30 // function | |
31 | |
32 // Version 3: Generic 'Q'uery command. Discontinued 'H'ardware query command | |
33 // from version 2. | |
34 | |
35 #define BOOTLOADER_VERSION '3' | |
36 | |
37 | |
38 /****************************************************************************** | |
39 * Bootstrap/Init | |
40 ******************************************************************************/ | |
41 | |
42 // Initialize stackpointer according to chipset. Note that we ALWAYS do | |
43 // this, no matter if we were laoded with JTAG or if we were compiled-in. | |
44 | |
45 #if (CHIPSET == 3) | |
46 asm("STACK_INIT .equ 03000000h"); | |
47 asm("STACK_ADD .equ 00020000h ; 128kB"); | |
48 #elif (CHIPSET == 7) | |
49 asm("STACK_INIT .equ 00800000h"); | |
50 asm("STACK_ADD .equ 00020000h ; 128kB"); | |
51 #elif (CHIPSET == 12) | |
52 asm("STACK_INIT .equ 08000000h"); | |
53 asm("STACK_ADD .equ 00020000h ; 128kB"); | |
54 #else | |
55 #error Unknown target hardware selected | |
56 #endif | |
57 | |
58 #ifdef FLUID_BOOT_STAND_ALONE | |
59 asm(" .def _c_int00 "); | |
60 asm("_c_int00:"); | |
61 #endif | |
62 | |
63 asm(" .state32 "); | |
64 asm(" mov sp,#STACK_INIT"); | |
65 asm(" add sp,sp,#STACK_ADD"); | |
66 asm(" adr lr,start_end + 1 ; module end address with lsb set"); | |
67 asm(" bx lr ; branch to start"); | |
68 asm(" nop"); | |
69 asm("start_end:"); | |
70 | |
71 | |
72 | |
73 /****************************************************************************** | |
74 * Main | |
75 ******************************************************************************/ | |
76 | |
77 uint32 uart; | |
78 | |
79 void jump(uint32, uint32); | |
80 | |
81 void putchar(uint8 ch); | |
82 uint8 getchar(void); | |
83 void uart_init(UBYTE dlh, UBYTE dll); | |
84 void hardware_init(uint16 *code); | |
85 | |
86 void fluid_bootloader(void) | |
87 { | |
88 uint8 ch; | |
89 uint16 *mem; | |
90 union32_t addr; | |
91 union16_t size; | |
92 union16_t data; | |
93 uint8 uart_dlh, uart_dll; | |
94 uint16 chip_id_code; | |
95 | |
96 hardware_init(&chip_id_code); | |
97 | |
98 uart = UART_MODEM; | |
99 uart_init(0, 0x07); // baudrate = 115200kbps | |
100 uart = UART_IRDA; | |
101 uart_init(0, 0x07); // baudrate = 115200kbps | |
102 | |
103 #ifdef TESTBOOT | |
104 while (1) { | |
105 uart = UART_MODEM; | |
106 if ((REGISTER_8_READ(uart + UART_LSR) & STAT_RXRDY)) | |
107 break; | |
108 uart = UART_IRDA; | |
109 if ((REGISTER_8_READ(uart + UART_LSR) & STAT_RXRDY)) | |
110 break; | |
111 } | |
112 while (getchar() != 0xAA) | |
113 ; | |
114 while (getchar() != 0x01) | |
115 ; | |
116 while (getchar() != 0xDD) | |
117 ; | |
118 #endif | |
119 | |
120 while (1) { | |
121 uart = UART_MODEM; | |
122 putchar(PROTO_HELLO); | |
123 if ((REGISTER_8_READ(uart + UART_LSR) & STAT_RXRDY)) | |
124 break; | |
125 uart = UART_IRDA; | |
126 putchar(PROTO_HELLO); | |
127 if ((REGISTER_8_READ(uart + UART_LSR) & STAT_RXRDY)) | |
128 break; | |
129 } | |
130 while (1) { | |
131 ch = getchar(); | |
132 switch (ch) { | |
133 case PROTO_VERSION: | |
134 putchar(BOOTLOADER_VERSION); | |
135 break; | |
136 case PROTO_QUERY: | |
137 ch = getchar(); | |
138 if (ch == PROTO_QUERY_CHIP) { | |
139 data.i = chip_id_code; | |
140 putchar(data.b[0]); | |
141 putchar(data.b[1]); | |
142 putchar(0); | |
143 putchar(0); | |
144 } | |
145 else { | |
146 putchar(PROTO_ERROR); | |
147 } | |
148 break; | |
149 case PROTO_BAUDRATE: | |
150 ch = getchar(); // Get DLH | |
151 case 0: | |
152 uart_init(ch, getchar()); | |
153 break; | |
154 case PROTO_DOWNLOAD: | |
155 addr.b[0] = getchar(); | |
156 addr.b[1] = getchar(); | |
157 addr.b[2] = getchar(); | |
158 addr.b[3] = getchar(); | |
159 size.b[0] = getchar(); | |
160 size.b[1] = getchar(); | |
161 putchar(PROTO_READY); | |
162 mem = (uint16 *) addr.i; | |
163 while (size.i--) { | |
164 // Data bytes arrive in reverse order due to little endian mode | |
165 data.b[1] = getchar(); | |
166 data.b[0] = getchar(); | |
167 *mem++ = data.i; | |
168 } | |
169 | |
170 #if DEBUG_TRACE | |
171 // Insert convenient tracing here... | |
172 #endif | |
173 // Start the program we loaded. | |
174 jump(uart, addr.i); | |
175 break; | |
176 default: | |
177 putchar(PROTO_ERROR); | |
178 } | |
179 } | |
180 } | |
181 | |
182 // Little assembly function that makes a jump to the address/argument, | |
183 // similar to the compiler's IND$CALL. We do not use the compiler's IND$CALL | |
184 // because when we compile for non-standalone, IND$CALL is already | |
185 // defined. We expect that the base address of the UART is in R0, so it can | |
186 // be properly passed on to the command interpreter. | |
187 asm("$jump:"); | |
188 asm(" bx r1"); | |
189 | |
190 void putchar(uint8 ch) | |
191 { | |
192 PUTCHAR_FUNCTION_CODE(uart) | |
193 } | |
194 | |
195 uint8 getchar(void) | |
196 { | |
197 GETCHAR_FUNCTION_CODE(uart) | |
198 } | |
199 | |
200 | |
201 /****************************************************************************** | |
202 * Initialization | |
203 ******************************************************************************/ | |
204 #if (CHIPSET == 3) | |
205 #define IQ_MASK (0xFFFFFA02) /* Mask Interrupt Register */ | |
206 #elif (CHIPSET == 7) || (CHIPSET == 12) | |
207 #define IQ_MASK1 (0xFFFFFA08) /* Mask Interrupt Register 1 */ | |
208 #define IQ_MASK2 (0xFFFFFA0A) /* Mask Interrupt Register 2 */ | |
209 #else | |
210 #error Unknown target hardware selected | |
211 #endif | |
212 | |
213 | |
214 void hardware_init(uint16 *chip_id_code) | |
215 { | |
216 uint16 clk; | |
217 char chip_set = 0; | |
218 | |
219 // We read the chipset version directly from the hardware because | |
220 // otherwise the stand-alone bootloader (to be downloaded with JTAG) is | |
221 // obviously not target independent! | |
222 *chip_id_code = *((volatile uint16 *) CHIP_ID_CODE); | |
223 | |
224 | |
225 // We should only intialize the hardware if we were downloaded with JTAG | |
226 | |
227 #ifdef FLUID_BOOT_STAND_ALONE | |
228 | |
229 // FIXME: we should perhaps have different init depending on chipset | |
230 // detected? | |
231 | |
232 // Mask all interrupts | |
233 #if (CHIPSET == 3) | |
234 *((volatile uint16 *) IQ_MASK) = 0xFFFF; | |
235 #elif (CHIPSET == 7) | |
236 *((volatile uint16 *) IQ_MASK1) = 0xFFFF; | |
237 *((volatile uint16 *) IQ_MASK2) = 0x001F; | |
238 #elif (CHIPSET == 12) | |
239 *((volatile uint16 *) IQ_MASK1) = 0xFFFF; | |
240 *((volatile uint16 *) IQ_MASK2) = 0xFFFF; //BJO Check IRQ_29_MSK - should it be 0 ? | |
241 #endif | |
242 | |
243 // Disable watchdog timer | |
244 *((volatile uint16 *) WATCHDOG_TIM_MODE) = 0xF5; | |
245 *((volatile uint16 *) WATCHDOG_TIM_MODE) = 0xA0; | |
246 #if (CHIPSET == 12) //BJO Check this (documented?) | |
247 *((volatile uint16 *) WATCHDOG_TIM_MODE+80) = 0xF5; // Secure watchdog CALPLUS | |
248 *((volatile uint16 *) WATCHDOG_TIM_MODE+80) = 0xA0; // Secure watchdog CALPLUS | |
249 #endif | |
250 | |
251 | |
252 #if (CHIPSET == 3) || (CHIPSET == 7) | |
253 // FIXME: Describe exactly how the CSs are initialized | |
254 *((volatile uint16 *) CS0_MEM_REG) = 0x2A1; | |
255 *((volatile uint16 *) CS1_MEM_REG) = 0x2A1; | |
256 *((volatile uint16 *) CS2_MEM_REG) = 0x2A1; | |
257 *((volatile uint16 *) CS3_MEM_REG) = 0x283; | |
258 *((volatile uint16 *) CS4_MEM_REG) = 0x283; | |
259 *((volatile uint16 *) CS6_MEM_REG) = 0x2C0; | |
260 #elif (CHIPSET == 12) | |
261 *((volatile uint16 *) CS0_MEM_REG) = 0x2A3; //*BJO Check these settings | |
262 *((volatile uint16 *) CS1_MEM_REG) = 0x2A3; | |
263 *((volatile uint16 *) CS2_MEM_REG) = 0x2A3; | |
264 *((volatile uint16 *) CS3_MEM_REG) = 0x2A3; | |
265 *((volatile uint16 *) CS4_MEM_REG) = 0x2A3; | |
266 *((volatile uint16 *) CS5_MEM_REG) = 0x2A3; | |
267 #endif | |
268 | |
269 | |
270 #if (CHIPSET == 3) | |
271 clk = *(volatile uint16 *) CLKM_CNTL_ARM_CLK; | |
272 clk &= ~(0x0C | 0x30); | |
273 clk |= (2 << 4); | |
274 *(volatile uint16 *) CLKM_CNTL_ARM_CLK = clk; | |
275 | |
276 #elif (CHIPSET == 7) | |
277 | |
278 // Reset DPLL register | |
279 * (volatile uint16 *) MEM_DPLL_ADDR = DPLL_RESET_VALUE; | |
280 | |
281 // Wait that DPLL is in BYPASS mode | |
282 while (((* (volatile uint16 *) MEM_DPLL_ADDR) & 1) != 1) | |
283 ; | |
284 | |
285 // Reset CLKM register | |
286 *(volatile uint16 *) MEM_CLKM_ADDR = CLKM_CNTL_ARM_CLK_RST; | |
287 | |
288 #elif (CHIPSET == 12) | |
289 | |
290 *((volatile uint8*)CTNL_CLK) = 0x91; // Make sure we are set to 26MHz mode (div 2) // CALPLUS | |
291 *((volatile uint16 *) MEM_DPLL_ADDR) = 0x6012 | (8<<7) | (1<<5); // multiplyer=8, divider=2 (-1) 52MHz!!! // CALPLUS | |
292 // Wait that DPLL is locked | |
293 while (((* (volatile unsigned short *) MEM_DPLL_ADDR) & 1) != 1) ; // CALPLUS | |
294 | |
295 #endif | |
296 | |
297 | |
298 #endif // ifdef FLUID_BOOT_STAND_ALONE | |
299 } | |
300 | |
301 void uart_init(uint8 my_dlh, uint8 my_dll) | |
302 { | |
303 uint8 ch; | |
304 | |
305 /* | |
306 * Transition from the DSP Rhea bus to the MCU Rhea bus. | |
307 */ | |
308 BIT_SET (UART_UIR, UART_MASK_IT); | |
309 BIT_CLR (UART_UIR, UART_ACCESS); | |
310 BIT_CLR (UART_UIR, UART_MASK_IT); | |
311 | |
312 /* | |
313 * Set the UART in reset mode. | |
314 */ | |
315 REGISTER_8_WRITE(uart + UART_MDR1, CMD_UART_RESET); | |
316 | |
317 /* | |
318 * FIFO configuration | |
319 */ | |
320 REGISTER_8_WRITE(uart + UART_LCR, CMD_EFR_EN); | |
321 BIT_SET (uart + UART_EFR, ENHANCED_EN); | |
322 REGISTER_8_WRITE(uart + UART_LCR, CMD_FCR_MCR_EN); | |
323 REGISTER_8_WRITE(uart + UART_FCR, CMD_FIFO_EN); | |
324 | |
325 /* | |
326 * Speed configuration | |
327 */ | |
328 REGISTER_8_WRITE(uart + UART_LCR, CMD_EFR_EN); | |
329 REGISTER_8_WRITE(uart + UART_DLL, my_dll); | |
330 REGISTER_8_WRITE(uart + UART_DLH, my_dlh); | |
331 | |
332 /* | |
333 * Character format configuration | |
334 */ | |
335 REGISTER_8_WRITE(uart + UART_LCR, CMD_CHAR8_STOP1_NOPAR); | |
336 | |
337 /* | |
338 * Modem configuration | |
339 */ | |
340 REGISTER_8_WRITE(uart + UART_MDR1, CMD_UART_MODE); | |
341 | |
342 /* | |
343 * Flush Rx buffer | |
344 */ | |
345 while ((REGISTER_8_READ(uart + UART_LSR) & STAT_RXRDY)) | |
346 ch = (REGISTER_8_READ(uart + UART_RHR)); | |
347 } | |
348 | |
349 | |
350 /****************************************************************************** | |
351 * Debug | |
352 ******************************************************************************/ | |
353 | |
354 #if (DEBUG_TRACE == 1) | |
355 #include "debug.c" | |
356 #endif | |
357 |