source: rtems/bsps/powerpc/mvme5500/start/bspstart.c @ c184b0c

5
Last change on this file since c184b0c was 34a7a12f, checked in by Sebastian Huber <sebastian.huber@…>, on 12/12/19 at 15:02:19

bsps: Add RTEMS_SYSINIT_BSP_EARLY

Add new BSP system initialization step for work to be performed before
the work areas are initialized.

Update #3838.

  • Property mode set to 100644
File size: 9.0 KB
Line 
1/*
2 *  This routine does the bulk of the system initialization.
3 */
4
5/*
6 *  COPYRIGHT (c) 1989-2007.
7 *  On-Line Applications Research Corporation (OAR).
8 *
9 *  The license and distribution terms for this file may be
10 *  found in the file LICENSE in this distribution or at
11 *  http://www.rtems.org/license/LICENSE.
12 *
13 *  Modified to support the MCP750.
14 *  Modifications Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
15 *
16 *  Modified to support the Synergy VGM & Motorola PowerPC boards
17 *  (C) by Till Straumann, <strauman@slac.stanford.edu>, 2002, 2004, 2005
18 *
19 *  Modified to support the MVME5500 board.
20 *  Also, the settings of L1, L2, and L3 caches is not necessary here.
21 *  (C) by Brookhaven National Lab., S. Kate Feng <feng1@bnl.gov>, 2003-2009
22 */
23
24#include <string.h>
25#include <stdlib.h>
26#include <ctype.h>
27
28#include <rtems/sysinit.h>
29#include <rtems/powerpc/powerpc.h>
30
31#include <libcpu/spr.h>   /* registers.h is included here */
32#include <bsp.h>
33#include <bsp/bootcard.h>
34#include <bsp/uart.h>
35#include <bsp/pci.h>
36#include <libcpu/bat.h>
37#include <libcpu/pte121.h>
38#include <libcpu/cpuIdent.h>
39#include <bsp/vectors.h>
40#include <bsp/VME.h>
41#include <bsp/bspException.h>
42
43#include <rtems/bspIo.h>
44#include <rtems/counter.h>
45
46/*
47#define SHOW_MORE_INIT_SETTINGS
48#define SHOW_LCR1_REGISTER
49#define SHOW_LCR2_REGISTER
50#define SHOW_LCR3_REGISTER
51#define CONF_VPD
52*/
53
54extern uint32_t probeMemoryEnd(void); /* from shared/startup/probeMemoryEnd.c */
55
56BSP_output_char_function_type     BSP_output_char = BSP_output_char_via_serial;
57BSP_polling_getchar_function_type BSP_poll_char = NULL;
58
59extern void _return_to_ppcbug(void);
60extern unsigned long __rtems_end[];
61extern unsigned get_L1CR(void), get_L2CR(void), get_L3CR(void);
62extern Triv121PgTbl BSP_pgtbl_setup(unsigned int *);
63extern void BSP_pgtbl_activate(Triv121PgTbl);
64extern int I2Cread_eeprom(unsigned char I2cBusAddr, uint32_t devA2A1A0, uint32_t AddrBytes, unsigned char *pBuff, uint32_t numBytes);
65extern void BSP_vme_config(void);
66
67extern unsigned char ReadConfVPD_buff(int offset);
68
69uint32_t bsp_clicks_per_usec;
70
71typedef struct CmdLineRec_ {
72    unsigned long  size;
73    char           buf[0];
74} CmdLineRec, *CmdLine;
75
76
77#define mtspr(reg, val)  \
78  __asm __volatile("mtspr %0,%1" : : "K"(reg), "r"(val))
79
80
81#define mfspr(reg) \
82  ( { unsigned val; \
83    __asm __volatile("mfspr %0,%1" : "=r"(val) : "K"(reg)); \
84    val; } )
85
86/*
87 * Copy Additional boot param passed by boot loader
88 */
89#define MAX_LOADER_ADD_PARM 80
90char loaderParam[MAX_LOADER_ADD_PARM];
91
92/*
93 * Total memory using RESIDUAL DATA
94 */
95unsigned int BSP_mem_size;
96/*
97 * PCI Bus Frequency
98 */
99unsigned int BSP_bus_frequency;
100/*
101 * processor clock frequency
102 */
103unsigned int BSP_processor_frequency;
104/*
105 * Time base divisior (how many tick for 1 second).
106 */
107unsigned int BSP_time_base_divisor;
108static unsigned char ConfVPD_buff[200];
109
110#define CMDLINE_BUF_SIZE  2048
111
112static char cmdline_buf[CMDLINE_BUF_SIZE];
113char *BSP_commandline_string = cmdline_buf;
114
115/* NOTE: we cannot simply malloc the commandline string;
116 * save_boot_params() is called during a very early stage when
117 * libc/malloc etc. are not yet initialized!
118 *
119 * Here's what we do:
120 *
121 * initial layout setup by the loader (preload.S):
122 *
123 * 0..RTEMS...__rtems_end | cmdline ....... TOP
124 *
125 * After the save_boot_params() routine returns, the stack area will be
126 * set up (start.S):
127 *
128 * 0..RTEMS..__rtems_end | INIT_STACK | IRQ_STACK | ..... TOP
129 *
130 * initialize_executive_early() [called from boot_card()]
131 * will initialize the workspace:
132 *
133 * 0..RTEMS..__rtems_end | INIT_STACK | IRQ_STACK | ...... | workspace | TOP
134 *
135 * and later calls our bsp_predriver_hook() which ends up initializing
136 * libc which in turn initializes the heap
137 *
138 * 0..RTEMS..__rtems_end | INIT_STACK | IRQ_STACK | heap | workspace | TOP
139 *
140 * The idea here is to first move the commandline to the future 'heap' area
141 * from where it will be picked up by our bsp_predriver_hook().
142 * bsp_predriver_hook() then moves it either to INIT_STACK or the workspace
143 * area using proper allocation, initializes libc and finally moves
144 * the data to the environment / malloced areas...
145 */
146
147/* this routine is called early at shared/start/start.S
148 * and must be safe with a not properly aligned stack
149 */
150char *
151save_boot_params(
152  void *r3,
153  void *r4,
154  void* r5,
155  char *cmdline_start,
156  char *cmdline_end
157)
158{
159  int i=cmdline_end-cmdline_start;
160
161  if ( i >= CMDLINE_BUF_SIZE )
162    i = CMDLINE_BUF_SIZE-1;
163  else if ( i < 0 )
164    i = 0;
165
166  memmove(cmdline_buf, cmdline_start, i);
167  cmdline_buf[i]=0;
168  return cmdline_buf;
169}
170
171uint32_t _CPU_Counter_frequency(void)
172{
173  return BSP_bus_frequency / (BSP_time_base_divisor / 1000);
174}
175
176static void bsp_early( void )
177{
178#ifdef CONF_VPD
179  int i;
180#endif
181#ifdef SHOW_LCR1_REGISTER
182  unsigned l1cr;
183#endif
184#ifdef SHOW_LCR2_REGISTER
185  unsigned l2cr;
186#endif
187#ifdef SHOW_LCR3_REGISTER
188  unsigned l3cr;
189#endif
190  Triv121PgTbl  pt=0;
191
192  /* Till Straumann: 4/2005
193   * Need to map the system registers early, so we can printk...
194   * (otherwise we silently die)
195   */
196  /*
197   * Kate Feng : PCI 0 domain memory space, want to leave room for the VME window
198   */
199  setdbat(2, PCI0_MEM_BASE, PCI0_MEM_BASE, 0x10000000, IO_PAGE);
200
201  /* Till Straumann: 2004
202   * map the PCI 0, 1 Domain I/O space, GT64260B registers
203   * and the reserved area so that the size is the power of 2.
204   * 2009 : map the entire 256 M space
205   *
206   */
207  setdbat(3,PCI0_IO_BASE, PCI0_IO_BASE, 0x10000000, IO_PAGE);
208
209
210  /*
211   * Get CPU identification dynamically. Note that the get_ppc_cpu_type()
212   * function store the result in global variables so that it can be used later.
213   */
214  get_ppc_cpu_type();
215  get_ppc_cpu_revision();
216
217#ifdef SHOW_LCR1_REGISTER
218  l1cr = get_L1CR();
219  printk("Initial L1CR value = %x\n", l1cr);
220#endif
221
222  ppc_exc_initialize();
223
224  /*
225   * Init MMU block address translation to enable hardware
226   * access
227   * More PCI1 memory mapping to be done after BSP_pgtbl_activate.
228   */
229  printk("-----------------------------------------\n");
230  printk("Welcome to %s on MVME5500-0163\n", _RTEMS_version );
231  printk("-----------------------------------------\n");
232
233  BSP_mem_size         =  probeMemoryEnd();
234
235  /* TODO: calculate the BSP_bus_frequency using the REF_CLK bit
236   *       of System Status  register
237   */
238  /* rtems_bsp_delay_in_bus_cycles are defined in registers.h */
239  BSP_bus_frequency      = 133333333;
240  BSP_processor_frequency    = 1000000000;
241  /* P94 : 7455 clocks the TB/DECR at 1/4 of the system bus clock frequency */
242  BSP_time_base_divisor      = 4000;
243
244  /* Maybe not setup yet becuase of the warning message */
245  /* Allocate and set up the page table mappings
246   * This is only available on >604 CPUs.
247   *
248   * NOTE: This setup routine may modify the available memory
249   *       size. It is essential to call it before
250   *       calculating the workspace etc.
251   */
252  pt = BSP_pgtbl_setup(&BSP_mem_size);
253  if (!pt)
254     printk("WARNING: unable to setup page tables.\n");
255
256  printk("Now BSP_mem_size = 0x%x\n",BSP_mem_size);
257
258  /* P94 : 7455 TB/DECR is clocked by the system bus clock frequency */
259
260  bsp_clicks_per_usec    = BSP_bus_frequency/(BSP_time_base_divisor * 1000);
261
262  /*
263   * Initalize RTEMS IRQ system
264   */
265   BSP_rtems_irq_mng_init(0);
266
267#ifdef SHOW_LCR2_REGISTER
268  l2cr = get_L2CR();
269  printk("Initial L2CR value = %x\n", l2cr);
270#endif
271
272#ifdef SHOW_LCR3_REGISTER
273  /* L3CR needs DEC int. handler installed for bsp_delay()*/
274  l3cr = get_L3CR();
275  printk("Initial L3CR value = %x\n", l3cr);
276#endif
277
278
279  /* Activate the page table mappings only after
280   * initializing interrupts because the irq_mng_init()
281   * routine needs to modify the text
282   */
283  if (pt) {
284#ifdef SHOW_MORE_INIT_SETTINGS
285    printk("Page table setup finished; will activate it NOW...\n");
286#endif
287    BSP_pgtbl_activate(pt);
288  }
289  /* Read Configuration Vital Product Data (VPD) */
290  if ( I2Cread_eeprom(0xa8, 4,2, &ConfVPD_buff[0], 150))
291     printk("I2Cread_eeprom() error \n");
292  else {
293#ifdef CONF_VPD
294    printk("\n");
295    for (i=0; i<150; i++) {
296      printk("%2x ", ConfVPD_buff[i]);
297      if ((i % 20)==0 ) printk("\n");
298    }
299    printk("\n");
300#endif
301  }
302
303  /*
304   * PCI 1 domain memory space
305   */
306  setdbat(1, PCI1_MEM_BASE, PCI1_MEM_BASE, 0x10000000, IO_PAGE);
307
308
309#ifdef SHOW_MORE_INIT_SETTINGS
310  printk("Going to start PCI buses scanning and initialization\n");
311#endif
312  pci_initialize();
313#ifdef SHOW_MORE_INIT_SETTINGS
314  printk("Number of PCI buses found is : %d\n", pci_bus_count());
315#endif
316
317  /* Install our own exception handler (needs PCI) */
318  globalExceptHdl = BSP_exceptionHandler;
319
320  /* clear hostbridge errors. MCP signal is not used on the MVME5500
321   * PCI config space scanning code will trip otherwise :-(
322   */
323  _BSP_clear_hostbridge_errors(0, 1 /*quiet*/);
324
325#ifdef SHOW_MORE_INIT_SETTINGS
326  printk("MSR %x \n", _read_MSR());
327  printk("Exit from bspstart\n");
328#endif
329
330}
331
332RTEMS_SYSINIT_ITEM(
333  bsp_early,
334  RTEMS_SYSINIT_BSP_EARLY,
335  RTEMS_SYSINIT_ORDER_MIDDLE
336);
337
338void bsp_start( void )
339{
340  /* Initialization was done by bsp_early() */
341}
342
343unsigned char ReadConfVPD_buff(int offset)
344{
345  return(ConfVPD_buff[offset]);
346}
347
348RTEMS_SYSINIT_ITEM(
349  BSP_vme_config,
350  RTEMS_SYSINIT_BSP_PRE_DRIVERS,
351  RTEMS_SYSINIT_ORDER_MIDDLE
352);
Note: See TracBrowser for help on using the repository browser.