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

4.104.114.84.95
Last change on this file since 5797b67 was 5797b67, checked in by Joel Sherrill <joel.sherrill@…>, on 08/01/07 at 21:51:23

2007-08-01 Joel Sherrill <joel.sherrill@…>

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