Back to home page

LXR

 
 

    


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

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.OARcorp.com/rtems/license.html.
0012  *
0013  *  Modified to support the MCP750.
0014  *  Modifications Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
0015  *
0016  *  Modified to support the Synergy VGM & Motorola PowerPC boards.
0017  *  (C) by Till Straumann, <strauman@slac.stanford.edu>, 2002, 2004, 2005
0018  * 
0019  *  Modified to support the mvme5500 BSP
0020  *  (C) by Kate Feng <feng1@bnl.gov>, 2003, 2004
0021  *      under the contract DE-AC02-98CH10886 with the Deaprtment of Energy
0022  *
0023  *  T. Straumann: 2005-2007; stolen again for 'beatnik'...
0024  */
0025 #include <string.h>
0026 #include <stdlib.h>
0027 #include <ctype.h>
0028 
0029 #include <rtems/libio.h>
0030 #include <rtems/libcsupport.h>
0031 #include <rtems/bspIo.h>
0032 #include <rtems/counter.h>
0033 #include <rtems/powerpc/powerpc.h>
0034 #include <rtems/sysinit.h>
0035 /*#include <bsp/consoleIo.h>*/
0036 #include <libcpu/spr.h>   /* registers.h is included here */
0037 #include <bsp.h>
0038 #include <bsp/bootcard.h>
0039 #include <bsp/uart.h>
0040 #include <bsp/pci.h>
0041 #include <bsp/gtreg.h>
0042 #include <bsp/gt_timer.h>
0043 #include <libcpu/bat.h>
0044 #include <libcpu/pte121.h>
0045 #include <libcpu/cpuIdent.h>
0046 #include <bsp/vectors.h>
0047 #include <bsp/VME.h>
0048 #include <bsp/vpd.h>
0049 
0050 #define SHOW_MORE_INIT_SETTINGS
0051 
0052 BSP_output_char_function_type     BSP_output_char = BSP_output_char_via_serial;
0053 BSP_polling_getchar_function_type BSP_poll_char = NULL;
0054 
0055 extern Triv121PgTbl BSP_pgtbl_setup(unsigned int *);
0056 extern void BSP_pgtbl_activate(Triv121PgTbl);
0057 extern void BSP_motload_pci_fixup(void);
0058 
0059 extern unsigned long __rtems_end[];
0060 
0061 /* We really shouldn't use these since MMUoff also sets IP;
0062  * nevertheless, during early init I don't care for now
0063  */
0064 extern void MMUoff(void);
0065 extern void MMUon(void);
0066 
0067 extern uint32_t probeMemoryEnd(void);
0068 
0069 SPR_RW(SPRG0)
0070 SPR_RW(SPRG1)
0071 SPR_RO(HID1)
0072 
0073 /* Table of PLL multipliers for 7455/7457:
0074 01000   2     00010   7.5       00000   11.5      00001   17
0075 10000   3     11000   8         10111   12        00101   18
0076 10100   4     01100   8.5       11111   12.5      00111   20
0077 10110   5     01111   9         01011   13        01001   21
0078 10010   5.5   01110   9.5       11100   13.5      01101   24
0079 11010   6     10101   10        11001   14        11101   28
0080 01010   6.5   10001   10.5      00011   15        00110   bypass
0081 00100   7     10011   11        11011   16        11110   off
0082 */
0083 
0084 /* Sorted according to CFG bits and multiplied by 2 it looks
0085  * like this (note that this is in sequential order, not
0086  * tabulated as above)
0087  */
0088 signed char mpc7450PllMultByTwo[32] = {
0089 23,       34,           15,           30,
0090 14,       36,           2/*bypass*/,  40,
0091 4,        42,           13,           26,
0092 17,       48,           19,           18,
0093 6,        21,           11,           22,
0094 8,        20,           10,           24,
0095 16,       28,           12,           32,
0096 27,       56,           0/*off*/,     25,
0097 };
0098 
0099 uint32_t bsp_clicks_per_usec         = 0;
0100 
0101 /*
0102  * Total memory using probing.
0103  */
0104 unsigned int BSP_mem_size;
0105 
0106 /*
0107  * PCI Bus Frequency
0108  */
0109 unsigned int BSP_bus_frequency       = 0xdeadbeef;
0110 /*
0111  * processor clock frequency
0112  */
0113 unsigned int BSP_processor_frequency = 0xdeadbeef;
0114 
0115 /*
0116  * Time base divisior (bus freq / TB clock)
0117  */
0118 unsigned int BSP_time_base_divisor   = 4000; /* most 604+ CPUs seem to use this */
0119 
0120 /* Board identification string */
0121 char BSP_productIdent[20] = {0};
0122 char BSP_serialNumber[20] = {0};
0123 
0124 /* VPD appends an extra char -- what for ? */
0125 char BSP_enetAddr0[7] = {0};
0126 char BSP_enetAddr1[7] = {0};
0127 
0128 char *rtems_progname;
0129 
0130 #define CMDLINE_BUF_SIZE    2048
0131 
0132 static char cmdline_buf[CMDLINE_BUF_SIZE];
0133 char *BSP_commandline_string = cmdline_buf;
0134 
0135 /* this routine is called early and must be safe with a not properly
0136  * aligned stack
0137  */
0138 char *save_boot_params(
0139   void *r3,
0140   void *r4,
0141   void *r5,
0142   char *cmdline_start,
0143   char *cmdline_end
0144 )
0145 {
0146 int             i=cmdline_end-cmdline_start;
0147     if ( i >= CMDLINE_BUF_SIZE )
0148         i = CMDLINE_BUF_SIZE-1;
0149     else if ( i < 0 )
0150         i = 0;
0151         memmove(cmdline_buf, cmdline_start, i);
0152     cmdline_buf[i]=0;
0153     return cmdline_buf;
0154 }
0155 
0156 static BSP_BoardType    board_type = Unknown;
0157 
0158 BSP_BoardType
0159 BSP_getBoardType( void )
0160 {
0161     return board_type;
0162 }
0163 
0164 uint32_t _CPU_Counter_frequency(void)
0165 {
0166   return BSP_bus_frequency / (BSP_time_base_divisor / 1000);
0167 }
0168 
0169 static void bsp_early( void )
0170 {
0171   unsigned char  *stack;
0172   char           *chpt;
0173 
0174   Triv121PgTbl  pt=0;
0175 
0176   VpdBufRec vpdData [] = {
0177     { key: ProductIdent, instance: 0, buf: BSP_productIdent, buflen: sizeof(BSP_productIdent) - 1 },
0178     { key: SerialNumber, instance: 0, buf: BSP_serialNumber, buflen: sizeof(BSP_serialNumber) - 1 },
0179     { key: CpuClockHz,   instance: 0, buf: &BSP_processor_frequency, buflen: sizeof(BSP_processor_frequency)  },
0180     { key: BusClockHz,   instance: 0, buf: &BSP_bus_frequency, buflen: sizeof(BSP_bus_frequency)  },
0181     { key: EthernetAddr, instance: 0, buf: BSP_enetAddr0, buflen: sizeof(BSP_enetAddr0) },
0182     { key: EthernetAddr, instance: 1, buf: BSP_enetAddr1, buflen: sizeof(BSP_enetAddr1) },
0183     VPD_END
0184   };
0185 
0186   /* T. Straumann: 4/2005
0187    *
0188    * Need to map the system registers early, so we can printk...
0189    * (otherwise we silently die)
0190    */
0191   /* map the PCI 0, 1 Domain I/O space, GT64260B registers
0192    * and the reserved area so that the size is the power of 2.
0193    */
0194   setdbat(7, BSP_DEV_AND_PCI_IO_BASE, BSP_DEV_AND_PCI_IO_BASE, BSP_DEV_AND_PCI_IO_SIZE, IO_PAGE);
0195 
0196   /* Intersperse messages with actions to help locate problems */
0197   printk("-----------------------------------------\n");
0198 
0199   /*
0200    * Get CPU identification dynamically. Note that the get_ppc_cpu_type() & friends functions
0201    * store the result in global variables so that it can be used latter...
0202    * This also verifies that we run on a known CPU.
0203    */
0204   get_ppc_cpu_type();
0205   get_ppc_cpu_revision();
0206 
0207   /* Make sure we detect a known host bridge */
0208   BSP_getDiscoveryVersion(/* assert detection */ 1);
0209 
0210   printk("Welcome to RTEMS %s\n", rtems_get_version_string() );
0211 
0212   /* Leave all caches as MotLoad left them. Seems to be fine */
0213 
0214   /*
0215    * the initial stack  has aready been set to this value in start.S
0216    * so there is no need to set it in r1 again... It is just for info
0217    * so that it can be printed without accessing R1.
0218    */
0219   __asm__ volatile("mr %0, 1":"=r"(stack));
0220 
0221   /* tag the bottom (T. Straumann 6/36/2001 <strauman@slac.stanford.edu>) */
0222 
0223   *((uint32_t *)stack) = 0;
0224 
0225   ppc_exc_initialize();
0226 
0227   printk("CPU: %s\n", get_ppc_cpu_type_name(current_ppc_cpu));
0228 
0229   /*
0230    * Initialize RTEMS IRQ system
0231    */
0232    BSP_rtems_irq_mng_init(0);
0233 
0234   BSP_vpdRetrieveFields(vpdData);
0235 
0236   if ( !strncmp(BSP_productIdent,"MVME5500",8) )
0237     board_type = MVME5500;
0238   else if ( !strncmp(BSP_productIdent,"MVME6100",8) )
0239     board_type = MVME6100;
0240 
0241   printk("Board Type: %s (S/N %s)\n",
0242         BSP_productIdent[0] ? BSP_productIdent : "n/a",
0243         BSP_serialNumber[0] ? BSP_serialNumber : "n/a");
0244 
0245   if ( 0xdeadbeef == BSP_bus_frequency ) {
0246     BSP_bus_frequency   = 133333333;
0247     printk("Bus Clock Freq NOT FOUND in VPD; using %10u Hz\n",
0248         BSP_bus_frequency);
0249   } else {
0250     printk("Bus Clock Freq:  %10u Hz\n",
0251         BSP_bus_frequency);
0252   }
0253 
0254   if ( 0xdeadbeef == BSP_processor_frequency ) {
0255     BSP_processor_frequency  = BSP_bus_frequency/2;
0256     BSP_processor_frequency *= mpc7450PllMultByTwo[ (_read_HID1() >> (31-19)) & 31 ];
0257   }
0258   printk("CPU Clock Freq:  %10u Hz\n", BSP_processor_frequency);
0259     
0260   /* probe real memory size; if it's more than 256M we can't currently access it
0261    * since at this point only BAT-0 maps 0..256M
0262    */
0263   BSP_mem_size              =  probeMemoryEnd();
0264 
0265   if ( (chpt = strstr(BSP_commandline_string,"MEMSZ=")) ) {
0266         char        *endp;
0267         uint32_t    sz;
0268         chpt+=6 /* strlen("MEMSZ=") */;
0269         sz = strtoul(chpt, &endp, 0);
0270         if ( endp != chpt )
0271             BSP_mem_size = sz;
0272   }
0273 
0274   printk("Memory:          %10u bytes\n", BSP_mem_size);
0275 
0276   if ( BSP_mem_size > 0x10000000 ) {
0277     uint32_t s;
0278     if ( BSP_mem_size > 0x80000000 ) {
0279         BSP_mem_size = 0x80000000;
0280         printk("Memory clipped to 0x%08x for now, sorry\n", BSP_mem_size);
0281     }
0282     for ( s = 0x20000000; s < BSP_mem_size ; s<<=1)
0283         ;
0284     MMUoff();
0285     /* since it's currently in use we must first surrender it */
0286     setdbat(0, 0, 0, 0, 0);
0287     setdbat(0, 0, 0, s, _PAGE_RW);
0288     MMUon();
0289   }
0290 
0291   printk("-----------------------------------------\n");
0292 
0293   /* Maybe not setup yet because of the warning message */
0294 
0295   /* Allocate and set up the page table mappings
0296    * This is only available on >604 CPUs.
0297    *
0298    * NOTE: This setup routine may modify the available memory
0299    *       size. It is essential to call it before
0300    *       calculating the workspace etc.
0301    */
0302   pt = BSP_pgtbl_setup(&BSP_mem_size);
0303   if (!pt)
0304      printk("WARNING: unable to setup page tables.\n");
0305 
0306 #ifdef SHOW_MORE_INIT_SETTINGS
0307   printk("Now BSP_mem_size = 0x%x\n",BSP_mem_size); 
0308 #endif
0309 
0310   /*
0311    * Set up our hooks
0312    */
0313 
0314   bsp_clicks_per_usec = BSP_bus_frequency/(BSP_time_base_divisor * 1000);
0315 
0316 #ifdef SHOW_MORE_INIT_SETTINGS
0317   printk(
0318     "Configuration.work_space_size = %x\n",
0319     rtems_configuration_get_work_space_size()
0320   );
0321 #endif
0322 
0323   /* Activate the page table mappings only after
0324    * initializing interrupts because the irq_mng_init()
0325    * routine needs to modify the text
0326    */           
0327   if ( pt ) {
0328 #ifdef SHOW_MORE_INIT_SETTINGS
0329     printk("Page table setup finished; will activate it NOW...\n");
0330 #endif
0331     BSP_pgtbl_activate(pt);
0332   }
0333 
0334 #ifdef SHOW_MORE_INIT_SETTINGS
0335   printk("Going to start PCI buses scanning and initialization\n");
0336 #endif 
0337   BSP_pci_initialize();
0338 
0339   /* need to tweak the motload setup */
0340   BSP_motload_pci_fixup();
0341 
0342   /* map 512M, 256 for PCI 256 for VME */
0343   setdbat(5,BSP_PCI_HOSE0_MEM_BASE, BSP_PCI_HOSE0_MEM_BASE, BSP_PCI_HOSE0_MEM_SIZE, IO_PAGE);
0344   setdbat(6,BSP_PCI_HOSE1_MEM_BASE, BSP_PCI_HOSE1_MEM_BASE, 0x10000000, IO_PAGE);
0345 
0346 #ifdef SHOW_MORE_INIT_SETTINGS
0347   printk("Number of PCI buses found is : %d\n", pci_bus_count());
0348 #endif
0349 
0350   /*
0351    * Initialize hardware timer facility (not used by BSP itself)
0352    * Needs PCI to identify discovery version...
0353    */
0354   BSP_timers_initialize();
0355 
0356 #ifdef SHOW_MORE_INIT_SETTINGS
0357   printk("MSR 0x%lx \n", _read_MSR());
0358   printk("Exit from bspstart\n");
0359 #endif
0360 }
0361 
0362 RTEMS_SYSINIT_ITEM(
0363   bsp_early,
0364   RTEMS_SYSINIT_BSP_EARLY,
0365   RTEMS_SYSINIT_ORDER_MIDDLE
0366 );
0367 
0368 void bsp_start( void )
0369 {
0370   /* Initialization was done by bsp_early() */
0371 }
0372 
0373 RTEMS_SYSINIT_ITEM(
0374   BSP_vme_config,
0375   RTEMS_SYSINIT_BSP_PRE_DRIVERS,
0376   RTEMS_SYSINIT_ORDER_MIDDLE
0377 );