Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:57

0001 /*
0002  *  This routine does the bulk of the system initialization.
0003  */
0004 
0005 /*
0006  *  COPYRIGHT (c) 1989-1998.
0007  *  On-Line Applications Research Corporation (OAR).
0008  *
0009  *  The license and distribution terms for this file may be
0010  *  found in the file LICENSE in this distribution or at
0011  *  http://www.rtems.org/license/LICENSE.
0012  *
0013  *  Modified to support the MCP750.
0014  *  Modifications Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
0015  *
0016  *  Modified for mvme3100 by T. Straumann
0017  */
0018 
0019 #include <string.h>
0020 #include <stdlib.h>
0021 #include <inttypes.h>
0022 
0023 #include <rtems.h>
0024 #include <bsp.h>
0025 #include <bsp/bootcard.h>
0026 #include <rtems/bspIo.h>
0027 #include <rtems/counter.h>
0028 #include <rtems/sysinit.h>
0029 #include <libcpu/spr.h>
0030 #include <libcpu/io.h>
0031 #include <libcpu/e500_mmu.h>
0032 #include <bsp/uart.h>
0033 #include <bsp/irq.h>
0034 #include <bsp/pci.h>
0035 #include <bsp/vpd.h>
0036 #include <libcpu/cpuIdent.h>
0037 #include <bsp/vectors.h>
0038 #include <bsp/VME.h>
0039 #include <rtems/powerpc/powerpc.h>
0040 
0041 #define SHOW_MORE_INIT_SETTINGS
0042 #undef  DEBUG
0043 
0044 #define NumberOf(arr) (sizeof(arr)/sizeof(arr[0]))
0045 
0046 #ifdef  DEBUG
0047 #define STATIC
0048 #else
0049 #define STATIC static
0050 #endif
0051 
0052 extern unsigned long __rtems_end[];
0053 extern unsigned      ppc_exc_lock_std, ppc_exc_gpr3_std;
0054 
0055 /*
0056  * Copy Additional boot param passed by boot loader
0057  */
0058 #define CMDLINE_BUF_SIZE  2048
0059 
0060 static char cmdline_buf[CMDLINE_BUF_SIZE] = {0};
0061 char *BSP_commandline_string         = cmdline_buf;
0062 
0063 /*
0064  * Vital Board data Start using DATA RESIDUAL
0065  */
0066 uint32_t bsp_clicks_per_usec         = 0;
0067 /*
0068  * Total memory using RESIDUAL DATA
0069  */
0070 unsigned int BSP_mem_size            = 0;
0071 /*
0072  * PCI Bus Frequency
0073  */
0074 unsigned int BSP_pci_bus_frequency   = 0xdeadbeef;
0075 /*
0076  * PPC Bus Frequency
0077  */
0078 unsigned int BSP_bus_frequency       = 0;
0079 /*
0080  * processor clock frequency
0081  */
0082 unsigned int BSP_processor_frequency = 0;
0083 /*
0084  * Time base divisior (how many tick for 1 second).
0085  */
0086 unsigned int BSP_time_base_divisor   = 8000; /* if external RTC clock unused (HID0) */
0087 
0088 /* Board identification string */
0089 char BSP_productIdent[20]            = {0};
0090 char BSP_serialNumber[20]            = {0};
0091 
0092 /* VPD appends an extra char -- what for ? */
0093 char BSP_enetAddr0[7]                = {0};
0094 char BSP_enetAddr1[7]                = {0};
0095 char BSP_enetAddr2[7]                = {0};
0096 
0097 static void
0098 prether(char *b, int idx)
0099 {
0100 int i;
0101   printk("Ethernet %i                  %02X", idx, *b++);
0102   for ( i=0; i<5; i++ )
0103     printk(":%02X",*b++);
0104   printk("\n");
0105 }
0106 
0107 BSP_output_char_function_type     BSP_output_char = BSP_output_char_via_serial;
0108 BSP_polling_getchar_function_type BSP_poll_char = NULL;
0109 
0110 char *rtems_progname;
0111 
0112 /*
0113  *  Use the shared implementations of the following routines
0114  */
0115 char *save_boot_params(
0116   void *r3,
0117   void *r4,
0118   void *r5,
0119   char *cmdline_start,
0120   char *cmdline_end
0121 )
0122 {
0123 
0124   strncpy(cmdline_buf, cmdline_start, CMDLINE_BUF_SIZE);
0125   cmdline_buf[CMDLINE_BUF_SIZE - 1] ='\0';
0126   return cmdline_buf;
0127 }
0128 
0129 #define CS_CONFIG_CS_EN (1<<31)
0130 #define CS_BNDS_SA(x)  ((((uint32_t)(x))>>(31-15)) & 0xff)
0131 #define CS_BNDS_EA(x)  ((((uint32_t)(x))>>(31-31)) & 0xff)
0132 
0133 static inline uint32_t
0134 _ccsr_rd32(uint32_t off)
0135 {
0136   return in_be32( (volatile uint32_t *)(BSP_8540_CCSR_BASE + off) );
0137 }
0138 
0139 static inline void
0140 _ccsr_wr32(uint32_t off, uint32_t val)
0141 {
0142   out_be32( (volatile uint32_t *)(BSP_8540_CCSR_BASE + off), val );
0143 }
0144 
0145 
0146 STATIC uint32_t
0147 BSP_get_mem_size( void )
0148 {
0149   int i;
0150   uint32_t  cs_bnds, cs_config;
0151   uint32_t  memsz=0;
0152   uint32_t  v;
0153 
0154   for ( cs_bnds = 0x2000, cs_config=0x2080, i=0; i<4; i++, cs_bnds+=8, cs_config+=4 ) {
0155     if ( CS_CONFIG_CS_EN & _ccsr_rd32( cs_config ) ) {
0156       v = _ccsr_rd32( cs_bnds );
0157 
0158       memsz += CS_BNDS_EA(v) - CS_BNDS_SA(v) + 1;
0159     }
0160   }
0161   return memsz << 24;
0162 }
0163 
0164 STATIC void
0165 BSP_calc_freqs( void )
0166 {
0167   uint32_t  porpllsr   = _ccsr_rd32( 0xe0000 );
0168   unsigned  plat_ratio = (porpllsr >> (31-30)) & 0x1f;
0169   unsigned    e500_ratio = (porpllsr >> (31-15)) & 0x3f;
0170 
0171   switch ( plat_ratio ) {
0172     case  2: case  3: case  4: case  5: case  6:
0173     case  8: case  9: case 10: case 12: case 16:
0174     /* supported ratios */
0175       BSP_bus_frequency = BSP_pci_bus_frequency * plat_ratio;
0176     break;
0177 
0178     default:
0179       rtems_panic("Unknown PLL sys-clock ratio; something's wrong here");
0180   }
0181 
0182   switch ( e500_ratio ) {
0183     case 4: case 5: case 6: case 7:
0184       BSP_processor_frequency = (BSP_pci_bus_frequency * e500_ratio) >> 1;
0185     break;
0186 
0187     default:
0188       rtems_panic("Unknown PLL e500-clock ratio; something's wrong here");
0189   }
0190 
0191   printk("Core Complex Bus (CCB) Clock Freq: %10u Hz\n", BSP_bus_frequency);
0192   printk("CPU Clock Freq:                    %10u Hz\n", BSP_processor_frequency);
0193 }
0194 
0195 uint32_t _CPU_Counter_frequency(void)
0196 {
0197   return BSP_bus_frequency / (BSP_time_base_divisor / 1000);
0198 }
0199 
0200 #include <libcpu/spr.h>
0201 
0202 SPR_RW(HID1)
0203 
0204 static void bsp_early( void )
0205 {
0206   unsigned char       *stack;
0207   char                *chpt;
0208   int                  i;
0209   ppc_cpu_id_t         myCpu;
0210   ppc_cpu_revision_t   myCpuRevision;
0211   E500_tlb_va_cache_t *tlb;
0212 
0213 VpdBufRec          vpdData [] = {
0214  { key: ProductIdent, instance: 0, buf: BSP_productIdent, buflen: sizeof(BSP_productIdent) - 1 },
0215  { key: SerialNumber, instance: 0, buf: BSP_serialNumber, buflen: sizeof(BSP_serialNumber) - 1 },
0216  { key: BusClockHz,   instance: 0, buf: &BSP_pci_bus_frequency, buflen: sizeof(BSP_pci_bus_frequency)  },
0217  { key: EthernetAddr, instance: 0, buf: BSP_enetAddr0, buflen: sizeof(BSP_enetAddr0) },
0218  { key: EthernetAddr, instance: 1, buf: BSP_enetAddr1, buflen: sizeof(BSP_enetAddr1) },
0219  { key: EthernetAddr, instance: 2, buf: BSP_enetAddr2, buflen: sizeof(BSP_enetAddr2) },
0220  VPD_END
0221 };
0222 
0223   /* Intersperse messages with actions to help locate problems */
0224   printk("-----------------------------------------\n");
0225 
0226   /*
0227    * Get CPU identification dynamically. Note that the get_ppc_cpu_type()
0228    * function store the result in global variables so that it can be used
0229    * later...
0230    */
0231   myCpu = get_ppc_cpu_type();
0232   myCpuRevision = get_ppc_cpu_revision();
0233 
0234   printk("Welcome to %s\n", rtems_get_version_string());
0235   printk("BSP: %s, CVS Release ($Name$)\n", "mvme3100");
0236 
0237   /*
0238    * the initial stack  has aready been set to this value in start.S
0239    * so there is no need to set it in r1 again... It is just for info
0240    * so that It can be printed without accessing R1.
0241    */
0242   asm volatile("mr %0, 1":"=r"(stack));
0243 
0244   /* tag the bottom */
0245   *((uint32_t*)stack) = 0;
0246 
0247   ppc_exc_initialize();
0248 
0249   printk("CPU 0x%x - rev 0x%x\n", myCpu, myCpuRevision);
0250 
0251 #ifdef SHOW_MORE_INIT_SETTINGS
0252   printk("Additionnal boot options are %s\n", BSP_commandline_string);
0253   printk("Initial system stack at %" PRIxPTR "\n", (uintptr_t) stack);
0254 #endif
0255 
0256 #ifdef SHOW_MORE_INIT_SETTINGS
0257   printk("Going to start PCI buses scanning and initialization\n");
0258 #endif
0259 
0260   BSP_mem_size            = BSP_get_mem_size();
0261 
0262   {
0263     /* memory-select errors were disabled in 'start.S';
0264      * motload has all TLBs mapping a possible larger area as
0265      * memory (not-guarded, caching-enabled) than actual physical
0266      * memory is available.
0267      * In case of speculative loads this may cause 'memory-select' errors
0268      * which seem to raise 'core_fault_in' (found no description in
0269      * the manual but I experienced this problem).
0270      * Such errors (if HID1[RFXE] is clear) may *stall* execution
0271      * leading to mysterious 'hangs'.
0272      *
0273      * Here we remove all mappings, re-enable memory-select
0274      * errors and make sure we enable HID1[RFXE] to avoid
0275      * stalls (since we don't implement handling individual
0276      * error-handling interrupts).
0277      */
0278 
0279     /* enable machine check for bad bus errors */
0280     _write_HID1( _read_HID1() | 0x20000 );
0281 
0282     rtems_e500_initlb();
0283 
0284     for ( i=0, tlb=rtems_e500_tlb_va_cache; i<NumberOf(rtems_e500_tlb_va_cache); i++, tlb++ ) {
0285       /* disable TLBs for caching-enabled, non-guarded areas
0286        * beyond physical memory
0287        */
0288       if (    tlb->att.v
0289           &&  0xa != (tlb->att.wimge & 0xa)
0290         &&  (tlb->va.va_epn<<12) >= BSP_mem_size ) {
0291         rtems_e500_clrtlb( E500_SELTLB_1 | i );
0292       }
0293     }
0294 
0295     /* clear all pending memory errors */
0296     _ccsr_wr32(0x2e40, 0xffffffff);
0297     /* enable checking for memory-select errors */
0298     _ccsr_wr32(0x2e44, _ccsr_rd32(0x2e44) & ~1 );
0299   }
0300 
0301   BSP_vpdRetrieveFields( vpdData );
0302 
0303   printk("Board Type: %s (S/N %s)\n",
0304       BSP_productIdent[0] ? BSP_productIdent : "n/a",
0305       BSP_serialNumber[0] ? BSP_serialNumber : "n/a");
0306 
0307   printk("External (=PCI Bus) Clock Freq   ");
0308   if ( 0xdeadbeef == BSP_pci_bus_frequency ) {
0309     BSP_pci_bus_frequency  = 66666666;
0310     printk(" NOT FOUND in VPD; using %10u Hz\n",
0311         BSP_pci_bus_frequency);
0312   } else {
0313     printk(": %10u Hz\n",
0314         BSP_pci_bus_frequency);
0315   }
0316 
0317   /* Calculate CPU and CCB bus freqs */
0318   BSP_calc_freqs();
0319 
0320   pci_initialize();
0321 
0322   prether(BSP_enetAddr0, 0);
0323   prether(BSP_enetAddr1, 1);
0324   prether(BSP_enetAddr2, 2);
0325 
0326   /* need to tweak the motload setup */
0327   BSP_motload_pci_fixup();
0328 
0329 #ifdef SHOW_MORE_INIT_SETTINGS
0330   printk("Number of PCI buses found is : %d\n", pci_bus_count());
0331   {
0332     BSP_pciConfigDump_early();
0333   }
0334 #endif
0335 
0336   if ( (chpt = strstr(BSP_commandline_string,"MEMSZ=")) ) {
0337     char    *endp;
0338     uint32_t   sz;
0339     chpt+=6 /* strlen("MEMSZ=") */;
0340     sz = strtoul(chpt, &endp, 0);
0341     if ( endp != chpt )
0342       BSP_mem_size = sz;
0343   }
0344 
0345   printk("Memory:                            %10u bytes\n", BSP_mem_size);
0346 
0347   BSP_bus_frequency       = 333333333;
0348   BSP_processor_frequency = 833333333;
0349   BSP_time_base_divisor   = 8000; /* if external RTC clock unused (HID0) */
0350 
0351   /* clear hostbridge errors but leave MCP disabled -
0352    * PCI config space scanning code will trip otherwise :-(
0353    */
0354   _BSP_clear_hostbridge_errors(0 /* enableMCP */, 0/*quiet*/);
0355 
0356   bsp_clicks_per_usec = BSP_bus_frequency/(BSP_time_base_divisor * 1000);
0357 
0358   /*
0359    * Initalize RTEMS IRQ system
0360    */
0361   BSP_rtems_irq_mng_init(0);
0362 
0363   if (1) {
0364     int i;
0365     unsigned msr,tcr;
0366     asm volatile("mfmsr %0":"=r"(msr));
0367     asm volatile (
0368       ".machine \"push\"\n"
0369       ".machine \"any\"\n"
0370       "mftcr %0\n"
0371       ".machine \"pop\"" :
0372       "=r"(tcr)
0373     );
0374     printk("MSR is 0x%08x, TCR 0x%08x\n",msr,tcr);
0375     asm volatile (
0376       ".machine \"push\"\n"
0377       ".machine \"any\"\n"
0378       "mttcr %0\n"
0379       ".machine \"pop\"" : :
0380       "r"(0)
0381     );
0382     if (0) {
0383       asm volatile("mtmsr %0"::"r"(msr|0x8000));
0384       for (i=0; i<12; i++)
0385         BSP_enable_irq_at_pic(i);
0386       printk("IRQS enabled\n");
0387     }
0388   }
0389 
0390   if (0) {
0391     unsigned x;
0392     asm volatile("mfivpr %0":"=r"(x));
0393     printk("IVPR: 0x%08x\n",x);
0394     asm volatile("mfivor8 %0":"=r"(x));
0395     printk("IVOR8: 0x%08x\n",x);
0396     printk("0x%08x\n",*(unsigned *)0xc00);
0397     printk("0x%08x\n",*(unsigned *)0xc04);
0398     printk("0x%08x\n",*(unsigned *)0xc08);
0399     printk("0x%08x\n\n\n",*(unsigned *)0xc0c);
0400     if (0) {
0401       *(unsigned *)0xc08 = 0x4c000064;
0402       asm volatile("dcbf 0, %0; icbi 0, %0; sync; isync"::"r"(0xc00));
0403     }
0404 
0405     printk("0x%08x\n", ppc_exc_lock_std);
0406     printk("0x%08x\n", ppc_exc_gpr3_std);
0407 
0408     asm volatile("sc");
0409 
0410     printk("0x%08x\n", ppc_exc_lock_std);
0411     printk("0x%08x\n", ppc_exc_gpr3_std);
0412   }
0413 
0414   printk("-----------------------------------------\n");
0415 
0416 #ifdef SHOW_MORE_INIT_SETTINGS
0417   printk("Exit from bspstart\n");
0418 #endif
0419 }
0420 
0421 RTEMS_SYSINIT_ITEM(
0422   bsp_early,
0423   RTEMS_SYSINIT_BSP_EARLY,
0424   RTEMS_SYSINIT_ORDER_MIDDLE
0425 );
0426 
0427 void bsp_start( void )
0428 {
0429   /* Initialization was done by bsp_early() */
0430 }
0431 
0432 static void mvme3100_i2c_initialize(void)
0433 {
0434   BSP_i2c_initialize();
0435 }
0436 
0437 RTEMS_SYSINIT_ITEM(
0438   mvme3100_i2c_initialize,
0439   RTEMS_SYSINIT_BSP_PRE_DRIVERS,
0440   RTEMS_SYSINIT_ORDER_MIDDLE
0441 );
0442 
0443 RTEMS_SYSINIT_ITEM(
0444   BSP_vme_config,
0445   RTEMS_SYSINIT_BSP_PRE_DRIVERS,
0446   RTEMS_SYSINIT_ORDER_MIDDLE
0447 );