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);
86 /*******************************************************************************
87 * Local variables
88 ******************************************************************************/
89 BOOT_TBL_CB_T btbl_inst; /* Boot table Control Instance */
91 /*******************************************************************************
92 * DATA DEFINITION: Boot Table Processing State Machine
93 ******************************************************************************/
94 BootTblProcFcn_t btbl_st_proc_fcn[BOOT_TBL_NUM_STATES];
96 /*******************************************************************************
97 * FUNCTION PURPOSE: Process the boot table in Init State
98 *******************************************************************************
99 * DESCRIPTION: Process the boot table in Init State
100 * Record the entry point
101 *
102 * void boot_proc_boot_tbl_init (
103 * BOOT_TBL_CB_T *p_inst) - A pointer to Boot Table Control instance
104 *
105 *****************************************************************************/
106 void boot_proc_boot_tbl_init(BOOT_TBL_CB_T* p_inst)
107 {
108 if(p_inst->f_wait_lsw)
109 {
110 /* Process the entry point LSW */
111 p_inst->code_start_addr += (*p_inst->p_data & 0xFFFF);
114 /* C55x boot tables contain an I/O space config. C6x boot tables
115 * do not */
116 #ifdef BOOTCONFIG_NO_BTBL_IO
117 p_inst->state = BOOT_TBL_STATE_SIZE;
118 #else
119 p_inst->state = BOOT_TBL_STATE_IO_CNT;
120 #endif
123 p_inst->f_wait_lsw = FALSE;
124 }
125 else
126 {
127 /* Process the entry point MSW */
128 p_inst->code_start_addr = ((UINT32)(*p_inst->p_data & 0xFFFF)) << 16;
129 p_inst->f_wait_lsw = (bool)TRUE;
130 }
132 /* Update data buffer and counter */
133 p_inst->p_data++;
134 p_inst->data_size_uint16--;
135 }
137 /*******************************************************************************
138 * FUNCTION PURPOSE: Process the boot table in IO_CNT State
139 *******************************************************************************
140 * DESCRIPTION: Process the boot table in IO_CNT State
141 * Record the number of IO Registers
142 *
143 * void boot_proc_boot_tbl_io_cnt (
144 * BOOT_TBL_CB_T *p_inst) - A pointer to Boot Table Control instance
145 *
146 *****************************************************************************/
147 #ifndef BOOTCONFIG_NO_BTBL_IO
148 void boot_proc_boot_tbl_io_cnt(BOOT_TBL_CB_T* p_inst)
149 {
150 if(p_inst->f_wait_lsw)
151 {
152 /* LSW processing */
153 p_inst->num_io_regs += (*p_inst->p_data & 0xFFFF);
154 p_inst->f_wait_lsw = FALSE;
155 if(p_inst->num_io_regs)
156 {
157 p_inst->state = BOOT_TBL_STATE_IO_REGS;
158 }
159 else
160 {
161 p_inst->state = BOOT_TBL_STATE_SIZE;
162 }
164 }
165 else
166 {
167 /* MSW processing */
168 p_inst->num_io_regs = ((UINT32)(*p_inst->p_data & 0xFFFF)) << 16;
169 p_inst->f_wait_lsw = TRUE;
170 }
172 /* Update data buffer and counter */
173 p_inst->p_data++;
174 p_inst->data_size_uint16--;
175 }
176 #endif
178 /*******************************************************************************
179 * FUNCTION PURPOSE: Process the boot table in IO_REGS State
180 *******************************************************************************
181 * DESCRIPTION: Process the boot table in IO_REG State
182 * Process IO Register configuration
183 *
184 * void boot_proc_boot_tbl_io_regs (
185 * BOOT_TBL_CB_T *p_inst) - A pointer to Boot Table Control instance
186 *
187 *****************************************************************************/
188 #ifndef BOOTCONFIG_NO_BTBL_IO
189 void boot_proc_boot_tbl_io_regs(BOOT_TBL_CB_T* p_inst)
190 {
191 UINT16 data;
193 if(p_inst->f_wait_lsw)
194 {
195 /* LSW processing */
196 data = *p_inst->p_data;
198 /* proess the IO register configuration based on its address (opcode) */
199 switch(p_inst->io_addr)
200 {
201 case BOOT_TBL_IO_CFG_DELAY:
202 /* perform the delay loop requested */
203 chipDelay(data);
204 break;
206 case BOOT_TBL_IO_CFG_START_CORE:
207 /* Verify whether the start_vector is valid */
208 if(data >= (BOOT_BIT_TO_MASK(chipReadNumCores())))
209 {
210 BOOT_EXCEPTION(BOOT_ERROR_CODE(BOOT_MODULE_ID_BTBL,
211 BTBL_ERR_INVALID_START_VECTOR));
212 }
213 /* record the core start vector */
214 p_inst->core_start_vector = data;
215 break;
217 default:
218 /* IO Configuration */
219 chipIoWrite(p_inst->io_addr, data);
220 break;
222 }
223 p_inst->f_wait_lsw = FALSE;
225 /* Is it the last IO Register to be configured */
226 if((--p_inst->num_io_regs) == 0)
227 {
228 p_inst->state = BOOT_TBL_STATE_SIZE;
229 }
230 }
231 else
232 {
233 /* MSW processing */
234 p_inst->io_addr = *p_inst->p_data;
235 p_inst->f_wait_lsw = TRUE;
236 }
238 /* Update data buffer and counter */
239 p_inst->p_data++;
240 p_inst->data_size_uint16--;
241 }
242 #endif
244 /*******************************************************************************
245 * FUNCTION PURPOSE: Process the boot table in SIZE State
246 *******************************************************************************
247 * DESCRIPTION: Process the boot table in SIZE State
248 * Record the size of the new code section
249 * perform end of table processing if size = 0
250 *
251 * void boot_proc_boot_tbl_size (
252 * BOOT_TBL_CB_T *p_inst) - A pointer to Boot Table Control instance
253 *
254 *****************************************************************************/
255 void boot_proc_boot_tbl_size(BOOT_TBL_CB_T* p_inst)
256 {
257 if(p_inst->f_wait_lsw)
258 {
259 /* LSW processing */
260 p_inst->section_size_bytes += (*p_inst->p_data & 0xFFFF);
262 /* Is it the end of the boot table */
263 if(p_inst->section_size_bytes == 0)
264 {
265 chipStartCore(p_inst->code_start_addr,
266 (UINT32)p_boot_entry_addr,
267 p_inst->core_start_vector);
269 /* End of Boot table:Clear the instance */
270 p_inst->state = BOOT_TBL_STATE_FLUSH;
271 p_inst->f_wait_lsw = FALSE;
272 return;
273 }
275 p_inst->state = BOOT_TBL_STATE_ADDR;
276 p_inst->f_wait_lsw = FALSE;
278 /* Update statistics */
279 bootStats.btbl.num_sections++;
280 }
281 else
282 {
283 /* MSW processing */
284 p_inst->section_size_bytes = ((UINT32)(*p_inst->p_data & 0xFFFF)) << 16;
285 p_inst->f_wait_lsw = (bool)TRUE;
286 }
288 /* Update data buffer and counter */
289 p_inst->p_data++;
290 p_inst->data_size_uint16--;
291 }
293 /*******************************************************************************
294 * FUNCTION PURPOSE: Process the boot table in ADDR State
295 *******************************************************************************
296 * DESCRIPTION: Process the boot table in ADDR State
297 * Record the start address of the new code section
298 *
299 * void boot_proc_boot_tbl_addr (
300 * BOOT_TBL_CB_T *p_inst) - A pointer to Boot Table Control instance
301 *
302 *****************************************************************************/
303 void boot_proc_boot_tbl_addr(BOOT_TBL_CB_T* p_inst)
304 {
305 if(p_inst->f_wait_lsw)
306 {
307 /* LSW processing */
308 p_inst->section_addr += (*p_inst->p_data & 0xFFFF);
309 p_inst->state = BOOT_TBL_STATE_DATA;
310 p_inst->f_wait_lsw = FALSE;
311 }
312 else
313 {
314 /* MSW processing */
315 p_inst->section_addr = ((UINT32)(*p_inst->p_data & 0xFFFF)) << 16;
316 p_inst->f_wait_lsw = (bool)TRUE;
317 }
319 /* Update data buffer and counter */
320 p_inst->p_data++;
321 p_inst->data_size_uint16--;
322 }
324 /*******************************************************************************
325 * FUNCTION PURPOSE: Process the boot table in DATA State
326 *******************************************************************************
327 * DESCRIPTION: Process the boot table in DATA State
328 * Copy the received section data to the destination memory
329 * locations
330 *
331 * void boot_proc_boot_tbl_data (
332 * BOOT_TBL_CB_T *p_inst) - A pointer to Boot Table Control instance
333 *
334 *****************************************************************************/
335 #define MIN(a,b) (a)<(b) ? (a) : (b)
336 void boot_proc_boot_tbl_data(BOOT_TBL_CB_T* p_inst)
337 {
338 UINT32 num_bytes; /* number of bytes to be copy */
339 UINT32 num_uint16_words; /* number of 16 bit words to copy */
340 UINT16 error;
342 num_bytes = MIN (p_inst->section_size_bytes, CHIP_UINT16_TO_BYTES(p_inst->data_size_uint16));
343 num_uint16_words = CHIP_BYTES_TO_UINT16(num_bytes);
345 /* Some processors add padding to the memwidth used in the rom (created by tools) */
346 num_uint16_words = chipAddBtblUint16Pad (num_uint16_words);
348 /*
349 * Record the last UINT16 word and copy the data to the destination
350 * locations
351 */
353 if((error = coreCopyData(p_inst->section_addr, p_inst->p_data, num_bytes,
354 p_inst->core_start_vector))
355 != CORE_NOERR)
356 {
357 /* Error Processing */
358 BOOT_EXCEPTION(BOOT_ERROR_CODE(BOOT_MODULE_ID_CHIP,
359 error));
360 }
362 /* Update instance variables for the next code section */
363 p_inst->data_size_uint16 -= num_uint16_words;
364 p_inst->p_data += num_uint16_words;
366 p_inst->section_addr += num_bytes;
367 p_inst->section_size_bytes -= num_bytes;
369 if(p_inst->section_size_bytes == 0)
370 {
371 p_inst->state = BOOT_TBL_STATE_SIZE;
373 /* Chip specific post block handling. Can be defined to an empty statement */
374 chipBtblBlockDone();
375 }
377 /* update statistics */
378 bootStats.btbl.num_pdma_copies++;
379 }
381 /*******************************************************************************
382 * FUNCTION PURPOSE: Process the boot table in Flush State
383 *******************************************************************************
384 * DESCRIPTION: Process the boot table in Flush State
385 * We will enter this state when the end of table or error
386 * condition occurs
387 * set data_size to 0, i.e. ignore the reamining data
388 *
389 * void boot_proc_boot_tbl_error (
390 * BOOT_TBL_CB_T *p_inst) - A pointer to Boot Table Control instance
391 *
392 *****************************************************************************/
393 void boot_proc_boot_tbl_flush(BOOT_TBL_CB_T* p_inst)
394 {
395 p_inst->data_size_uint16 = 0;
396 }
398 /* ------------------- PUBLIC FUNCTIONS START HERE ----------------------- */
399 /*******************************************************************************
400 * FUNCTION PURPOSE: Initialize the boot table control instance
401 *******************************************************************************
402 * DESCRIPTION: Initialize and allocate the boot table control instance
403 * Initialize all the variables to zero
404 * Set the state to Init
405 *
406 * void boot_init_boot_tbl_inst ( void )
407 *
408 * Note: only one instance is used at this moment
409 * a free instance function will be needed when multiple instances are
410 * supported
411 *
412 *****************************************************************************/
413 void boot_init_boot_tbl_inst(BOOT_TBL_CB_T *p_btbl_inst)
414 {
415 memset(p_btbl_inst, 0, sizeof(BOOT_TBL_CB_T));
416 p_btbl_inst->state = BOOT_TBL_STATE_INIT;
418 /*
419 * Set the core start vector to start core A only as its default value
420 * in case the boot table does not contain the setting of the core
421 * start vector.
422 */
423 p_btbl_inst->core_start_vector = 1;
426 /* Initialize the toot table processing function table */
427 btbl_st_proc_fcn[BOOT_TBL_STATE_INIT] = boot_proc_boot_tbl_init;
429 #ifndef BOOTCONFIG_NO_BTBL_IO
430 btbl_st_proc_fcn[BOOT_TBL_STATE_IO_CNT] = boot_proc_boot_tbl_io_cnt;
431 btbl_st_proc_fcn[BOOT_TBL_STATE_IO_REGS] = boot_proc_boot_tbl_io_regs;
432 #endif
434 btbl_st_proc_fcn[BOOT_TBL_STATE_SIZE] = boot_proc_boot_tbl_size;
435 btbl_st_proc_fcn[BOOT_TBL_STATE_ADDR] = boot_proc_boot_tbl_addr;
436 btbl_st_proc_fcn[BOOT_TBL_STATE_DATA] = boot_proc_boot_tbl_data;
437 btbl_st_proc_fcn[BOOT_TBL_STATE_FLUSH] = boot_proc_boot_tbl_flush;
439 } /* end of boot_init_boot_tbl_inst() */
441 /*******************************************************************************
442 * FUNCTION PURPOSE: Process the boot table
443 *******************************************************************************
444 * DESCRIPTION: Process the whole or partial boot table received by going
445 * through the boot table processing state machine until all
446 * the UINT16 words are processed or the end of table condition
447 * (section size == 0) is satisfied.
448 *
449 * void boot_proc_boot_tbl (
450 * UINT16 *p_data, - 16-bit boot table content to be processed
451 * UINT16 size) - number of 16-bit words
452 *
453 *
454 * Note: It is up to the caller to reserve 4 16-bit word space in front of the
455 * input buffer since the data may be moved to achieve 32-bit alignment
456 * requirement for PDMA transfer
457 *****************************************************************************/
458 void boot_proc_boot_tbl(BOOT_TBL_CB_T *p_btbl_inst, UINT16* p_data, UINT32 size)
459 {
461 /* Record the input data buffer and size */
462 p_btbl_inst->p_data = p_data;
463 p_btbl_inst->data_size_uint16 = size;
465 /* Optional: verify the inst state is valid */
466 if(p_btbl_inst->state > BOOT_TBL_LAST_STATE)
467 {
468 /* Error Processing */
469 BOOT_EXCEPTION(BOOT_ERROR_CODE(BOOT_MODULE_ID_BTBL,
470 BTBL_ERR_INVALID_STATE));
472 }
474 /*
475 * Invoke the Boot table processing state machine until all the input
476 * data are processed or the end of table condition is satified
477 */
478 while (p_btbl_inst->data_size_uint16 != 0)
479 {
480 btbl_st_proc_fcn[p_btbl_inst->state](p_btbl_inst);
481 }
483 } /* end of boot_proc_boot_tbl() */