diff options
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r-- | arch/powerpc/kernel/Makefile | 9 | ||||
-rw-r--r-- | arch/powerpc/kernel/align.c | 57 | ||||
-rw-r--r-- | arch/powerpc/kernel/asm-offsets.c | 8 | ||||
-rw-r--r-- | arch/powerpc/kernel/btext.c | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/crash.c | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/crash_dump.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/head_40x.S (renamed from arch/powerpc/kernel/head_4xx.S) | 3 | ||||
-rw-r--r-- | arch/powerpc/kernel/head_64.S | 585 | ||||
-rw-r--r-- | arch/powerpc/kernel/iommu.c | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/irq.c | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/lparmap.c | 32 | ||||
-rw-r--r-- | arch/powerpc/kernel/nvram_64.c | 23 | ||||
-rw-r--r-- | arch/powerpc/kernel/pci_32.c | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/ppc_ksyms.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/prom.c | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/prom_init.c | 11 | ||||
-rw-r--r-- | arch/powerpc/kernel/rtas_pci.c | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/setup_32.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/time.c | 3 |
19 files changed, 103 insertions, 650 deletions
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index b0cb2e662c2..967afc517d8 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -46,7 +46,7 @@ ifeq ($(CONFIG_PPC_MERGE),y) extra-$(CONFIG_PPC_STD_MMU) := head_32.o extra-$(CONFIG_PPC64) := head_64.o -extra-$(CONFIG_40x) := head_4xx.o +extra-$(CONFIG_40x) := head_40x.o extra-$(CONFIG_44x) := head_44x.o extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o extra-$(CONFIG_8xx) := head_8xx.o @@ -80,13 +80,6 @@ ifneq ($(CONFIG_PPC_INDIRECT_IO),y) obj-y += iomap.o endif -ifeq ($(CONFIG_PPC_ISERIES),y) -CFLAGS_lparmap.s += -g0 -extra-y += lparmap.s -$(obj)/head_64.o: $(obj)/lparmap.s -AFLAGS_head_64.o += -I$(obj) -endif - else # stuff used from here for ARCH=ppc smpobj-$(CONFIG_SMP) += smp.o diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c index 5c9ff7f5c44..4c47f9cc0d9 100644 --- a/arch/powerpc/kernel/align.c +++ b/arch/powerpc/kernel/align.c @@ -38,7 +38,7 @@ struct aligninfo { /* Bits in the flags field */ #define LD 0 /* load */ #define ST 1 /* store */ -#define SE 2 /* sign-extend value */ +#define SE 2 /* sign-extend value, or FP ld/st as word */ #define F 4 /* to/from fp regs */ #define U 8 /* update index register */ #define M 0x10 /* multiple load/store */ @@ -87,9 +87,9 @@ static struct aligninfo aligninfo[128] = { { 8, LD+F+U }, /* 00 1 1001: lfdu */ { 4, ST+F+S+U }, /* 00 1 1010: stfsu */ { 8, ST+F+U }, /* 00 1 1011: stfdu */ - INVALID, /* 00 1 1100 */ + { 16, LD+F }, /* 00 1 1100: lfdp */ INVALID, /* 00 1 1101 */ - INVALID, /* 00 1 1110 */ + { 16, ST+F }, /* 00 1 1110: stfdp */ INVALID, /* 00 1 1111 */ { 8, LD }, /* 01 0 0000: ldx */ INVALID, /* 01 0 0001 */ @@ -167,10 +167,10 @@ static struct aligninfo aligninfo[128] = { { 8, LD+F }, /* 11 0 1001: lfdx */ { 4, ST+F+S }, /* 11 0 1010: stfsx */ { 8, ST+F }, /* 11 0 1011: stfdx */ - INVALID, /* 11 0 1100 */ - { 8, LD+M }, /* 11 0 1101: lmd */ - INVALID, /* 11 0 1110 */ - { 8, ST+M }, /* 11 0 1111: stmd */ + { 16, LD+F }, /* 11 0 1100: lfdpx */ + { 4, LD+F+SE }, /* 11 0 1101: lfiwax */ + { 16, ST+F }, /* 11 0 1110: stfdpx */ + { 4, ST+F }, /* 11 0 1111: stfiwx */ { 4, LD+U }, /* 11 1 0000: lwzux */ INVALID, /* 11 1 0001 */ { 4, ST+U }, /* 11 1 0010: stwux */ @@ -356,6 +356,42 @@ static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr, return 1; } +/* + * Emulate floating-point pair loads and stores. + * Only POWER6 has these instructions, and it does true little-endian, + * so we don't need the address swizzling. + */ +static int emulate_fp_pair(struct pt_regs *regs, unsigned char __user *addr, + unsigned int reg, unsigned int flags) +{ + char *ptr = (char *) ¤t->thread.fpr[reg]; + int i, ret; + + if (!(flags & F)) + return 0; + if (reg & 1) + return 0; /* invalid form: FRS/FRT must be even */ + if (!(flags & SW)) { + /* not byte-swapped - easy */ + if (!(flags & ST)) + ret = __copy_from_user(ptr, addr, 16); + else + ret = __copy_to_user(addr, ptr, 16); + } else { + /* each FPR value is byte-swapped separately */ + ret = 0; + for (i = 0; i < 16; ++i) { + if (!(flags & ST)) + ret |= __get_user(ptr[i^7], addr + i); + else + ret |= __put_user(ptr[i^7], addr + i); + } + } + if (ret) + return -EFAULT; + return 1; /* exception handled and fixed up */ +} + /* * Called on alignment exception. Attempts to fixup @@ -471,6 +507,10 @@ int fix_alignment(struct pt_regs *regs) flush_fp_to_thread(current); } + /* Special case for 16-byte FP loads and stores */ + if (nb == 16) + return emulate_fp_pair(regs, addr, reg, flags); + /* If we are loading, get the data from user space, else * get it from register values */ @@ -531,7 +571,8 @@ int fix_alignment(struct pt_regs *regs) * or floating point single precision conversion */ switch (flags & ~(U|SW)) { - case LD+SE: /* sign extend */ + case LD+SE: /* sign extending integer loads */ + case LD+F+SE: /* sign extend for lfiwax */ if ( nb == 2 ) data.ll = data.x16.low16; else /* nb must be 4 */ diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 2cb1d948779..a40805328f9 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -312,5 +312,13 @@ int main(void) #ifdef CONFIG_BUG DEFINE(BUG_ENTRY_SIZE, sizeof(struct bug_entry)); #endif + +#ifdef CONFIG_PPC_ISERIES + /* the assembler miscalculates the VSID values */ + DEFINE(PAGE_OFFSET_ESID, GET_ESID(PAGE_OFFSET)); + DEFINE(PAGE_OFFSET_VSID, KERNEL_VSID(PAGE_OFFSET)); + DEFINE(VMALLOC_START_ESID, GET_ESID(VMALLOC_START)); + DEFINE(VMALLOC_START_VSID, KERNEL_VSID(VMALLOC_START)); +#endif return 0; } diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c index e7b684689e0..3ef51fb6f10 100644 --- a/arch/powerpc/kernel/btext.c +++ b/arch/powerpc/kernel/btext.c @@ -11,7 +11,6 @@ #include <asm/sections.h> #include <asm/prom.h> #include <asm/btext.h> -#include <asm/prom.h> #include <asm/page.h> #include <asm/mmu.h> #include <asm/pgtable.h> diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c index 37658ea417f..77c749a1337 100644 --- a/arch/powerpc/kernel/crash.c +++ b/arch/powerpc/kernel/crash.c @@ -24,7 +24,6 @@ #include <linux/init.h> #include <linux/irq.h> #include <linux/types.h> -#include <linux/irq.h> #include <asm/processor.h> #include <asm/machdep.h> diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c index 2f6f5a7bc69..ffa91d673ec 100644 --- a/arch/powerpc/kernel/crash_dump.c +++ b/arch/powerpc/kernel/crash_dump.c @@ -25,7 +25,7 @@ #define DBG(fmt...) #endif -void reserve_kdump_trampoline(void) +void __init reserve_kdump_trampoline(void) { lmb_reserve(0, KDUMP_RESERVE_LIMIT); } diff --git a/arch/powerpc/kernel/head_4xx.S b/arch/powerpc/kernel/head_40x.S index adc7f8097cd..a8e045773a9 100644 --- a/arch/powerpc/kernel/head_4xx.S +++ b/arch/powerpc/kernel/head_40x.S @@ -35,7 +35,6 @@ #include <asm/page.h> #include <asm/mmu.h> #include <asm/pgtable.h> -#include <asm/ibm4xx.h> #include <asm/cputable.h> #include <asm/thread_info.h> #include <asm/ppc_asm.h> @@ -772,7 +771,7 @@ finish_tlb_load: */ lwz r9, tlb_4xx_index@l(0) addi r9, r9, 1 - andi. r9, r9, (PPC4XX_TLB_SIZE-1) + andi. r9, r9, (PPC40X_TLB_SIZE-1) stw r9, tlb_4xx_index@l(0) 6: diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 171800002ed..33c4e8cab0b 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -34,6 +34,8 @@ #include <asm/iseries/lpar_map.h> #include <asm/thread_info.h> #include <asm/firmware.h> +#include <asm/page_64.h> +#include <asm/exception.h> #define DO_SOFT_DISABLE @@ -144,344 +146,9 @@ exception_marker: .text /* - * The following macros define the code that appears as - * the prologue to each of the exception handlers. They - * are split into two parts to allow a single kernel binary - * to be used for pSeries and iSeries. - * LOL. One day... - paulus - */ - -/* - * We make as much of the exception code common between native - * exception handlers (including pSeries LPAR) and iSeries LPAR - * implementations as possible. - */ - -/* * This is the start of the interrupt handlers for pSeries * This code runs with relocation off. */ -#define EX_R9 0 -#define EX_R10 8 -#define EX_R11 16 -#define EX_R12 24 -#define EX_R13 32 -#define EX_SRR0 40 -#define EX_DAR 48 -#define EX_DSISR 56 -#define EX_CCR 60 -#define EX_R3 64 -#define EX_LR 72 - -/* - * We're short on space and time in the exception prolog, so we can't - * use the normal SET_REG_IMMEDIATE macro. Normally we just need the - * low halfword of the address, but for Kdump we need the whole low - * word. - */ -#ifdef CONFIG_CRASH_DUMP -#define LOAD_HANDLER(reg, label) \ - oris reg,reg,(label)@h; /* virt addr of handler ... */ \ - ori reg,reg,(label)@l; /* .. and the rest */ -#else -#define LOAD_HANDLER(reg, label) \ - ori reg,reg,(label)@l; /* virt addr of handler ... */ -#endif - -/* - * Equal to EXCEPTION_PROLOG_PSERIES, except that it forces 64bit mode. - * The firmware calls the registered system_reset_fwnmi and - * machine_check_fwnmi handlers in 32bit mode if the cpu happens to run - * a 32bit application at the time of the event. - * This firmware bug is present on POWER4 and JS20. - */ -#define EXCEPTION_PROLOG_PSERIES_FORCE_64BIT(area, label) \ - mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \ - std r9,area+EX_R9(r13); /* save r9 - r12 */ \ - std r10,area+EX_R10(r13); \ - std r11,area+EX_R11(r13); \ - std r12,area+EX_R12(r13); \ - mfspr r9,SPRN_SPRG1; \ - std r9,area+EX_R13(r13); \ - mfcr r9; \ - clrrdi r12,r13,32; /* get high part of &label */ \ - mfmsr r10; \ - /* force 64bit mode */ \ - li r11,5; /* MSR_SF_LG|MSR_ISF_LG */ \ - rldimi r10,r11,61,0; /* insert into top 3 bits */ \ - /* done 64bit mode */ \ - mfspr r11,SPRN_SRR0; /* save SRR0 */ \ - LOAD_HANDLER(r12,label) \ - ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \ - mtspr SPRN_SRR0,r12; \ - mfspr r12,SPRN_SRR1; /* and SRR1 */ \ - mtspr SPRN_SRR1,r10; \ - rfid; \ - b . /* prevent speculative execution */ - -#define EXCEPTION_PROLOG_PSERIES(area, label) \ - mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \ - std r9,area+EX_R9(r13); /* save r9 - r12 */ \ - std r10,area+EX_R10(r13); \ - std r11,area+EX_R11(r13); \ - std r12,area+EX_R12(r13); \ - mfspr r9,SPRN_SPRG1; \ - std r9,area+EX_R13(r13); \ - mfcr r9; \ - clrrdi r12,r13,32; /* get high part of &label */ \ - mfmsr r10; \ - mfspr r11,SPRN_SRR0; /* save SRR0 */ \ - LOAD_HANDLER(r12,label) \ - ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \ - mtspr SPRN_SRR0,r12; \ - mfspr r12,SPRN_SRR1; /* and SRR1 */ \ - mtspr SPRN_SRR1,r10; \ - rfid; \ - b . /* prevent speculative execution */ - -/* - * This is the start of the interrupt handlers for iSeries - * This code runs with relocation on. - */ -#define EXCEPTION_PROLOG_ISERIES_1(area) \ - mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \ - std r9,area+EX_R9(r13); /* save r9 - r12 */ \ - std r10,area+EX_R10(r13); \ - std r11,area+EX_R11(r13); \ - std r12,area+EX_R12(r13); \ - mfspr r9,SPRN_SPRG1; \ - std r9,area+EX_R13(r13); \ - mfcr r9 - -#define EXCEPTION_PROLOG_ISERIES_2 \ - mfmsr r10; \ - ld r12,PACALPPACAPTR(r13); \ - ld r11,LPPACASRR0(r12); \ - ld r12,LPPACASRR1(r12); \ - ori r10,r10,MSR_RI; \ - mtmsrd r10,1 - -/* - * The common exception prolog is used for all except a few exceptions - * such as a segment miss on a kernel address. We have to be prepared - * to take another exception from the point where we first touch the - * kernel stack onwards. - * - * On entry r13 points to the paca, r9-r13 are saved in the paca, - * r9 contains the saved CR, r11 and r12 contain the saved SRR0 and - * SRR1, and relocation is on. - */ -#define EXCEPTION_PROLOG_COMMON(n, area) \ - andi. r10,r12,MSR_PR; /* See if coming from user */ \ - mr r10,r1; /* Save r1 */ \ - subi r1,r1,INT_FRAME_SIZE; /* alloc frame on kernel stack */ \ - beq- 1f; \ - ld r1,PACAKSAVE(r13); /* kernel stack to use */ \ -1: cmpdi cr1,r1,0; /* check if r1 is in userspace */ \ - bge- cr1,2f; /* abort if it is */ \ - b 3f; \ -2: li r1,(n); /* will be reloaded later */ \ - sth r1,PACA_TRAP_SAVE(r13); \ - b bad_stack; \ -3: std r9,_CCR(r1); /* save CR in stackframe */ \ - std r11,_NIP(r1); /* save SRR0 in stackframe */ \ - std r12,_MSR(r1); /* save SRR1 in stackframe */ \ - std r10,0(r1); /* make stack chain pointer */ \ - std r0,GPR0(r1); /* save r0 in stackframe */ \ - std r10,GPR1(r1); /* save r1 in stackframe */ \ - ACCOUNT_CPU_USER_ENTRY(r9, r10); \ - std r2,GPR2(r1); /* save r2 in stackframe */ \ - SAVE_4GPRS(3, r1); /* save r3 - r6 in stackframe */ \ - SAVE_2GPRS(7, r1); /* save r7, r8 in stackframe */ \ - ld r9,area+EX_R9(r13); /* move r9, r10 to stackframe */ \ - ld r10,area+EX_R10(r13); \ - std r9,GPR9(r1); \ - std r10,GPR10(r1); \ - ld r9,area+EX_R11(r13); /* move r11 - r13 to stackframe */ \ - ld r10,area+EX_R12(r13); \ - ld r11,area+EX_R13(r13); \ - std r9,GPR11(r1); \ - std r10,GPR12(r1); \ - std r11,GPR13(r1); \ - ld r2,PACATOC(r13); /* get kernel TOC into r2 */ \ - mflr r9; /* save LR in stackframe */ \ - std r9,_LINK(r1); \ - mfctr r10; /* save CTR in stackframe */ \ - std r10,_CTR(r1); \ - lbz r10,PACASOFTIRQEN(r13); \ - mfspr r11,SPRN_XER; /* save XER in stackframe */ \ - std r10,SOFTE(r1); \ - std r11,_XER(r1); \ - li r9,(n)+1; \ - std r9,_TRAP(r1); /* set trap number */ \ - li r10,0; \ - ld r11,exception_marker@toc(r2); \ - std r10,RESULT(r1); /* clear regs->result */ \ - std r11,STACK_FRAME_OVERHEAD-16(r1); /* mark the frame */ - -/* - * Exception vectors. - */ -#define STD_EXCEPTION_PSERIES(n, label) \ - . = n; \ - .globl label##_pSeries; \ -label##_pSeries: \ - HMT_MEDIUM; \ - mtspr SPRN_SPRG1,r13; /* save r13 */ \ - EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common) - -#define HSTD_EXCEPTION_PSERIES(n, label) \ - . = n; \ - .globl label##_pSeries; \ -label##_pSeries: \ - HMT_MEDIUM; \ - mtspr SPRN_SPRG1,r20; /* save r20 */ \ - mfspr r20,SPRN_HSRR0; /* copy HSRR0 to SRR0 */ \ - mtspr SPRN_SRR0,r20; \ - mfspr r20,SPRN_HSRR1; /* copy HSRR0 to SRR0 */ \ - mtspr SPRN_SRR1,r20; \ - mfspr r20,SPRN_SPRG1; /* restore r20 */ \ - mtspr SPRN_SPRG1,r13; /* save r13 */ \ - EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common) - - -#define MASKABLE_EXCEPTION_PSERIES(n, label) \ - . = n; \ - .globl label##_pSeries; \ -label##_pSeries: \ - HMT_MEDIUM; \ - mtspr SPRN_SPRG1,r13; /* save r13 */ \ - mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \ - std r9,PACA_EXGEN+EX_R9(r13); /* save r9, r10 */ \ - std r10,PACA_EXGEN+EX_R10(r13); \ - lbz r10,PACASOFTIRQEN(r13); \ - mfcr r9; \ - cmpwi r10,0; \ - beq masked_interrupt; \ - mfspr r10,SPRN_SPRG1; \ - std r10,PACA_EXGEN+EX_R13(r13); \ - std r11,PACA_EXGEN+EX_R11(r13); \ - std r12,PACA_EXGEN+EX_R12(r13); \ - clrrdi r12,r13,32; /* get high part of &label */ \ - mfmsr r10; \ - mfspr r11,SPRN_SRR0; /* save SRR0 */ \ - LOAD_HANDLER(r12,label##_common) \ - ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \ - mtspr SPRN_SRR0,r12; \ - mfspr r12,SPRN_SRR1; /* and SRR1 */ \ - mtspr SPRN_SRR1,r10; \ - rfid; \ - b . /* prevent speculative execution */ - -#define STD_EXCEPTION_ISERIES(n, label, area) \ - .globl label##_iSeries; \ -label##_iSeries: \ - HMT_MEDIUM; \ - mtspr SPRN_SPRG1,r13; /* save r13 */ \ - EXCEPTION_PROLOG_ISERIES_1(area); \ - EXCEPTION_PROLOG_ISERIES_2; \ - b label##_common - -#define MASKABLE_EXCEPTION_ISERIES(n, label) \ - .globl label##_iSeries; \ -label##_iSeries: \ - HMT_MEDIUM; \ - mtspr SPRN_SPRG1,r13; /* save r13 */ \ - EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN); \ - lbz r10,PACASOFTIRQEN(r13); \ - cmpwi 0,r10,0; \ - beq- label##_iSeries_masked; \ - EXCEPTION_PROLOG_ISERIES_2; \ - b label##_common; \ - -#ifdef CONFIG_PPC_ISERIES -#define DISABLE_INTS \ - li r11,0; \ - stb r11,PACASOFTIRQEN(r13); \ -BEGIN_FW_FTR_SECTION; \ - stb r11,PACAHARDIRQEN(r13); \ -END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES); \ -BEGIN_FW_FTR_SECTION; \ - mfmsr r10; \ - ori r10,r10,MSR_EE; \ - mtmsrd r10,1; \ -END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) - -#else -#define DISABLE_INTS \ - li r11,0; \ - stb r11,PACASOFTIRQEN(r13); \ - stb r11,PACAHARDIRQEN(r13) - -#endif /* CONFIG_PPC_ISERIES */ - -#define ENABLE_INTS \ - ld r12,_MSR(r1); \ - mfmsr r11; \ - rlwimi r11,r12,0,MSR_EE; \ - mtmsrd r11,1 - -#define STD_EXCEPTION_COMMON(trap, label, hdlr) \ - .align 7; \ - .globl label##_common; \ -label##_common: \ - EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \ - DISABLE_INTS; \ - bl .save_nvgprs; \ - addi r3,r1,STACK_FRAME_OVERHEAD; \ - bl hdlr; \ - b .ret_from_except - -/* - * Like STD_EXCEPTION_COMMON, but for exceptions that can occur - * in the idle task and therefore need the special idle handling. - */ -#define STD_EXCEPTION_COMMON_IDLE(trap, label, hdlr) \ - .align 7; \ - .globl label##_common; \ -label##_common: \ - EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \ - FINISH_NAP; \ - DISABLE_INTS; \ - bl .save_nvgprs; \ - addi r3,r1,STACK_FRAME_OVERHEAD; \ - bl hdlr; \ - b .ret_from_except - -#define STD_EXCEPTION_COMMON_LITE(trap, label, hdlr) \ - .align 7; \ - .globl label##_common; \ -label##_common: \ - EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \ - FINISH_NAP; \ - DISABLE_INTS; \ - bl .ppc64_runlatch_on; \ - addi r3,r1,STACK_FRAME_OVERHEAD; \ - bl hdlr; \ - b .ret_from_except_lite - -/* - * When the idle code in power4_idle puts the CPU into NAP mode, - * it has to do so in a loop, and relies on the external interrupt - * and decrementer interrupt entry code to get it out of the loop. - * It sets the _TLF_NAPPING bit in current_thread_info()->local_flags - * to signal that it is in the loop and needs help to get out. - */ -#ifdef CONFIG_PPC_970_NAP -#define FINISH_NAP \ -BEGIN_FTR_SECTION \ - clrrdi r11,r1,THREAD_SHIFT; \ - ld r9,TI_LOCAL_FLAGS(r11); \ - andi. r10,r9,_TLF_NAPPING; \ - bnel power4_fixup_nap; \ -END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) -#else -#define FINISH_NAP -#endif - -/* - * Start of pSeries system interrupt routines - */ . = 0x100 .globl __start_interrupts __start_interrupts: @@ -691,192 +358,6 @@ machine_check_fwnmi: mtspr SPRN_SPRG1,r13 /* save r13 */ EXCEPTION_PROLOG_PSERIES_FORCE_64BIT(PACA_EXMC, machine_check_common) -#ifdef CONFIG_PPC_ISERIES -/*** ISeries-LPAR interrupt handlers ***/ - - STD_EXCEPTION_ISERIES(0x200, machine_check, PACA_EXMC) - - .globl data_access_iSeries -data_access_iSeries: - mtspr SPRN_SPRG1,r13 -BEGIN_FTR_SECTION - mtspr SPRN_SPRG2,r12 - mfspr r13,SPRN_DAR - mfspr r12,SPRN_DSISR - srdi r13,r13,60 - rlwimi r13,r12,16,0x20 - mfcr r12 - cmpwi r13,0x2c - beq .do_stab_bolted_iSeries - mtcrf 0x80,r12 - mfspr r12,SPRN_SPRG2 -END_FTR_SECTION_IFCLR(CPU_FTR_SLB) - EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN) - EXCEPTION_PROLOG_ISERIES_2 - b data_access_common - -.do_stab_bolted_iSeries: - mtcrf 0x80,r12 - mfspr r12,SPRN_SPRG2 - EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB) - EXCEPTION_PROLOG_ISERIES_2 - b .do_stab_bolted - - .globl data_access_slb_iSeries -data_access_slb_iSeries: - mtspr SPRN_SPRG1,r13 /* save r13 */ - mfspr r13,SPRN_SPRG3 /* get paca address into r13 */ - std r3,PACA_EXSLB+EX_R3(r13) - mfspr r3,SPRN_DAR - std r9,PACA_EXSLB+EX_R9(r13) - mfcr r9 -#ifdef __DISABLED__ - cmpdi r3,0 - bge slb_miss_user_iseries -#endif - std r10,PACA_EXSLB+EX_R10(r13) - std r11,PACA_EXSLB+EX_R11(r13) - std r12,PACA_EXSLB+EX_R12(r13) - mfspr r10,SPRN_SPRG1 - std r10,PACA_EXSLB+EX_R13(r13) - ld r12,PACALPPACAPTR(r13) - ld r12,LPPACASRR1(r12) - b .slb_miss_realmode - - STD_EXCEPTION_ISERIES(0x400, instruction_access, PACA_EXGEN) - - .globl instruction_access_slb_iSeries -instruction_access_slb_iSeries: - mtspr SPRN_SPRG1,r13 /* save r13 */ - mfspr r13,SPRN_SPRG3 /* get paca address into r13 */ - std r3,PACA_EXSLB+EX_R3(r13) - ld r3,PACALPPACAPTR(r13) - ld r3,LPPACASRR0(r3) /* get SRR0 value */ - std r9,PACA_EXSLB+EX_R9(r13) - mfcr r9 -#ifdef __DISABLED__ - cmpdi r3,0 - bge .slb_miss_user_iseries -#endif - std r10,PACA_EXSLB+EX_R10(r13) - std r11,PACA_EXSLB+EX_R11(r13) - std r12,PACA_EXSLB+EX_R12(r13) - mfspr r10,SPRN_SPRG1 - std r10,PACA_EXSLB+EX_R13(r13) - ld r12,PACALPPACAPTR(r13) - ld r12,LPPACASRR1(r12) - b .slb_miss_realmode - -#ifdef __DISABLED__ -slb_miss_user_iseries: - std r10,PACA_EXGEN+EX_R10(r13) - std r11,PACA_EXGEN+EX_R11(r13) - std r12,PACA_EXGEN+EX_R12(r13) - mfspr r10,SPRG1 - ld r11,PACA_EXSLB+EX_R9(r13) - ld r12,PACA_EXSLB+EX_R3(r13) - std r10,PACA_EXGEN+EX_R13(r13) - std r11,PACA_EXGEN+EX_R9(r13) - std r12,PACA_EXGEN+EX_R3(r13) - EXCEPTION_PROLOG_ISERIES_2 - b slb_miss_user_common -#endif - - MASKABLE_EXCEPTION_ISERIES(0x500, hardware_interrupt) - STD_EXCEPTION_ISERIES(0x600, alignment, PACA_EXGEN) - STD_EXCEPTION_ISERIES(0x700, program_check, PACA_EXGEN) - STD_EXCEPTION_ISERIES(0x800, fp_unavailable, PACA_EXGEN) - MASKABLE_EXCEPTION_ISERIES(0x900, decrementer) - STD_EXCEPTION_ISERIES(0xa00, trap_0a, PACA_EXGEN) - STD_EXCEPTION_ISERIES(0xb00, trap_0b, PACA_EXGEN) - - .globl system_call_iSeries -system_call_iSeries: - mr r9,r13 - mfspr r13,SPRN_SPRG3 - EXCEPTION_PROLOG_ISERIES_2 - b system_call_common - - STD_EXCEPTION_ISERIES( 0xd00, single_step, PACA_EXGEN) - STD_EXCEPTION_ISERIES( 0xe00, trap_0e, PACA_EXGEN) - STD_EXCEPTION_ISERIES( 0xf00, performance_monitor, PACA_EXGEN) - - .globl system_reset_iSeries -system_reset_iSeries: - mfspr r13,SPRN_SPRG3 /* Get paca address */ - mfmsr r24 - ori r24,r24,MSR_RI - mtmsrd r24 /* RI on */ - lhz r24,PACAPACAINDEX(r13) /* Get processor # */ - cmpwi 0,r24,0 /* Are we processor 0? */ - bne 1f - b .__start_initialization_iSeries /* Start up the first processor */ -1: mfspr r4,SPRN_CTRLF - li r5,CTRL_RUNLATCH /* Turn off the run light */ - andc r4,r4,r5 - mtspr SPRN_CTRLT,r4 - -1: - HMT_LOW -#ifdef CONFIG_SMP - lbz r23,PACAPROCSTART(r13) /* Test if this processor - * should start */ - sync - LOAD_REG_IMMEDIATE(r3,current_set) - sldi r28,r24,3 /* get current_set[cpu#] */ - ldx r3,r3,r28 - addi r1,r3,THREAD_SIZE - subi r1,r1,STACK_FRAME_OVERHEAD - - cmpwi 0,r23,0 - beq iSeries_secondary_smp_loop /* Loop until told to go */ - bne __secondary_start /* Loop until told to go */ -iSeries_secondary_smp_loop: - /* Let the Hypervisor know we are alive */ - /* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */ - lis r3,0x8002 - rldicr r3,r3,32,15 /* r0 = (r3 << 32) & 0xffff000000000000 */ -#else /* CONFIG_SMP */ - /* Yield the processor. This is required for non-SMP kernels - which are running on multi-threaded machines. */ - lis r3,0x8000 - rldicr r3,r3,32,15 /* r3 = (r3 << 32) & 0xffff000000000000 */ - addi r3,r3,18 /* r3 = 0x8000000000000012 which is "yield" */ - li r4,0 /* "yield timed" */ - li r5,-1 /* "yield forever" */ -#endif /* CONFIG_SMP */ - li r0,-1 /* r0=-1 indicates a Hypervisor call */ - sc /* Invoke the hypervisor via a system call */ - mfspr r13,SPRN_SPRG3 /* Put r13 back ???? */ - b 1b /* If SMP not configured, secondaries - * loop forever */ - -decrementer_iSeries_masked: - /* We may not have a valid TOC pointer in here. */ - li r11,1 - ld r12,PACALPPACAPTR(r13) - stb r11,LPPACADECRINT(r12) - LOAD_REG_IMMEDIATE(r12, tb_ticks_per_jiffy) - lwz r12,0(r12) - mtspr SPRN_DEC,r12 - /* fall through */ - -hardware_interrupt_iSeries_masked: - mtcrf 0x80,r9 /* Restore regs */ - ld r12,PACALPPACAPTR(r13) - ld r11,LPPACASRR0(r12) - ld r12,LPPACASRR1(r12) - mtspr SPRN_SRR0,r11 - mtspr SPRN_SRR1,r12 - ld r9,PACA_EXGEN+EX_R9(r13) - ld r10,PACA_EXGEN+EX_R10(r13) - ld r11,PACA_EXGEN+EX_R11(r13) - ld r12,PACA_EXGEN+EX_R12(r13) - ld r13,PACA_EXGEN+EX_R13(r13) - rfid - b . /* prevent speculative execution */ -#endif /* CONFIG_PPC_ISERIES */ - /*** Common interrupt handlers ***/ STD_EXCEPTION_COMMON(0x100, system_reset, .system_reset_exception) @@ -1519,8 +1000,8 @@ _GLOBAL(do_stab_bolted) * 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 + * we get control (with relocate on). The address is given to the hv + * as a page number (see xLparMap below), so this must be at a * fixed address (the linker can't compute (u64)&initial_stab >> * PAGE_SHIFT). */ @@ -1542,12 +1023,22 @@ fwnmi_data_area: * 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 + .globl xLparMap +xLparMap: + .quad HvEsidsToMap /* xNumberEsids */ + .quad HvRangesToMap /* xNumberRanges */ + .quad STAB0_PAGE /* xSegmentTableOffs */ + .zero 40 /* xRsvd */ + /* xEsids (HvEsidsToMap entries of 2 quads) */ + .quad PAGE_OFFSET_ESID /* xKernelEsid */ + .quad PAGE_OFFSET_VSID /* xKernelVsid */ + .quad VMALLOC_START_ESID /* xKernelEsid */ + .quad VMALLOC_START_VSID /* xKernelVsid */ + /* xRanges (HvRangesToMap entries of 3 quads) */ + .quad HvPagesToMap /* xPages */ + .quad 0 /* xOffset */ + .quad PAGE_OFFSET_VSID << (SID_SHIFT - HW_PAGE_SHIFT) /* xVPN */ + #endif /* CONFIG_PPC_ISERIES */ . = 0x8000 @@ -1611,39 +1102,6 @@ _GLOBAL(generic_secondary_smp_init) b __secondary_start #endif -#ifdef CONFIG_PPC_ISERIES -_INIT_STATIC(__start_initialization_iSeries) - /* Clear out the BSS */ - LOAD_REG_IMMEDIATE(r11,__bss_stop) - LOAD_REG_IMMEDIATE(r8,__bss_start) - sub r11,r11,r8 /* bss size */ - addi r11,r11,7 /* round up to an even double word */ - rldicl. r11,r11,61,3 /* shift right by 3 */ - beq 4f - addi r8,r8,-8 - li r0,0 - mtctr r11 /* zero this many doublewords */ -3: stdu r0,8(r8) - bdnz 3b -4: - LOAD_REG_IMMEDIATE(r1,init_thread_union) - addi r1,r1,THREAD_SIZE - li r0,0 - stdu r0,-STACK_FRAME_OVERHEAD(r1) - - LOAD_REG_IMMEDIATE(r2,__toc_start) - addi r2,r2,0x4000 - addi r2,r2,0x4000 - - bl .iSeries_early_setup - bl .early_setup - - /* relocation is on at this point */ - - b .start_here_common -#endif /* CONFIG_PPC_ISERIES */ - - _STATIC(__mmu_off) mfmsr r3 andi. r0,r3,MSR_IR|MSR_DR @@ -1891,6 +1349,7 @@ _GLOBAL(pmac_secondary_start) * r13 = paca virtual address * SPRG3 = paca virtual address */ + .globl __secondary_start __secondary_start: /* Set thread priority to MEDIUM */ HMT_MEDIUM @@ -2021,7 +1480,7 @@ _INIT_STATIC(start_here_multiplatform) b . /* prevent speculative execution */ /* This is where all platforms converge execution */ -_INIT_STATIC(start_here_common) +_INIT_GLOBAL(start_here_common) /* relocation is on at this point */ /* The following code sets up the SP and TOC now that we are */ diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index c08ceca6277..e4ec6eee81a 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -30,7 +30,6 @@ #include <linux/spinlock.h> #include <linux/string.h> #include <linux/dma-mapping.h> -#include <linux/init.h> #include <linux/bitops.h> #include <asm/io.h> #include <asm/prom.h> diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 24bea97c736..dfad0e469ee 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -272,7 +272,7 @@ void do_IRQ(struct pt_regs *regs) struct thread_info *curtp, *irqtp; #endif - irq_enter(); + irq_enter(); #ifdef CONFIG_DEBUG_STACKOVERFLOW /* Debugging check for stack overflow: is there less than 2KB free? */ @@ -321,7 +321,7 @@ void do_IRQ(struct pt_regs *regs) /* That's not SMP safe ... but who cares ? */ ppc_spurious_interrupts++; - irq_exit(); + irq_exit(); set_irq_regs(old_regs); #ifdef CONFIG_PPC_ISERIES diff --git a/arch/powerpc/kernel/lparmap.c b/arch/powerpc/kernel/lparmap.c deleted file mode 100644 index af11285ffbd..00000000000 --- a/arch/powerpc/kernel/lparmap.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2005 Stephen Rothwell IBM Corp. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#include <asm/mmu.h> -#include <asm/pgtable.h> -#include <asm/iseries/lpar_map.h> - -/* The # is to stop gcc trying to make .text nonexecutable */ -const struct LparMap __attribute__((__section__(".text #"))) xLparMap = { - .xNumberEsids = HvEsidsToMap, - .xNumberRanges = HvRangesToMap, - .xSegmentTableOffs = STAB0_PAGE, - - .xEsids = { - { .xKernelEsid = GET_ESID(PAGE_OFFSET), - .xKernelVsid = KERNEL_VSID(PAGE_OFFSET), }, - { .xKernelEsid = GET_ESID(VMALLOC_START), - .xKernelVsid = KERNEL_VSID(VMALLOC_START), }, - }, - - .xRanges = { - { .xPages = HvPagesToMap, - .xOffset = 0, - .xVPN = KERNEL_VSID(PAGE_OFFSET) << (SID_SHIFT - HW_PAGE_SHIFT), - }, - }, -}; diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c index f9676f52c6d..0ed31f22048 100644 --- a/arch/powerpc/kernel/nvram_64.c +++ b/arch/powerpc/kernel/nvram_64.c @@ -34,21 +34,10 @@ #undef DEBUG_NVRAM -static int nvram_scan_partitions(void); -static int nvram_setup_partition(void); -static int nvram_create_os_partition(void); -static int nvram_remove_os_partition(void); - static struct nvram_partition * nvram_part; static long nvram_error_log_index = -1; static long nvram_error_log_size = 0; -int no_logging = 1; /* Until we initialize everything, - * make sure we don't try logging - * anything */ - -extern volatile int error_log_cnt; - struct err_log_info { int error_type; unsigned int seq_num; @@ -636,16 +625,13 @@ void __exit nvram_cleanup(void) * sequence #: The unique sequence # for each event. (until it wraps) * error log: The error log from event_scan */ -int nvram_write_error_log(char * buff, int length, unsigned int err_type) +int nvram_write_error_log(char * buff, int length, + unsigned int err_type, unsigned int error_log_cnt) { int rc; loff_t tmp_index; struct err_log_info info; - if (no_logging) { - return -EPERM; - } - if (nvram_error_log_index == -1) { return -ESPIPE; } @@ -678,7 +664,8 @@ int nvram_write_error_log(char * buff, int length, unsigned int err_type) * * Reads nvram for error log for at most 'length' */ -int nvram_read_error_log(char * buff, int length, unsigned int * err_type) +int nvram_read_error_log(char * buff, int length, + unsigned int * err_type, unsigned int * error_log_cnt) { int rc; loff_t tmp_index; @@ -704,7 +691,7 @@ int nvram_read_error_log(char * buff, int length, unsigned int * err_type) return rc; } - error_log_cnt = info.seq_num; + *error_log_cnt = info.seq_num; *err_type = info.error_type; return 0; diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c index 04a3109ae3c..0e2bee46304 100644 --- a/arch/powerpc/kernel/pci_32.c +++ b/arch/powerpc/kernel/pci_32.c @@ -1457,8 +1457,8 @@ null_write_config(struct pci_bus *bus, unsigned int devfn, int offset, static struct pci_ops null_pci_ops = { - null_read_config, - null_write_config + .read = null_read_config, + .write = null_write_config, }; /* diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index a20f1951a5c..430c502179c 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c @@ -180,7 +180,7 @@ EXPORT_SYMBOL(cacheable_memcpy); EXPORT_SYMBOL(cpm_install_handler); EXPORT_SYMBOL(cpm_free_handler); #endif /* CONFIG_8xx */ -#if defined(CONFIG_8xx) || defined(CONFIG_40x) +#if defined(CONFIG_8xx) EXPORT_SYMBOL(__res); #endif diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index a38197b12d3..0028fe68e09 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -52,7 +52,6 @@ #include <asm/pSeries_reconfig.h> #include <asm/pci-bridge.h> #include <asm/kexec.h> -#include <asm/system.h> #ifdef DEBUG #define DBG(fmt...) printk(KERN_ERR fmt) diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index a1d582e3862..29c2160bcbb 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -2046,6 +2046,7 @@ static void __init fixup_device_tree_maple(void) /* * Pegasos and BriQ lacks the "ranges" property in the isa node * Pegasos needs decimal IRQ 14/15, not hexadecimal + * Pegasos has the IDE configured in legacy mode, but advertised as native */ static void __init fixup_device_tree_chrp(void) { @@ -2083,9 +2084,13 @@ static void __init fixup_device_tree_chrp(void) prom_printf("Fixing up IDE interrupt on Pegasos...\n"); prop[0] = 14; prop[1] = 0x0; - prop[2] = 15; - prop[3] = 0x0; - prom_setprop(ph, name, "interrupts", prop, 4*sizeof(u32)); + prom_setprop(ph, name, "interrupts", prop, 2*sizeof(u32)); + prom_printf("Fixing up IDE class-code on Pegasos...\n"); + rc = prom_getprop(ph, "class-code", prop, sizeof(u32)); + if (rc == sizeof(u32)) { + prop[0] &= ~0x5; + prom_setprop(ph, name, "class-code", prop, sizeof(u32)); + } } } #else diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c index a5de6211b97..21f14e57d1f 100644 --- a/arch/powerpc/kernel/rtas_pci.c +++ b/arch/powerpc/kernel/rtas_pci.c @@ -171,8 +171,8 @@ static int rtas_pci_write_config(struct pci_bus *bus, } struct pci_ops rtas_pci_ops = { - rtas_pci_read_config, - rtas_pci_write_config + .read = rtas_pci_read_config, + .write = rtas_pci_write_config, }; int is_python(struct device_node *dev) diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 7ec6ba56d83..a288a5f2dbc 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -18,13 +18,11 @@ #include <linux/cpu.h> #include <linux/console.h> -#include <asm/residual.h> #include <asm/io.h> #include <asm/prom.h> #include <asm/processor.h> #include <asm/pgtable.h> #include <asm/setup.h> -#include <asm/amigappc.h> #include <asm/smp.h> #include <asm/elf.h> #include <asm/cputable.h> diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 727a6699f2f..b5944d8e380 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -72,7 +72,6 @@ #include <asm/iseries/it_lp_queue.h> #include <asm/iseries/hv_call_xm.h> #endif -#include <asm/smp.h> /* keep track of when we need to update the rtc */ time_t last_rtc_update; @@ -867,7 +866,7 @@ void __init generic_calibrate_decr(void) "(not found)\n"); } -#ifdef CONFIG_BOOKE +#if defined(CONFIG_BOOKE) || defined(CONFIG_40x) /* Set the time base to zero */ mtspr(SPRN_TBWL, 0); mtspr(SPRN_TBWU, 0); |