source: rtems/c/src/lib/libbsp/powerpc/mvme5500/startup/bspstart.c @ ee732739

4.104.114.84.9
Last change on this file since ee732739 was ee732739, checked in by Joel Sherrill <joel.sherrill@…>, on Sep 13, 2007 at 2:26:24 PM

2007-09-07 Kate Feng <feng1@…>

  • ChangeLog?, Makefile.am, README, README.booting, README.irq, preinstall.am, GT64260/MVME5500I2C.c, include/bsp.h, irq/irq.c, irq/irq.h, irq/irq_init.c, pci/detect_host_bridge.c, pci/pci.c, pci/pci_interface.c, pci/pcifinddevice.c, start/preload.S, startup/bspclean.c, startup/bspstart.c, startup/pgtbl_activate.c, startup/reboot.c, vectors/bspException.h, vectors/exceptionhandler.c: Merge my improvements in this BSP including a new network driver for the 1GHz NIC.
  • network/if_100MHz/GT64260eth.c, network/if_100MHz/GT64260eth.h, network/if_100MHz/GT64260ethreg.h, network/if_100MHz/Makefile.am, network/if_1GHz/Makefile.am, network/if_1GHz/POSSIBLEBUG, network/if_1GHz/if_wm.c, network/if_1GHz/if_wmreg.h, network/if_1GHz/pci_map.c, network/if_1GHz/pcireg.h: New files.
  • Property mode set to 100644
File size: 13.0 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-1998.
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 *  Modified to support the MCP750.
15 *  Modifications Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
16 *
17 *  Modified to support the Synergy VGM & Motorola PowerPC boards
18 *  (C) by Till Straumann, <strauman@slac.stanford.edu>, 2002, 2004, 2005
19 *
20 *  Modified to support the MVME5500 board.
21 *  Also, the settings of L1, L2, and L3 caches is not necessary here.
22 *  (C) by Brookhaven National Lab., S. Kate Feng <feng1@bnl.gov>, 2003, 2004, 2005
23 * 
24 *  $Id$
25 */
26
27#include <string.h>
28#include <stdlib.h>
29#include <ctype.h>
30
31#include <rtems/system.h>
32#include <rtems/libio.h>
33#include <rtems/libcsupport.h>
34#include <rtems/powerpc/powerpc.h>
35
36#include <libcpu/spr.h>   /* registers.h is included here */
37#include <bsp.h>
38#include <bsp/uart.h>
39#include <bsp/pci.h>
40#include <libcpu/bat.h>
41#include <libcpu/pte121.h>
42#include <libcpu/cpuIdent.h>
43#include <bsp/vectors.h>
44#include <bsp/bspException.h>
45
46#include <rtems/bspIo.h>
47#include <rtems/sptables.h>
48
49#ifdef __RTEMS_APPLICATION__
50#undef __RTEMS_APPLICATION__
51#endif
52
53/*
54#define SHOW_MORE_INIT_SETTINGS
55#define SHOW_LCR1_REGISTER
56#define SHOW_LCR2_REGISTER
57#define SHOW_LCR3_REGISTER
58#define CONF_VPD
59*/
60
61/* there is no public Workspace_Free() variant :-( */
62#include <rtems/score/wkspace.h>
63
64BSP_output_char_function_type BSP_output_char = BSP_output_char_via_serial;
65
66extern void _return_to_ppcbug();
67extern unsigned long __rtems_end[];
68extern unsigned get_L1CR(), get_L2CR(), get_L3CR();
69extern void bsp_cleanup(void);
70extern Triv121PgTbl BSP_pgtbl_setup();
71extern void BSP_pgtbl_activate();
72extern int I2Cread_eeprom();
73extern void BSP_vme_config(void);
74
75SPR_RW(SPRG0)
76SPR_RW(SPRG1)
77
78typedef struct CmdLineRec_ {
79                unsigned long   size;
80                char            buf[0];
81} CmdLineRec, *CmdLine;
82
83
84#define mtspr(reg, val) \
85        __asm __volatile("mtspr %0,%1" : : "K"(reg), "r"(val))
86
87
88#define mfspr(reg) \
89        ( { unsigned val; \
90          __asm __volatile("mfspr %0,%1" : "=r"(val) : "K"(reg)); \
91          val; } )
92
93/*
94 * Copy Additional boot param passed by boot loader
95 */
96#define MAX_LOADER_ADD_PARM 80
97char loaderParam[MAX_LOADER_ADD_PARM];
98
99/*
100 * Total memory using RESIDUAL DATA
101 */
102unsigned int BSP_mem_size;
103/*
104 * PCI Bus Frequency
105 */
106/*
107 * Start of the heap
108 */
109unsigned int BSP_heap_start;
110
111unsigned int BSP_bus_frequency;
112/*
113 * processor clock frequency
114 */
115unsigned int BSP_processor_frequency;
116/*
117 * Time base divisior (how many tick for 1 second).
118 */
119unsigned int BSP_time_base_divisor;
120unsigned char ConfVPD_buff[200];
121
122#define CMDLINE_BUF_SIZE        2048
123
124static char cmdline_buf[CMDLINE_BUF_SIZE];
125char *BSP_commandline_string = cmdline_buf;
126
127/*
128 * system init stack and soft ir stack size
129 */
130#define INIT_STACK_SIZE 0x1000
131#define INTR_STACK_SIZE CONFIGURE_INTERRUPT_STACK_MEMORY
132
133void BSP_panic(char *s)
134{
135  printk("%s PANIC %s\n",_RTEMS_version, s);
136  __asm__ __volatile ("sc"); 
137}
138
139void _BSP_Fatal_error(unsigned int v)
140{
141  printk("%s PANIC ERROR %x\n",_RTEMS_version, v);
142  __asm__ __volatile ("sc"); 
143}
144 
145/*
146 *  The original table from the application and our copy of it with
147 *  some changes.
148 */
149
150extern rtems_configuration_table Configuration;
151
152rtems_configuration_table  BSP_Configuration;
153
154rtems_cpu_table Cpu_table;
155
156char *rtems_progname;
157
158/*
159 *  Use the shared implementations of the following routines
160 */
161 
162extern void bsp_postdriver_hook(void); /* see c/src/lib/libbsp/shared/bsppost.c */
163
164extern void bsp_libc_init( void *, uint32_t, int );
165
166extern void bsp_pretasking_hook(void);
167
168void zero_bss()
169{
170  /* prevent these from being accessed in the short data areas */
171  extern unsigned long __bss_start[], __SBSS_START__[], __SBSS_END__[];
172  extern unsigned long __SBSS2_START__[], __SBSS2_END__[];
173  memset(__SBSS_START__, 0, ((unsigned) __SBSS_END__) - ((unsigned)__SBSS_START__));
174  memset(__SBSS2_START__, 0, ((unsigned) __SBSS2_END__) - ((unsigned)__SBSS2_START__));
175  memset(__bss_start, 0, ((unsigned) __rtems_end) - ((unsigned)__bss_start));
176}
177
178/* NOTE: we cannot simply malloc the commandline string;
179 * save_boot_params() is called during a very early stage when
180 * libc/malloc etc. are not yet initialized!
181 *
182 * Here's what we do:
183 *
184 * initial layout setup by the loader (preload.S):
185 *
186 * 0..RTEMS...__rtems_end | cmdline ....... TOP
187 *
188 * After the save_boot_params() routine returns, the stack area will be
189 * set up (start.S):
190 *
191 * 0..RTEMS..__rtems_end | INIT_STACK | IRQ_STACK | ..... TOP
192 *
193 * initialize_executive_early() [called from boot_card()]
194 * will initialize the workspace:
195 *
196 * 0..RTEMS..__rtems_end | INIT_STACK | IRQ_STACK | ...... | workspace | TOP
197 *
198 * and later calls our pretasking_hook() which ends up initializing
199 * libc which in turn initializes the heap
200 *
201 * 0..RTEMS..__rtems_end | INIT_STACK | IRQ_STACK | heap | workspace | TOP
202 *
203 * The idea here is to first move the commandline to the future 'heap' area
204 * from where it will be picked up by our pretasking_hook().
205 * pretasking_hook() then moves it either to INIT_STACK or the workspace
206 * area using proper allocation, initializes libc and finally moves
207 * the data to the environment / malloced areas...
208 */
209
210/* this routine is called early at shared/start/start.S
211 * and must be safe with a not properly aligned stack
212 */
213void
214save_boot_params(void *r3, void *r4, void* r5, char *cmdline_start, char *cmdline_end)
215{
216int             i=cmdline_end-cmdline_start;
217        if ( i >= CMDLINE_BUF_SIZE )
218                i = CMDLINE_BUF_SIZE-1;
219        else if ( i < 0 )
220                i = 0;
221        memmove(cmdline_buf, cmdline_start, i);
222        cmdline_buf[i]=0;
223}
224
225/*
226 *  bsp_start
227 *
228 *  This routine does the bulk of the system initialization.
229 */
230
231void bsp_start( void )
232{
233#ifdef CONF_VPD
234  int i;
235#endif
236  unsigned char *stack;
237  unsigned long  *r1sp;
238#ifdef SHOW_LCR1_REGISTER
239  unsigned l1cr;
240#endif
241#ifdef SHOW_LCR2_REGISTER
242  unsigned l2cr;
243#endif
244#ifdef SHOW_LCR3_REGISTER
245  unsigned l3cr;
246#endif
247  register uint32_t  intrStack;
248  register uint32_t *intrStackPtr;
249  unsigned char *work_space_start;
250  ppc_cpu_id_t myCpu;
251  ppc_cpu_revision_t myCpuRevision;
252  Triv121PgTbl  pt=0;
253
254  /* Till Straumann: 4/2005
255   * Need to map the system registers early, so we can printk...
256   * (otherwise we silently die)
257   */
258  /*
259   * Kate Feng : PCI 0 domain memory space, want to leave room for the VME window
260   */
261  setdbat(2, PCI0_MEM_BASE, PCI0_MEM_BASE, 0x10000000, IO_PAGE);
262
263  /* Till Straumann: 2004
264   * map the PCI 0, 1 Domain I/O space, GT64260B registers
265   * and the reserved area so that the size is the power of 2.
266   *
267   */
268  setdbat(3,PCI0_IO_BASE, PCI0_IO_BASE, 0x2000000, IO_PAGE);
269
270
271  /*
272   * Get CPU identification dynamically. Note that the get_ppc_cpu_type() function
273   * store the result in global variables so that it can be used latter...
274   */
275  myCpu         = get_ppc_cpu_type();
276  myCpuRevision = get_ppc_cpu_revision();
277
278#ifdef SHOW_LCR1_REGISTER
279  l1cr = get_L1CR();
280  printk("Initial L1CR value = %x\n", l1cr); 
281#endif
282
283  /*
284   * the initial stack  has aready been set to this value in start.S
285   * so there is no need to set it in r1 again... It is just for info
286   * so that it can be printed without accessing R1.
287   */
288  stack = ((unsigned char*) __rtems_end) + INIT_STACK_SIZE - PPC_MINIMUM_STACK_FRAME_SIZE;
289
290 /* tag the bottom (T. Straumann 6/36/2001 <strauman@slac.stanford.edu>) */
291  *((uint32_t *)stack) = 0;
292
293  /* fill stack with pattern for debugging */
294  __asm__ __volatile__("mr %0, %%r1":"=r"(r1sp));
295  while (--r1sp >= (unsigned long*)__rtems_end)
296          *r1sp=0xeeeeeeee;
297
298  /*
299   * Initialize the interrupt related settings
300   * SPRG0 = interrupt nesting level count
301   * SPRG1 = software managed IRQ stack
302   *
303   * This could be done latter (e.g in IRQ_INIT) but it helps to understand
304   * some settings below...
305   */
306  BSP_heap_start = ((uint32_t) __rtems_end) + INIT_STACK_SIZE + INTR_STACK_SIZE;
307  intrStack = BSP_heap_start - PPC_MINIMUM_STACK_FRAME_SIZE;
308
309  /* make sure it's properly aligned */
310  intrStack &= ~(CPU_STACK_ALIGNMENT-1);
311
312  /* tag the bottom (T. Straumann 6/36/2001 <strauman@slac.stanford.edu>) */
313  intrStackPtr = (uint32_t*) intrStack;
314  *intrStackPtr = 0;
315
316  _write_SPRG1(intrStack);
317
318  _write_SPRG0(PPC_BSP_HAS_FIXED_PR288);
319
320  /*
321   * Initialize default raw exception hanlders. See vectors/vectors_init.c
322   */
323  Cpu_table.exceptions_in_RAM = TRUE;
324  initialize_exceptions();
325  /*
326   * Init MMU block address translation to enable hardware
327   * access
328   * More PCI1 memory mapping to be done after BSP_pgtbl_activate.
329   */
330  printk("-----------------------------------------\n");
331  printk("Welcome to %s on MVME5500-0163\n", _RTEMS_version );
332  printk("-----------------------------------------\n");
333
334#ifdef TEST_RETURN_TO_PPCBUG 
335  printk("Hit <Enter> to return to PPCBUG monitor\n");
336  printk("When Finished hit GO. It should print <Back from monitor>\n");
337  debug_getc();
338  _return_to_ppcbug();
339  printk("Back from monitor\n");
340  _return_to_ppcbug();
341#endif /* TEST_RETURN_TO_PPCBUG  */
342
343#ifdef TEST_RAW_EXCEPTION_CODE 
344  printk("Testing exception handling Part 1\n");
345  /*
346   * Cause a software exception
347   */
348  __asm__ __volatile ("sc");
349  /*
350   * Check we can still catch exceptions and returned coorectly.
351   */
352  printk("Testing exception handling Part 2\n");
353  __asm__ __volatile ("sc");
354#endif 
355
356  BSP_mem_size                          =  _512M;
357  /* TODO: calculate the BSP_bus_frequency using the REF_CLK bit of System Status  register */
358  /* rtems_bsp_delay_in_bus_cycles are defined in registers.h */
359  BSP_bus_frequency                     = 133333333;
360  BSP_processor_frequency               = 1000000000;
361  BSP_time_base_divisor                 = 4000;/* P94 : 7455 clocks the TB/DECR at 1/4 of the system bus clock frequency */
362
363
364  /* Maybe not setup yet becuase of the warning message */
365  /* Allocate and set up the page table mappings
366   * This is only available on >604 CPUs.
367   *
368   * NOTE: This setup routine may modify the available memory
369   *       size. It is essential to call it before
370   *       calculating the workspace etc.
371   */
372  pt = BSP_pgtbl_setup(&BSP_mem_size);
373  if (!pt)
374     printk("WARNING: unable to setup page tables.\n");
375
376  printk("Now BSP_mem_size = 0x%x\n",BSP_mem_size); 
377
378  /*
379   * Set up our hooks
380   * Make sure libc_init is done before drivers initialized so that
381   * they can use atexit()
382   */
383
384  Cpu_table.pretasking_hook      = bsp_pretasking_hook;    /* init libc, etc. */
385  Cpu_table.postdriver_hook      = bsp_postdriver_hook;
386  Cpu_table.do_zero_of_workspace = TRUE;
387  Cpu_table.interrupt_stack_size = CONFIGURE_INTERRUPT_STACK_MEMORY;
388  /* P94 : 7455 TB/DECR is clocked by the system bus clock frequency */
389  Cpu_table.clicks_per_usec      = BSP_bus_frequency/(BSP_time_base_divisor * 1000);
390  Cpu_table.exceptions_in_RAM    = TRUE;
391  _CPU_Table                     = Cpu_table;/* S. Kate Feng <feng1@bnl.gov>, for rtems_bsp_delay() */
392
393  printk("BSP_Configuration.work_space_size = %x\n", BSP_Configuration.work_space_size); 
394  work_space_start = 
395    (unsigned char *)BSP_mem_size - BSP_Configuration.work_space_size;
396
397  if ( work_space_start <= ((unsigned char *)__rtems_end) + INIT_STACK_SIZE + INTR_STACK_SIZE) {
398    printk( "bspstart: Not enough RAM!!!\n" );
399    bsp_cleanup();
400  }
401
402  BSP_Configuration.work_space_start = work_space_start;
403
404  /*
405   * Initalize RTEMS IRQ system
406   */
407   BSP_rtems_irq_mng_init(0);
408
409#ifdef SHOW_LCR2_REGISTER
410  l2cr = get_L2CR();
411  printk("Initial L2CR value = %x\n", l2cr);
412#endif 
413
414#ifdef SHOW_LCR3_REGISTER
415  /* L3CR needs DEC int. handler installed for bsp_delay()*/
416  l3cr = get_L3CR();
417  printk("Initial L3CR value = %x\n", l3cr);
418#endif 
419
420
421  /* Activate the page table mappings only after
422   * initializing interrupts because the irq_mng_init()
423   * routine needs to modify the text
424   */           
425  if (pt) {
426#ifdef SHOW_MORE_INIT_SETTINGS
427    printk("Page table setup finished; will activate it NOW...\n");
428#endif
429    BSP_pgtbl_activate(pt);
430  }
431
432  /*
433   * PCI 1 domain memory space
434   */
435  setdbat(1, PCI1_MEM_BASE, PCI1_MEM_BASE, 0x10000000, IO_PAGE);
436 
437
438#ifdef SHOW_MORE_INIT_SETTINGS
439  printk("Going to start PCI buses scanning and initialization\n");
440#endif 
441  pci_initialize();
442#ifdef SHOW_MORE_INIT_SETTINGS
443  printk("Number of PCI buses found is : %d\n", pci_bus_count());
444#endif
445
446  /* Install our own exception handler (needs PCI) */
447  globalExceptHdl = BSP_exceptionHandler;
448
449  /* clear hostbridge errors. MCP signal is not used on the MVME5500
450   * PCI config space scanning code will trip otherwise :-(
451   */
452  _BSP_clear_hostbridge_errors(0, 1 /*quiet*/);
453
454  /* Read Configuration Vital Product Data (VPD) */
455  if ( I2Cread_eeprom(0xa8, 4,2, &ConfVPD_buff[0], 150))
456     printk("I2Cread_eeprom() error \n");
457  else {
458#ifdef CONF_VPD
459    printk("\n");
460    for (i=0; i<150; i++) {
461      printk("%2x ", ConfVPD_buff[i]); 
462      if ((i % 20)==0 ) printk("\n");
463    }
464    printk("\n");
465#endif
466  }
467
468#ifdef SHOW_MORE_INIT_SETTINGS
469  printk("MSR %x \n", _read_MSR());
470  printk("Exit from bspstart\n");
471#endif
472
473}
Note: See TracBrowser for help on using the repository browser.