source: rtems/c/src/lib/libbsp/powerpc/mvme3100/startup/bspstart.c @ 05b0c8a

4.104.115
Last change on this file since 05b0c8a was 05b0c8a, checked in by Till Straumann <strauman@…>, on 03/05/09 at 21:17:55

2009-03-05 Till Straumann <strauman@…>

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