* 2 of the License, or (at your option) any later version.
*/
-#define SECONDARY_PROCESSORS
-
#include <linux/config.h>
#include <linux/threads.h>
#include <asm/processor.h>
#include <asm/mmu.h>
#include <asm/systemcfg.h>
#include <asm/ppc_asm.h>
-#include <asm/offsets.h>
+#include <asm/asm-offsets.h>
#include <asm/bug.h>
#include <asm/cputable.h>
#include <asm/setup.h>
#define DO_SOFT_DISABLE
#endif
-/*
- * hcall interface to pSeries LPAR
- */
-#define H_SET_ASR 0x30
-
/*
* We layout physical memory as follows:
* 0x0000 - 0x00ff : Secondary processor spin code
* 0x0100 - 0x2fff : pSeries Interrupt prologs
- * 0x3000 - 0x6fff : interrupt support, iSeries and common interrupt prologs
+ * 0x3000 - 0x5fff : interrupt support, iSeries and common interrupt prologs
+ * 0x6000 - 0x6fff : Initial (CPU0) segment table
* 0x7000 - 0x7fff : FWNMI data area
- * 0x9000 - 0x9fff : Initial segment table
+ * 0x8000 - : Early init and support code
*/
/*
/* Catch branch to 0 in real mode */
trap
+
#ifdef CONFIG_PPC_ISERIES
/*
* At offset 0x20, there is a pointer to iSeries LPAR data.
.llong hvReleaseData-KERNELBASE
/*
- * At offset 0x28 and 0x30 are offsets to the msChunks
+ * At offset 0x28 and 0x30 are offsets to the mschunks_map
* array (used by the iSeries LPAR debugger to do translation
* between physical addresses and absolute addresses) and
* to the pidhash table (also used by the debugger)
*/
- .llong msChunks-KERNELBASE
+ .llong mschunks_map-KERNELBASE
.llong 0 /* pidhash-KERNELBASE SFRXXX */
/* Offset 0x38 - Pointer to start of embedded System.map */
embedded_sysmap_end:
.llong 0
-#else /* CONFIG_PPC_ISERIES */
+#endif /* CONFIG_PPC_ISERIES */
/* Secondary processors spin on this value until it goes to 1. */
.globl __secondary_hold_spinloop
std r24,__secondary_hold_acknowledge@l(0)
sync
- /* All secondary cpu's wait here until told to start. */
+ /* All secondary cpus wait here until told to start. */
100: ld r4,__secondary_hold_spinloop@l(0)
cmpdi 0,r4,1
bne 100b
BUG_OPCODE
#endif
#endif
-#endif
/* This value is used to mark exception frames on the stack. */
.section ".toc","aw"
cmpwi 0,r23,0
beq iSeries_secondary_smp_loop /* Loop until told to go */
-#ifdef SECONDARY_PROCESSORS
bne .__secondary_start /* Loop until told to go */
-#endif
iSeries_secondary_smp_loop:
/* Let the Hypervisor know we are alive */
/* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */
* R9 contains the saved CR, r13 points to the paca,
* r10 contains the (bad) kernel stack pointer,
* r11 and r12 contain the saved SRR0 and SRR1.
- * We switch to using the paca guard page as an emergency stack,
- * save the registers there, and call kernel_bad_stack(), which panics.
+ * We switch to using an emergency stack, save the registers there,
+ * and call kernel_bad_stack(), which panics.
*/
bad_stack:
ld r1,PACAEMERGSP(r13)
bl .unrecoverable_exception
b 1b
+/*
+ * Space for CPU0's segment table.
+ *
+ * On iSeries, the hypervisor must fill in at least one entry before
+ * we get control (with relocate on). The address is give to the hv
+ * as a page number (see xLparMap in LparData.c), so this must be at a
+ * fixed address (the linker can't compute (u64)&initial_stab >>
+ * PAGE_SHIFT).
+ */
+ . = STAB0_PHYS_ADDR /* 0x6000 */
+ .globl initial_stab
+initial_stab:
+ .space 4096
+
/*
* Data area reserved for FWNMI option.
* This address (0x7000) is fixed by the RPA.
.= 0x7000
.globl fwnmi_data_area
fwnmi_data_area:
- .space PAGE_SIZE
- /*
- * Space for the initial segment table
- * For LPAR, the hypervisor must fill in at least one entry
- * before we get control (with relocate on)
- */
- . = STAB0_PHYS_ADDR
- .globl __start_stab
-__start_stab:
+ /* iSeries does not use the FWNMI stuff, so it is safe to put
+ * this here, even if we later allow kernels that will boot on
+ * both pSeries and iSeries */
+#ifdef CONFIG_PPC_ISERIES
+ . = LPARMAP_PHYS
+#include "lparmap.s"
+/*
+ * This ".text" is here for old compilers that generate a trailing
+ * .note section when compiling .c files to .s
+ */
+ .text
+#endif /* CONFIG_PPC_ISERIES */
- . = (STAB0_PHYS_ADDR + PAGE_SIZE)
- .globl __end_stab
-__end_stab:
+ . = 0x8000
/*
* On pSeries, secondary processors spin in the following code.
b .kexec_wait /* next kernel might do better */
2: mtspr SPRG3,r13 /* Save vaddr of paca in SPRG3 */
- /* From now on, r24 is expected to be logica cpuid */
+ /* From now on, r24 is expected to be logical cpuid */
mr r24,r5
3: HMT_LOW
lbz r23,PACAPROCSTART(r13) /* Test if this processor should */
cmpwi 0,r23,0
#ifdef CONFIG_SMP
-#ifdef SECONDARY_PROCESSORS
bne .__secondary_start
-#endif
#endif
b 3b /* Loop until told to go */
.align 8
copy_to_here:
-/*
- * disable_kernel_fp()
- * Disable the FPU.
- */
-_GLOBAL(disable_kernel_fp)
- mfmsr r3
- rldicl r0,r3,(63-MSR_FP_LG),1
- rldicl r3,r0,(MSR_FP_LG+1),0
- mtmsrd r3 /* disable use of fpu now */
- isync
- blr
-
-/*
- * giveup_fpu(tsk)
- * Disable FP for the task given as the argument,
- * and save the floating-point registers in its thread_struct.
- * Enables the FPU for use in the kernel on return.
- */
-_GLOBAL(giveup_fpu)
- mfmsr r5
- ori r5,r5,MSR_FP
- mtmsrd r5 /* enable use of fpu now */
- isync
- cmpdi 0,r3,0
- beqlr- /* if no previous owner, done */
- addi r3,r3,THREAD /* want THREAD of task */
- ld r5,PT_REGS(r3)
- cmpdi 0,r5,0
- SAVE_32FPRS(0, r3)
- mffs fr0
- stfd fr0,THREAD_FPSCR(r3)
- beq 1f
- ld r4,_MSR-STACK_FRAME_OVERHEAD(r5)
- li r3,MSR_FP|MSR_FE0|MSR_FE1
- andc r4,r4,r3 /* disable FP for previous task */
- std r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#ifndef CONFIG_SMP
- li r5,0
- ld r4,last_task_used_math@got(r2)
- std r5,0(r4)
-#endif /* CONFIG_SMP */
- blr
-
-#ifdef CONFIG_ALTIVEC
-/*
- * disable_kernel_altivec()
- * Disable the VMX.
- */
-_GLOBAL(disable_kernel_altivec)
- mfmsr r3
- rldicl r0,r3,(63-MSR_VEC_LG),1
- rldicl r3,r0,(MSR_VEC_LG+1),0
- mtmsrd r3 /* disable use of VMX now */
- isync
- blr
-
-/*
- * giveup_altivec(tsk)
- * Disable VMX for the task given as the argument,
- * and save the vector registers in its thread_struct.
- * Enables the VMX for use in the kernel on return.
- */
-_GLOBAL(giveup_altivec)
- mfmsr r5
- oris r5,r5,MSR_VEC@h
- mtmsrd r5 /* enable use of VMX now */
- isync
- cmpdi 0,r3,0
- beqlr- /* if no previous owner, done */
- addi r3,r3,THREAD /* want THREAD of task */
- ld r5,PT_REGS(r3)
- cmpdi 0,r5,0
- SAVE_32VRS(0,r4,r3)
- mfvscr vr0
- li r4,THREAD_VSCR
- stvx vr0,r4,r3
- beq 1f
- ld r4,_MSR-STACK_FRAME_OVERHEAD(r5)
- lis r3,MSR_VEC@h
- andc r4,r4,r3 /* disable FP for previous task */
- std r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#ifndef CONFIG_SMP
- li r5,0
- ld r4,last_task_used_altivec@got(r2)
- std r5,0(r4)
-#endif /* CONFIG_SMP */
- blr
-
-#endif /* CONFIG_ALTIVEC */
-
#ifdef CONFIG_SMP
#ifdef CONFIG_PPC_PMAC
/*
#else
/* set the ASR */
ld r3,systemcfg@got(r2) /* r3 = ptr to systemcfg */
+ ld r3,0(r3)
lwz r3,PLATFORM(r3) /* r3 = platform flags */
- cmpldi r3,PLATFORM_PSERIES_LPAR
+ andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */
bne 98f
mfspr r3,PVR
srwi r3,r3,16
ld r3,PACASTABREAL(r13)
ori r4,r3,1 /* turn on valid bit */
ld r3,systemcfg@got(r2) /* r3 = ptr to systemcfg */
+ ld r3,0(r3)
lwz r3,PLATFORM(r3) /* r3 = platform flags */
- cmpldi r3,PLATFORM_PSERIES_LPAR
+ andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */
bne 98f
mfspr r3,PVR
srwi r3,r3,16
99:
/* Set SDR1 (hash table pointer) */
ld r3,systemcfg@got(r2) /* r3 = ptr to systemcfg */
+ ld r3,0(r3)
lwz r3,PLATFORM(r3) /* r3 = platform flags */
/* Test if bit 0 is set (LPAR bit) */
- andi. r3,r3,0x1
+ andi. r3,r3,PLATFORM_LPAR
bne 98f
LOADADDR(r6,_SDR1) /* Only if NOT LPAR */
sub r6,r6,r26
bl .start_kernel
-_GLOBAL(__setup_cpu_power3)
- blr
-
_GLOBAL(hmt_init)
#ifdef CONFIG_HMT
LOADADDR(r5, hmt_thread_data)
/*
* We put a few things here that have to be page-aligned.
- * This stuff goes at the beginning of the data segment,
- * which is page-aligned.
+ * This stuff goes at the beginning of the bss, which is page-aligned.
*/
- .data
+ .section ".bss"
+
.align 12
- .globl sdata
-sdata:
+
.globl empty_zero_page
empty_zero_page:
- .space 4096
+ .space PAGE_SIZE
.globl swapper_pg_dir
swapper_pg_dir:
- .space 4096
+ .space PAGE_SIZE
/*
* This space gets a copy of optional info passed to us by the bootstrap