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

4.104.114.9
Last change on this file since 07e9642c was 07e9642c, checked in by Joel Sherrill <joel.sherrill@…>, on Nov 28, 2007 at 9:44:46 PM

2007-11-28 Joel Sherrill <joel.sherrill@…>

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