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

5
Last change on this file since 34a7a12f 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
RevLine 
[7be6ad9]1/*
[48aa5e2c]2 *  This routine does the bulk of the system initialization.
3 */
4
5/*
[07e9642c]6 *  COPYRIGHT (c) 1989-2007.
[7be6ad9]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
[c499856]11 *  http://www.rtems.org/license/LICENSE.
[7be6ad9]12 *
13 *  Modified to support the MCP750.
14 *  Modifications Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
15 *
[ee732739]16 *  Modified to support the Synergy VGM & Motorola PowerPC boards
17 *  (C) by Till Straumann, <strauman@slac.stanford.edu>, 2002, 2004, 2005
[7be6ad9]18 *
[ee732739]19 *  Modified to support the MVME5500 board.
20 *  Also, the settings of L1, L2, and L3 caches is not necessary here.
[72510eb2]21 *  (C) by Brookhaven National Lab., S. Kate Feng <feng1@bnl.gov>, 2003-2009
[7be6ad9]22 */
[f8e0327]23
[7be6ad9]24#include <string.h>
25#include <stdlib.h>
26#include <ctype.h>
27
[c4ccf26c]28#include <rtems/sysinit.h>
[1899fe4]29#include <rtems/powerpc/powerpc.h>
30
[7be6ad9]31#include <libcpu/spr.h>   /* registers.h is included here */
32#include <bsp.h>
[48aa5e2c]33#include <bsp/bootcard.h>
[7be6ad9]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>
[c4ccf26c]40#include <bsp/VME.h>
[7be6ad9]41#include <bsp/bspException.h>
42
[ef9e015]43#include <rtems/bspIo.h>
[24bf11e]44#include <rtems/counter.h>
[7be6ad9]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
[2e9d27c0]54extern uint32_t probeMemoryEnd(void); /* from shared/startup/probeMemoryEnd.c */
55
[bd0fb919]56BSP_output_char_function_type     BSP_output_char = BSP_output_char_via_serial;
57BSP_polling_getchar_function_type BSP_poll_char = NULL;
[7be6ad9]58
[6771a9e7]59extern void _return_to_ppcbug(void);
[7be6ad9]60extern unsigned long __rtems_end[];
[6771a9e7]61extern unsigned get_L1CR(void), get_L2CR(void), get_L3CR(void);
[06d14130]62extern Triv121PgTbl BSP_pgtbl_setup(unsigned int *);
[6771a9e7]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);
[7be6ad9]65extern void BSP_vme_config(void);
66
[2e9d27c0]67extern unsigned char ReadConfVPD_buff(int offset);
68
[07e9642c]69uint32_t bsp_clicks_per_usec;
70
[7be6ad9]71typedef struct CmdLineRec_ {
[b5e7018]72    unsigned long  size;
73    char           buf[0];
[7be6ad9]74} CmdLineRec, *CmdLine;
75
76
[b5e7018]77#define mtspr(reg, val)  \
78  __asm __volatile("mtspr %0,%1" : : "K"(reg), "r"(val))
[7be6ad9]79
80
[b5e7018]81#define mfspr(reg) \
82  ( { unsigned val; \
83    __asm __volatile("mfspr %0,%1" : "=r"(val) : "K"(reg)); \
84    val; } )
[7be6ad9]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;
[72510eb2]108static unsigned char ConfVPD_buff[200];
[7be6ad9]109
[b5e7018]110#define CMDLINE_BUF_SIZE  2048
[ee732739]111
112static char cmdline_buf[CMDLINE_BUF_SIZE];
113char *BSP_commandline_string = cmdline_buf;
114
[7be6ad9]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 *
[e7545f1b]135 * and later calls our bsp_predriver_hook() which ends up initializing
[7be6ad9]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
[e7545f1b]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
[7be6ad9]143 * area using proper allocation, initializes libc and finally moves
144 * the data to the environment / malloced areas...
145 */
146
[ac7af4a]147/* this routine is called early at shared/start/start.S
[7be6ad9]148 * and must be safe with a not properly aligned stack
149 */
[5eccbac]150char *
[b5e7018]151save_boot_params(
152  void *r3,
153  void *r4,
154  void* r5,
155  char *cmdline_start,
156  char *cmdline_end
157)
[7be6ad9]158{
[b5e7018]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;
[5eccbac]168  return cmdline_buf;
[7be6ad9]169}
170
[65f868c]171uint32_t _CPU_Counter_frequency(void)
172{
173  return BSP_bus_frequency / (BSP_time_base_divisor / 1000);
174}
175
[34a7a12f]176static void bsp_early( void )
[7be6ad9]177{
[05682dc]178#ifdef CONF_VPD
[7be6ad9]179  int i;
[05682dc]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
[b5e7018]190  Triv121PgTbl  pt=0;
[ee732739]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  /*
[ac7af4a]197   * Kate Feng : PCI 0 domain memory space, want to leave room for the VME window
[ee732739]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.
[72510eb2]204   * 2009 : map the entire 256 M space
[ac7af4a]205   *
[ee732739]206   */
[72510eb2]207  setdbat(3,PCI0_IO_BASE, PCI0_IO_BASE, 0x10000000, IO_PAGE);
[ee732739]208
209
[7be6ad9]210  /*
[958ed38]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.
[7be6ad9]213   */
[958ed38]214  get_ppc_cpu_type();
215  get_ppc_cpu_revision();
[7be6ad9]216
217#ifdef SHOW_LCR1_REGISTER
218  l1cr = get_L1CR();
[ac7af4a]219  printk("Initial L1CR value = %x\n", l1cr);
[7be6ad9]220#endif
221
[54d87f2]222  ppc_exc_initialize();
[b5e7018]223
[7be6ad9]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
[72510eb2]233  BSP_mem_size         =  probeMemoryEnd();
[169480b]234
[b5e7018]235  /* TODO: calculate the BSP_bus_frequency using the REF_CLK bit
236   *       of System Status  register
237   */
[7be6ad9]238  /* rtems_bsp_delay_in_bus_cycles are defined in registers.h */
[b5e7018]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;
[7be6ad9]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
[ac7af4a]256  printk("Now BSP_mem_size = 0x%x\n",BSP_mem_size);
[7be6ad9]257
258  /* P94 : 7455 TB/DECR is clocked by the system bus clock frequency */
259
[b5e7018]260  bsp_clicks_per_usec    = BSP_bus_frequency/(BSP_time_base_divisor * 1000);
261
[7be6ad9]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);
[ac7af4a]270#endif
[7be6ad9]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);
[ac7af4a]276#endif
[7be6ad9]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
[ac7af4a]282   */
[7be6ad9]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  }
[72510eb2]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++) {
[ac7af4a]296      printk("%2x ", ConfVPD_buff[i]);
[72510eb2]297      if ((i % 20)==0 ) printk("\n");
298    }
299    printk("\n");
300#endif
301  }
[7be6ad9]302
303  /*
304   * PCI 1 domain memory space
305   */
306  setdbat(1, PCI1_MEM_BASE, PCI1_MEM_BASE, 0x10000000, IO_PAGE);
[ac7af4a]307
[7be6ad9]308
309#ifdef SHOW_MORE_INIT_SETTINGS
310  printk("Going to start PCI buses scanning and initialization\n");
[ac7af4a]311#endif
[037864f5]312  pci_initialize();
[7be6ad9]313#ifdef SHOW_MORE_INIT_SETTINGS
[4cbb57da]314  printk("Number of PCI buses found is : %d\n", pci_bus_count());
[7be6ad9]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}
[72510eb2]331
[34a7a12f]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
[72510eb2]343unsigned char ReadConfVPD_buff(int offset)
344{
345  return(ConfVPD_buff[offset]);
346}
[c4ccf26c]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.