source: rtems/c/src/lib/libbsp/powerpc/beatnik/startup/bspstart.c @ f17a8e01

4.115
Last change on this file since f17a8e01 was f17a8e01, checked in by Ralf Corsepius <ralf.corsepius@…>, on 01/26/11 at 12:27:46

2011-01-26 Ralf Corsépius <ralf.corsepius@…>

  • network/porting/README, network/porting/if_xxx_rtems.c, startup/bspstart.c: Remove CVS artefacts.
  • Property mode set to 100644
File size: 11.3 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.OARcorp.com/rtems/license.html.
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 BSP
21 *  (C) by Kate Feng <feng1@bnl.gov>, 2003, 2004
22 *      under the contract DE-AC02-98CH10886 with the Deaprtment of Energy
23 *
24 *  T. Straumann: 2005-2007; stolen again for 'beatnik'...
25 */
26#include <string.h>
27#include <stdlib.h>
28#include <ctype.h>
29
30#include <rtems/system.h>
31#include <rtems/libio.h>
32#include <rtems/libcsupport.h>
33#include <rtems/bspIo.h>
34#include <rtems/powerpc/powerpc.h>
35/*#include <bsp/consoleIo.h>*/
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 <bsp/gtreg.h>
41#include <bsp/gt_timer.h>
42#include <libcpu/bat.h>
43#include <libcpu/pte121.h>
44#include <libcpu/cpuIdent.h>
45#include <bsp/vectors.h>
46#include <bsp/vpd.h>
47
48/* for RTEMS_VERSION :-( I dont like the preassembled string */
49#include <rtems/sptables.h>
50
51#ifdef __RTEMS_APPLICATION__
52#undef __RTEMS_APPLICATION__
53#endif
54
55#define SHOW_MORE_INIT_SETTINGS
56
57BSP_output_char_function_type     BSP_output_char = BSP_output_char_via_serial;
58BSP_polling_getchar_function_type BSP_poll_char = NULL;
59
60extern char *BSP_build_date;
61extern void bsp_cleanup(void);
62extern Triv121PgTbl BSP_pgtbl_setup(unsigned int *);
63extern void BSP_pgtbl_activate(Triv121PgTbl);
64extern void BSP_motload_pci_fixup(void);
65
66extern unsigned long __rtems_end[];
67
68/* We really shouldn't use these since MMUoff also sets IP;
69 * nevertheless, during early init I don't care for now
70 */
71extern void MMUoff(void);
72extern void MMUon(void);
73
74extern uint32_t probeMemoryEnd(void);
75
76SPR_RW(SPRG0)
77SPR_RW(SPRG1)
78SPR_RO(HID1)
79
80/* Table of PLL multipliers for 7455/7457:
8101000   2     00010   7.5       00000   11.5      00001   17
8210000   3     11000   8         10111   12        00101   18
8310100   4     01100   8.5       11111   12.5      00111   20
8410110   5     01111   9         01011   13        01001   21
8510010   5.5   01110   9.5       11100   13.5      01101   24
8611010   6     10101   10        11001   14        11101   28
8701010   6.5   10001   10.5      00011   15        00110   bypass
8800100   7     10011   11        11011   16        11110   off
89*/
90
91/* Sorted according to CFG bits and multiplied by 2 it looks
92 * like this (note that this is in sequential order, not
93 * tabulated as above)
94 */
95signed char mpc7450PllMultByTwo[32] = {
9623,       34,           15,           30,
9714,       36,           2/*bypass*/,  40,
984,        42,           13,           26,
9917,       48,           19,           18,
1006,        21,           11,           22,
1018,        20,           10,           24,
10216,       28,           12,           32,
10327,       56,           0/*off*/,     25,
104};
105
106uint32_t bsp_clicks_per_usec         = 0;
107
108/*
109 * Total memory using probing.
110 */
111unsigned int BSP_mem_size;
112
113/*
114 * PCI Bus Frequency
115 */
116unsigned int BSP_bus_frequency       = 0xdeadbeef;
117/*
118 * processor clock frequency
119 */
120unsigned int BSP_processor_frequency = 0xdeadbeef;
121
122/*
123 * Time base divisior (bus freq / TB clock)
124 */
125unsigned int BSP_time_base_divisor   = 4000; /* most 604+ CPUs seem to use this */
126
127/* Board identification string */
128char BSP_productIdent[20] = {0};
129char BSP_serialNumber[20] = {0};
130
131/* VPD appends an extra char -- what for ? */
132char BSP_enetAddr0[7] = {0};
133char BSP_enetAddr1[7] = {0};
134
135/*
136 *  The original table from the application and our copy of it with
137 *  some changes.
138 */
139
140extern rtems_configuration_table Configuration;
141
142char *rtems_progname;
143
144/*
145 *  Use the shared implementations of the following routines
146 */
147 
148extern void bsp_pretasking_hook(void);
149
150#define CMDLINE_BUF_SIZE        2048
151
152static char cmdline_buf[CMDLINE_BUF_SIZE];
153char *BSP_commandline_string = cmdline_buf;
154
155/* this routine is called early and must be safe with a not properly
156 * aligned stack
157 */
158char *
159save_boot_params(void *r3, void *r4, void* r5, char *cmdline_start, char *cmdline_end)
160{
161int             i=cmdline_end-cmdline_start;
162        if ( i >= CMDLINE_BUF_SIZE )
163                i = CMDLINE_BUF_SIZE-1;
164        else if ( i < 0 )
165                i = 0;
166        memmove(cmdline_buf, cmdline_start, i);
167        cmdline_buf[i]=0;
168    return cmdline_buf;
169}
170
171static BSP_BoardType    board_type = Unknown;
172
173BSP_BoardType
174BSP_getBoardType( void )
175{
176        return board_type;
177}
178
179/*
180 *  bsp_start
181 *
182 *  This routine does the bulk of the system initialization.
183 */
184
185void bsp_start( void )
186{
187  unsigned char  *stack;
188  char           *chpt;
189  uint32_t       intrStackStart;
190  uint32_t       intrStackSize;
191
192  Triv121PgTbl  pt=0;
193
194  VpdBufRec vpdData [] = {
195        { key: ProductIdent, instance: 0, buf: BSP_productIdent, buflen: sizeof(BSP_productIdent) - 1 },
196        { key: SerialNumber, instance: 0, buf: BSP_serialNumber, buflen: sizeof(BSP_serialNumber) - 1 },
197        { key: CpuClockHz,   instance: 0, buf: &BSP_processor_frequency, buflen: sizeof(BSP_processor_frequency)  },
198        { key: BusClockHz,   instance: 0, buf: &BSP_bus_frequency, buflen: sizeof(BSP_bus_frequency)  },
199        { key: EthernetAddr, instance: 0, buf: BSP_enetAddr0, buflen: sizeof(BSP_enetAddr0) },
200        { key: EthernetAddr, instance: 1, buf: BSP_enetAddr1, buflen: sizeof(BSP_enetAddr1) },
201        VPD_END
202  };
203
204  /* T. Straumann: 4/2005
205   *
206   * Need to map the system registers early, so we can printk...
207   * (otherwise we silently die)
208   */
209  /* map the PCI 0, 1 Domain I/O space, GT64260B registers
210   * and the reserved area so that the size is the power of 2.
211   */
212  setdbat(7, BSP_DEV_AND_PCI_IO_BASE, BSP_DEV_AND_PCI_IO_BASE, BSP_DEV_AND_PCI_IO_SIZE, IO_PAGE);
213
214  /* Intersperse messages with actions to help locate problems */
215  printk("-----------------------------------------\n");
216
217  /*
218   * Get CPU identification dynamically. Note that the get_ppc_cpu_type() & friends functions
219   * store the result in global variables so that it can be used latter...
220   * This also verifies that we run on a known CPU.
221   */
222  get_ppc_cpu_type();
223  get_ppc_cpu_revision();
224
225  /* Make sure we detect a known host bridge */
226  BSP_getDiscoveryVersion(/* assert detection */ 1);
227
228  printk("Welcome to RTEMS %s\n", _RTEMS_version );
229
230  /* Leave all caches as MotLoad left them. Seems to be fine */
231
232  /*
233   * the initial stack  has aready been set to this value in start.S
234   * so there is no need to set it in r1 again... It is just for info
235   * so that it can be printed without accessing R1.
236   */
237  asm volatile("mr %0, 1":"=r"(stack));
238
239  /* tag the bottom (T. Straumann 6/36/2001 <strauman@slac.stanford.edu>) */
240
241  *((uint32_t *)stack) = 0;
242
243  /*
244   * Initialize the interrupt related settings
245   * SPRG0 = interrupt nesting level count
246   * SPRG1 = software managed IRQ stack
247   *
248   * This could be done latter (e.g in IRQ_INIT) but it helps to understand
249   * some settings below...
250   */
251  intrStackStart = (uint32_t)__rtems_end;
252  intrStackSize  = rtems_configuration_get_interrupt_stack_size();
253
254
255  /*
256   * Initialize default raw exception handlers. See vectors/vectors_init.c
257   */
258  ppc_exc_initialize(
259                  PPC_INTERRUPT_DISABLE_MASK_DEFAULT,
260                  intrStackStart,
261                  intrStackSize
262                  );
263
264  printk("CPU: %s\n", get_ppc_cpu_type_name(current_ppc_cpu));
265
266  /*
267   * Initialize RTEMS IRQ system
268   */
269   BSP_rtems_irq_mng_init(0);
270
271  printk("Build Date: %s\n",BSP_build_date);
272
273  BSP_vpdRetrieveFields(vpdData);
274
275  if ( !strncmp(BSP_productIdent,"MVME5500",8) )
276        board_type = MVME5500;
277  else if ( !strncmp(BSP_productIdent,"MVME6100",8) )
278        board_type = MVME6100;
279
280  printk("Board Type: %s (S/N %s)\n",
281                BSP_productIdent[0] ? BSP_productIdent : "n/a",
282                BSP_serialNumber[0] ? BSP_serialNumber : "n/a");
283
284  if ( 0xdeadbeef == BSP_bus_frequency ) {
285        BSP_bus_frequency       = 133333333;
286        printk("Bus Clock Freq NOT FOUND in VPD; using %10u Hz\n",
287                BSP_bus_frequency);
288  } else {
289        printk("Bus Clock Freq:  %10u Hz\n",
290                BSP_bus_frequency);
291  }
292
293  if ( 0xdeadbeef == BSP_processor_frequency ) {
294        BSP_processor_frequency  = BSP_bus_frequency/2;
295        BSP_processor_frequency *= mpc7450PllMultByTwo[ (_read_HID1() >> (31-19)) & 31 ];
296  }
297  printk("CPU Clock Freq:  %10u Hz\n", BSP_processor_frequency);
298       
299  /* probe real memory size; if it's more than 256M we can't currently access it
300   * since at this point only BAT-0 maps 0..256M
301   */
302  BSP_mem_size                          =  probeMemoryEnd();
303
304  if ( (chpt = strstr(BSP_commandline_string,"MEMSZ=")) ) {
305                char            *endp;
306                uint32_t        sz;
307                chpt+=6 /* strlen("MEMSZ=") */;
308                sz = strtoul(chpt, &endp, 0);
309                if ( endp != chpt )
310                        BSP_mem_size = sz;
311  }
312
313  printk("Memory:          %10u bytes\n", BSP_mem_size);
314
315  if ( BSP_mem_size > 0x10000000 ) {
316        uint32_t s;
317        if ( BSP_mem_size > 0x80000000 ) {
318                BSP_mem_size = 0x80000000;
319                printk("Memory clipped to 0x%08x for now, sorry\n", BSP_mem_size);
320        }
321        for ( s = 0x20000000; s < BSP_mem_size ; s<<=1)
322                ;
323        MMUoff();
324        /* since it's currently in use we must first surrender it */
325        setdbat(0, 0, 0, 0, 0);
326        setdbat(0, 0, 0, s, _PAGE_RW);
327        MMUon();
328  }
329
330  printk("-----------------------------------------\n");
331
332  /* Maybe not setup yet because of the warning message */
333
334  /* Allocate and set up the page table mappings
335   * This is only available on >604 CPUs.
336   *
337   * NOTE: This setup routine may modify the available memory
338   *       size. It is essential to call it before
339   *       calculating the workspace etc.
340   */
341  pt = BSP_pgtbl_setup(&BSP_mem_size);
342  if (!pt)
343     printk("WARNING: unable to setup page tables.\n");
344
345#ifdef SHOW_MORE_INIT_SETTINGS
346  printk("Now BSP_mem_size = 0x%x\n",BSP_mem_size);
347#endif
348
349  /*
350   * Set up our hooks
351   * Make sure libc_init is done before drivers initialized so that
352   * they can use atexit()
353   */
354
355  bsp_clicks_per_usec            = BSP_bus_frequency/(BSP_time_base_divisor * 1000);
356
357#ifdef SHOW_MORE_INIT_SETTINGS
358  printk("Configuration.work_space_size = %x\n", Configuration.work_space_size);
359#endif
360
361  /* Activate the page table mappings only after
362   * initializing interrupts because the irq_mng_init()
363   * routine needs to modify the text
364   */           
365  if ( pt ) {
366#ifdef SHOW_MORE_INIT_SETTINGS
367    printk("Page table setup finished; will activate it NOW...\n");
368#endif
369    BSP_pgtbl_activate(pt);
370  }
371
372#ifdef SHOW_MORE_INIT_SETTINGS
373  printk("Going to start PCI buses scanning and initialization\n");
374#endif
375  BSP_pci_initialize();
376
377  /* need to tweak the motload setup */
378  BSP_motload_pci_fixup();
379
380  /* map 512M, 256 for PCI 256 for VME */
381  setdbat(5,BSP_PCI_HOSE0_MEM_BASE, BSP_PCI_HOSE0_MEM_BASE, BSP_PCI_HOSE0_MEM_SIZE, IO_PAGE);
382  setdbat(6,BSP_PCI_HOSE1_MEM_BASE, BSP_PCI_HOSE1_MEM_BASE, 0x10000000, IO_PAGE);
383
384#ifdef SHOW_MORE_INIT_SETTINGS
385  printk("Number of PCI buses found is : %d\n", pci_bus_count());
386#endif
387
388  /*
389   * Initialize hardware timer facility (not used by BSP itself)
390   * Needs PCI to identify discovery version...
391   */
392  BSP_timers_initialize();
393
394#ifdef SHOW_MORE_INIT_SETTINGS
395  printk("MSR %x \n", _read_MSR());
396  printk("Exit from bspstart\n");
397#endif
398}
Note: See TracBrowser for help on using the repository browser.