source: rtems/bsps/powerpc/mvme3100/start/bspstart.c @ 511dc4b

5
Last change on this file since 511dc4b was 511dc4b, checked in by Sebastian Huber <sebastian.huber@…>, on Jun 19, 2018 at 7:09:51 AM

Rework initialization and interrupt stack support

Statically initialize the interrupt stack area
(_Configuration_Interrupt_stack_area_begin,
_Configuration_Interrupt_stack_area_end, and
_Configuration_Interrupt_stack_size) via <rtems/confdefs.h>. Place the
interrupt stack area in a special section ".rtemsstack.interrupt". Let
BSPs define the optimal placement of this section in their linker
command files (e.g. in a fast on-chip memory).

This change makes makes the CPU_HAS_SOFTWARE_INTERRUPT_STACK and
CPU_HAS_HARDWARE_INTERRUPT_STACK CPU port defines superfluous, since the
low level initialization code has all information available via global
symbols.

This change makes the CPU_ALLOCATE_INTERRUPT_STACK CPU port define
superfluous, since the interrupt stacks are allocated by confdefs.h for
all architectures. There is no need for BSP-specific linker command
file magic (except the section placement), see previous ARM linker
command file as a bad example.

Remove _CPU_Install_interrupt_stack(). Initialize the hardware
interrupt stack in _CPU_Initialize() if necessary (e.g.
m68k_install_interrupt_stack()).

The optional _CPU_Interrupt_stack_setup() is still useful to customize
the registration of the interrupt stack area in the per-CPU information.

The initialization stack can reuse the interrupt stack, since

  • interrupts are disabled during the sequential system initialization, and
  • the boot_card() function does not return.

This stack resuse saves memory.

Changes per architecture:

arm:

  • Mostly replace the linker symbol based configuration of stacks with the standard <rtems/confdefs.h> configuration via CONFIGURE_INTERRUPT_STACK_SIZE. The size of the FIQ, ABT and UND mode stack is still defined via linker symbols. These modes are rarely used in applications and the default values provided by the BSP should be sufficient in most cases.
  • Remove the bsp_processor_count linker symbol hack used for the SMP support. This is possible since the interrupt stack area is now allocated by the linker and not allocated from the heap. This makes some configure.ac stuff obsolete. Remove the now superfluous BSP variants altcycv_devkit_smp and realview_pbx_a9_qemu_smp.

bfin:

  • Remove unused magic linker command file allocation of initialization stack. Maybe a previous linker command file copy and paste problem? In the start.S the initialization stack is set to a hard coded value.

lm32, m32c, mips, nios2, riscv, sh, v850:

  • Remove magic linker command file allocation of initialization stack. Reuse interrupt stack for initialization stack.

m68k:

  • Remove magic linker command file allocation of initialization stack. Reuse interrupt stack for initialization stack.

powerpc:

  • Remove magic linker command file allocation of initialization stack. Reuse interrupt stack for initialization stack.
  • Used dedicated memory region (REGION_RTEMSSTACK) for the interrupt stack on BSPs using the shared linkcmds.base (replacement for REGION_RWEXTRA).

sparc:

  • Remove the hard coded initialization stack. Use the interrupt stack for the initialization stack on the boot processor. This saves 16KiB of RAM.

Update #3459.

  • Property mode set to 100644
File size: 11.6 KB
Line 
1/*
2 *  This routine does the bulk of the system initialization.
3 */
4
5/*
6 *  COPYRIGHT (c) 1989-1998.
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 for mvme3100 by T. Straumann
17 */
18
19#include <string.h>
20#include <stdlib.h>
21#include <inttypes.h>
22
23#include <rtems.h>
24#include <bsp.h>
25#include <bsp/bootcard.h>
26#include <rtems/bspIo.h>
27#include <rtems/counter.h>
28#include <rtems/sysinit.h>
29#include <libcpu/spr.h>
30#include <libcpu/io.h>
31#include <libcpu/e500_mmu.h>
32#include <bsp/uart.h>
33#include <bsp/irq.h>
34#include <bsp/pci.h>
35#include <bsp/vpd.h>
36#include <libcpu/cpuIdent.h>
37#include <bsp/vectors.h>
38#include <bsp/VME.h>
39#include <rtems/powerpc/powerpc.h>
40
41#define SHOW_MORE_INIT_SETTINGS
42#undef  DEBUG
43
44#define NumberOf(arr) (sizeof(arr)/sizeof(arr[0]))
45
46#ifdef  DEBUG
47#define STATIC
48#else
49#define STATIC static
50#endif
51
52extern unsigned long __rtems_end[];
53extern unsigned      ppc_exc_lock_std, ppc_exc_gpr3_std;
54
55/*
56 * Copy Additional boot param passed by boot loader
57 */
58#define CMDLINE_BUF_SIZE  2048
59
60static char cmdline_buf[CMDLINE_BUF_SIZE] = {0};
61char *BSP_commandline_string         = cmdline_buf;
62
63/*
64 * Vital Board data Start using DATA RESIDUAL
65 */
66uint32_t bsp_clicks_per_usec         = 0;
67/*
68 * Total memory using RESIDUAL DATA
69 */
70unsigned int BSP_mem_size            = 0;
71/*
72 * PCI Bus Frequency
73 */
74unsigned int BSP_pci_bus_frequency   = 0xdeadbeef;
75/*
76 * PPC Bus Frequency
77 */
78unsigned int BSP_bus_frequency       = 0;
79/*
80 * processor clock frequency
81 */
82unsigned int BSP_processor_frequency = 0;
83/*
84 * Time base divisior (how many tick for 1 second).
85 */
86unsigned int BSP_time_base_divisor   = 8000; /* if external RTC clock unused (HID0) */
87
88/* Board identification string */
89char BSP_productIdent[20]            = {0};
90char BSP_serialNumber[20]            = {0};
91
92/* VPD appends an extra char -- what for ? */
93char BSP_enetAddr0[7]                = {0};
94char BSP_enetAddr1[7]                = {0};
95char BSP_enetAddr2[7]                = {0};
96
97static void
98prether(char *b, int idx)
99{
100int i;
101  printk("Ethernet %i                  %02X", idx, *b++);
102  for ( i=0; i<5; i++ )
103    printk(":%02X",*b++);
104  printk("\n");
105}
106
107BSP_output_char_function_type     BSP_output_char = BSP_output_char_via_serial;
108BSP_polling_getchar_function_type BSP_poll_char = NULL;
109
110char *rtems_progname;
111
112/*
113 *  Use the shared implementations of the following routines
114 */
115char *save_boot_params(
116  void *r3,
117  void *r4,
118  void *r5,
119  char *cmdline_start,
120  char *cmdline_end
121)
122{
123
124  strncpy(cmdline_buf, cmdline_start, CMDLINE_BUF_SIZE);
125  cmdline_buf[CMDLINE_BUF_SIZE - 1] ='\0';
126  return cmdline_buf;
127}
128
129#define CS_CONFIG_CS_EN (1<<31)
130#define CS_BNDS_SA(x)  ((((uint32_t)(x))>>(31-15)) & 0xff)
131#define CS_BNDS_EA(x)  ((((uint32_t)(x))>>(31-31)) & 0xff)
132
133static inline uint32_t
134_ccsr_rd32(uint32_t off)
135{
136  return in_be32( (volatile uint32_t *)(BSP_8540_CCSR_BASE + off) );
137}
138
139static inline void
140_ccsr_wr32(uint32_t off, uint32_t val)
141{
142  out_be32( (volatile uint32_t *)(BSP_8540_CCSR_BASE + off), val );
143}
144
145
146STATIC uint32_t
147BSP_get_mem_size( void )
148{
149  int i;
150  uint32_t  cs_bnds, cs_config;
151  uint32_t  memsz=0;
152  uint32_t  v;
153
154  for ( cs_bnds = 0x2000, cs_config=0x2080, i=0; i<4; i++, cs_bnds+=8, cs_config+=4 ) {
155    if ( CS_CONFIG_CS_EN & _ccsr_rd32( cs_config ) ) {
156      v = _ccsr_rd32( cs_bnds );
157
158      memsz += CS_BNDS_EA(v) - CS_BNDS_SA(v) + 1;
159    }
160  }
161  return memsz << 24;
162}
163
164STATIC void
165BSP_calc_freqs( void )
166{
167  uint32_t  porpllsr   = _ccsr_rd32( 0xe0000 );
168  unsigned  plat_ratio = (porpllsr >> (31-30)) & 0x1f;
169  unsigned    e500_ratio = (porpllsr >> (31-15)) & 0x3f;
170
171  switch ( plat_ratio ) {
172    case  2: case  3: case  4: case  5: case  6:
173    case  8: case  9: case 10: case 12: case 16:
174    /* supported ratios */
175      BSP_bus_frequency = BSP_pci_bus_frequency * plat_ratio;
176    break;
177
178    default:
179      rtems_panic("Unknown PLL sys-clock ratio; something's wrong here");
180  }
181
182  switch ( e500_ratio ) {
183    case 4: case 5: case 6: case 7:
184      BSP_processor_frequency = (BSP_pci_bus_frequency * e500_ratio) >> 1;
185    break;
186
187    default:
188      rtems_panic("Unknown PLL e500-clock ratio; something's wrong here");
189  }
190
191  printk("Core Complex Bus (CCB) Clock Freq: %10u Hz\n", BSP_bus_frequency);
192  printk("CPU Clock Freq:                    %10u Hz\n", BSP_processor_frequency);
193}
194
195uint32_t _CPU_Counter_frequency(void)
196{
197  return BSP_bus_frequency / (BSP_time_base_divisor / 1000);
198}
199
200/*
201 *  bsp_start
202 *
203 *  This routine does the bulk of the system initialization.
204 */
205
206#include <libcpu/spr.h>
207
208SPR_RW(HID1)
209
210void bsp_start( void )
211{
212  unsigned char       *stack;
213  uintptr_t            intrStackStart;
214  uintptr_t            intrStackSize;
215  char                *chpt;
216  int                  i;
217  ppc_cpu_id_t         myCpu;
218  ppc_cpu_revision_t   myCpuRevision;
219  E500_tlb_va_cache_t *tlb;
220
221VpdBufRec          vpdData [] = {
222 { key: ProductIdent, instance: 0, buf: BSP_productIdent, buflen: sizeof(BSP_productIdent) - 1 },
223 { key: SerialNumber, instance: 0, buf: BSP_serialNumber, buflen: sizeof(BSP_serialNumber) - 1 },
224 { key: BusClockHz,   instance: 0, buf: &BSP_pci_bus_frequency, buflen: sizeof(BSP_pci_bus_frequency)  },
225 { key: EthernetAddr, instance: 0, buf: BSP_enetAddr0, buflen: sizeof(BSP_enetAddr0) },
226 { key: EthernetAddr, instance: 1, buf: BSP_enetAddr1, buflen: sizeof(BSP_enetAddr1) },
227 { key: EthernetAddr, instance: 2, buf: BSP_enetAddr2, buflen: sizeof(BSP_enetAddr2) },
228 VPD_END
229};
230
231  /* Intersperse messages with actions to help locate problems */
232  printk("-----------------------------------------\n");
233
234  /*
235   * Get CPU identification dynamically. Note that the get_ppc_cpu_type()
236   * function store the result in global variables so that it can be used
237   * later...
238   */
239  myCpu = get_ppc_cpu_type();
240  myCpuRevision = get_ppc_cpu_revision();
241
242  printk("Welcome to %s\n", _RTEMS_version);
243  printk("BSP: %s, CVS Release ($Name$)\n", "mvme3100");
244
245  /*
246   * the initial stack  has aready been set to this value in start.S
247   * so there is no need to set it in r1 again... It is just for info
248   * so that It can be printed without accessing R1.
249   */
250  asm volatile("mr %0, 1":"=r"(stack));
251
252  /* tag the bottom */
253  *((uint32_t*)stack) = 0;
254
255  /*
256   * Initialize the interrupt related settings.
257   */
258  intrStackStart = (uintptr_t) _Configuration_Interrupt_stack_area_begin;
259  intrStackSize = rtems_configuration_get_interrupt_stack_size();
260
261  /*
262   * Initialize default raw exception handlers.
263   */
264  ppc_exc_initialize(intrStackStart, intrStackSize);
265
266  printk("CPU 0x%x - rev 0x%x\n", myCpu, myCpuRevision);
267
268#ifdef SHOW_MORE_INIT_SETTINGS
269  printk("Additionnal boot options are %s\n", BSP_commandline_string);
270  printk("Initial system stack at %" PRIxPTR "\n", (uintptr_t) stack);
271  printk("Software IRQ stack starts at %x with size %u\n", intrStackStart, intrStackSize);
272#endif
273
274#ifdef SHOW_MORE_INIT_SETTINGS
275  printk("Going to start PCI buses scanning and initialization\n");
276#endif
277
278  BSP_mem_size            = BSP_get_mem_size();
279
280  {
281    /* memory-select errors were disabled in 'start.S';
282     * motload has all TLBs mapping a possible larger area as
283     * memory (not-guarded, caching-enabled) than actual physical
284     * memory is available.
285     * In case of speculative loads this may cause 'memory-select' errors
286     * which seem to raise 'core_fault_in' (found no description in
287     * the manual but I experienced this problem).
288     * Such errors (if HID1[RFXE] is clear) may *stall* execution
289     * leading to mysterious 'hangs'.
290     *
291     * Here we remove all mappings, re-enable memory-select
292     * errors and make sure we enable HID1[RFXE] to avoid
293     * stalls (since we don't implement handling individual
294     * error-handling interrupts).
295     */
296
297    /* enable machine check for bad bus errors */
298    _write_HID1( _read_HID1() | 0x20000 );
299
300    rtems_e500_initlb();
301
302    for ( i=0, tlb=rtems_e500_tlb_va_cache; i<NumberOf(rtems_e500_tlb_va_cache); i++, tlb++ ) {
303      /* disable TLBs for caching-enabled, non-guarded areas
304       * beyond physical memory
305       */
306      if (    tlb->att.v
307          &&  0xa != (tlb->att.wimge & 0xa)
308        &&  (tlb->va.va_epn<<12) >= BSP_mem_size ) {
309        rtems_e500_clrtlb( E500_SELTLB_1 | i );
310      }
311    }
312
313    /* clear all pending memory errors */
314    _ccsr_wr32(0x2e40, 0xffffffff);
315    /* enable checking for memory-select errors */
316    _ccsr_wr32(0x2e44, _ccsr_rd32(0x2e44) & ~1 );
317  }
318
319  BSP_vpdRetrieveFields( vpdData );
320
321  printk("Board Type: %s (S/N %s)\n",
322      BSP_productIdent[0] ? BSP_productIdent : "n/a",
323      BSP_serialNumber[0] ? BSP_serialNumber : "n/a");
324
325  printk("External (=PCI Bus) Clock Freq   ");
326  if ( 0xdeadbeef == BSP_pci_bus_frequency ) {
327    BSP_pci_bus_frequency  = 66666666;
328    printk(" NOT FOUND in VPD; using %10u Hz\n",
329        BSP_pci_bus_frequency);
330  } else {
331    printk(": %10u Hz\n",
332        BSP_pci_bus_frequency);
333  }
334
335  /* Calculate CPU and CCB bus freqs */
336  BSP_calc_freqs();
337
338  pci_initialize();
339
340  prether(BSP_enetAddr0, 0);
341  prether(BSP_enetAddr1, 1);
342  prether(BSP_enetAddr2, 2);
343
344  /* need to tweak the motload setup */
345  BSP_motload_pci_fixup();
346
347#ifdef SHOW_MORE_INIT_SETTINGS
348  printk("Number of PCI buses found is : %d\n", pci_bus_count());
349  {
350    BSP_pciConfigDump_early();
351  }
352#endif
353
354  if ( (chpt = strstr(BSP_commandline_string,"MEMSZ=")) ) {
355    char    *endp;
356    uint32_t   sz;
357    chpt+=6 /* strlen("MEMSZ=") */;
358    sz = strtoul(chpt, &endp, 0);
359    if ( endp != chpt )
360      BSP_mem_size = sz;
361  }
362
363  printk("Memory:                            %10u bytes\n", BSP_mem_size);
364
365  BSP_bus_frequency       = 333333333;
366  BSP_processor_frequency = 833333333;
367  BSP_time_base_divisor   = 8000; /* if external RTC clock unused (HID0) */
368
369  /* clear hostbridge errors but leave MCP disabled -
370   * PCI config space scanning code will trip otherwise :-(
371   */
372  _BSP_clear_hostbridge_errors(0 /* enableMCP */, 0/*quiet*/);
373
374  bsp_clicks_per_usec = BSP_bus_frequency/(BSP_time_base_divisor * 1000);
375
376  /*
377   * Initalize RTEMS IRQ system
378   */
379  BSP_rtems_irq_mng_init(0);
380
381  if (1) {
382    int i;
383    unsigned msr,tcr;
384    asm volatile("mfmsr %0":"=r"(msr));
385    asm volatile("mftcr %0":"=r"(tcr));
386    printk("MSR is 0x%08x, TCR 0x%08x\n",msr,tcr);
387    asm volatile("mttcr %0"::"r"(0));
388    if (0) {
389      asm volatile("mtmsr %0"::"r"(msr|0x8000));
390      for (i=0; i<12; i++)
391        BSP_enable_irq_at_pic(i);
392      printk("IRQS enabled\n");
393    }
394  }
395
396  if (0) {
397    unsigned x;
398    asm volatile("mfivpr %0":"=r"(x));
399    printk("IVPR: 0x%08x\n",x);
400    asm volatile("mfivor8 %0":"=r"(x));
401    printk("IVOR8: 0x%08x\n",x);
402    printk("0x%08x\n",*(unsigned *)0xc00);
403    printk("0x%08x\n",*(unsigned *)0xc04);
404    printk("0x%08x\n",*(unsigned *)0xc08);
405    printk("0x%08x\n\n\n",*(unsigned *)0xc0c);
406    if (0) {
407      *(unsigned *)0xc08 = 0x4c000064;
408      asm volatile("dcbf 0, %0; icbi 0, %0; sync; isync"::"r"(0xc00));
409    }
410
411    printk("0x%08x\n", ppc_exc_lock_std);
412    printk("0x%08x\n", ppc_exc_gpr3_std);
413
414    asm volatile("sc");
415
416    printk("0x%08x\n", ppc_exc_lock_std);
417    printk("0x%08x\n", ppc_exc_gpr3_std);
418  }
419
420  printk("-----------------------------------------\n");
421
422#ifdef SHOW_MORE_INIT_SETTINGS
423  printk("Exit from bspstart\n");
424#endif
425}
426
427static void mvme3100_i2c_initialize(void)
428{
429  BSP_i2c_initialize();
430}
431
432RTEMS_SYSINIT_ITEM(
433  mvme3100_i2c_initialize,
434  RTEMS_SYSINIT_BSP_PRE_DRIVERS,
435  RTEMS_SYSINIT_ORDER_MIDDLE
436);
437
438RTEMS_SYSINIT_ITEM(
439  BSP_vme_config,
440  RTEMS_SYSINIT_BSP_PRE_DRIVERS,
441  RTEMS_SYSINIT_ORDER_MIDDLE
442);
Note: See TracBrowser for help on using the repository browser.