source: rtems/c/src/lib/libbsp/powerpc/shared/startup/bspstart.c @ 4570d76

4.104.114.95
Last change on this file since 4570d76 was 4570d76, checked in by Joel Sherrill <joel.sherrill@…>, on 05/12/08 at 18:42:39

2008-05-12 Joel Sherrill <joel.sherrill@…>

  • shared/startup/bspstart.c: Refactored and renamed initialization routines to rtems_initialize_data_structures, rtems_initialize_before_drivers, rtems_initialize_device_drivers, and rtems_initialize_start_multitasking. This opened the sequence up so that bootcard() could provide a more robust and flexible framework which is easier to explain and understand. This also lays the groundwork for sharing the division of available memory between the RTEMS workspace and heap and the C library initialization across all BSPs.
  • Property mode set to 100644
File size: 11.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 *  $Id$
18 */
19
20#include <string.h>
21
22#include <bsp.h>
23#include <rtems/libio.h>
24#include <rtems/libcsupport.h>
25#include <rtems/bspIo.h>
26#include <bsp/consoleIo.h>
27#include <libcpu/spr.h>
28#include <bsp/residual.h>
29#include <bsp/pci.h>
30#include <bsp/openpic.h>
31#include <bsp/irq.h>
32#include <libcpu/bat.h>
33#include <libcpu/pte121.h>
34#include <libcpu/cpuIdent.h>
35#include <bsp/vectors.h>
36#include <bsp/motorola.h>
37#include <rtems/powerpc/powerpc.h>
38
39extern void _return_to_ppcbug();
40extern unsigned long __rtems_end[];
41extern void L1_caches_enables();
42extern unsigned get_L2CR();
43extern void set_L2CR(unsigned);
44extern void bsp_cleanup(void);
45extern Triv121PgTbl BSP_pgtbl_setup();
46extern void                     BSP_pgtbl_activate();
47extern void                     BSP_vme_config();
48
49SPR_RW(SPRG0)
50SPR_RW(SPRG1)
51
52#if defined(DEBUG_BATS)
53extern void ShowBATS();`
54#endif
55
56/*
57 *  Driver configuration parameters
58 */
59uint32_t   bsp_clicks_per_usec;
60
61/*
62 * Copy of residuals passed by firmware
63 */
64RESIDUAL residualCopy;
65/*
66 * Copy Additional boot param passed by boot loader
67 */
68#define MAX_LOADER_ADD_PARM 80
69char loaderParam[MAX_LOADER_ADD_PARM];
70
71char *BSP_commandline_string = loaderParam;
72/*
73 * Vital Board data Start using DATA RESIDUAL
74 */
75/*
76 * Total memory using RESIDUAL DATA
77 */
78unsigned int BSP_mem_size;
79/*
80 * Where the heap starts; is used by bsp_pretasking_hook;
81 */
82unsigned int BSP_heap_start;
83/*
84 * PCI Bus Frequency
85 */
86unsigned int BSP_bus_frequency;
87/*
88 * processor clock frequency
89 */
90unsigned int BSP_processor_frequency;
91/*
92 * Time base divisior (how many tick for 1 second).
93 */
94unsigned int BSP_time_base_divisor;
95/*
96 * system init stack
97 */
98#define INIT_STACK_SIZE 0x1000
99
100void BSP_panic(char *s)
101{
102  printk("%s PANIC %s\n",_RTEMS_version, s);
103  __asm__ __volatile ("sc");
104}
105
106void _BSP_Fatal_error(unsigned int v)
107{
108  printk("%s PANIC ERROR %x\n",_RTEMS_version, v);
109  __asm__ __volatile ("sc");
110}
111
112/*
113 *  Use the shared implementations of the following routines
114 */
115
116void bsp_libc_init( void *, uint32_t, int );
117
118void save_boot_params(RESIDUAL* r3, void *r4, void* r5, char *additional_boot_options)
119{
120
121  residualCopy = *r3;
122  strncpy(loaderParam, additional_boot_options, MAX_LOADER_ADD_PARM);
123  loaderParam[MAX_LOADER_ADD_PARM - 1] ='\0';
124}
125
126#if defined(mvme2100)
127unsigned int EUMBBAR;
128
129/*
130 * Return the current value of the Embedded Utilities Memory Block Base Address
131 * Register (EUMBBAR) as read from the processor configuration register using
132 * Processor Address Map B (CHRP).
133 */
134unsigned int get_eumbbar() {
135  out_le32( (uint32_t*)0xfec00000, 0x80000078 );
136  return in_le32( (uint32_t*)0xfee00000 );
137}
138#endif
139
140/*
141 *  bsp_start
142 *
143 *  This routine does the bulk of the system initialization.
144 */
145
146void bsp_start( void )
147{
148  unsigned char *stack;
149#if !defined(mvme2100)
150  unsigned l2cr;
151#endif
152  register uint32_t  intrStack;
153  register uint32_t *intrStackPtr;
154  unsigned char *work_space_start;
155  ppc_cpu_id_t myCpu;
156  ppc_cpu_revision_t myCpuRevision;
157  prep_t boardManufacturer;
158  motorolaBoard myBoard;
159  Triv121PgTbl  pt=0;
160
161  /*
162   * Get CPU identification dynamically. Note that the get_ppc_cpu_type()
163   * function store the result in global variables so that it can be used
164   * later...
165   */
166  myCpu         = get_ppc_cpu_type();
167  myCpuRevision = get_ppc_cpu_revision();
168
169  /*
170   * Init MMU block address translation to enable hardware access
171   */
172
173#if !defined(mvme2100)
174  /*
175   * PC legacy IO space used for inb/outb and all PC compatible hardware
176   */
177  setdbat(1, _IO_BASE, _IO_BASE, 0x10000000, IO_PAGE);
178#endif
179
180  /*
181   * PCI devices memory area. Needed to access OpenPIC features
182   * provided by the Raven
183   *
184   * T. Straumann: give more PCI address space
185   */
186  setdbat(2, PCI_MEM_BASE+PCI_MEM_WIN0, PCI_MEM_BASE+PCI_MEM_WIN0, 0x10000000, IO_PAGE);
187
188  /*
189   * Must have acces to open pic PCI ACK registers provided by the RAVEN
190   */
191  setdbat(3, 0xf0000000, 0xf0000000, 0x10000000, IO_PAGE);
192
193#if defined(mvme2100)
194  /* Need 0xfec00000 mapped for this */
195  EUMBBAR = get_eumbbar();
196#endif
197
198  /*
199   * enables L1 Cache. Note that the L1_caches_enables() codes checks for
200   * relevant CPU type so that the reason why there is no use of myCpu...
201   */
202  L1_caches_enables();
203
204#if !defined(mvme2100)
205  /*
206   * Enable L2 Cache. Note that the set_L2CR(L2CR) codes checks for
207   * relevant CPU type (mpc750)...
208   */
209  l2cr = get_L2CR();
210#ifdef SHOW_LCR2_REGISTER
211  printk("Initial L2CR value = %x\n", l2cr);
212#endif
213  if ( (! (l2cr & 0x80000000)) && ((int) l2cr == -1))
214    set_L2CR(0xb9A14000);
215#endif
216
217  /*
218   * the initial stack  has aready been set to this value in start.S
219   * so there is no need to set it in r1 again... It is just for info
220   * so that It can be printed without accessing R1.
221   */
222  stack = ((unsigned char*) __rtems_end) +
223               INIT_STACK_SIZE - PPC_MINIMUM_STACK_FRAME_SIZE;
224
225  /* tag the bottom (T. Straumann 6/36/2001 <strauman@slac.stanford.edu>) */
226  *((uint32_t*)stack) = 0;
227
228  /*
229   * Initialize the interrupt related settings
230   * SPRG1 = software managed IRQ stack
231   *
232   * This could be done later (e.g in IRQ_INIT) but it helps to understand
233   * some settings below...
234   */
235  BSP_heap_start = ((uint32_t) __rtems_end) +
236    INIT_STACK_SIZE + rtems_configuration_get_interrupt_stack_size();
237
238  /* reserve space for the marker/tag frame */
239  intrStack      = BSP_heap_start - PPC_MINIMUM_STACK_FRAME_SIZE;
240
241  /* make sure it's properly aligned */
242  intrStack &= ~(CPU_STACK_ALIGNMENT-1);
243
244  /* tag the bottom (T. Straumann 6/36/2001 <strauman@slac.stanford.edu>) */
245  intrStackPtr = (uint32_t*) intrStack;
246  *intrStackPtr = 0;
247
248  _write_SPRG1(intrStack);
249
250  /* signal them that we have fixed PR288 - eventually, this should go away */
251  _write_SPRG0(PPC_BSP_HAS_FIXED_PR288);
252
253  /*
254   * Initialize default raw exception handlers. See vectors/vectors_init.c
255   */
256  initialize_exceptions();
257
258  select_console(CONSOLE_LOG);
259
260  /*
261   * We check that the keyboard is present and immediately
262   * select the serial console if not.
263   */
264#if defined(BSP_KBD_IOBASE)
265  { int err;
266    err = kbdreset();
267    if (err) select_console(CONSOLE_SERIAL);
268  }
269#else
270  select_console(CONSOLE_SERIAL);
271#endif
272
273  boardManufacturer   =  checkPrepBoardType(&residualCopy);
274  if (boardManufacturer != PREP_Motorola) {
275    printk("Unsupported hardware vendor\n");
276    while (1);
277  }
278  myBoard = getMotorolaBoard();
279
280  printk("-----------------------------------------\n");
281  printk("Welcome to %s on %s\n", _RTEMS_version,
282                                    motorolaBoardToString(myBoard));
283  printk("-----------------------------------------\n");
284#ifdef SHOW_MORE_INIT_SETTINGS
285  printk("Residuals are located at %x\n", (unsigned) &residualCopy);
286  printk("Additionnal boot options are %s\n", loaderParam);
287  printk("Initial system stack at %x\n",stack);
288  printk("Software IRQ stack at %x\n",intrStack);
289  printk("-----------------------------------------\n");
290#endif
291
292#ifdef TEST_RETURN_TO_PPCBUG
293  printk("Hit <Enter> to return to PPCBUG monitor\n");
294  printk("When Finished hit GO. It should print <Back from monitor>\n");
295  debug_getc();
296  _return_to_ppcbug();
297  printk("Back from monitor\n");
298  _return_to_ppcbug();
299#endif /* TEST_RETURN_TO_PPCBUG  */
300
301#ifdef SHOW_MORE_INIT_SETTINGS
302  printk("Going to start PCI buses scanning and initialization\n");
303#endif
304
305  pci_initialize();
306  {
307    const struct _int_map *bspmap  = motorolaIntMap(currentBoard);
308    if( bspmap ) {
309       printk("pci : Configuring interrupt routing for '%s'\n",
310          motorolaBoardToString(currentBoard));
311       FixupPCI(bspmap, motorolaIntSwizzle(currentBoard));
312    }
313    else
314       printk("pci : Interrupt routing not available for this bsp\n");
315 }
316
317#ifdef SHOW_MORE_INIT_SETTINGS
318  printk("Number of PCI buses found is : %d\n", pci_bus_count());
319#endif
320#ifdef TEST_RAW_EXCEPTION_CODE
321  printk("Testing exception handling Part 1\n");
322  /*
323   * Cause a software exception
324   */
325  __asm__ __volatile ("sc");
326  /*
327   * Check we can still catch exceptions and return coorectly.
328   */
329  printk("Testing exception handling Part 2\n");
330  __asm__ __volatile ("sc");
331
332  /*
333   *  Somehow doing the above seems to clobber SPRG0 on the mvme2100.  It
334   *  is probably a not so subtle hint that you do not want to use PPCBug
335   *  once RTEMS is up and running.  Anyway, we still needs to indicate
336   *  that we have fixed PR288.  Eventually, this should go away.
337   */
338  _write_SPRG0(PPC_BSP_HAS_FIXED_PR288);
339#endif
340
341  BSP_mem_size            = residualCopy.TotalMemory;
342  BSP_bus_frequency       = residualCopy.VitalProductData.ProcessorBusHz;
343  BSP_processor_frequency = residualCopy.VitalProductData.ProcessorHz;
344  BSP_time_base_divisor   = (residualCopy.VitalProductData.TimeBaseDivisor?
345                    residualCopy.VitalProductData.TimeBaseDivisor : 4000);
346
347  /* clear hostbridge errors but leave MCP disabled -
348   * PCI config space scanning code will trip otherwise :-(
349   */
350  _BSP_clear_hostbridge_errors(0 /* enableMCP */, 0/*quiet*/);
351
352  /* Allocate and set up the page table mappings
353   * This is only available on >604 CPUs.
354   *
355   * NOTE: This setup routine may modify the available memory
356   *       size. It is essential to call it before
357   *       calculating the workspace etc.
358   */
359  pt = BSP_pgtbl_setup(&BSP_mem_size);
360
361  if (!pt || TRIV121_MAP_SUCCESS != triv121PgTblMap(
362            pt, TRIV121_121_VSID, 0xfeff0000, 1,
363            TRIV121_ATTR_IO_PAGE, TRIV121_PP_RW_PAGE)) {
364        printk("WARNING: unable to setup page tables VME "
365               "bridge must share PCI space\n");
366  }
367
368  /*
369   *  initialize the device driver parameters
370   */
371  bsp_clicks_per_usec    = BSP_bus_frequency/(BSP_time_base_divisor * 1000);
372
373#ifdef SHOW_MORE_INIT_SETTINGS
374  printk("rtems_configuration_get_work_space_size() = %x\n",
375          rtems_configuration_get_work_space_size());
376#endif
377
378  work_space_start =
379    (unsigned char *)BSP_mem_size - rtems_configuration_get_work_space_size();
380
381  if ( work_space_start <= ((unsigned char *)__rtems_end) + INIT_STACK_SIZE +
382        rtems_configuration_get_interrupt_stack_size()) {
383    printk( "bspstart: Not enough RAM!!!\n" );
384    bsp_cleanup();
385  }
386
387  Configuration.work_space_start = work_space_start;
388
389  /*
390   * Initalize RTEMS IRQ system
391   */
392  BSP_rtems_irq_mng_init(0);
393
394  /* Activate the page table mappings only after
395   * initializing interrupts because the irq_mng_init()
396   * routine needs to modify the text
397   */
398  if (pt) {
399#ifdef  SHOW_MORE_INIT_SETTINGS
400    printk("Page table setup finished; will activate it NOW...\n");
401#endif
402    BSP_pgtbl_activate(pt);
403    /* finally, switch off DBAT3 */
404    setdbat(3, 0, 0, 0, 0);
405  }
406
407#if defined(DEBUG_BATS)
408  ShowBATS();
409#endif
410
411#ifdef SHOW_MORE_INIT_SETTINGS
412  printk("Exit from bspstart\n");
413#endif
414}
Note: See TracBrowser for help on using the repository browser.