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