source: rtems/c/src/lib/libbsp/powerpc/shared/startup/bspstart.c @ 4b39acf

4.104.114.95
Last change on this file since 4b39acf was 4b39acf, checked in by Joel Sherrill <joel.sherrill@…>, on 12/11/07 at 15:46:56

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

  • shared/startup/bspstart.c, shared/startup/pretaskinghook.c: Eliminate copies of the Configuration Table. Use the RTEMS provided accessor macros to obtain configuration fields.
  • 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_postdriver_hook(void);
117void bsp_pretasking_hook(void);
118void bsp_libc_init( void *, uint32_t, int );
119
120void save_boot_params(RESIDUAL* r3, void *r4, void* r5, char *additional_boot_options)
121{
122
123  residualCopy = *r3;
124  strncpy(loaderParam, additional_boot_options, MAX_LOADER_ADD_PARM);
125  loaderParam[MAX_LOADER_ADD_PARM - 1] ='\0';
126}
127
128#if defined(mvme2100)
129unsigned int EUMBBAR;
130
131/*
132 * Return the current value of the Embedded Utilities Memory Block Base Address
133 * Register (EUMBBAR) as read from the processor configuration register using
134 * Processor Address Map B (CHRP).
135 */
136unsigned int get_eumbbar() {
137  out_le32( (uint32_t*)0xfec00000, 0x80000078 );
138  return in_le32( (uint32_t*)0xfee00000 );
139}
140#endif
141
142/*
143 *  bsp_start
144 *
145 *  This routine does the bulk of the system initialization.
146 */
147
148void bsp_start( void )
149{
150  unsigned char *stack;
151#if !defined(mvme2100)
152  unsigned l2cr;
153#endif
154  register uint32_t  intrStack;
155  register uint32_t *intrStackPtr;
156  unsigned char *work_space_start;
157  ppc_cpu_id_t myCpu;
158  ppc_cpu_revision_t myCpuRevision;
159  prep_t boardManufacturer;
160  motorolaBoard myBoard;
161  Triv121PgTbl  pt=0;
162
163  /*
164   * Get CPU identification dynamically. Note that the get_ppc_cpu_type()
165   * function store the result in global variables so that it can be used
166   * later...
167   */
168  myCpu         = get_ppc_cpu_type();
169  myCpuRevision = get_ppc_cpu_revision();
170
171  /*
172   * Init MMU block address translation to enable hardware access
173   */
174
175#if !defined(mvme2100)
176  /*
177   * PC legacy IO space used for inb/outb and all PC compatible hardware
178   */
179  setdbat(1, _IO_BASE, _IO_BASE, 0x10000000, IO_PAGE);
180#endif
181
182  /*
183   * PCI devices memory area. Needed to access OpenPIC features
184   * provided by the Raven
185   *
186   * T. Straumann: give more PCI address space
187   */
188  setdbat(2, PCI_MEM_BASE+PCI_MEM_WIN0, PCI_MEM_BASE+PCI_MEM_WIN0, 0x10000000, IO_PAGE);
189
190  /*
191   * Must have acces to open pic PCI ACK registers provided by the RAVEN
192   */
193  setdbat(3, 0xf0000000, 0xf0000000, 0x10000000, IO_PAGE);
194
195#if defined(mvme2100)
196  /* Need 0xfec00000 mapped for this */
197  EUMBBAR = get_eumbbar();
198#endif
199
200  /*
201   * enables L1 Cache. Note that the L1_caches_enables() codes checks for
202   * relevant CPU type so that the reason why there is no use of myCpu...
203   */
204  L1_caches_enables();
205
206#if !defined(mvme2100)
207  /*
208   * Enable L2 Cache. Note that the set_L2CR(L2CR) codes checks for
209   * relevant CPU type (mpc750)...
210   */
211  l2cr = get_L2CR();
212#ifdef SHOW_LCR2_REGISTER
213  printk("Initial L2CR value = %x\n", l2cr);
214#endif
215  if ( (! (l2cr & 0x80000000)) && ((int) l2cr == -1))
216    set_L2CR(0xb9A14000);
217#endif
218
219  /*
220   * the initial stack  has aready been set to this value in start.S
221   * so there is no need to set it in r1 again... It is just for info
222   * so that It can be printed without accessing R1.
223   */
224  stack = ((unsigned char*) __rtems_end) +
225               INIT_STACK_SIZE - PPC_MINIMUM_STACK_FRAME_SIZE;
226
227  /* tag the bottom (T. Straumann 6/36/2001 <strauman@slac.stanford.edu>) */
228  *((uint32_t*)stack) = 0;
229
230  /*
231   * Initialize the interrupt related settings
232   * SPRG1 = software managed IRQ stack
233   *
234   * This could be done later (e.g in IRQ_INIT) but it helps to understand
235   * some settings below...
236   */
237  BSP_heap_start = ((uint32_t) __rtems_end) +
238    INIT_STACK_SIZE + rtems_configuration_get_interrupt_stack_size();
239
240  /* reserve space for the marker/tag frame */
241  intrStack      = BSP_heap_start - PPC_MINIMUM_STACK_FRAME_SIZE;
242
243  /* make sure it's properly aligned */
244  intrStack &= ~(CPU_STACK_ALIGNMENT-1);
245
246  /* tag the bottom (T. Straumann 6/36/2001 <strauman@slac.stanford.edu>) */
247  intrStackPtr = (uint32_t*) intrStack;
248  *intrStackPtr = 0;
249
250  _write_SPRG1(intrStack);
251
252  /* signal them that we have fixed PR288 - eventually, this should go away */
253  _write_SPRG0(PPC_BSP_HAS_FIXED_PR288);
254
255  /*
256   * Initialize default raw exception handlers. See vectors/vectors_init.c
257   */
258  initialize_exceptions();
259
260  select_console(CONSOLE_LOG);
261
262  /*
263   * We check that the keyboard is present and immediately
264   * select the serial console if not.
265   */
266#if defined(BSP_KBD_IOBASE)
267  { int err;
268    err = kbdreset();
269    if (err) select_console(CONSOLE_SERIAL);
270  }
271#else
272  select_console(CONSOLE_SERIAL);
273#endif
274
275  boardManufacturer   =  checkPrepBoardType(&residualCopy);
276  if (boardManufacturer != PREP_Motorola) {
277    printk("Unsupported hardware vendor\n");
278    while (1);
279  }
280  myBoard = getMotorolaBoard();
281
282  printk("-----------------------------------------\n");
283  printk("Welcome to %s on %s\n", _RTEMS_version,
284                                    motorolaBoardToString(myBoard));
285  printk("-----------------------------------------\n");
286#ifdef SHOW_MORE_INIT_SETTINGS
287  printk("Residuals are located at %x\n", (unsigned) &residualCopy);
288  printk("Additionnal boot options are %s\n", loaderParam);
289  printk("Initial system stack at %x\n",stack);
290  printk("Software IRQ stack at %x\n",intrStack);
291  printk("-----------------------------------------\n");
292#endif
293
294#ifdef TEST_RETURN_TO_PPCBUG
295  printk("Hit <Enter> to return to PPCBUG monitor\n");
296  printk("When Finished hit GO. It should print <Back from monitor>\n");
297  debug_getc();
298  _return_to_ppcbug();
299  printk("Back from monitor\n");
300  _return_to_ppcbug();
301#endif /* TEST_RETURN_TO_PPCBUG  */
302
303#ifdef SHOW_MORE_INIT_SETTINGS
304  printk("Going to start PCI buses scanning and initialization\n");
305#endif
306
307  pci_initialize();
308  {
309    const struct _int_map *bspmap  = motorolaIntMap(currentBoard);
310    if( bspmap ) {
311       printk("pci : Configuring interrupt routing for '%s'\n",
312          motorolaBoardToString(currentBoard));
313       FixupPCI(bspmap, motorolaIntSwizzle(currentBoard));
314    }
315    else
316       printk("pci : Interrupt routing not available for this bsp\n");
317 }
318
319#ifdef SHOW_MORE_INIT_SETTINGS
320  printk("Number of PCI buses found is : %d\n", pci_bus_count());
321#endif
322#ifdef TEST_RAW_EXCEPTION_CODE
323  printk("Testing exception handling Part 1\n");
324  /*
325   * Cause a software exception
326   */
327  __asm__ __volatile ("sc");
328  /*
329   * Check we can still catch exceptions and return coorectly.
330   */
331  printk("Testing exception handling Part 2\n");
332  __asm__ __volatile ("sc");
333
334  /*
335   *  Somehow doing the above seems to clobber SPRG0 on the mvme2100.  It
336   *  is probably a not so subtle hint that you do not want to use PPCBug
337   *  once RTEMS is up and running.  Anyway, we still needs to indicate
338   *  that we have fixed PR288.  Eventually, this should go away.
339   */
340  _write_SPRG0(PPC_BSP_HAS_FIXED_PR288);
341#endif
342
343  BSP_mem_size            = residualCopy.TotalMemory;
344  BSP_bus_frequency       = residualCopy.VitalProductData.ProcessorBusHz;
345  BSP_processor_frequency = residualCopy.VitalProductData.ProcessorHz;
346  BSP_time_base_divisor   = (residualCopy.VitalProductData.TimeBaseDivisor?
347                    residualCopy.VitalProductData.TimeBaseDivisor : 4000);
348
349  /* clear hostbridge errors but leave MCP disabled -
350   * PCI config space scanning code will trip otherwise :-(
351   */
352  _BSP_clear_hostbridge_errors(0 /* enableMCP */, 0/*quiet*/);
353
354  /* Allocate and set up the page table mappings
355   * This is only available on >604 CPUs.
356   *
357   * NOTE: This setup routine may modify the available memory
358   *       size. It is essential to call it before
359   *       calculating the workspace etc.
360   */
361  pt = BSP_pgtbl_setup(&BSP_mem_size);
362
363  if (!pt || TRIV121_MAP_SUCCESS != triv121PgTblMap(
364            pt, TRIV121_121_VSID, 0xfeff0000, 1,
365            TRIV121_ATTR_IO_PAGE, TRIV121_PP_RW_PAGE)) {
366        printk("WARNING: unable to setup page tables VME "
367               "bridge must share PCI space\n");
368  }
369
370  /*
371   *  initialize the device driver parameters
372   */
373  bsp_clicks_per_usec    = BSP_bus_frequency/(BSP_time_base_divisor * 1000);
374
375#ifdef SHOW_MORE_INIT_SETTINGS
376  printk("rtems_configuration_get_work_space_size() = %x\n",
377          rtems_configuration_get_work_space_size());
378#endif
379
380  work_space_start =
381    (unsigned char *)BSP_mem_size - rtems_configuration_get_work_space_size();
382
383  if ( work_space_start <= ((unsigned char *)__rtems_end) + INIT_STACK_SIZE +
384        rtems_configuration_get_interrupt_stack_size()) {
385    printk( "bspstart: Not enough RAM!!!\n" );
386    bsp_cleanup();
387  }
388
389  Configuration.work_space_start = work_space_start;
390
391  /*
392   * Initalize RTEMS IRQ system
393   */
394  BSP_rtems_irq_mng_init(0);
395
396  /* Activate the page table mappings only after
397   * initializing interrupts because the irq_mng_init()
398   * routine needs to modify the text
399   */
400  if (pt) {
401#ifdef  SHOW_MORE_INIT_SETTINGS
402    printk("Page table setup finished; will activate it NOW...\n");
403#endif
404    BSP_pgtbl_activate(pt);
405    /* finally, switch off DBAT3 */
406    setdbat(3, 0, 0, 0, 0);
407  }
408
409#if defined(DEBUG_BATS)
410  ShowBATS();
411#endif
412
413#ifdef SHOW_MORE_INIT_SETTINGS
414  printk("Exit from bspstart\n");
415#endif
416}
Note: See TracBrowser for help on using the repository browser.