1 /******************************************************************************
2 * FILE PURPOSE: Boot TaBLe (btbl) processing file
3 ******************************************************************************
4 * FILE NAME: btblpr.c
5 *
6 * DESCRIPTION: This file contains the main boot table processing state machine.
7 *
8 * For reference here is the Boot table format:
9 *
10 * (32-bit) Entry point byte address : Code Execution start address
11 * (32-bit) Number of I/O Registers, delay and etc.
12 * (32-bit) 1st Word for I/O Register configuration(optional)
13 * ...
14 * (32-bit) Nth Word for I/O Register configuration(optional)
15 * (32-bit) Words for added delay in CPU cycles (optional)
16 * (32-bit) Words for Core Start Vector (optional)
17 * (32-bit) 1st code section byte count
18 * (32-bit) 1st code section starting address in bytes
19 * 1st section code byte
20 * ...
21 * (32-bit) Nth code section byte count
22 * (32-bit) Nth code section starting address in bytes
23 * Nth section code byte
24 * ...
25 * Last word of Nth section code type
26 * (32-bit) Zero byte count
27 *
28 * Note1: Core start vector and added delay are special format of I/O Registers
29 * 0xFFFF: NOP execution
30 * 0xFFFE: core start vector
31 *
32 * Note2: There will be a padded byte added if the code section contains odd
33 * number of bytes
34 *
35 * FUNCTION DESCRIPTION
36 * -------- -----------
37 *
38 * btblpr.c:
39 * boot_init_boot_tbl_inst() Initialize the boot table control instance
40 * boot_proc_boot_tbl() Boot Table main processing routine
41 * boot_proc_boot_tbl_xxx() Boot Table procssing routine in xxx state
42 *
43 * (C) Copyright 2004, TELOGY Networks, Inc.
44 *****************************************************************************/
45 /* types.h must be included before stdlib.h for splint to work */
46 #include "types.h"
48 /* Ansi header files */
49 #include <stdlib.h>
50 #include <string.h> /* For memset() */
52 #include "btblwrap.h"
54 #if 0
56 /* System utility files */
57 #include "tiboot.h"
59 /* Main level */
60 #include "rmain.h"
62 /* Device utilities */
63 #include "device.h"
65 #endif
67 /* Module specific file */
68 #include "btbl.h"
69 #include "btblloc.h"
71 /* Build specific Configuration */
72 #include "iblcfg.h"
74 /*******************************************************************************
75 * Private prototypes
76 ******************************************************************************/
77 /* boot table processing state machine functions */
78 void boot_proc_boot_tbl_init(BOOT_TBL_CB_T* p_inst);
79 void boot_proc_boot_tbl_io_cnt(BOOT_TBL_CB_T* p_inst);
80 void boot_proc_boot_tbl_io_regs(BOOT_TBL_CB_T* p_inst);
81 void boot_proc_boot_tbl_size(BOOT_TBL_CB_T* p_inst);
82 void boot_proc_boot_tbl_addr(BOOT_TBL_CB_T* p_inst);
83 void boot_proc_boot_tbl_data(BOOT_TBL_CB_T* p_inst);
84 void boot_proc_boot_tbl_flush(BOOT_TBL_CB_T* p_inst);
85 void boot_proc_boot_tbl_pad(BOOT_TBL_CB_T* p_inst);
87 /*******************************************************************************
88 * Local variables
89 ******************************************************************************/
90 BOOT_TBL_CB_T btbl_inst; /* Boot table Control Instance */
92 /*******************************************************************************
93 * DATA DEFINITION: Boot Table Processing State Machine
94 ******************************************************************************/
95 BootTblProcFcn_t btbl_st_proc_fcn[BOOT_TBL_NUM_STATES];
97 /*******************************************************************************
98 * FUNCTION PURPOSE: Process the boot table in Init State
99 *******************************************************************************
100 * DESCRIPTION: Process the boot table in Init State
101 * Record the entry point
102 *
103 * void boot_proc_boot_tbl_init (
104 * BOOT_TBL_CB_T *p_inst) - A pointer to Boot Table Control instance
105 *
106 *****************************************************************************/
107 void boot_proc_boot_tbl_init(BOOT_TBL_CB_T* p_inst)
108 {
109 if(p_inst->f_wait_lsw)
110 {
111 /* Process the entry point LSW */
112 p_inst->code_start_addr += (*p_inst->p_data & 0xFFFF);
115 /* C55x boot tables contain an I/O space config. C6x boot tables
116 * do not */
117 #ifdef BOOTCONFIG_NO_BTBL_IO
118 p_inst->state = BOOT_TBL_STATE_SIZE;
119 #else
120 p_inst->state = BOOT_TBL_STATE_IO_CNT;
121 #endif
124 p_inst->f_wait_lsw = FALSE;
125 }
126 else
127 {
128 /* Process the entry point MSW */
129 p_inst->code_start_addr = ((UINT32)(*p_inst->p_data & 0xFFFF)) << 16;
130 p_inst->f_wait_lsw = (bool)TRUE;
131 }
133 /* Update data buffer and counter */
134 p_inst->p_data++;
135 p_inst->data_size_uint16--;
136 }
138 /*******************************************************************************
139 * FUNCTION PURPOSE: Process the boot table in IO_CNT State
140 *******************************************************************************
141 * DESCRIPTION: Process the boot table in IO_CNT State
142 * Record the number of IO Registers
143 *
144 * void boot_proc_boot_tbl_io_cnt (
145 * BOOT_TBL_CB_T *p_inst) - A pointer to Boot Table Control instance
146 *
147 *****************************************************************************/
148 #ifndef BOOTCONFIG_NO_BTBL_IO
149 void boot_proc_boot_tbl_io_cnt(BOOT_TBL_CB_T* p_inst)
150 {
151 if(p_inst->f_wait_lsw)
152 {
153 /* LSW processing */
154 p_inst->num_io_regs += (*p_inst->p_data & 0xFFFF);
155 p_inst->f_wait_lsw = FALSE;
156 if(p_inst->num_io_regs)
157 {
158 p_inst->state = BOOT_TBL_STATE_IO_REGS;
159 }
160 else
161 {
162 p_inst->state = BOOT_TBL_STATE_SIZE;
163 }
165 }
166 else
167 {
168 /* MSW processing */
169 p_inst->num_io_regs = ((UINT32)(*p_inst->p_data & 0xFFFF)) << 16;
170 p_inst->f_wait_lsw = TRUE;
171 }
173 /* Update data buffer and counter */
174 p_inst->p_data++;
175 p_inst->data_size_uint16--;
176 }
177 #endif
179 /*******************************************************************************
180 * FUNCTION PURPOSE: Process the boot table in IO_REGS State
181 *******************************************************************************
182 * DESCRIPTION: Process the boot table in IO_REG State
183 * Process IO Register configuration
184 *
185 * void boot_proc_boot_tbl_io_regs (
186 * BOOT_TBL_CB_T *p_inst) - A pointer to Boot Table Control instance
187 *
188 *****************************************************************************/
189 #ifndef BOOTCONFIG_NO_BTBL_IO
190 void boot_proc_boot_tbl_io_regs(BOOT_TBL_CB_T* p_inst)
191 {
192 UINT16 data;
194 if(p_inst->f_wait_lsw)
195 {
196 /* LSW processing */
197 data = *p_inst->p_data;
199 /* proess the IO register configuration based on its address (opcode) */
200 switch(p_inst->io_addr)
201 {
202 case BOOT_TBL_IO_CFG_DELAY:
203 /* perform the delay loop requested */
204 chipDelay(data);
205 break;
207 case BOOT_TBL_IO_CFG_START_CORE:
208 /* Verify whether the start_vector is valid */
209 if(data >= (BOOT_BIT_TO_MASK(chipReadNumCores())))
210 {
211 BOOT_EXCEPTION(BOOT_ERROR_CODE(BOOT_MODULE_ID_BTBL,
212 BTBL_ERR_INVALID_START_VECTOR));
213 }
214 /* record the core start vector */
215 p_inst->core_start_vector = data;
216 break;
218 default:
219 /* IO Configuration */
220 chipIoWrite(p_inst->io_addr, data);
221 break;
223 }
224 p_inst->f_wait_lsw = FALSE;
226 /* Is it the last IO Register to be configured */
227 if((--p_inst->num_io_regs) == 0)
228 {
229 p_inst->state = BOOT_TBL_STATE_SIZE;
230 }
231 }
232 else
233 {
234 /* MSW processing */
235 p_inst->io_addr = *p_inst->p_data;
236 p_inst->f_wait_lsw = TRUE;
237 }
239 /* Update data buffer and counter */
240 p_inst->p_data++;
241 p_inst->data_size_uint16--;
242 }
243 #endif
245 /*******************************************************************************
246 * FUNCTION PURPOSE: Process the boot table in SIZE State
247 *******************************************************************************
248 * DESCRIPTION: Process the boot table in SIZE State
249 * Record the size of the new code section
250 * perform end of table processing if size = 0
251 *
252 * void boot_proc_boot_tbl_size (
253 * BOOT_TBL_CB_T *p_inst) - A pointer to Boot Table Control instance
254 *
255 *****************************************************************************/
256 void boot_proc_boot_tbl_size(BOOT_TBL_CB_T* p_inst)
257 {
258 if(p_inst->f_wait_lsw)
259 {
260 /* LSW processing */
261 p_inst->section_size_bytes += (*p_inst->p_data & 0xFFFF);
263 /* Is it the end of the boot table */
264 if(p_inst->section_size_bytes == 0)
265 {
266 chipStartCore(p_inst->code_start_addr,
267 (UINT32)p_boot_entry_addr,
268 p_inst->core_start_vector);
270 /* End of Boot table:Clear the instance */
271 p_inst->state = BOOT_TBL_STATE_FLUSH;
272 p_inst->f_wait_lsw = FALSE;
273 return;
274 }
276 p_inst->state = BOOT_TBL_STATE_ADDR;
277 p_inst->f_wait_lsw = FALSE;
279 /* Update statistics */
280 bootStats.btbl.num_sections++;
281 }
282 else
283 {
284 /* MSW processing */
285 p_inst->section_size_bytes = ((UINT32)(*p_inst->p_data & 0xFFFF)) << 16;
286 p_inst->f_wait_lsw = (bool)TRUE;
287 }
289 /* Update data buffer and counter */
290 p_inst->p_data++;
291 p_inst->data_size_uint16--;
292 }
294 /*******************************************************************************
295 * FUNCTION PURPOSE: Process the boot table in ADDR State
296 *******************************************************************************
297 * DESCRIPTION: Process the boot table in ADDR State
298 * Record the start address of the new code section
299 *
300 * void boot_proc_boot_tbl_addr (
301 * BOOT_TBL_CB_T *p_inst) - A pointer to Boot Table Control instance
302 *
303 *****************************************************************************/
304 void boot_proc_boot_tbl_addr(BOOT_TBL_CB_T* p_inst)
305 {
306 if(p_inst->f_wait_lsw)
307 {
308 /* LSW processing */
309 p_inst->section_addr += (*p_inst->p_data & 0xFFFF);
310 p_inst->state = BOOT_TBL_STATE_DATA;
311 p_inst->f_wait_lsw = FALSE;
312 }
313 else
314 {
315 /* MSW processing */
316 p_inst->section_addr = ((UINT32)(*p_inst->p_data & 0xFFFF)) << 16;
317 p_inst->f_wait_lsw = (bool)TRUE;
318 }
320 /* Update data buffer and counter */
321 p_inst->p_data++;
322 p_inst->data_size_uint16--;
323 }
325 /*******************************************************************************
326 * FUNCTION PURPOSE: Process the boot table in the PAD state
327 *******************************************************************************
328 * DESCRIPTION: Toss data bytes to advance to the next section
329 *******************************************************************************/
330 #define MIN(a,b) (a)<(b) ? (a) : (b)
331 void boot_proc_boot_tbl_pad(BOOT_TBL_CB_T* p_inst)
332 {
333 UINT32 num_bytes;
334 UINT32 num_uint16_words;
336 num_bytes = MIN (p_inst->section_size_bytes, CHIP_UINT16_TO_BYTES(p_inst->data_size_uint16));
337 num_uint16_words = CHIP_BYTES_TO_UINT16(num_bytes);
339 /* Update instance variables for the next code section */
340 p_inst->data_size_uint16 -= num_uint16_words;
341 p_inst->p_data += num_uint16_words;
343 p_inst->section_addr += num_bytes;
344 p_inst->section_size_bytes -= num_bytes;
346 if(p_inst->section_size_bytes == 0)
347 {
348 p_inst->state = BOOT_TBL_STATE_SIZE;
350 /* Chip specific post block handling. Can be defined to an empty statement */
351 chipBtblBlockDone();
352 }
353 }
357 /*******************************************************************************
358 * FUNCTION PURPOSE: Process the boot table in DATA State
359 *******************************************************************************
360 * DESCRIPTION: Process the boot table in DATA State
361 * Copy the received section data to the destination memory
362 * locations
363 *
364 * void boot_proc_boot_tbl_data (
365 * BOOT_TBL_CB_T *p_inst) - A pointer to Boot Table Control instance
366 *
367 *****************************************************************************/
368 void boot_proc_boot_tbl_data(BOOT_TBL_CB_T* p_inst)
369 {
370 UINT32 num_bytes; /* number of bytes to be copy */
371 UINT32 num_uint16_words; /* number of 16 bit words to copy */
372 UINT32 num_uint16_words_pad; /* number of 16 bit words, rounded up to a multiple of 4 bytes */
373 UINT32 pad_uint16; /* The amount of pad present */
374 UINT16 error;
376 num_bytes = MIN (p_inst->section_size_bytes, CHIP_UINT16_TO_BYTES(p_inst->data_size_uint16));
377 num_uint16_words = CHIP_BYTES_TO_UINT16(num_bytes);
379 /* Some processors add padding to the memwidth used in the rom (created by tools) */
380 num_uint16_words_pad = chipAddBtblUint16Pad (num_uint16_words);
381 pad_uint16 = num_uint16_words_pad - num_uint16_words;
383 /*
384 * Record the last UINT16 word and copy the data to the destination
385 * locations
386 */
388 if((error = coreCopyData(p_inst->section_addr, p_inst->p_data, num_bytes,
389 p_inst->core_start_vector))
390 != CORE_NOERR)
391 {
392 /* Error Processing */
393 BOOT_EXCEPTION(BOOT_ERROR_CODE(BOOT_MODULE_ID_CHIP,
394 error));
395 }
397 /* Update instance variables for the next code section */
398 p_inst->data_size_uint16 -= num_uint16_words;
399 p_inst->p_data += num_uint16_words;
401 p_inst->section_addr += num_bytes;
402 p_inst->section_size_bytes -= num_bytes;
404 if(p_inst->section_size_bytes == 0)
405 {
407 if (pad_uint16)
408 {
409 p_inst->state = BOOT_TBL_STATE_PAD;
410 p_inst->section_size_bytes = CHIP_UINT16_TO_BYTES(pad_uint16);
411 }
412 else
413 {
414 p_inst->state = BOOT_TBL_STATE_SIZE;
416 /* Chip specific post block handling. Can be defined to an empty statement */
417 chipBtblBlockDone();
418 }
419 }
421 /* update statistics */
422 bootStats.btbl.num_pdma_copies++;
423 }
425 /*******************************************************************************
426 * FUNCTION PURPOSE: Process the boot table in Flush State
427 *******************************************************************************
428 * DESCRIPTION: Process the boot table in Flush State
429 * We will enter this state when the end of table or error
430 * condition occurs
431 * set data_size to 0, i.e. ignore the reamining data
432 *
433 * void boot_proc_boot_tbl_error (
434 * BOOT_TBL_CB_T *p_inst) - A pointer to Boot Table Control instance
435 *
436 *****************************************************************************/
437 void boot_proc_boot_tbl_flush(BOOT_TBL_CB_T* p_inst)
438 {
439 p_inst->data_size_uint16 = 0;
440 }
442 /* ------------------- PUBLIC FUNCTIONS START HERE ----------------------- */
443 /*******************************************************************************
444 * FUNCTION PURPOSE: Initialize the boot table control instance
445 *******************************************************************************
446 * DESCRIPTION: Initialize and allocate the boot table control instance
447 * Initialize all the variables to zero
448 * Set the state to Init
449 *
450 * void boot_init_boot_tbl_inst ( void )
451 *
452 * Note: only one instance is used at this moment
453 * a free instance function will be needed when multiple instances are
454 * supported
455 *
456 *****************************************************************************/
457 void boot_init_boot_tbl_inst(BOOT_TBL_CB_T *p_btbl_inst)
458 {
459 btblMemset(p_btbl_inst, 0, sizeof(BOOT_TBL_CB_T));
460 p_btbl_inst->state = BOOT_TBL_STATE_INIT;
462 /*
463 * Set the core start vector to start core A only as its default value
464 * in case the boot table does not contain the setting of the core
465 * start vector.
466 */
467 p_btbl_inst->core_start_vector = 1;
470 /* Initialize the toot table processing function table */
471 btbl_st_proc_fcn[BOOT_TBL_STATE_INIT] = boot_proc_boot_tbl_init;
473 #ifndef BOOTCONFIG_NO_BTBL_IO
474 btbl_st_proc_fcn[BOOT_TBL_STATE_IO_CNT] = boot_proc_boot_tbl_io_cnt;
475 btbl_st_proc_fcn[BOOT_TBL_STATE_IO_REGS] = boot_proc_boot_tbl_io_regs;
476 #endif
478 btbl_st_proc_fcn[BOOT_TBL_STATE_SIZE] = boot_proc_boot_tbl_size;
479 btbl_st_proc_fcn[BOOT_TBL_STATE_ADDR] = boot_proc_boot_tbl_addr;
480 btbl_st_proc_fcn[BOOT_TBL_STATE_DATA] = boot_proc_boot_tbl_data;
481 btbl_st_proc_fcn[BOOT_TBL_STATE_PAD] = boot_proc_boot_tbl_pad;
482 btbl_st_proc_fcn[BOOT_TBL_STATE_FLUSH] = boot_proc_boot_tbl_flush;
484 } /* end of boot_init_boot_tbl_inst() */
486 /*******************************************************************************
487 * FUNCTION PURPOSE: Process the boot table
488 *******************************************************************************
489 * DESCRIPTION: Process the whole or partial boot table received by going
490 * through the boot table processing state machine until all
491 * the UINT16 words are processed or the end of table condition
492 * (section size == 0) is satisfied.
493 *
494 * void boot_proc_boot_tbl (
495 * UINT16 *p_data, - 16-bit boot table content to be processed
496 * UINT16 size) - number of 16-bit words
497 *
498 *
499 * Note: It is up to the caller to reserve 4 16-bit word space in front of the
500 * input buffer since the data may be moved to achieve 32-bit alignment
501 * requirement for PDMA transfer
502 *****************************************************************************/
503 void boot_proc_boot_tbl(BOOT_TBL_CB_T *p_btbl_inst, UINT16* p_data, UINT32 size)
504 {
506 /* Record the input data buffer and size */
507 p_btbl_inst->p_data = p_data;
508 p_btbl_inst->data_size_uint16 = size;
510 /* Optional: verify the inst state is valid */
511 if(p_btbl_inst->state > BOOT_TBL_LAST_STATE)
512 {
513 /* Error Processing */
514 BOOT_EXCEPTION(BOOT_ERROR_CODE(BOOT_MODULE_ID_BTBL,
515 BTBL_ERR_INVALID_STATE));
517 }
519 /*
520 * Invoke the Boot table processing state machine until all the input
521 * data are processed or the end of table condition is satified
522 */
523 while (p_btbl_inst->data_size_uint16 != 0)
524 {
525 btbl_st_proc_fcn[p_btbl_inst->state](p_btbl_inst);
526 }
528 } /* end of boot_proc_boot_tbl() */