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

4.104.114.95
Last change on this file since b5e7018 was b5e7018, checked in by Joel Sherrill <joel.sherrill@…>, on 12/03/07 at 22:24:44

2007-12-03 Joel Sherrill <joel.sherrill@…>

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