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

4.104.114.84.95
Last change on this file since f774fc06 was 920fb9c, checked in by Joel Sherrill <joel.sherrill@…>, on 11/15/06 at 15:21:24

2006-11-15 Joel Sherrill <joel@…>

  • shared/startup/bspstart.c: Merge c_rtems_main() into boot_card(). This eliminated a file and simplified initialization.
  • Property mode set to 100644
File size: 12.7 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 *  $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)
53void printBAT( int bat, uint32_t upper, uint32_t lower )
54{
55  uint32_t lowest_addr;
56  uint32_t size;
57
58  printk("BAT%d raw(upper=0x%08x, lower=0x%08x) ", bat, upper, lower );
59
60  lowest_addr = (upper & 0xFFFE0000);
61  size = (((upper & 0x00001FFC) >> 2) + 1) * (128 * 1024);
62  printk(" range(0x%08x, 0x%08x) %s%s %s%s%s%s %s\n",
63    lowest_addr,
64    lowest_addr + (size - 1),
65    (upper & 0x01) ? "P" : "p",
66    (upper & 0x02) ? "S" : "s",
67    (lower & 0x08) ? "G" : "g",
68    (lower & 0x10) ? "M" : "m",
69    (lower & 0x20) ? "I" : "i",
70    (lower & 0x40) ? "W" : "w",
71    (lower & 0x01) ? "Read Only" :
72      ((lower & 0x02) ? "Read/Write" : "No Access")
73  );
74}
75
76void ShowBATS(){
77  uint32_t lower;
78  uint32_t upper;
79
80  __MFSPR(536, upper); __MFSPR(537, lower); printBAT( 0, upper, lower );
81  __MFSPR(538, upper); __MFSPR(539, lower); printBAT( 1, upper, lower );
82  __MFSPR(540, upper); __MFSPR(541, lower); printBAT( 2, upper, lower );
83  __MFSPR(542, upper); __MFSPR(543, lower); printBAT( 3, upper, lower );
84}
85#endif
86
87/*
88 * Copy of residuals passed by firmware
89 */
90RESIDUAL residualCopy;
91/*
92 * Copy Additional boot param passed by boot loader
93 */
94#define MAX_LOADER_ADD_PARM 80
95char loaderParam[MAX_LOADER_ADD_PARM];
96/*
97 * Vital Board data Start using DATA RESIDUAL
98 */
99/*
100 * Total memory using RESIDUAL DATA
101 */
102unsigned int BSP_mem_size;
103/*
104 * Where the heap starts; is used by bsp_pretasking_hook;
105 */
106unsigned int BSP_heap_start;
107/*
108 * PCI Bus Frequency
109 */
110unsigned int BSP_bus_frequency;
111/*
112 * processor clock frequency
113 */
114unsigned int BSP_processor_frequency;
115/*
116 * Time base divisior (how many tick for 1 second).
117 */
118unsigned int BSP_time_base_divisor;
119/*
120 * system init stack and soft ir stack size
121 */
122#define INIT_STACK_SIZE 0x1000
123#define INTR_STACK_SIZE CONFIGURE_INTERRUPT_STACK_MEMORY
124
125void BSP_panic(char *s)
126{
127  printk("%s PANIC %s\n",_RTEMS_version, s);
128  __asm__ __volatile ("sc");
129}
130
131void _BSP_Fatal_error(unsigned int v)
132{
133  printk("%s PANIC ERROR %x\n",_RTEMS_version, v);
134  __asm__ __volatile ("sc");
135}
136
137/*
138 *  The original table from the application and our copy of it with
139 *  some changes.
140 */
141
142extern rtems_configuration_table Configuration;
143
144rtems_configuration_table  BSP_Configuration;
145
146rtems_cpu_table Cpu_table;
147
148char *rtems_progname;
149
150/*
151 *  Use the shared implementations of the following routines
152 */
153
154void bsp_postdriver_hook(void);
155void bsp_pretasking_hook(void);
156void bsp_libc_init( void *, uint32_t, int );
157
158void save_boot_params(RESIDUAL* r3, void *r4, void* r5, char *additional_boot_options)
159{
160
161  residualCopy = *r3;
162  strncpy(loaderParam, additional_boot_options, MAX_LOADER_ADD_PARM);
163  loaderParam[MAX_LOADER_ADD_PARM - 1] ='\0';
164}
165
166#if defined(mpc8240) || defined(mpc8245)
167unsigned int EUMBBAR;
168
169/*
170 * Return the current value of the Embedded Utilities Memory Block Base Address
171 * Register (EUMBBAR) as read from the processor configuration register using
172 * Processor Address Map B (CHRP).
173 */
174unsigned int get_eumbbar() {
175  out_le32( (uint32_t*)0xfec00000, 0x80000078 );
176  return in_le32( (uint32_t*)0xfee00000 );
177}
178#endif
179
180/*
181 *  bsp_start
182 *
183 *  This routine does the bulk of the system initialization.
184 */
185
186void bsp_start( void )
187{
188  unsigned char *stack;
189#if !defined(mpc8240) && !defined(mpc8245)
190  unsigned l2cr;
191#endif
192  register uint32_t  intrStack;
193  register uint32_t *intrStackPtr;
194  unsigned char *work_space_start;
195  ppc_cpu_id_t myCpu;
196  ppc_cpu_revision_t myCpuRevision;
197  prep_t boardManufacturer;
198  motorolaBoard myBoard;
199  Triv121PgTbl  pt=0;
200
201  /*
202   * Get CPU identification dynamically. Note that the get_ppc_cpu_type()
203   * function store the result in global variables so that it can be used
204   * later...
205   */
206  myCpu         = get_ppc_cpu_type();
207  myCpuRevision = get_ppc_cpu_revision();
208
209  /*
210   * Init MMU block address translation to enable hardware access
211   */
212
213#if !defined(mvme2100)
214  /*
215   * PC legacy IO space used for inb/outb and all PC compatible hardware
216   */
217  setdbat(1, _IO_BASE, _IO_BASE, 0x10000000, IO_PAGE);
218#endif
219
220  /*
221   * PCI devices memory area. Needed to access OpenPIC features
222   * provided by the Raven
223   *
224   * T. Straumann: give more PCI address space
225   */
226  setdbat(2, PCI_MEM_BASE+PCI_MEM_WIN0, PCI_MEM_BASE+PCI_MEM_WIN0, 0x10000000, IO_PAGE);
227
228  /*
229   * Must have acces to open pic PCI ACK registers provided by the RAVEN
230   */
231  setdbat(3, 0xf0000000, 0xf0000000, 0x10000000, IO_PAGE);
232
233#if defined(mvme2100)
234  /* Need 0xfec00000 mapped for this */
235  EUMBBAR = get_eumbbar();
236#endif
237
238  /*
239   * enables L1 Cache. Note that the L1_caches_enables() codes checks for
240   * relevant CPU type so that the reason why there is no use of myCpu...
241   */
242  L1_caches_enables();
243
244#if !defined(mpc8240) && !defined(mpc8245)
245  /*
246   * Enable L2 Cache. Note that the set_L2CR(L2CR) codes checks for
247   * relevant CPU type (mpc750)...
248   */
249  l2cr = get_L2CR();
250#ifdef SHOW_LCR2_REGISTER
251  printk("Initial L2CR value = %x\n", l2cr);
252#endif
253  if ( (! (l2cr & 0x80000000)) && ((int) l2cr == -1))
254    set_L2CR(0xb9A14000);
255#endif
256
257  /*
258   * the initial stack  has aready been set to this value in start.S
259   * so there is no need to set it in r1 again... It is just for info
260   * so that It can be printed without accessing R1.
261   */
262  stack = ((unsigned char*) __rtems_end) +
263               INIT_STACK_SIZE - PPC_MINIMUM_STACK_FRAME_SIZE;
264
265  /* tag the bottom (T. Straumann 6/36/2001 <strauman@slac.stanford.edu>) */
266  *((uint32_t*)stack) = 0;
267
268  /*
269   * Initialize the interrupt related settings
270   * SPRG1 = software managed IRQ stack
271   *
272   * This could be done later (e.g in IRQ_INIT) but it helps to understand
273   * some settings below...
274   */
275  BSP_heap_start = ((uint32_t) __rtems_end) + INIT_STACK_SIZE + INTR_STACK_SIZE;
276
277  /* reserve space for the marker/tag frame */
278  intrStack      = BSP_heap_start - PPC_MINIMUM_STACK_FRAME_SIZE;
279
280  /* make sure it's properly aligned */
281  intrStack &= ~(CPU_STACK_ALIGNMENT-1);
282
283  /* tag the bottom (T. Straumann 6/36/2001 <strauman@slac.stanford.edu>) */
284  intrStackPtr = (uint32_t*) intrStack;
285  *intrStackPtr = 0;
286
287  _write_SPRG1(intrStack);
288
289  /* signal them that we have fixed PR288 - eventually, this should go away */
290  _write_SPRG0(PPC_BSP_HAS_FIXED_PR288);
291
292  /* initialize_exceptions() evaluates the exceptions_in_RAM flag */
293  Cpu_table.exceptions_in_RAM    = TRUE;
294  /*
295   * Initialize default raw exception handlers. See vectors/vectors_init.c
296   */
297  initialize_exceptions();
298
299  select_console(CONSOLE_LOG);
300
301  /*
302   * We check that the keyboard is present and immediately
303   * select the serial console if not.
304   */
305#if defined(BSP_KBD_IOBASE)
306  { int err;
307    err = kbdreset();
308    if (err) select_console(CONSOLE_SERIAL);
309  }
310#else
311  select_console(CONSOLE_SERIAL);
312#endif
313
314  boardManufacturer   =  checkPrepBoardType(&residualCopy);
315  if (boardManufacturer != PREP_Motorola) {
316    printk("Unsupported hardware vendor\n");
317    while (1);
318  }
319  myBoard = getMotorolaBoard();
320
321  printk("-----------------------------------------\n");
322  printk("Welcome to %s on %s\n", _RTEMS_version,
323                                    motorolaBoardToString(myBoard));
324  printk("-----------------------------------------\n");
325#ifdef SHOW_MORE_INIT_SETTINGS
326  printk("Residuals are located at %x\n", (unsigned) &residualCopy);
327  printk("Additionnal boot options are %s\n", loaderParam);
328  printk("Initial system stack at %x\n",stack);
329  printk("Software IRQ stack at %x\n",intrStack);
330  printk("-----------------------------------------\n");
331#endif
332
333#ifdef TEST_RETURN_TO_PPCBUG
334  printk("Hit <Enter> to return to PPCBUG monitor\n");
335  printk("When Finished hit GO. It should print <Back from monitor>\n");
336  debug_getc();
337  _return_to_ppcbug();
338  printk("Back from monitor\n");
339  _return_to_ppcbug();
340#endif /* TEST_RETURN_TO_PPCBUG  */
341
342#ifdef SHOW_MORE_INIT_SETTINGS
343  printk("Going to start PCI buses scanning and initialization\n");
344#endif
345
346  pci_initialize();
347  {
348    const struct _int_map *bspmap  = motorolaIntMap(currentBoard);
349    if( bspmap ) {
350       printk("pci : Configuring interrupt routing for '%s'\n",
351          motorolaBoardToString(currentBoard));
352       FixupPCI(bspmap, motorolaIntSwizzle(currentBoard));
353    }
354    else
355       printk("pci : Interrupt routing not available for this bsp\n");
356 }
357
358#ifdef SHOW_MORE_INIT_SETTINGS
359  printk("Number of PCI buses found is : %d\n", pci_bus_count());
360#endif
361#ifdef TEST_RAW_EXCEPTION_CODE
362  printk("Testing exception handling Part 1\n");
363  /*
364   * Cause a software exception
365   */
366  __asm__ __volatile ("sc");
367  /*
368   * Check we can still catch exceptions and return coorectly.
369   */
370  printk("Testing exception handling Part 2\n");
371  __asm__ __volatile ("sc");
372
373  /*
374   *  Somehow doing the above seems to clobber SPRG0 on the mvme2100.  It
375   *  is probably a not so subtle hint that you do not want to use PPCBug
376   *  once RTEMS is up and running.  Anyway, we still needs to indicate
377   *  that we have fixed PR288.  Eventually, this should go away.
378   */
379  _write_SPRG0(PPC_BSP_HAS_FIXED_PR288);
380#endif
381
382  BSP_mem_size            = residualCopy.TotalMemory;
383  BSP_bus_frequency       = residualCopy.VitalProductData.ProcessorBusHz;
384  BSP_processor_frequency = residualCopy.VitalProductData.ProcessorHz;
385  BSP_time_base_divisor   = (residualCopy.VitalProductData.TimeBaseDivisor?
386                    residualCopy.VitalProductData.TimeBaseDivisor : 4000);
387
388  /* clear hostbridge errors but leave MCP disabled -
389   * PCI config space scanning code will trip otherwise :-(
390   */
391  _BSP_clear_hostbridge_errors(0 /* enableMCP */, 0/*quiet*/);
392
393  /* Allocate and set up the page table mappings
394   * This is only available on >604 CPUs.
395   *
396   * NOTE: This setup routine may modify the available memory
397   *       size. It is essential to call it before
398   *       calculating the workspace etc.
399   */
400  pt = BSP_pgtbl_setup(&BSP_mem_size);
401
402  if (!pt || TRIV121_MAP_SUCCESS != triv121PgTblMap(
403            pt, TRIV121_121_VSID, 0xfeff0000, 1,
404            TRIV121_ATTR_IO_PAGE, TRIV121_PP_RW_PAGE)) {
405        printk("WARNING: unable to setup page tables VME "
406               "bridge must share PCI space\n");
407  }
408
409  /*
410   * Set up our hooks
411   * Make sure libc_init is done before drivers initialized so that
412   * they can use atexit()
413   */
414
415  Cpu_table.pretasking_hook      = bsp_pretasking_hook;    /* init libc, etc. */
416  Cpu_table.postdriver_hook      = bsp_postdriver_hook;
417  Cpu_table.do_zero_of_workspace = TRUE;
418  Cpu_table.interrupt_stack_size = CONFIGURE_INTERRUPT_STACK_MEMORY;
419  Cpu_table.clicks_per_usec      = BSP_bus_frequency/(BSP_time_base_divisor * 1000);
420
421#ifdef SHOW_MORE_INIT_SETTINGS
422  printk("BSP_Configuration.work_space_size = %x\n",
423          BSP_Configuration.work_space_size);
424#endif
425
426  work_space_start =
427    (unsigned char *)BSP_mem_size - BSP_Configuration.work_space_size;
428
429  if ( work_space_start <=
430       ((unsigned char *)__rtems_end) + INIT_STACK_SIZE + INTR_STACK_SIZE) {
431    printk( "bspstart: Not enough RAM!!!\n" );
432    bsp_cleanup();
433  }
434
435  BSP_Configuration.work_space_start = work_space_start;
436
437  /*
438   * Initalize RTEMS IRQ system
439   */
440  BSP_rtems_irq_mng_init(0);
441
442  /* Activate the page table mappings only after
443   * initializing interrupts because the irq_mng_init()
444   * routine needs to modify the text
445   */
446  if (pt) {
447#ifdef  SHOW_MORE_INIT_SETTINGS
448    printk("Page table setup finished; will activate it NOW...\n");
449#endif
450    BSP_pgtbl_activate(pt);
451    /* finally, switch off DBAT3 */
452    setdbat(3, 0, 0, 0, 0);
453  }
454
455#if defined(DEBUG_BATS)
456  ShowBATS();
457#endif
458
459#ifdef SHOW_MORE_INIT_SETTINGS
460  printk("Exit from bspstart\n");
461#endif
462}
Note: See TracBrowser for help on using the repository browser.