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

4.104.114.9
Last change on this file since a86f3aac was a86f3aac, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on Jul 11, 2008 at 10:01:37 AM

adapted powerpc BSPs to new exception code

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