upgrade to fedora-2.6.12-1.1398.FC4 + vserver 2.0.rc7
[linux-2.6.git] / arch / ppc64 / kernel / setup.c
index abb1441..dce198d 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/string.h>
 #include <linux/sched.h>
 #include <linux/init.h>
+#include <linux/kernel.h>
 #include <linux/reboot.h>
 #include <linux/delay.h>
 #include <linux/initrd.h>
@@ -41,7 +42,6 @@
 #include <asm/elf.h>
 #include <asm/machdep.h>
 #include <asm/iSeries/LparData.h>
-#include <asm/naca.h>
 #include <asm/paca.h>
 #include <asm/ppcdebug.h>
 #include <asm/time.h>
@@ -54,6 +54,9 @@
 #include <asm/rtas.h>
 #include <asm/iommu.h>
 #include <asm/serial.h>
+#include <asm/cache.h>
+#include <asm/page.h>
+#include <asm/mmu.h>
 
 #ifdef DEBUG
 #define DBG(fmt...) udbg_printf(fmt)
@@ -89,7 +92,6 @@ extern void udbg_init_maple_realmode(void);
 #endif
 
 /* extern void *stab; */
-extern HTAB htab_data;
 extern unsigned long klimit;
 
 extern void mm_init_ppc64(void);
@@ -101,15 +103,15 @@ extern void unflatten_device_tree(void);
 
 extern void smp_release_cpus(void);
 
-unsigned long decr_overclock = 1;
-unsigned long decr_overclock_proc0 = 1;
-unsigned long decr_overclock_set = 0;
-unsigned long decr_overclock_proc0_set = 0;
-
 int have_of = 1;
 int boot_cpuid = 0;
 int boot_cpuid_phys = 0;
 dev_t boot_dev;
+u64 ppc64_pft_size;
+u64 ppc64_debug_switch;
+
+struct ppc64_caches ppc64_caches;
+EXPORT_SYMBOL_GPL(ppc64_caches);
 
 /*
  * These are used in binfmt_elf.c to put aux entries on the stack
@@ -122,6 +124,7 @@ int ucache_bsize;
 /* The main machine-dep calls structure
  */
 struct machdep_calls ppc_md;
+EXPORT_SYMBOL(ppc_md);
 
 #ifdef CONFIG_MAGIC_SYSRQ
 unsigned long SYSRQ_KEY;
@@ -156,7 +159,7 @@ struct screen_info screen_info = {
  */
 void __init ppcdbg_initialize(void)
 {
-       naca->debug_switch = PPC_DEBUG_DEFAULT; /* | PPCDBG_BUSWALK | */
+       ppc64_debug_switch = PPC_DEBUG_DEFAULT; /* | PPCDBG_BUSWALK | */
        /* PPCDBG_PHBINIT | PPCDBG_MM | PPCDBG_MMINIT | PPCDBG_TCEINIT | PPCDBG_TCE */;
 }
 
@@ -261,15 +264,9 @@ static void __init setup_cpu_maps(void)
                nthreads = len / sizeof(u32);
 
                for (j = 0; j < nthreads && cpu < NR_CPUS; j++) {
-                       /*
-                        * Only spin up secondary threads if SMT is enabled.
-                        * We must leave space in the logical map for the
-                        * threads.
-                        */
-                       if (j == 0 || smt_enabled_at_boot) {
-                               cpu_set(cpu, cpu_present_map);
-                               set_hard_smp_processor_id(cpu, intserv[j]);
-                       }
+                       cpu_set(cpu, cpu_present_map);
+                       set_hard_smp_processor_id(cpu, intserv[j]);
+
                        if (intserv[j] == boot_cpuid_phys)
                                swap_cpuid = cpu;
                        cpu_set(cpu, cpu_possible_map);
@@ -308,7 +305,7 @@ static void __init setup_cpu_maps(void)
                maxcpus = ireg[num_addr_cell + num_size_cell];
 
                /* Double maxcpus for processors which have SMT capability */
-               if (cur_cpu_spec->cpu_features & CPU_FTR_SMT)
+               if (cpu_has_feature(CPU_FTR_SMT))
                        maxcpus *= 2;
 
                if (maxcpus > NR_CPUS) {
@@ -332,7 +329,7 @@ static void __init setup_cpu_maps(void)
         */
        for_each_cpu(cpu) {
                cpu_set(cpu, cpu_sibling_map[cpu]);
-               if (cur_cpu_spec->cpu_features & CPU_FTR_SMT)
+               if (cpu_has_feature(CPU_FTR_SMT))
                        cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]);
        }
 
@@ -394,7 +391,7 @@ void __init early_setup(unsigned long dt_ptr)
        DBG(" -> early_setup()\n");
 
        /*
-        * Fill the default DBG level in naca (do we want to keep
+        * Fill the default DBG level (do we want to keep
         * that old mecanism around forever ?)
         */
        ppcdbg_initialize();
@@ -448,17 +445,17 @@ void __init early_setup(unsigned long dt_ptr)
 
 
 /*
- * Initialize some remaining members of the naca and systemcfg structures
+ * Initialize some remaining members of the ppc64_caches and systemcfg structures
  * (at least until we get rid of them completely). This is mostly some
  * cache informations about the CPU that will be used by cache flush
  * routines and/or provided to userland
  */
-static void __init initialize_naca(void)
+static void __init initialize_cache_info(void)
 {
        struct device_node *np;
        unsigned long num_cpus = 0;
 
-       DBG(" -> initialize_naca()\n");
+       DBG(" -> initialize_cache_info()\n");
 
        for (np = NULL; (np = of_find_node_by_type(np, "cpu"));) {
                num_cpus += 1;
@@ -489,15 +486,15 @@ static void __init initialize_naca(void)
                        lsizep = (u32 *) get_property(np, dc, NULL);
                        if (lsizep != NULL)
                                lsize = *lsizep;
-
                        if (sizep == 0 || lsizep == 0)
                                DBG("Argh, can't find dcache properties ! "
                                    "sizep: %p, lsizep: %p\n", sizep, lsizep);
 
-                       systemcfg->dCacheL1Size = size;
-                       systemcfg->dCacheL1LineSize = lsize;
-                       naca->dCacheL1LogLineSize = __ilog2(lsize);
-                       naca->dCacheL1LinesPerPage = PAGE_SIZE/(lsize);
+                       systemcfg->dcache_size = ppc64_caches.dsize = size;
+                       systemcfg->dcache_line_size =
+                               ppc64_caches.dline_size = lsize;
+                       ppc64_caches.log_dline_size = __ilog2(lsize);
+                       ppc64_caches.dlines_per_page = PAGE_SIZE / lsize;
 
                        size = 0;
                        lsize = cur_cpu_spec->icache_bsize;
@@ -511,11 +508,11 @@ static void __init initialize_naca(void)
                                DBG("Argh, can't find icache properties ! "
                                    "sizep: %p, lsizep: %p\n", sizep, lsizep);
 
-                       systemcfg->iCacheL1Size = size;
-                       systemcfg->iCacheL1LineSize = lsize;
-                       naca->iCacheL1LogLineSize = __ilog2(lsize);
-                       naca->iCacheL1LinesPerPage = PAGE_SIZE/(lsize);
-
+                       systemcfg->icache_size = ppc64_caches.isize = size;
+                       systemcfg->icache_line_size =
+                               ppc64_caches.iline_size = lsize;
+                       ppc64_caches.log_iline_size = __ilog2(lsize);
+                       ppc64_caches.ilines_per_page = PAGE_SIZE / lsize;
                }
        }
 
@@ -525,7 +522,7 @@ static void __init initialize_naca(void)
        systemcfg->version.minor = SYSTEMCFG_MINOR;
        systemcfg->processor = mfspr(SPRN_PVR);
 
-       DBG(" <- initialize_naca()\n");
+       DBG(" <- initialize_cache_info()\n");
 }
 
 static void __init check_for_initrd(void)
@@ -586,7 +583,7 @@ void __init setup_system(void)
        unflatten_device_tree();
 
        /*
-        * Fill the naca & systemcfg structures with informations
+        * Fill the ppc64_caches & systemcfg structures with informations
         * retreived from the device-tree. Need to be called before
         * finish_device_tree() since the later requires some of the
         * informations filled up here to properly parse the interrupt
@@ -595,14 +592,14 @@ void __init setup_system(void)
         * routines like flush_icache_range (used by the hash init
         * later on).
         */
-       initialize_naca();
+       initialize_cache_info();
 
-#ifdef CONFIG_PPC_PSERIES
+#ifdef CONFIG_PPC_RTAS
        /*
         * Initialize RTAS if available
         */
        rtas_initialize();
-#endif /* CONFIG_PPC_PSERIES */
+#endif /* CONFIG_PPC_RTAS */
 
        /*
         * Check if we have an initrd provided via the device-tree
@@ -634,12 +631,11 @@ void __init setup_system(void)
        early_console_initialized = 1;
        register_console(&udbg_console);
 
-#endif /* !CONFIG_PPC_ISERIES */
-
        /* Save unparsed command line copy for /proc/cmdline */
        strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);
 
        parse_early_param();
+#endif /* !CONFIG_PPC_ISERIES */
 
 #if defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES)
        /*
@@ -656,18 +652,19 @@ void __init setup_system(void)
        printk("Starting Linux PPC64 %s\n", UTS_RELEASE);
 
        printk("-----------------------------------------------------\n");
-       printk("naca                          = 0x%p\n", naca);
-       printk("naca->pftSize                 = 0x%lx\n", naca->pftSize);
-       printk("naca->debug_switch            = 0x%lx\n", naca->debug_switch);
-       printk("naca->interrupt_controller    = 0x%ld\n", naca->interrupt_controller);
+       printk("ppc64_pft_size                = 0x%lx\n", ppc64_pft_size);
+       printk("ppc64_debug_switch            = 0x%lx\n", ppc64_debug_switch);
+       printk("ppc64_interrupt_controller    = 0x%ld\n", ppc64_interrupt_controller);
        printk("systemcfg                     = 0x%p\n", systemcfg);
        printk("systemcfg->platform           = 0x%x\n", systemcfg->platform);
        printk("systemcfg->processorCount     = 0x%lx\n", systemcfg->processorCount);
        printk("systemcfg->physicalMemorySize = 0x%lx\n", systemcfg->physicalMemorySize);
-       printk("systemcfg->dCacheL1LineSize   = 0x%x\n", systemcfg->dCacheL1LineSize);
-       printk("systemcfg->iCacheL1LineSize   = 0x%x\n", systemcfg->iCacheL1LineSize);
-       printk("htab_data.htab                = 0x%p\n", htab_data.htab);
-       printk("htab_data.num_ptegs           = 0x%lx\n", htab_data.htab_num_ptegs);
+       printk("ppc64_caches.dcache_line_size = 0x%x\n",
+                       ppc64_caches.dline_size);
+       printk("ppc64_caches.icache_line_size = 0x%x\n",
+                       ppc64_caches.iline_size);
+       printk("htab_address                  = 0x%p\n", htab_address);
+       printk("htab_hash_mask                = 0x%lx\n", htab_hash_mask);
        printk("-----------------------------------------------------\n");
 
        mm_init_ppc64();
@@ -759,7 +756,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                seq_printf(m, "unknown (%08x)", pvr);
 
 #ifdef CONFIG_ALTIVEC
-       if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC)
+       if (cpu_has_feature(CPU_FTR_ALTIVEC))
                seq_printf(m, ", altivec supported");
 #endif /* CONFIG_ALTIVEC */
 
@@ -797,20 +794,31 @@ struct seq_operations cpuinfo_op = {
        .show = show_cpuinfo,
 };
 
-#if 0 /* XXX not currently used */
+/*
+ * These three variables are used to save values passed to us by prom_init()
+ * via the device tree. The TCE variables are needed because with a memory_limit
+ * in force we may need to explicitly map the TCE are at the top of RAM.
+ */
 unsigned long memory_limit;
+unsigned long tce_alloc_start;
+unsigned long tce_alloc_end;
 
+#ifdef CONFIG_PPC_ISERIES
+/*
+ * On iSeries we just parse the mem=X option from the command line.
+ * On pSeries it's a bit more complicated, see prom_init_mem()
+ */
 static int __init early_parsemem(char *p)
 {
        if (!p)
                return 0;
 
-       memory_limit = memparse(p, &p);
+       memory_limit = ALIGN(memparse(p, &p), PAGE_SIZE);
 
        return 0;
 }
 early_param("mem", early_parsemem);
-#endif
+#endif /* CONFIG_PPC_ISERIES */
 
 #ifdef CONFIG_PPC_MULTIPLATFORM
 static int __init set_preferred_console(void)
@@ -981,6 +989,34 @@ static void __init emergency_stack_init(void)
                                                limit)) + PAGE_SIZE;
 }
 
+/*
+ * Called from setup_arch to initialize the bitmap of available
+ * syscalls in the systemcfg page
+ */
+void __init setup_syscall_map(void)
+{
+       unsigned int i, count64 = 0, count32 = 0;
+       extern unsigned long *sys_call_table;
+       extern unsigned long *sys_call_table32;
+       extern unsigned long sys_ni_syscall;
+
+
+       for (i = 0; i < __NR_syscalls; i++) {
+               if (sys_call_table[i] == sys_ni_syscall)
+                       continue;
+               count64++;
+               systemcfg->syscall_map_64[i >> 5] |= 0x80000000UL >> (i & 0x1f);
+       }
+       for (i = 0; i < __NR_syscalls; i++) {
+               if (sys_call_table32[i] == sys_ni_syscall)
+                       continue;
+               count32++;
+               systemcfg->syscall_map_32[i >> 5] |= 0x80000000UL >> (i & 0x1f);
+       }
+       printk(KERN_INFO "Syscall map setup, %d 32 bits and %d 64 bits syscalls\n",
+              count32, count64);
+}
+
 /*
  * Called into from start_kernel, after lock_kernel has been called.
  * Initializes bootmem, which is unsed to manage page allocation until
@@ -988,7 +1024,6 @@ static void __init emergency_stack_init(void)
  */
 void __init setup_arch(char **cmdline_p)
 {
-       extern int panic_timeout;
        extern void do_init_bootmem(void);
 
        ppc64_boot_msg(0x12, "Setup Arch");
@@ -1000,8 +1035,8 @@ void __init setup_arch(char **cmdline_p)
         * Systems with OF can look in the properties on the cpu node(s)
         * for a possibly more accurate value.
         */
-       dcache_bsize = systemcfg->dCacheL1LineSize; 
-       icache_bsize = systemcfg->iCacheL1LineSize; 
+       dcache_bsize = ppc64_caches.dline_size;
+       icache_bsize = ppc64_caches.iline_size;
 
        /* reboot on panic */
        panic_timeout = 180;
@@ -1020,6 +1055,9 @@ void __init setup_arch(char **cmdline_p)
        /* set up the bootmem stuff with available memory */
        do_init_bootmem();
 
+       /* initialize the syscall map in systemcfg */
+       setup_syscall_map();
+
        ppc_md.setup_arch();
 
        /* Select the correct idle loop for the platform. */
@@ -1077,64 +1115,15 @@ void ppc64_dump_msg(unsigned int src, const char *msg)
        printk("[dump]%04x %s\n", src, msg);
 }
 
-int set_spread_lpevents( char * str )
-{
-       /* The parameter is the number of processors to share in processing lp events */
-       unsigned long i;
-       unsigned long val = simple_strtoul( str, NULL, 0 );
-       if ( ( val > 0 ) && ( val <= NR_CPUS ) ) {
-               for ( i=1; i<val; ++i )
-                       paca[i].lpqueue_ptr = paca[0].lpqueue_ptr;
-               printk("lpevent processing spread over %ld processors\n", val);
-       }
-       else
-               printk("invalid spreaqd_lpevents %ld\n", val);
-       return 1;
-}      
-
 /* This should only be called on processor 0 during calibrate decr */
 void setup_default_decr(void)
 {
        struct paca_struct *lpaca = get_paca();
 
-       if ( decr_overclock_set && !decr_overclock_proc0_set )
-               decr_overclock_proc0 = decr_overclock;
-
-       lpaca->default_decr = tb_ticks_per_jiffy / decr_overclock_proc0;        
+       lpaca->default_decr = tb_ticks_per_jiffy;
        lpaca->next_jiffy_update_tb = get_tb() + tb_ticks_per_jiffy;
 }
 
-int set_decr_overclock_proc0( char * str )
-{
-       unsigned long val = simple_strtoul( str, NULL, 0 );
-       if ( ( val >= 1 ) && ( val <= 48 ) ) {
-               decr_overclock_proc0_set = 1;
-               decr_overclock_proc0 = val;
-               printk("proc 0 decrementer overclock factor of %ld\n", val);
-       }
-       else
-               printk("invalid proc 0 decrementer overclock factor of %ld\n", val);
-       return 1;
-}
-
-int set_decr_overclock( char * str )
-{
-       unsigned long val = simple_strtoul( str, NULL, 0 );
-       if ( ( val >= 1 ) && ( val <= 48 ) ) {
-               decr_overclock_set = 1;
-               decr_overclock = val;
-               printk("decrementer overclock factor of %ld\n", val);
-       }
-       else
-               printk("invalid decrementer overclock factor of %ld\n", val);
-       return 1;
-
-}
-
-__setup("spread_lpevents=", set_spread_lpevents );
-__setup("decr_overclock_proc0=", set_decr_overclock_proc0 );
-__setup("decr_overclock=", set_decr_overclock );
-
 #ifndef CONFIG_PPC_ISERIES
 /*
  * This function can be used by platforms to "find" legacy serial ports.
@@ -1147,7 +1136,8 @@ __setup("decr_overclock=", set_decr_overclock );
 static struct plat_serial8250_port serial_ports[MAX_LEGACY_SERIAL_PORTS+1];
 static unsigned int old_serial_count;
 
-void __init generic_find_legacy_serial_ports(unsigned int *default_speed)
+void __init generic_find_legacy_serial_ports(u64 *physport,
+               unsigned int *default_speed)
 {
        struct device_node *np;
        u32 *sizeprop;
@@ -1165,7 +1155,7 @@ void __init generic_find_legacy_serial_ports(unsigned int *default_speed)
 
        DBG(" -> generic_find_legacy_serial_port()\n");
 
-       naca->serialPortAddr = 0;
+       *physport = 0;
        if (default_speed)
                *default_speed = 0;
 
@@ -1287,7 +1277,7 @@ void __init generic_find_legacy_serial_ports(unsigned int *default_speed)
                                io_base = (io_base << 32) | rangesp[4];
                }
                if (io_base != 0) {
-                       naca->serialPortAddr = io_base + reg->address;
+                       *physport = io_base + reg->address;
                        if (default_speed && spd)
                                *default_speed = *spd;
                }
@@ -1327,6 +1317,12 @@ EXPORT_SYMBOL(check_legacy_ioport);
 static int __init early_xmon(char *p)
 {
        /* ensure xmon is enabled */
+       if (p) {
+               if (strncmp(p, "on", 2) == 0)
+                       xmon_init();
+               if (strncmp(p, "early", 5) != 0)
+                       return 0;
+       }
        xmon_init();
        debugger(NULL);
 
@@ -1339,6 +1335,4 @@ void cpu_die(void)
 {
        if (ppc_md.cpu_die)
                ppc_md.cpu_die();
-       local_irq_disable();
-       for (;;);
 }