source: rtems/c/src/lib/libbsp/powerpc/ep1a/startup/bspstart.c @ 6ea100c1

4.104.114.95
Last change on this file since 6ea100c1 was 6ea100c1, checked in by Joel Sherrill <joel.sherrill@…>, on 05/12/08 at 18:43:55

2008-05-12 Joel Sherrill <joel.sherrill@…>

  • startup/bspstart.c: Refactored and renamed initialization routines to rtems_initialize_data_structures, rtems_initialize_before_drivers, rtems_initialize_device_drivers, and rtems_initialize_start_multitasking. This opened the sequence up so that bootcard() could provide a more robust and flexible framework which is easier to explain and understand. This also lays the groundwork for sharing the division of available memory between the RTEMS workspace and heap and the C library initialization across all BSPs.
  • Property mode set to 100644
File size: 12.8 KB
Line 
1/*
2 *  This routine starts the application.  It includes application,
3 *  board, and monitor specific initialization and configuration.
4 *  The generic CPU dependent initialization has been performed
5 *  before this routine is invoked.
6 *
7 *  COPYRIGHT (c) 1989-2007.
8 *  On-Line Applications Research Corporation (OAR).
9 *
10 *  The license and distribution terms for this file may be
11 *  found in the file LICENSE in this distribution or at
12 *  http://www.rtems.com/license/LICENSE.
13 *
14 *  $Id$
15 */
16
17#include <string.h>
18
19#include <rtems/libio.h>
20#include <rtems/libcsupport.h>
21#include <bsp/consoleIo.h>
22#include <libcpu/spr.h>
23#include <bsp/residual.h>
24#include <bsp/pci.h>
25#include <bsp/openpic.h>
26#include <bsp/irq.h>
27#include <bsp/VME.h>
28#include <bsp.h>
29#include <libcpu/bat.h>
30#include <libcpu/pte121.h>
31#include <libcpu/cpuIdent.h>
32#include <bsp/vectors.h>
33#include <rtems/powerpc/powerpc.h>
34
35extern unsigned long __rtems_end[];
36extern void L1_caches_enables();
37extern unsigned get_L2CR();
38extern void set_L2CR(unsigned);
39extern void bsp_cleanup(void);
40extern Triv121PgTbl BSP_pgtbl_setup();
41extern void BSP_pgtbl_activate();
42extern void BSP_vme_config();
43extern void ShowBATS();
44unsigned int rsPMCQ1Init();
45
46uint32_t bsp_clicks_per_usec;
47
48SPR_RW(SPRG0)
49SPR_RW(SPRG1)
50
51uint8_t LightIdx = 0;
52
53void BSP_Increment_Light(){
54  uint8_t data;
55  data = *GENERAL_REGISTER1;
56  data &= 0xf0;
57  data |= LightIdx++;
58  *GENERAL_REGISTER1 = data;
59}
60
61void BSP_Fatal_Fault_Light() {
62  uint8_t data;
63  data = *GENERAL_REGISTER1;
64  data &= 0xf0;
65  data |= 0x7;
66  while(1)
67    *GENERAL_REGISTER1 = data;
68}
69
70void write_to_Q2ram(int offset, unsigned int data )
71{
72printk("0x%x ==> %d\n", offset, data );
73#if 0
74  unsigned int *ptr = 0x82000000;
75  ptr += offset;
76  *ptr = data;
77#endif
78}
79
80/*
81 * Vital Board data Start using DATA RESIDUAL
82 */
83
84uint32_t VME_Slot1 = FALSE;
85
86/*
87 * Total memory.
88 * Note: RAM_END is defined in linkcmds.  We want to verify that the application
89 *       is only using 10M of memory, and we do this by only accounting for this
90 *       much memory.
91 */
92extern int   RAM_END; 
93unsigned int BSP_mem_size = (unsigned int)&RAM_END;
94
95/*
96 * PCI Bus Frequency
97 */
98unsigned int BSP_bus_frequency;
99
100/*
101 * processor clock frequency
102 */
103unsigned int BSP_processor_frequency;
104
105/*
106 * Time base divisior (how many tick for 1 second).
107 */
108unsigned int BSP_time_base_divisor = 1000;  /* XXX - Just a guess */
109
110/*
111 * system init stack
112 */
113#define INIT_STACK_SIZE 0x1000
114
115void BSP_panic(char *s)
116{
117  printk("%s PANIC %s\n",_RTEMS_version, s);
118  __asm__ __volatile ("sc");
119}
120
121void _BSP_Fatal_error(unsigned int v)
122{
123  printk("%s PANIC ERROR %x\n",_RTEMS_version, v);
124  __asm__ __volatile ("sc");
125}
126 
127int BSP_FLASH_Disable_writes(
128  uint32_t    area
129)
130{
131  unsigned char    data;
132 
133  data = *GENERAL_REGISTER1;
134  data |= DISABLE_USER_FLASH;
135  *GENERAL_REGISTER1 = data;
136                                                                           
137  return RTEMS_SUCCESSFUL;
138}
139
140int BSP_FLASH_Enable_writes(
141 uint32_t               area                           /* IN  */
142)
143{
144  unsigned char    data;
145                                                                                                                       
146  data = *GENERAL_REGISTER1;
147  data &= (~DISABLE_USER_FLASH);
148  *GENERAL_REGISTER1 = data;
149                                                                                                                       
150  return RTEMS_SUCCESSFUL;
151}
152
153void BSP_FLASH_set_page(
154  uint8_t  page
155)
156{
157  unsigned char  data;
158                                                                                                                       
159  /* Set the flash page register. */
160  data = *GENERAL_REGISTER2;
161  data &= ~(BSP_FLASH_PAGE_MASK);
162  data |= 0x80 | (page << BSP_FLASH_PAGE_SHIFT);
163  *GENERAL_REGISTER2 = data;
164}
165
166/*
167 *  Use the shared implementations of the following routines
168 */
169 
170void bsp_libc_init( void *, uint32_t, int );
171
172/*
173 *  Function:   bsp_pretasking_hook
174 *  Created:    95/03/10
175 *
176 *  Description:
177 *      BSP pretasking hook.  Called just before drivers are initialized.
178 *      Used to setup libc and install any BSP extensions.
179 *
180 *  NOTES:
181 *      Must not use libc (to do io) from here, since drivers are
182 *      not yet initialized.
183 *
184 */
185 
186void bsp_pretasking_hook(void)
187{
188  uint32_t        heap_start;   
189  uint32_t        heap_size;
190  uint32_t        heap_sbrk_spared;
191
192  extern uint32_t _bsp_sbrk_init(uint32_t, uint32_t*);
193 
194  heap_start = ((uint32_t) __rtems_end) +
195    INIT_STACK_SIZE + rtems_configuration_get_interrupt_stack_size();
196  if (heap_start & (CPU_ALIGNMENT-1))
197    heap_start = (heap_start + CPU_ALIGNMENT) & ~(CPU_ALIGNMENT-1);
198
199  heap_size = (BSP_mem_size - heap_start) - rtems_configuration_get_work_space_size();
200
201  heap_sbrk_spared=_bsp_sbrk_init(heap_start, &heap_size);
202
203#ifdef SHOW_MORE_INIT_SETTINGS
204  printk(" HEAP start %x  size %x (%x bytes spared for sbrk)\n",
205    heap_start, heap_size, heap_sbrk_spared);
206#endif   
207
208  bsp_libc_init((void *) 0, heap_size, heap_sbrk_spared);
209  rsPMCQ1Init();
210
211#ifdef RTEMS_DEBUG
212  rtems_debug_enable( RTEMS_DEBUG_ALL_MASK );
213#endif
214}
215
216void zero_bss()
217{
218  /* prevent these from being accessed in the short data areas */
219  extern unsigned long __bss_start[], __SBSS_START__[], __SBSS_END__[];
220  extern unsigned long __SBSS2_START__[], __SBSS2_END__[];
221  memset(__SBSS_START__, 0, ((unsigned) __SBSS_END__) - ((unsigned)__SBSS_START__));
222  memset(__SBSS2_START__, 0, ((unsigned) __SBSS2_END__) - ((unsigned)__SBSS2_START__));
223  memset(__bss_start, 0, ((unsigned) __rtems_end) - ((unsigned)__bss_start));
224}
225
226void save_boot_params(RESIDUAL* r3, void *r4, void* r5, char *additional_boot_options)
227{
228#if 0 
229  residualCopy = *r3;
230  strncpy(loaderParam, additional_boot_options, MAX_LOADER_ADD_PARM);
231  loaderParam[MAX_LOADER_ADD_PARM - 1] ='\0';
232#endif
233}
234
235unsigned int EUMBBAR;
236
237unsigned int get_eumbbar() {
238  register int a, e;
239
240  asm volatile( "lis %0,0xfec0; ori  %0,%0,0x0000": "=r" (a) );
241  asm volatile("sync");
242                                                               
243  asm volatile("lis %0,0x8000; ori %0,%0,0x0078": "=r"(e) );
244  asm volatile("stwbrx  %0,0x0,%1": "=r"(e): "r"(a)); 
245  asm volatile("sync");
246
247  asm volatile("lis %0,0xfee0; ori %0,%0,0x0000": "=r" (a) );
248  asm volatile("sync");
249                                                         
250  asm volatile("lwbrx %0,0x0,%1": "=r" (e): "r" (a));
251  asm volatile("isync");
252  return e;
253}
254
255void Read_ep1a_config_registers( ppc_cpu_id_t myCpu ) {
256  unsigned char value;
257
258  /*
259   * Print out the board and revision.
260   */
261
262  printk("Board:  ");
263  printk( get_ppc_cpu_type_name(myCpu) );
264
265  value = *BOARD_REVISION_REGISTER2 & HARDWARE_ID_MASK;
266  if ( value == HARDWARE_ID_PPC5_EP1A )
267    printk("  EP1A     ");
268  else if ( value == HARDWARE_ID_EP1B )
269    printk("  EP1B     ");
270  else
271    printk("  Unknown  ");
272 
273  value = *BOARD_REVISION_REGISTER2&0x1;
274  printk("Board ID %08x", value);
275  if(value == 0x0){
276    VME_Slot1 = TRUE;
277    printk("VME Slot 1\n");
278  }
279  else{
280    VME_Slot1 = FALSE;
281    printk("\n");
282  }
283
284  printk("Revision: ");
285  value = *BOARD_REVISION_REGISTER1;
286  printk("%d%c\n\n", value>>4, 'A'+(value&BUILD_REVISION_MASK) );
287
288  /*
289   * Get the CPU, XXX frequency
290   */
291  value = *EQUIPMENT_PRESENT_REGISTER2 & PLL_CFG_MASK;
292  switch( value ) {
293    case MHZ_33_66_200:     /* PCI, MEM, & CPU Frequency */
294      BSP_processor_frequency = 200000000;
295      BSP_bus_frequency       =  33000000;
296      break;
297    case MHZ_33_100_200:   /* PCI, MEM, & CPU Frequency */
298      BSP_processor_frequency = 200000000;
299      BSP_bus_frequency       =  33000000;
300      break;
301    case MHZ_33_66_266:    /* PCI, MEM, & CPU Frequency */
302      BSP_processor_frequency = 266000000;
303      BSP_bus_frequency       =  33000000;
304      break;
305    case MHZ_33_66_333:   /* PCI, MEM, & CPU Frequency */
306      BSP_processor_frequency = 333000000;
307      BSP_bus_frequency       =  33000000;
308      break;
309    case MHZ_33_100_333:   /* PCI, MEM, & CPU Frequency */
310      BSP_processor_frequency = 333000000;
311      BSP_bus_frequency       =  33000000;
312      break;
313    case MHZ_33_100_350:   /* PCI, MEM, & CPU Frequency */
314      BSP_processor_frequency = 350000000;
315      BSP_bus_frequency       =  33000000;
316      break;
317    default:
318      printk("ERROR: Unknown Processor frequency 0x%02x please fill in bspstart.c\n",value);
319      BSP_processor_frequency = 350000000;
320      BSP_bus_frequency       =  33000000;
321      break;
322  }
323}
324
325/*
326 *  bsp_start
327 *
328 *  This routine does the bulk of the system initialization.
329 */
330
331void bsp_start( void )
332{
333  unsigned char *stack;
334  register uint32_t  intrStack;
335  register uint32_t *intrStackPtr;
336  unsigned char *work_space_start;
337  ppc_cpu_id_t myCpu;
338  ppc_cpu_revision_t myCpuRevision;
339  Triv121PgTbl  pt=0;   /*  R = e; */
340
341  /*
342   * Get CPU identification dynamically. Note that the get_ppc_cpu_type() function
343   * store the result in global variables so that it can be used latter...
344   */
345  BSP_Increment_Light();
346  myCpu         = get_ppc_cpu_type();
347  myCpuRevision = get_ppc_cpu_revision();
348
349  EUMBBAR = get_eumbbar();
350  printk("EUMBBAR 0x%08x\n", EUMBBAR );
351
352  /*
353   * Note this sets BSP_processor_frequency based upon register settings.
354   * It must be done prior to setting up hooks.
355   */
356  Read_ep1a_config_registers( myCpu );
357
358  bsp_clicks_per_usec = BSP_processor_frequency/(BSP_time_base_divisor * 1000);
359
360ShowBATS();
361#if 0   /* XXX - Add back in cache enable when we get this up and running!! */
362  /*
363   * enables L1 Cache. Note that the L1_caches_enables() codes checks for
364   * relevant CPU type so that the reason why there is no use of myCpu...
365   */
366  L1_caches_enables();
367#endif
368
369  /*
370   * the initial stack  has aready been set to this value in start.S
371   * so there is no need to set it in r1 again... It is just for info
372   * so that It can be printed without accessing R1.
373   */
374  stack = ((unsigned char*) __rtems_end) + INIT_STACK_SIZE - PPC_MINIMUM_STACK_FRAME_SIZE;
375
376 /* tag the bottom (T. Straumann 6/36/2001 <strauman@slac.stanford.edu>) */
377  *((uint32_t *)stack) = 0;
378
379  /*
380   * Initialize the interrupt related settings
381   * SPRG1 = software managed IRQ stack
382   *
383   * This could be done latter (e.g in IRQ_INIT) but it helps to understand
384   * some settings below...
385   */
386  intrStack = ((uint32_t) __rtems_end) +
387    INIT_STACK_SIZE + rtems_configuration_get_interrupt_stack_size() -
388    PPC_MINIMUM_STACK_FRAME_SIZE;
389
390  /* make sure it's properly aligned */
391  intrStack &= ~(CPU_STACK_ALIGNMENT-1);
392
393  /* tag the bottom (T. Straumann 6/36/2001 <strauman@slac.stanford.edu>) */
394  intrStackPtr = (uint32_t*) intrStack;
395  *intrStackPtr = 0;
396
397  _write_SPRG1((unsigned int)intrStack);
398
399  /* signal them that we have fixed PR288 - eventually, this should go away */
400  _write_SPRG0(PPC_BSP_HAS_FIXED_PR288);
401
402  /*
403   * Initialize default raw exception hanlders. See vectors/vectors_init.c
404   */
405  initialize_exceptions();
406
407  /*
408   * Init MMU block address translation to enable hardware
409   * access
410   */
411  setdbat(1, 0xf0000000, 0xf0000000, 0x10000000, IO_PAGE);
412  setdbat(3, 0x90000000, 0x90000000, 0x10000000, IO_PAGE);
413
414
415#ifdef SHOW_MORE_INIT_SETTINGS
416  printk("Going to start PCI buses scanning and initialization\n");
417#endif 
418  pci_initialize();
419
420#ifdef SHOW_MORE_INIT_SETTINGS
421  printk("Number of PCI buses found is : %d\n", pci_bus_count());
422#endif
423#ifdef TEST_RAW_EXCEPTION_CODE 
424  printk("Testing exception handling Part 1\n");
425
426  /*
427   * Cause a software exception
428   */
429  __asm__ __volatile ("sc");
430
431  /*
432   * Check we can still catch exceptions and returned coorectly.
433   */
434  printk("Testing exception handling Part 2\n");
435  __asm__ __volatile ("sc");
436#endif 
437
438#ifdef SHOW_MORE_INIT_SETTINGS
439  printk("rtems_configuration_get_work_space_size() = %x\n",
440     rtems_configuration_get_work_space_size());
441#endif 
442  work_space_start =
443    (unsigned char *)BSP_mem_size - rtems_configuration_get_work_space_size();
444
445  if ( work_space_start <= ((unsigned char *)__rtems_end) +
446        INIT_STACK_SIZE + rtems_configuration_get_interrupt_stack_size()) {
447    printk( "bspstart: Not enough RAM!!!\n" );
448    bsp_cleanup();
449  }
450
451  Configuration.work_space_start = work_space_start;
452
453  /*
454   * Initalize RTEMS IRQ system
455   */
456  BSP_rtems_irq_mng_init(0);
457 
458  /* Activate the page table mappings only after
459   * initializing interrupts because the irq_mng_init()
460   * routine needs to modify the text
461   */           
462  if (pt) {
463#ifdef  SHOW_MORE_INIT_SETTINGS
464    printk("Page table setup finished; will activate it NOW...\n");
465#endif
466    BSP_pgtbl_activate(pt);
467  }
468
469  /*
470   * Initialize VME bridge - needs working PCI
471   * and IRQ subsystems...
472   */
473#ifdef SHOW_MORE_INIT_SETTINGS
474  printk("Going to initialize VME bridge\n");
475#endif
476  /* VME initialization is in a separate file so apps which don't use
477   * VME or want a different configuration may link against a customized
478   * routine.
479   */
480  BSP_vme_config();
481
482#ifdef SHOW_MORE_INIT_SETTINGS
483  ShowBATS();
484  printk("Exit from bspstart\n");
485#endif 
486}
Note: See TracBrowser for help on using the repository browser.