diff options
Diffstat (limited to 'arch/ppc64/kernel')
-rw-r--r-- | arch/ppc64/kernel/LparData.c | 88 | ||||
-rw-r--r-- | arch/ppc64/kernel/head.S | 40 | ||||
-rw-r--r-- | arch/ppc64/kernel/pmac_setup.c | 12 | ||||
-rw-r--r-- | arch/ppc64/kernel/setup.c | 2 | ||||
-rw-r--r-- | arch/ppc64/kernel/smp.c | 15 | ||||
-rw-r--r-- | arch/ppc64/kernel/udbg.c | 2 |
6 files changed, 94 insertions, 65 deletions
diff --git a/arch/ppc64/kernel/LparData.c b/arch/ppc64/kernel/LparData.c index 6ffcf67dd50..76cfd1449d5 100644 --- a/arch/ppc64/kernel/LparData.c +++ b/arch/ppc64/kernel/LparData.c @@ -33,17 +33,36 @@ * the hypervisor and Linux. */ +/* + * WARNING - magic here + * + * Ok, this is a horrid hack below, but marginally better than the + * alternatives. What we really want is just to initialize + * hvReleaseData in C as in the #if 0 section here. However, gcc + * refuses to believe that (u32)&x is a constant expression, so will + * not allow the xMsNucDataOffset field to be properly initialized. + * So, we declare hvReleaseData in inline asm instead. We use inline + * asm, rather than a .S file, because the assembler won't generate + * the necessary relocation for the LparMap either, unless that symbol + * is declared in the same source file. Finally, we put the asm in a + * dummy, attribute-used function, instead of at file scope, because + * file scope asms don't allow contraints. We want to use the "i" + * constraints to put sizeof() and offsetof() expressions in there, + * because including asm/offsets.h in C code then stringifying causes + * all manner of warnings. + */ +#if 0 struct HvReleaseData hvReleaseData = { .xDesc = 0xc8a5d9c4, /* "HvRD" ebcdic */ .xSize = sizeof(struct HvReleaseData), .xVpdAreasPtrOffset = offsetof(struct naca_struct, xItVpdAreas), .xSlicNacaAddr = &naca, /* 64-bit Naca address */ - .xMsNucDataOffset = 0x4800, /* offset of LparMap within loadarea (see head.S) */ - .xTagsMode = 1, /* tags inactive */ - .xAddressSize = 0, /* 64 bit */ - .xNoSharedProcs = 0, /* shared processors */ - .xNoHMT = 0, /* HMT allowed */ - .xRsvd2 = 6, /* TEMP: This allows non-GA driver */ + .xMsNucDataOffset = (u32)((unsigned long)&xLparMap - KERNELBASE), + .xFlags = HVREL_TAGSINACTIVE /* tags inactive */ + /* 64 bit */ + /* shared processors */ + /* HMT allowed */ + | 6, /* TEMP: This allows non-GA driver */ .xVrmIndex = 4, /* We are v5r2m0 */ .xMinSupportedPlicVrmIndex = 3, /* v5r1m0 */ .xMinCompatablePlicVrmIndex = 3, /* v5r1m0 */ @@ -51,6 +70,63 @@ struct HvReleaseData hvReleaseData = { 0xa7, 0x40, 0xf2, 0x4b, 0xf4, 0x4b, 0xf6, 0xf4 }, }; +#endif + + +extern struct HvReleaseData hvReleaseData; + +static void __attribute_used__ hvReleaseData_wrapper(void) +{ + /* This doesn't appear to need any alignment (even 4 byte) */ + asm volatile ( + " lparMapPhys = xLparMap - %3\n" + " .data\n" + " .globl hvReleaseData\n" + "hvReleaseData:\n" + " .long 0xc8a5d9c4\n" /* xDesc */ + /* "HvRD" in ebcdic */ + " .short %0\n" /* xSize */ + " .short %1\n" /* xVpdAreasPtrOffset */ + " .llong naca\n" /* xSlicNacaAddr */ + " .long lparMapPhys\n" /* xMsNucDataOffset */ + " .long 0\n" /* xRsvd1 */ + " .short %2\n" /* xFlags */ + " .short 4\n" /* xVrmIndex - v5r2m0 */ + " .short 3\n" /* xMinSupportedPlicVrmIndex - v5r1m0 */ + " .short 3\n" /* xMinCompatablePlicVrmIndex - v5r1m0 */ + " .long 0xd38995a4\n" /* xVrmName */ + " .long 0xa740f24b\n" /* "Linux 2.4.64" ebcdic */ + " .long 0xf44bf6f4\n" + " . = hvReleaseData + %0\n" + " .previous\n" + : : "i"(sizeof(hvReleaseData)), + "i"(offsetof(struct naca_struct, xItVpdAreas)), + "i"(HVREL_TAGSINACTIVE /* tags inactive, 64 bit, */ + /* shared processors, HMT allowed */ + | 6), /* TEMP: This allows non-GA drivers */ + "i"(KERNELBASE) + ); +} + +struct LparMap __attribute__((aligned (16))) xLparMap = { + .xNumberEsids = HvEsidsToMap, + .xNumberRanges = HvRangesToMap, + .xSegmentTableOffs = STAB0_PAGE, + + .xEsids = { + { .xKernelEsid = GET_ESID(KERNELBASE), + .xKernelVsid = KERNEL_VSID(KERNELBASE), }, + { .xKernelEsid = GET_ESID(VMALLOCBASE), + .xKernelVsid = KERNEL_VSID(VMALLOCBASE), }, + }, + + .xRanges = { + { .xPages = HvPagesToMap, + .xOffset = 0, + .xVPN = KERNEL_VSID(KERNELBASE) << (SID_SHIFT - PAGE_SHIFT), + }, + }, +}; extern void system_reset_iSeries(void); extern void machine_check_iSeries(void); diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S index 93ebcac0d5a..74fc3bc6860 100644 --- a/arch/ppc64/kernel/head.S +++ b/arch/ppc64/kernel/head.S @@ -522,36 +522,9 @@ __end_interrupts: #ifdef CONFIG_PPC_ISERIES .globl naca naca: - .llong itVpdAreas - - /* - * The iSeries LPAR map is at this fixed address - * so that the HvReleaseData structure can address - * it with a 32-bit offset. - * - * The VSID values below are dependent on the - * VSID generation algorithm. See include/asm/mmu_context.h. - */ - - . = 0x4800 - - .llong 2 /* # ESIDs to be mapped by hypervisor */ - .llong 1 /* # memory ranges to be mapped by hypervisor */ - .llong STAB0_PAGE /* Page # of segment table within load area */ - .llong 0 /* Reserved */ - .llong 0 /* Reserved */ - .llong 0 /* Reserved */ - .llong 0 /* Reserved */ - .llong 0 /* Reserved */ - .llong (KERNELBASE>>SID_SHIFT) - .llong 0x408f92c94 /* KERNELBASE VSID */ - /* We have to list the bolted VMALLOC segment here, too, so that it - * will be restored on shared processor switch */ - .llong (VMALLOCBASE>>SID_SHIFT) - .llong 0xf09b89af5 /* VMALLOCBASE VSID */ - .llong 8192 /* # pages to map (32 MB) */ - .llong 0 /* Offset from start of loadarea to start of map */ - .llong 0x408f92c940000 /* VPN of first page to map */ + .llong itVpdAreas + .llong 0 /* xRamDisk */ + .llong 0 /* xRamDiskSize */ . = 0x6100 @@ -2131,13 +2104,6 @@ empty_zero_page: swapper_pg_dir: .space 4096 -#ifdef CONFIG_SMP -/* 1 page segment table per cpu (max 48, cpu0 allocated at STAB0_PHYS_ADDR) */ - .globl stab_array -stab_array: - .space 4096 * 48 -#endif - /* * This space gets a copy of optional info passed to us by the bootstrap * Used to pass parameters into the kernel like root=/dev/sda1, etc. diff --git a/arch/ppc64/kernel/pmac_setup.c b/arch/ppc64/kernel/pmac_setup.c index 3013cdb5f93..e40877fa67c 100644 --- a/arch/ppc64/kernel/pmac_setup.c +++ b/arch/ppc64/kernel/pmac_setup.c @@ -97,7 +97,7 @@ EXPORT_SYMBOL(smu_cmdbuf_abs); extern void udbg_init_scc(struct device_node *np); -void __pmac pmac_show_cpuinfo(struct seq_file *m) +static void __pmac pmac_show_cpuinfo(struct seq_file *m) { struct device_node *np; char *pp; @@ -144,7 +144,7 @@ void __pmac pmac_show_cpuinfo(struct seq_file *m) } -void __init pmac_setup_arch(void) +static void __init pmac_setup_arch(void) { /* init to some ~sane value until calibrate_delay() runs */ loops_per_jiffy = 50000000; @@ -230,7 +230,7 @@ void __pmac note_bootable_part(dev_t dev, int part, int goodness) } } -void __pmac pmac_restart(char *cmd) +static void __pmac pmac_restart(char *cmd) { switch(sys_ctrler) { #ifdef CONFIG_ADB_PMU @@ -249,7 +249,7 @@ void __pmac pmac_restart(char *cmd) } } -void __pmac pmac_power_off(void) +static void __pmac pmac_power_off(void) { switch(sys_ctrler) { #ifdef CONFIG_ADB_PMU @@ -267,7 +267,7 @@ void __pmac pmac_power_off(void) } } -void __pmac pmac_halt(void) +static void __pmac pmac_halt(void) { pmac_power_off(); } @@ -327,7 +327,7 @@ static void __init init_boot_display(void) /* * Early initialization. */ -void __init pmac_init_early(void) +static void __init pmac_init_early(void) { DBG(" -> pmac_init_early\n"); diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c index e80f10c8982..687e8559520 100644 --- a/arch/ppc64/kernel/setup.c +++ b/arch/ppc64/kernel/setup.c @@ -1068,6 +1068,8 @@ void __init setup_arch(char **cmdline_p) irqstack_early_init(); emergency_stack_init(); + stabs_alloc(); + /* set up the bootmem stuff with available memory */ do_init_bootmem(); sparse_init(); diff --git a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c index 2fcddfcb594..793b562da65 100644 --- a/arch/ppc64/kernel/smp.c +++ b/arch/ppc64/kernel/smp.c @@ -65,8 +65,6 @@ struct smp_ops_t *smp_ops; static volatile unsigned int cpu_callin_map[NR_CPUS]; -extern unsigned char stab_array[]; - void smp_call_function_interrupt(void); int smt_enabled_at_boot = 1; @@ -492,19 +490,6 @@ int __devinit __cpu_up(unsigned int cpu) paca[cpu].default_decr = tb_ticks_per_jiffy; - if (!cpu_has_feature(CPU_FTR_SLB)) { - void *tmp; - - /* maximum of 48 CPUs on machines with a segment table */ - if (cpu >= 48) - BUG(); - - tmp = &stab_array[PAGE_SIZE * cpu]; - memset(tmp, 0, PAGE_SIZE); - paca[cpu].stab_addr = (unsigned long)tmp; - paca[cpu].stab_real = virt_to_abs(tmp); - } - /* Make sure callin-map entry is 0 (can be leftover a CPU * hotplug */ diff --git a/arch/ppc64/kernel/udbg.c b/arch/ppc64/kernel/udbg.c index d4ccd6f1ef4..c0da45540f0 100644 --- a/arch/ppc64/kernel/udbg.c +++ b/arch/ppc64/kernel/udbg.c @@ -141,7 +141,7 @@ void udbg_init_scc(struct device_node *np) #endif /* CONFIG_PPC_PMAC */ -#if CONFIG_PPC_PMAC +#ifdef CONFIG_PPC_PMAC static void udbg_real_putc(unsigned char c) { while ((real_readb(sccc) & SCC_TXRDY) == 0) |