Debugged the IBL two stage load process
[keystone-rtos/ibl.git] / src / interp / btbl / btblpr.c
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)
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     }
132     
133     /* Update data buffer and counter */
134     p_inst->p_data++;
135     p_inst->data_size_uint16--;
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)
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         }
164         
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     }
172     
173     /* Update data buffer and counter */
174     p_inst->p_data++;
175     p_inst->data_size_uint16--;
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)
192     UINT16 data;
193     
194     if(p_inst->f_wait_lsw)
195     {
196         /* LSW processing */
197         data = *p_inst->p_data;
198         
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;    
206                 
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;    
217                 
218             default:
219                 /* IO Configuration */
220                 chipIoWrite(p_inst->io_addr, data);
221                 break;                
222                 
223         }
224         p_inst->f_wait_lsw = FALSE;
225         
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     }
238     
239     /* Update data buffer and counter */
240     p_inst->p_data++;
241     p_inst->data_size_uint16--;
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)
258     if(p_inst->f_wait_lsw)
259     {
260         /* LSW processing */
261         p_inst->section_size_bytes += (*p_inst->p_data & 0xFFFF);
262         
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);
269                     
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         }
275         
276         p_inst->state = BOOT_TBL_STATE_ADDR;
277         p_inst->f_wait_lsw = FALSE;
278         
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     }
288     
289     /* Update data buffer and counter */
290     p_inst->p_data++;
291     p_inst->data_size_uint16--;
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)
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     }
319     
320     /* Update data buffer and counter */
321     p_inst->p_data++;
322     p_inst->data_size_uint16--;
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)
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;
342     
343     p_inst->section_addr       += num_bytes;
344     p_inst->section_size_bytes -= num_bytes;
345     
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     }
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)
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;
375     
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;
382     
383     /* 
384      * Record the last UINT16 word and copy the data to the destination
385      * locations
386      */
387     
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     } 
396     
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;
400     
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     }
420     
421     /* update statistics */
422     bootStats.btbl.num_pdma_copies++;
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)
439     p_inst->data_size_uint16 = 0;
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)
459     memset(p_btbl_inst, 0, sizeof(BOOT_TBL_CB_T));
460     p_btbl_inst->state = BOOT_TBL_STATE_INIT;
461     
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; 
468     
469     
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;
483     
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)
505     
506     /* Record the input data buffer and size */
507     p_btbl_inst->p_data           = p_data;
508     p_btbl_inst->data_size_uint16 = size;
509     
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));
516          
517     }
518     
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     }
527     
528 } /* end of boot_proc_boot_tbl() */