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

4.104.115
Last change on this file since 8da29747 was 8da29747, checked in by Joel Sherrill <joel.sherrill@…>, on 09/10/08 at 21:35:19

2008-09-10 Joel Sherrill <joel.sherrill@…>

  • startup/bspstart.c: Review of all bsp_cleanup() implementations. In this phase, all prototypes were removed from bsp.h and empty implementations were removed and made to use the shared stub.
  • Property mode set to 100644
File size: 12.1 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#warning The interrupt disable mask is now stored in SPRG0, please verify that this is compatible to this BSP (see also bootcard.c).
28
29#include <string.h>
30#include <stdlib.h>
31#include <ctype.h>
32
33#include <rtems/system.h>
34#include <rtems/libio.h>
35#include <rtems/libcsupport.h>
36#include <rtems/powerpc/powerpc.h>
37
38#include <libcpu/spr.h>   /* registers.h is included here */
39#include <bsp.h>
40#include <bsp/uart.h>
41#include <bsp/pci.h>
42#include <libcpu/bat.h>
43#include <libcpu/pte121.h>
44#include <libcpu/cpuIdent.h>
45#include <bsp/vectors.h>
46#include <bsp/bspException.h>
47
48#include <rtems/bspIo.h>
49#include <rtems/sptables.h>
50
51#ifdef __RTEMS_APPLICATION__
52#undef __RTEMS_APPLICATION__
53#endif
54
55/*
56#define SHOW_MORE_INIT_SETTINGS
57#define SHOW_LCR1_REGISTER
58#define SHOW_LCR2_REGISTER
59#define SHOW_LCR3_REGISTER
60#define CONF_VPD
61*/
62
63/* there is no public Workspace_Free() variant :-( */
64#include <rtems/score/wkspace.h>
65
66BSP_output_char_function_type BSP_output_char = BSP_output_char_via_serial;
67
68extern void _return_to_ppcbug(void);
69extern unsigned long __rtems_end[];
70extern unsigned get_L1CR(void), get_L2CR(void), get_L3CR(void);
71extern Triv121PgTbl BSP_pgtbl_setup(unsigned long);
72extern void BSP_pgtbl_activate(Triv121PgTbl);
73extern int I2Cread_eeprom(unsigned char I2cBusAddr, uint32_t devA2A1A0, uint32_t AddrBytes, unsigned char *pBuff, uint32_t numBytes);
74extern void BSP_vme_config(void);
75
76uint32_t bsp_clicks_per_usec;
77
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
131 */
132#define INIT_STACK_SIZE 0x1000
133
134void BSP_panic(char *s)
135{
136  printk("%s PANIC %s\n",_RTEMS_version, s);
137  __asm__ __volatile ("sc");
138}
139
140void _BSP_Fatal_error(unsigned int v)
141{
142  printk("%s PANIC ERROR %x\n",_RTEMS_version, v);
143  __asm__ __volatile ("sc");
144}
145 
146/*
147 *  Use the shared implementations of the following routines
148 */
149 
150extern void bsp_libc_init( void *, uint32_t, int );
151
152void zero_bss()
153{
154  /* prevent these from being accessed in the short data areas */
155  extern unsigned long __bss_start[], __SBSS_START__[], __SBSS_END__[];
156  extern unsigned long __SBSS2_START__[], __SBSS2_END__[];
157
158  memset(
159    __SBSS_START__,
160    0,
161    ((unsigned) __SBSS_END__) - ((unsigned)__SBSS_START__)
162  );
163  memset(
164    __SBSS2_START__,
165    0,
166    ((unsigned) __SBSS2_END__) - ((unsigned)__SBSS2_START__)
167  );
168  memset(
169    __bss_start,
170    0,
171    ((unsigned) __rtems_end) - ((unsigned)__bss_start)
172  );
173}
174
175/* NOTE: we cannot simply malloc the commandline string;
176 * save_boot_params() is called during a very early stage when
177 * libc/malloc etc. are not yet initialized!
178 *
179 * Here's what we do:
180 *
181 * initial layout setup by the loader (preload.S):
182 *
183 * 0..RTEMS...__rtems_end | cmdline ....... TOP
184 *
185 * After the save_boot_params() routine returns, the stack area will be
186 * set up (start.S):
187 *
188 * 0..RTEMS..__rtems_end | INIT_STACK | IRQ_STACK | ..... TOP
189 *
190 * initialize_executive_early() [called from boot_card()]
191 * will initialize the workspace:
192 *
193 * 0..RTEMS..__rtems_end | INIT_STACK | IRQ_STACK | ...... | workspace | TOP
194 *
195 * and later calls our pretasking_hook() which ends up initializing
196 * libc which in turn initializes the heap
197 *
198 * 0..RTEMS..__rtems_end | INIT_STACK | IRQ_STACK | heap | workspace | TOP
199 *
200 * The idea here is to first move the commandline to the future 'heap' area
201 * from where it will be picked up by our pretasking_hook().
202 * pretasking_hook() then moves it either to INIT_STACK or the workspace
203 * area using proper allocation, initializes libc and finally moves
204 * the data to the environment / malloced areas...
205 */
206
207/* this routine is called early at shared/start/start.S
208 * and must be safe with a not properly aligned stack
209 */
210void
211save_boot_params(
212  void *r3,
213  void *r4,
214  void* r5,
215  char *cmdline_start,
216  char *cmdline_end
217)
218{
219  int i=cmdline_end-cmdline_start;
220
221  if ( i >= CMDLINE_BUF_SIZE )
222    i = CMDLINE_BUF_SIZE-1;
223  else if ( i < 0 )
224    i = 0;
225
226  memmove(cmdline_buf, cmdline_start, i);
227  cmdline_buf[i]=0;
228}
229
230/*
231 *  bsp_start
232 *
233 *  This routine does the bulk of the system initialization.
234 */
235
236void bsp_start( void )
237{
238#ifdef CONF_VPD
239  int i;
240#endif
241  unsigned char *stack;
242  unsigned long   *r1sp;
243#ifdef SHOW_LCR1_REGISTER
244  unsigned l1cr;
245#endif
246#ifdef SHOW_LCR2_REGISTER
247  unsigned l2cr;
248#endif
249#ifdef SHOW_LCR3_REGISTER
250  unsigned l3cr;
251#endif
252  uint32_t intrStackStart;
253  uint32_t intrStackSize;
254  unsigned char *work_space_start;
255  ppc_cpu_id_t myCpu;
256  ppc_cpu_revision_t myCpuRevision;
257  Triv121PgTbl  pt=0;
258
259  /* Till Straumann: 4/2005
260   * Need to map the system registers early, so we can printk...
261   * (otherwise we silently die)
262   */
263  /*
264   * Kate Feng : PCI 0 domain memory space, want to leave room for the VME window
265   */
266  setdbat(2, PCI0_MEM_BASE, PCI0_MEM_BASE, 0x10000000, IO_PAGE);
267
268  /* Till Straumann: 2004
269   * map the PCI 0, 1 Domain I/O space, GT64260B registers
270   * and the reserved area so that the size is the power of 2.
271   *
272   */
273  setdbat(3,PCI0_IO_BASE, PCI0_IO_BASE, 0x2000000, IO_PAGE);
274
275
276  /*
277   * Get CPU identification dynamically. Note that the get_ppc_cpu_type() function
278   * store the result in global variables so that it can be used latter...
279   */
280  myCpu   = get_ppc_cpu_type();
281  myCpuRevision = get_ppc_cpu_revision();
282
283#ifdef SHOW_LCR1_REGISTER
284  l1cr = get_L1CR();
285  printk("Initial L1CR value = %x\n", l1cr);
286#endif
287
288  /*
289   * the initial stack  has aready been set to this value in start.S
290   * so there is no need to set it in r1 again... It is just for info
291   * so that it can be printed without accessing R1.
292   */
293  stack = ((unsigned char*) __rtems_end) +
294          INIT_STACK_SIZE - PPC_MINIMUM_STACK_FRAME_SIZE;
295
296  /* tag the bottom (T. Straumann 6/36/2001 <strauman@slac.stanford.edu>) */
297  *((uint32_t *)stack) = 0;
298
299  /* fill stack with pattern for debugging */
300  __asm__ __volatile__("mr %0, %%r1":"=r"(r1sp));
301  while (--r1sp >= (unsigned long*)__rtems_end)
302    *r1sp=0xeeeeeeee;
303
304  /*
305   * Initialize the interrupt related settings.
306   */
307  intrStackStart = (uint32_t) __rtems_end + INIT_STACK_SIZE;
308  intrStackSize = rtems_configuration_get_interrupt_stack_size();
309  BSP_heap_start = intrStackStart + intrStackSize;
310
311  /*
312   * Initialize default raw exception handlers.
313   */
314  ppc_exc_initialize(
315    PPC_INTERRUPT_DISABLE_MASK_DEFAULT,
316    intrStackStart,
317    intrStackSize
318  );
319
320  /*
321   * Init MMU block address translation to enable hardware
322   * access
323   * More PCI1 memory mapping to be done after BSP_pgtbl_activate.
324   */
325  printk("-----------------------------------------\n");
326  printk("Welcome to %s on MVME5500-0163\n", _RTEMS_version );
327  printk("-----------------------------------------\n");
328
329#ifdef TEST_RETURN_TO_PPCBUG 
330  printk("Hit <Enter> to return to PPCBUG monitor\n");
331  printk("When Finished hit GO. It should print <Back from monitor>\n");
332  debug_getc();
333  _return_to_ppcbug();
334  printk("Back from monitor\n");
335  _return_to_ppcbug();
336#endif /* TEST_RETURN_TO_PPCBUG  */
337
338#ifdef TEST_RAW_EXCEPTION_CODE 
339  printk("Testing exception handling Part 1\n");
340  /*
341   * Cause a software exception
342   */
343  __asm__ __volatile ("sc");
344  /*
345   * Check we can still catch exceptions and returned coorectly.
346   */
347  printk("Testing exception handling Part 2\n");
348  __asm__ __volatile ("sc");
349#endif 
350
351  BSP_mem_size         =  _512M;
352  /* TODO: calculate the BSP_bus_frequency using the REF_CLK bit
353   *       of System Status  register
354   */
355  /* rtems_bsp_delay_in_bus_cycles are defined in registers.h */
356  BSP_bus_frequency      = 133333333;
357  BSP_processor_frequency    = 1000000000;
358  /* P94 : 7455 clocks the TB/DECR at 1/4 of the system bus clock frequency */
359  BSP_time_base_divisor      = 4000;
360
361
362  /* Maybe not setup yet becuase of the warning message */
363  /* Allocate and set up the page table mappings
364   * This is only available on >604 CPUs.
365   *
366   * NOTE: This setup routine may modify the available memory
367   *       size. It is essential to call it before
368   *       calculating the workspace etc.
369   */
370  pt = BSP_pgtbl_setup(&BSP_mem_size);
371  if (!pt)
372     printk("WARNING: unable to setup page tables.\n");
373
374  printk("Now BSP_mem_size = 0x%x\n",BSP_mem_size);
375
376  /* P94 : 7455 TB/DECR is clocked by the system bus clock frequency */
377
378  bsp_clicks_per_usec    = BSP_bus_frequency/(BSP_time_base_divisor * 1000);
379
380  printk(
381    "rtems_configuration_get_work_space_size() = %x\n",
382     rtems_configuration_get_work_space_size()
383  );
384
385  work_space_start =
386    (unsigned char *)BSP_mem_size - rtems_configuration_get_work_space_size();
387
388  if ( work_space_start <= ((unsigned char *)__rtems_end) + INIT_STACK_SIZE +
389        rtems_configuration_get_interrupt_stack_size()) {
390    printk( "bspstart: Not enough RAM!!!\n" );
391    bsp_cleanup();
392  }
393
394  Configuration.work_space_start = work_space_start;
395
396  /*
397   * Initalize RTEMS IRQ system
398   */
399   BSP_rtems_irq_mng_init(0);
400
401#ifdef SHOW_LCR2_REGISTER
402  l2cr = get_L2CR();
403  printk("Initial L2CR value = %x\n", l2cr);
404#endif 
405
406#ifdef SHOW_LCR3_REGISTER
407  /* L3CR needs DEC int. handler installed for bsp_delay()*/
408  l3cr = get_L3CR();
409  printk("Initial L3CR value = %x\n", l3cr);
410#endif 
411
412
413  /* Activate the page table mappings only after
414   * initializing interrupts because the irq_mng_init()
415   * routine needs to modify the text
416   */           
417  if (pt) {
418#ifdef SHOW_MORE_INIT_SETTINGS
419    printk("Page table setup finished; will activate it NOW...\n");
420#endif
421    BSP_pgtbl_activate(pt);
422  }
423
424  /*
425   * PCI 1 domain memory space
426   */
427  setdbat(1, PCI1_MEM_BASE, PCI1_MEM_BASE, 0x10000000, IO_PAGE);
428 
429
430#ifdef SHOW_MORE_INIT_SETTINGS
431  printk("Going to start PCI buses scanning and initialization\n");
432#endif 
433  pci_initialize();
434#ifdef SHOW_MORE_INIT_SETTINGS
435  printk("Number of PCI buses found is : %d\n", pci_bus_count());
436#endif
437
438  /* Install our own exception handler (needs PCI) */
439  globalExceptHdl = BSP_exceptionHandler;
440
441  /* clear hostbridge errors. MCP signal is not used on the MVME5500
442   * PCI config space scanning code will trip otherwise :-(
443   */
444  _BSP_clear_hostbridge_errors(0, 1 /*quiet*/);
445
446  /* Read Configuration Vital Product Data (VPD) */
447  if ( I2Cread_eeprom(0xa8, 4,2, &ConfVPD_buff[0], 150))
448     printk("I2Cread_eeprom() error \n");
449  else {
450#ifdef CONF_VPD
451    printk("\n");
452    for (i=0; i<150; i++) {
453      printk("%2x ", ConfVPD_buff[i]); 
454      if ((i % 20)==0 ) printk("\n");
455    }
456    printk("\n");
457#endif
458  }
459
460#ifdef SHOW_MORE_INIT_SETTINGS
461  printk("MSR %x \n", _read_MSR());
462  printk("Exit from bspstart\n");
463#endif
464
465}
Note: See TracBrowser for help on using the repository browser.