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

4.104.114.95
Last change on this file since dde1fedb was dde1fedb, checked in by Joel Sherrill <joel.sherrill@…>, on 05/15/08 at 15:55:28

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

  • startup/bspstart.c: Add capability for bootcard.c BSP Initialization Framework to ask the BSP where it has memory for the RTEMS Workspace and C Program Heap. These collectively are referred to as work area. If the BSP supports this, then it does not have to include code to split the available memory between the two areas. This reduces the amount of code in the BSP specific bspstart.c file. Additionally, the shared framework can initialize the C Library, call rtems_debug_enable(), and dirty the work area memory. Until most/all BSPs support this new capability, if the BSP supports this, it should call RTEMS_BSP_BOOTCARD_HANDLES_RAM_ALLOCATION from its configure.ac. When the transition is complete, this autoconf macro can be removed.
  • Property mode set to 100644
File size: 12.7 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
212void zero_bss()
213{
214  /* prevent these from being accessed in the short data areas */
215  extern unsigned long __bss_start[], __SBSS_START__[], __SBSS_END__[];
216  extern unsigned long __SBSS2_START__[], __SBSS2_END__[];
217  memset(__SBSS_START__, 0, ((unsigned) __SBSS_END__) - ((unsigned)__SBSS_START__));
218  memset(__SBSS2_START__, 0, ((unsigned) __SBSS2_END__) - ((unsigned)__SBSS2_START__));
219  memset(__bss_start, 0, ((unsigned) __rtems_end) - ((unsigned)__bss_start));
220}
221
222void save_boot_params(RESIDUAL* r3, void *r4, void* r5, char *additional_boot_options)
223{
224#if 0 
225  residualCopy = *r3;
226  strncpy(loaderParam, additional_boot_options, MAX_LOADER_ADD_PARM);
227  loaderParam[MAX_LOADER_ADD_PARM - 1] ='\0';
228#endif
229}
230
231unsigned int EUMBBAR;
232
233unsigned int get_eumbbar() {
234  register int a, e;
235
236  asm volatile( "lis %0,0xfec0; ori  %0,%0,0x0000": "=r" (a) );
237  asm volatile("sync");
238                                                               
239  asm volatile("lis %0,0x8000; ori %0,%0,0x0078": "=r"(e) );
240  asm volatile("stwbrx  %0,0x0,%1": "=r"(e): "r"(a)); 
241  asm volatile("sync");
242
243  asm volatile("lis %0,0xfee0; ori %0,%0,0x0000": "=r" (a) );
244  asm volatile("sync");
245                                                         
246  asm volatile("lwbrx %0,0x0,%1": "=r" (e): "r" (a));
247  asm volatile("isync");
248  return e;
249}
250
251void Read_ep1a_config_registers( ppc_cpu_id_t myCpu ) {
252  unsigned char value;
253
254  /*
255   * Print out the board and revision.
256   */
257
258  printk("Board:  ");
259  printk( get_ppc_cpu_type_name(myCpu) );
260
261  value = *BOARD_REVISION_REGISTER2 & HARDWARE_ID_MASK;
262  if ( value == HARDWARE_ID_PPC5_EP1A )
263    printk("  EP1A     ");
264  else if ( value == HARDWARE_ID_EP1B )
265    printk("  EP1B     ");
266  else
267    printk("  Unknown  ");
268 
269  value = *BOARD_REVISION_REGISTER2&0x1;
270  printk("Board ID %08x", value);
271  if(value == 0x0){
272    VME_Slot1 = TRUE;
273    printk("VME Slot 1\n");
274  }
275  else{
276    VME_Slot1 = FALSE;
277    printk("\n");
278  }
279
280  printk("Revision: ");
281  value = *BOARD_REVISION_REGISTER1;
282  printk("%d%c\n\n", value>>4, 'A'+(value&BUILD_REVISION_MASK) );
283
284  /*
285   * Get the CPU, XXX frequency
286   */
287  value = *EQUIPMENT_PRESENT_REGISTER2 & PLL_CFG_MASK;
288  switch( value ) {
289    case MHZ_33_66_200:     /* PCI, MEM, & CPU Frequency */
290      BSP_processor_frequency = 200000000;
291      BSP_bus_frequency       =  33000000;
292      break;
293    case MHZ_33_100_200:   /* PCI, MEM, & CPU Frequency */
294      BSP_processor_frequency = 200000000;
295      BSP_bus_frequency       =  33000000;
296      break;
297    case MHZ_33_66_266:    /* PCI, MEM, & CPU Frequency */
298      BSP_processor_frequency = 266000000;
299      BSP_bus_frequency       =  33000000;
300      break;
301    case MHZ_33_66_333:   /* PCI, MEM, & CPU Frequency */
302      BSP_processor_frequency = 333000000;
303      BSP_bus_frequency       =  33000000;
304      break;
305    case MHZ_33_100_333:   /* PCI, MEM, & CPU Frequency */
306      BSP_processor_frequency = 333000000;
307      BSP_bus_frequency       =  33000000;
308      break;
309    case MHZ_33_100_350:   /* PCI, MEM, & CPU Frequency */
310      BSP_processor_frequency = 350000000;
311      BSP_bus_frequency       =  33000000;
312      break;
313    default:
314      printk("ERROR: Unknown Processor frequency 0x%02x please fill in bspstart.c\n",value);
315      BSP_processor_frequency = 350000000;
316      BSP_bus_frequency       =  33000000;
317      break;
318  }
319}
320
321/*
322 *  bsp_start
323 *
324 *  This routine does the bulk of the system initialization.
325 */
326
327void bsp_start( void )
328{
329  unsigned char *stack;
330  register uint32_t  intrStack;
331  register uint32_t *intrStackPtr;
332  unsigned char *work_space_start;
333  ppc_cpu_id_t myCpu;
334  ppc_cpu_revision_t myCpuRevision;
335  Triv121PgTbl  pt=0;   /*  R = e; */
336
337  /*
338   * Get CPU identification dynamically. Note that the get_ppc_cpu_type() function
339   * store the result in global variables so that it can be used latter...
340   */
341  BSP_Increment_Light();
342  myCpu         = get_ppc_cpu_type();
343  myCpuRevision = get_ppc_cpu_revision();
344
345  EUMBBAR = get_eumbbar();
346  printk("EUMBBAR 0x%08x\n", EUMBBAR );
347
348  /*
349   * Note this sets BSP_processor_frequency based upon register settings.
350   * It must be done prior to setting up hooks.
351   */
352  Read_ep1a_config_registers( myCpu );
353
354  bsp_clicks_per_usec = BSP_processor_frequency/(BSP_time_base_divisor * 1000);
355
356ShowBATS();
357#if 0   /* XXX - Add back in cache enable when we get this up and running!! */
358  /*
359   * enables L1 Cache. Note that the L1_caches_enables() codes checks for
360   * relevant CPU type so that the reason why there is no use of myCpu...
361   */
362  L1_caches_enables();
363#endif
364
365  /*
366   * the initial stack  has aready been set to this value in start.S
367   * so there is no need to set it in r1 again... It is just for info
368   * so that It can be printed without accessing R1.
369   */
370  stack = ((unsigned char*) __rtems_end) + INIT_STACK_SIZE - PPC_MINIMUM_STACK_FRAME_SIZE;
371
372 /* tag the bottom (T. Straumann 6/36/2001 <strauman@slac.stanford.edu>) */
373  *((uint32_t *)stack) = 0;
374
375  /*
376   * Initialize the interrupt related settings
377   * SPRG1 = software managed IRQ stack
378   *
379   * This could be done latter (e.g in IRQ_INIT) but it helps to understand
380   * some settings below...
381   */
382  intrStack = ((uint32_t) __rtems_end) +
383    INIT_STACK_SIZE + rtems_configuration_get_interrupt_stack_size() -
384    PPC_MINIMUM_STACK_FRAME_SIZE;
385
386  /* make sure it's properly aligned */
387  intrStack &= ~(CPU_STACK_ALIGNMENT-1);
388
389  /* tag the bottom (T. Straumann 6/36/2001 <strauman@slac.stanford.edu>) */
390  intrStackPtr = (uint32_t*) intrStack;
391  *intrStackPtr = 0;
392
393  _write_SPRG1((unsigned int)intrStack);
394
395  /* signal them that we have fixed PR288 - eventually, this should go away */
396  _write_SPRG0(PPC_BSP_HAS_FIXED_PR288);
397
398  /*
399   * Initialize default raw exception hanlders. See vectors/vectors_init.c
400   */
401  initialize_exceptions();
402
403  /*
404   * Init MMU block address translation to enable hardware
405   * access
406   */
407  setdbat(1, 0xf0000000, 0xf0000000, 0x10000000, IO_PAGE);
408  setdbat(3, 0x90000000, 0x90000000, 0x10000000, IO_PAGE);
409
410
411#ifdef SHOW_MORE_INIT_SETTINGS
412  printk("Going to start PCI buses scanning and initialization\n");
413#endif 
414  pci_initialize();
415
416#ifdef SHOW_MORE_INIT_SETTINGS
417  printk("Number of PCI buses found is : %d\n", pci_bus_count());
418#endif
419#ifdef TEST_RAW_EXCEPTION_CODE 
420  printk("Testing exception handling Part 1\n");
421
422  /*
423   * Cause a software exception
424   */
425  __asm__ __volatile ("sc");
426
427  /*
428   * Check we can still catch exceptions and returned coorectly.
429   */
430  printk("Testing exception handling Part 2\n");
431  __asm__ __volatile ("sc");
432#endif 
433
434#ifdef SHOW_MORE_INIT_SETTINGS
435  printk("rtems_configuration_get_work_space_size() = %x\n",
436     rtems_configuration_get_work_space_size());
437#endif 
438  work_space_start =
439    (unsigned char *)BSP_mem_size - rtems_configuration_get_work_space_size();
440
441  if ( work_space_start <= ((unsigned char *)__rtems_end) +
442        INIT_STACK_SIZE + rtems_configuration_get_interrupt_stack_size()) {
443    printk( "bspstart: Not enough RAM!!!\n" );
444    bsp_cleanup();
445  }
446
447  Configuration.work_space_start = work_space_start;
448
449  /*
450   * Initalize RTEMS IRQ system
451   */
452  BSP_rtems_irq_mng_init(0);
453 
454  /* Activate the page table mappings only after
455   * initializing interrupts because the irq_mng_init()
456   * routine needs to modify the text
457   */           
458  if (pt) {
459#ifdef  SHOW_MORE_INIT_SETTINGS
460    printk("Page table setup finished; will activate it NOW...\n");
461#endif
462    BSP_pgtbl_activate(pt);
463  }
464
465  /*
466   * Initialize VME bridge - needs working PCI
467   * and IRQ subsystems...
468   */
469#ifdef SHOW_MORE_INIT_SETTINGS
470  printk("Going to initialize VME bridge\n");
471#endif
472  /* VME initialization is in a separate file so apps which don't use
473   * VME or want a different configuration may link against a customized
474   * routine.
475   */
476  BSP_vme_config();
477
478#ifdef SHOW_MORE_INIT_SETTINGS
479  ShowBATS();
480  printk("Exit from bspstart\n");
481#endif 
482}
Note: See TracBrowser for help on using the repository browser.