vserver 1.9.5.x5
[linux-2.6.git] / arch / ppc64 / kernel / iSeries_setup.c
index 3f17d5e..7191f57 100644 (file)
@@ -16,6 +16,8 @@
  *      2 of the License, or (at your option) any later version.
  */
  
+#undef DEBUG
+
 #include <linux/config.h>
 #include <linux/init.h>
 #include <linux/threads.h>
 #include <asm/pgtable.h>
 #include <asm/mmu_context.h>
 #include <asm/cputable.h>
+#include <asm/sections.h>
 
 #include <asm/time.h>
 #include "iSeries_setup.h"
 #include <asm/naca.h>
 #include <asm/paca.h>
+#include <asm/cache.h>
 #include <asm/sections.h>
 #include <asm/iSeries/LparData.h>
 #include <asm/iSeries/HvCallHpt.h>
 #include <asm/iSeries/IoHriMainStore.h>
 #include <asm/iSeries/iSeries_proc.h>
 #include <asm/iSeries/mf.h>
+#include <asm/iSeries/HvLpEvent.h>
+
+extern void hvlog(char *fmt, ...);
+
+#ifdef DEBUG
+#define DBG(fmt...) hvlog(fmt)
+#else
+#define DBG(fmt...)
+#endif
 
 /* Function Prototypes */
-extern void abort(void);
 extern void ppcdbg_initialize(void);
-extern void iSeries_pcibios_init(void);
-extern void tce_init_iSeries(void);
 
 static void build_iSeries_Memory_Map(void);
 static void setup_iSeries_cache_sizes(void);
 static void iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr);
-extern void build_valid_hpte(unsigned long vsid, unsigned long ea, unsigned long pa,
-                            pte_t *ptep, unsigned hpteflags, unsigned bolted);
-static void iSeries_setup_dprofile(void);
 extern void iSeries_setup_arch(void);
 extern void iSeries_pci_final_fixup(void);
 
@@ -77,16 +84,8 @@ static unsigned long tbFreqHz;
 static unsigned long tbFreqMhz;
 static unsigned long tbFreqMhzHundreths;
 
-unsigned long dprof_shift;
-unsigned long dprof_len;
-unsigned int *dprof_buffer;
-
 int piranha_simulator;
 
-int boot_cpuid;
-
-extern char _end[];
-
 extern int rd_size;            /* Defined in drivers/block/rd.c */
 extern unsigned long klimit;
 extern unsigned long embedded_sysmap_start;
@@ -285,8 +284,28 @@ unsigned long iSeries_process_mainstore_vpd(struct MemoryBlock *mb_array,
        return mem_blocks;
 }
 
-void __init iSeries_init_early(void)
+static void __init iSeries_parse_cmdline(void)
 {
+       char *p, *q;
+
+       /* copy the command line parameter from the primary VSP  */
+       HvCallEvent_dmaToSp(cmd_line, 2 * 64* 1024, 256,
+                       HvLpDma_Direction_RemoteToLocal);
+
+       p = cmd_line;
+       q = cmd_line + 255;
+       while(p < q) {
+               if (!*p || *p == '\n')
+                       break;
+               ++p;
+       }
+       *p = 0;
+}
+
+/*static*/ void __init iSeries_init_early(void)
+{
+       DBG(" -> iSeries_init_early()\n");
+
        ppcdbg_initialize();
 
 #if defined(CONFIG_BLK_DEV_INITRD)
@@ -294,13 +313,13 @@ void __init iSeries_init_early(void)
         * If the init RAM disk has been configured and there is
         * a non-zero starting address for it, set it up
         */
-       if (naca->xRamDisk) {
-               initrd_start = (unsigned long)__va(naca->xRamDisk);
-               initrd_end = initrd_start + naca->xRamDiskSize * PAGE_SIZE;
+       if (naca.xRamDisk) {
+               initrd_start = (unsigned long)__va(naca.xRamDisk);
+               initrd_end = initrd_start + naca.xRamDiskSize * PAGE_SIZE;
                initrd_below_start_ok = 1;      // ramdisk in kernel space
                ROOT_DEV = Root_RAM0;
-               if (((rd_size * 1024) / PAGE_SIZE) < naca->xRamDiskSize)
-                       rd_size = (naca->xRamDiskSize * PAGE_SIZE) / 1024;
+               if (((rd_size * 1024) / PAGE_SIZE) < naca.xRamDiskSize)
+                       rd_size = (naca.xRamDiskSize * PAGE_SIZE) / 1024;
        } else
 #endif /* CONFIG_BLK_DEV_INITRD */
        {
@@ -310,90 +329,57 @@ void __init iSeries_init_early(void)
        iSeries_recal_tb = get_tb();
        iSeries_recal_titan = HvCallXm_loadTod();
 
-       ppc_md.setup_arch = iSeries_setup_arch;
-       ppc_md.get_cpuinfo = iSeries_get_cpuinfo;
-       ppc_md.init_IRQ = iSeries_init_IRQ;
-       ppc_md.get_irq = iSeries_get_irq;
-       ppc_md.init = NULL;
-
-       ppc_md.pcibios_fixup  = iSeries_pci_final_fixup;
-
-       ppc_md.restart = iSeries_restart;
-       ppc_md.power_off = iSeries_power_off;
-       ppc_md.halt = iSeries_halt;
-
-       ppc_md.get_boot_time = iSeries_get_boot_time;
-       ppc_md.set_rtc_time = iSeries_set_rtc_time;
-       ppc_md.get_rtc_time = iSeries_get_rtc_time;
-       ppc_md.calibrate_decr = iSeries_calibrate_decr;
-       ppc_md.progress = iSeries_progress;
+       /*
+        * Cache sizes must be initialized before hpte_init_iSeries is called
+        * as the later need them for flush_icache_range()
+        */
+       setup_iSeries_cache_sizes();
 
+       /*
+        * Initialize the hash table management pointers
+        */
        hpte_init_iSeries();
-       tce_init_iSeries();
+
+       /*
+        * Initialize the DMA/TCE management
+        */
+       iommu_init_early_iSeries();
 
        /*
         * Initialize the table which translate Linux physical addresses to
         * AS/400 absolute addresses
         */
        build_iSeries_Memory_Map();
-       setup_iSeries_cache_sizes();
+
        /* Initialize machine-dependency vectors */
 #ifdef CONFIG_SMP
        smp_init_iSeries();
 #endif
        if (itLpNaca.xPirEnvironMode == 0) 
                piranha_simulator = 1;
-}
-
-void __init iSeries_init(unsigned long r3, unsigned long r4, unsigned long r5, 
-          unsigned long r6, unsigned long r7)
-{
-       char *p, *q;
 
        /* Associate Lp Event Queue 0 with processor 0 */
        HvCallEvent_setLpEventQueueInterruptProc(0, 0);
 
-       /* copy the command line parameter from the primary VSP  */
-       HvCallEvent_dmaToSp(cmd_line, 2 * 64* 1024, 256,
-                       HvLpDma_Direction_RemoteToLocal);
-
-       p = q = cmd_line + 255;
-       while (p > cmd_line) {
-               if ((*p == 0) || (*p == ' ') || (*p == '\n'))
-                       --p;
-               else
-                       break;
-       }
-       if (p < q)
-               *(p + 1) = 0;
-
-        if (strstr(cmd_line, "dprofile=")) {
-                for (q = cmd_line; (p = strstr(q, "dprofile=")) != 0; ) {
-                       unsigned long size, new_klimit;
-
-                        q = p + 9;
-                        if ((p > cmd_line) && (p[-1] != ' '))
-                                continue;
-                        dprof_shift = simple_strtoul(q, &q, 0);
-                       dprof_len = (unsigned long)_etext -
-                               (unsigned long)_stext;
-                       dprof_len >>= dprof_shift;
-                       size = ((dprof_len * sizeof(unsigned int)) +
-                                       (PAGE_SIZE-1)) & PAGE_MASK;
-                       dprof_buffer = (unsigned int *)((klimit +
-                                               (PAGE_SIZE-1)) & PAGE_MASK);
-                       new_klimit = ((unsigned long)dprof_buffer) + size;
-                       lmb_reserve(__pa(klimit), (new_klimit-klimit));
-                       klimit = new_klimit;
-                       memset(dprof_buffer, 0, size);
-                }
-        }
-
-       iSeries_setup_dprofile();
-
        mf_init();
        mf_initialized = 1;
        mb();
+
+       /* If we were passed an initrd, set the ROOT_DEV properly if the values
+        * look sensible. If not, clear initrd reference.
+        */
+#ifdef CONFIG_BLK_DEV_INITRD
+       if (initrd_start >= KERNELBASE && initrd_end >= KERNELBASE &&
+           initrd_end > initrd_start)
+               ROOT_DEV = Root_RAM0;
+       else
+               initrd_start = initrd_end = 0;
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+
+       iSeries_parse_cmdline();
+
+       DBG(" <- iSeries_init_early()\n");
 }
 
 /*
@@ -485,18 +471,16 @@ static void __init build_iSeries_Memory_Map(void)
        printk("HPT absolute addr = %016lx, size = %dK\n",
                        chunk_to_addr(hptFirstChunk), hptSizeChunks * 256);
 
-       /* Fill in the htab_data structure */
-       /* Fill in size of hashed page table */
+       /* Fill in the hashed page table hash mask */
        num_ptegs = hptSizePages *
                (PAGE_SIZE / (sizeof(HPTE) * HPTES_PER_GROUP));
-       htab_data.htab_num_ptegs = num_ptegs;
-       htab_data.htab_hash_mask = num_ptegs - 1;
+       htab_hash_mask = num_ptegs - 1;
        
        /*
         * The actual hashed page table is in the hypervisor,
         * we have no direct access
         */
-       htab_data.htab = NULL;
+       htab_address = NULL;
 
        /*
         * Determine if absolute memory has any
@@ -572,35 +556,38 @@ static void __init build_iSeries_Memory_Map(void)
 static void __init setup_iSeries_cache_sizes(void)
 {
        unsigned int i, n;
-       unsigned int procIx = get_paca()->xLpPaca.xDynHvPhysicalProcIndex;
+       unsigned int procIx = get_paca()->lppaca.dyn_hv_phys_proc_index;
 
-       systemcfg->iCacheL1Size =
-               xIoHriProcessorVpd[procIx].xInstCacheSize * 1024;
-       systemcfg->iCacheL1LineSize =
+       systemcfg->icache_size =
+       ppc64_caches.isize = xIoHriProcessorVpd[procIx].xInstCacheSize * 1024;
+       systemcfg->icache_line_size =
+       ppc64_caches.iline_size =
                xIoHriProcessorVpd[procIx].xInstCacheOperandSize;
-       systemcfg->dCacheL1Size =
+       systemcfg->dcache_size =
+       ppc64_caches.dsize =
                xIoHriProcessorVpd[procIx].xDataL1CacheSizeKB * 1024;
-       systemcfg->dCacheL1LineSize =
+       systemcfg->dcache_line_size =
+       ppc64_caches.dline_size =
                xIoHriProcessorVpd[procIx].xDataCacheOperandSize;
-       naca->iCacheL1LinesPerPage = PAGE_SIZE / systemcfg->iCacheL1LineSize;
-       naca->dCacheL1LinesPerPage = PAGE_SIZE / systemcfg->dCacheL1LineSize;
+       ppc64_caches.ilines_per_page = PAGE_SIZE / ppc64_caches.iline_size;
+       ppc64_caches.dlines_per_page = PAGE_SIZE / ppc64_caches.dline_size;
 
-       i = systemcfg->iCacheL1LineSize;
+       i = ppc64_caches.iline_size;
        n = 0;
        while ((i = (i / 2)))
                ++n;
-       naca->iCacheL1LogLineSize = n;
+       ppc64_caches.log_iline_size = n;
 
-       i = systemcfg->dCacheL1LineSize;
+       i = ppc64_caches.dline_size;
        n = 0;
        while ((i = (i / 2)))
                ++n;
-       naca->dCacheL1LogLineSize = n;
+       ppc64_caches.log_dline_size = n;
 
        printk("D-cache line size = %d\n",
-                       (unsigned int)systemcfg->dCacheL1LineSize);
+                       (unsigned int)ppc64_caches.dline_size);
        printk("I-cache line size = %d\n",
-                       (unsigned int)systemcfg->iCacheL1LineSize);
+                       (unsigned int)ppc64_caches.iline_size);
 }
 
 /*
@@ -666,7 +653,7 @@ extern unsigned long ppc_tb_freq;
 void __init iSeries_setup_arch(void)
 {
        void *eventStack;
-       unsigned procIx = get_paca()->xLpPaca.xDynHvPhysicalProcIndex;
+       unsigned procIx = get_paca()->lppaca.dyn_hv_phys_proc_index;
 
        /* Add an eye catcher and the systemcfg layout version number */
        strcpy(systemcfg->eye_catcher, "SYSTEMCFG:PPC64");
@@ -747,7 +734,7 @@ void iSeries_restart(char *cmd)
  */
 void iSeries_power_off(void)
 {
-       mf_powerOff();
+       mf_power_off();
 }
 
 /*
@@ -755,7 +742,7 @@ void iSeries_power_off(void)
  */
 void iSeries_halt(void)
 {
-       mf_powerOff();
+       mf_power_off();
 }
 
 /* JDH Hack */
@@ -811,21 +798,21 @@ void __init iSeries_progress(char * st, unsigned short code)
        printk("Progress: [%04x] - %s\n", (unsigned)code, st);
        if (!piranha_simulator && mf_initialized) {
                if (code != 0xffff)
-                       mf_displayProgress(code);
+                       mf_display_progress(code);
                else
-                       mf_clearSrc();
+                       mf_clear_src();
        }
 }
 
-void iSeries_fixup_klimit(void)
+static void __init iSeries_fixup_klimit(void)
 {
        /*
         * Change klimit to take into account any ram disk
         * that may be included
         */
-       if (naca->xRamDisk)
-               klimit = KERNELBASE + (u64)naca->xRamDisk +
-                       (naca->xRamDiskSize * PAGE_SIZE);
+       if (naca.xRamDisk)
+               klimit = KERNELBASE + (u64)naca.xRamDisk +
+                       (naca.xRamDiskSize * PAGE_SIZE);
        else {
                /*
                 * No ram disk was included - check and see if there
@@ -838,22 +825,6 @@ void iSeries_fixup_klimit(void)
        }
 }
 
-static void iSeries_setup_dprofile(void)
-{
-       if (dprof_buffer) {
-               unsigned i;
-
-               for (i = 0; i < NR_CPUS; ++i) {
-                       paca[i].prof_shift = dprof_shift;
-                       paca[i].prof_len = dprof_len - 1;
-                       paca[i].prof_buffer = dprof_buffer;
-                       paca[i].prof_stext = (unsigned *)_stext;
-                       mb();
-                       paca[i].prof_enabled = 1;
-               }
-       }
-}
-
 int __init iSeries_src_init(void)
 {
         /* clear the progress line */
@@ -862,3 +833,27 @@ int __init iSeries_src_init(void)
 }
 
 late_initcall(iSeries_src_init);
+
+void __init iSeries_early_setup(void)
+{
+       iSeries_fixup_klimit();
+
+       ppc_md.setup_arch = iSeries_setup_arch;
+       ppc_md.get_cpuinfo = iSeries_get_cpuinfo;
+       ppc_md.init_IRQ = iSeries_init_IRQ;
+       ppc_md.get_irq = iSeries_get_irq;
+       ppc_md.init_early = iSeries_init_early,
+
+       ppc_md.pcibios_fixup  = iSeries_pci_final_fixup;
+
+       ppc_md.restart = iSeries_restart;
+       ppc_md.power_off = iSeries_power_off;
+       ppc_md.halt = iSeries_halt;
+
+       ppc_md.get_boot_time = iSeries_get_boot_time;
+       ppc_md.set_rtc_time = iSeries_set_rtc_time;
+       ppc_md.get_rtc_time = iSeries_get_rtc_time;
+       ppc_md.calibrate_decr = iSeries_calibrate_decr;
+       ppc_md.progress = iSeries_progress;
+}
+