diff options
Diffstat (limited to 'arch/powerpc/kernel')
39 files changed, 531 insertions, 243 deletions
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index b9dbfff9afe9..ce1e8d24e747 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -67,6 +67,7 @@ obj-$(CONFIG_BOOTX_TEXT) += btext.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o +obj-$(CONFIG_STACKTRACE) += stacktrace.o pci64-$(CONFIG_PPC64) += pci_dn.o isa-bridge.o obj-$(CONFIG_PCI) += pci_$(CONFIG_WORD_SIZE).o $(pci64-y) \ diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 4b749c416464..292c6d8db0e1 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -26,8 +26,6 @@ #ifdef CONFIG_PPC64 #include <linux/time.h> #include <linux/hardirq.h> -#else -#include <linux/ptrace.h> #endif #include <asm/io.h> @@ -46,6 +44,9 @@ #include <asm/mmu.h> #include <asm/hvcall.h> #endif +#ifdef CONFIG_PPC_ISERIES +#include <asm/iseries/alpaca.h> +#endif #define DEFINE(sym, val) \ asm volatile("\n->" #sym " %0 " #val : : "i" (val)) @@ -60,7 +61,6 @@ int main(void) DEFINE(AUDITCONTEXT, offsetof(struct task_struct, audit_context)); #else DEFINE(THREAD_INFO, offsetof(struct task_struct, stack)); - DEFINE(PTRACE, offsetof(struct task_struct, ptrace)); #endif /* CONFIG_PPC64 */ DEFINE(KSP, offsetof(struct thread_struct, ksp)); @@ -80,7 +80,6 @@ int main(void) DEFINE(PGDIR, offsetof(struct thread_struct, pgdir)); #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) DEFINE(THREAD_DBCR0, offsetof(struct thread_struct, dbcr0)); - DEFINE(PT_PTRACED, PT_PTRACED); #endif #ifdef CONFIG_SPE DEFINE(THREAD_EVR0, offsetof(struct thread_struct, evr[0])); @@ -325,6 +324,9 @@ int main(void) DEFINE(PAGE_OFFSET_VSID, KERNEL_VSID(PAGE_OFFSET)); DEFINE(VMALLOC_START_ESID, GET_ESID(VMALLOC_START)); DEFINE(VMALLOC_START_VSID, KERNEL_VSID(VMALLOC_START)); + + /* alpaca */ + DEFINE(ALPACA_SIZE, sizeof(struct alpaca)); #endif DEFINE(PGD_TABLE_SIZE, PGD_TABLE_SIZE); diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c index 80e2eef05b2e..9f9377745490 100644 --- a/arch/powerpc/kernel/btext.c +++ b/arch/powerpc/kernel/btext.c @@ -7,6 +7,7 @@ #include <linux/string.h> #include <linux/init.h> #include <linux/module.h> +#include <linux/lmb.h> #include <asm/sections.h> #include <asm/prom.h> @@ -15,7 +16,7 @@ #include <asm/mmu.h> #include <asm/pgtable.h> #include <asm/io.h> -#include <asm/lmb.h> +#include <asm/prom.h> #include <asm/processor.h> #include <asm/udbg.h> diff --git a/arch/powerpc/kernel/cpu_setup_44x.S b/arch/powerpc/kernel/cpu_setup_44x.S index 6250443ab9c9..5465e8de0e61 100644 --- a/arch/powerpc/kernel/cpu_setup_44x.S +++ b/arch/powerpc/kernel/cpu_setup_44x.S @@ -3,7 +3,7 @@ * Valentine Barshak <vbarshak@ru.mvista.com> * MontaVista Software, Inc (c) 2007 * - * Based on cpu_setup_6xx code by + * Based on cpu_setup_6xx code by * Benjamin Herrenschmidt <benh@kernel.crashing.org> * * This program is free software; you can redistribute it and/or @@ -32,6 +32,9 @@ _GLOBAL(__setup_cpu_440grx) bl __fixup_440A_mcheck mtlr r4 blr +_GLOBAL(__setup_cpu_460ex) +_GLOBAL(__setup_cpu_460gt) + b __init_fpu_44x _GLOBAL(__setup_cpu_440gx) _GLOBAL(__setup_cpu_440spe) b __fixup_440A_mcheck diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 2a8f5cc5184f..26ffb44e2701 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -36,6 +36,8 @@ extern void __setup_cpu_440epx(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_440gx(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_440grx(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_440spe(unsigned long offset, struct cpu_spec* spec); +extern void __setup_cpu_460ex(unsigned long offset, struct cpu_spec* spec); +extern void __setup_cpu_460gt(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_603(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_604(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_750(unsigned long offset, struct cpu_spec* spec); @@ -1397,6 +1399,30 @@ static struct cpu_spec __initdata cpu_specs[] = { .machine_check = machine_check_440A, .platform = "ppc440", }, + { /* 460EX */ + .pvr_mask = 0xffff0002, + .pvr_value = 0x13020002, + .cpu_name = "460EX", + .cpu_features = CPU_FTRS_44X, + .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, + .icache_bsize = 32, + .dcache_bsize = 32, + .cpu_setup = __setup_cpu_460ex, + .machine_check = machine_check_440A, + .platform = "ppc440", + }, + { /* 460GT */ + .pvr_mask = 0xffff0002, + .pvr_value = 0x13020000, + .cpu_name = "460GT", + .cpu_features = CPU_FTRS_44X, + .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, + .icache_bsize = 32, + .dcache_bsize = 32, + .cpu_setup = __setup_cpu_460gt, + .machine_check = machine_check_440A, + .platform = "ppc440", + }, #endif /* CONFIG_44x */ #ifdef CONFIG_FSL_BOOKE #ifdef CONFIG_E200 @@ -1512,7 +1538,7 @@ struct cpu_spec * __init identify_cpu(unsigned long offset, unsigned int pvr) *t = *s; *PTRRELOC(&cur_cpu_spec) = &the_cpu_spec; #if defined(CONFIG_PPC64) || defined(CONFIG_BOOKE) - /* ppc64 and booke expect identify_cpu to also call + /* ppc64 and booke expect identify_cpu to also call * setup_cpu for that processor. I will consolidate * that at a later time, for now, just use #ifdef. * we also don't need to PTRRELOC the function pointer diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c index 571132ed12c1..eae401de3f76 100644 --- a/arch/powerpc/kernel/crash.c +++ b/arch/powerpc/kernel/crash.c @@ -24,12 +24,13 @@ #include <linux/init.h> #include <linux/irq.h> #include <linux/types.h> +#include <linux/lmb.h> #include <asm/processor.h> #include <asm/machdep.h> #include <asm/kexec.h> #include <asm/kdump.h> -#include <asm/lmb.h> +#include <asm/prom.h> #include <asm/firmware.h> #include <asm/smp.h> #include <asm/system.h> diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c index 29ff77c468ac..9ee3c5278db0 100644 --- a/arch/powerpc/kernel/crash_dump.c +++ b/arch/powerpc/kernel/crash_dump.c @@ -13,8 +13,9 @@ #include <linux/crash_dump.h> #include <linux/bootmem.h> +#include <linux/lmb.h> #include <asm/kdump.h> -#include <asm/lmb.h> +#include <asm/prom.h> #include <asm/firmware.h> #include <asm/uaccess.h> diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index 69a91bd46115..84c868633068 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S @@ -110,9 +110,9 @@ transfer_to_handler: stw r11,PT_REGS(r12) #if defined(CONFIG_40x) || defined(CONFIG_BOOKE) /* Check to see if the dbcr0 register is set up to debug. Use the - single-step bit to do this. */ + internal debug mode bit to do this. */ lwz r12,THREAD_DBCR0(r12) - andis. r12,r12,DBCR0_IC@h + andis. r12,r12,DBCR0_IDM@h beq+ 3f /* From user and task is ptraced - load up global dbcr0 */ li r12,-1 /* clear all pending debug events */ @@ -120,6 +120,12 @@ transfer_to_handler: lis r11,global_dbcr0@ha tophys(r11,r11) addi r11,r11,global_dbcr0@l +#ifdef CONFIG_SMP + rlwinm r9,r1,0,0,(31-THREAD_SHIFT) + lwz r9,TI_CPU(r9) + slwi r9,r9,3 + add r11,r11,r9 +#endif lwz r12,0(r11) mtspr SPRN_DBCR0,r12 lwz r12,4(r11) @@ -238,10 +244,10 @@ ret_from_syscall: stw r11,_CCR(r1) syscall_exit_cont: #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) - /* If the process has its own DBCR0 value, load it up. The single - step bit tells us that dbcr0 should be loaded. */ + /* If the process has its own DBCR0 value, load it up. The internal + debug mode bit tells us that dbcr0 should be loaded. */ lwz r0,THREAD+THREAD_DBCR0(r2) - andis. r10,r0,DBCR0_IC@h + andis. r10,r0,DBCR0_IDM@h bnel- load_dbcr0 #endif #ifdef CONFIG_44x @@ -666,10 +672,10 @@ user_exc_return: /* r10 contains MSR_KERNEL here */ restore_user: #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) - /* Check whether this process has its own DBCR0 value. The single - step bit tells us that dbcr0 should be loaded. */ + /* Check whether this process has its own DBCR0 value. The internal + debug mode bit tells us that dbcr0 should be loaded. */ lwz r0,THREAD+THREAD_DBCR0(r2) - andis. r10,r0,DBCR0_IC@h + andis. r10,r0,DBCR0_IDM@h bnel- load_dbcr0 #endif @@ -879,6 +885,12 @@ load_dbcr0: mfspr r10,SPRN_DBCR0 lis r11,global_dbcr0@ha addi r11,r11,global_dbcr0@l +#ifdef CONFIG_SMP + rlwinm r9,r1,0,0,(31-THREAD_SHIFT) + lwz r9,TI_CPU(r9) + slwi r9,r9,3 + add r11,r11,r9 +#endif stw r10,0(r11) mtspr SPRN_DBCR0,r0 lwz r10,4(r11) @@ -891,7 +903,7 @@ load_dbcr0: .section .bss .align 4 global_dbcr0: - .space 8 + .space 8*NR_CPUS .previous #endif /* !(CONFIG_4xx || CONFIG_BOOKE) */ diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 148a3547c9aa..c0db5b769e55 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -29,6 +29,8 @@ #include <asm/cputable.h> #include <asm/firmware.h> #include <asm/bug.h> +#include <asm/ptrace.h> +#include <asm/irqflags.h> /* * System calls. @@ -39,7 +41,7 @@ /* This value is used to mark exception frames on the stack. */ exception_marker: - .tc ID_72656773_68657265[TC],0x7265677368657265 + .tc ID_EXC_MARKER[TC],STACK_FRAME_REGS_MARKER .section ".text" .align 7 @@ -88,6 +90,14 @@ system_call_common: addi r9,r1,STACK_FRAME_OVERHEAD ld r11,exception_marker@toc(r2) std r11,-16(r9) /* "regshere" marker */ +#ifdef CONFIG_TRACE_IRQFLAGS + bl .trace_hardirqs_on + REST_GPR(0,r1) + REST_4GPRS(3,r1) + REST_2GPRS(7,r1) + addi r9,r1,STACK_FRAME_OVERHEAD + ld r12,_MSR(r1) +#endif /* CONFIG_TRACE_IRQFLAGS */ li r10,1 stb r10,PACASOFTIRQEN(r13) stb r10,PACAHARDIRQEN(r13) @@ -102,7 +112,7 @@ BEGIN_FW_FTR_SECTION b hardware_interrupt_entry 2: END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) -#endif +#endif /* CONFIG_PPC_ISERIES */ mfmsr r11 ori r11,r11,MSR_EE mtmsrd r11,1 @@ -504,6 +514,10 @@ BEGIN_FW_FTR_SECTION li r3,0 stb r3,PACASOFTIRQEN(r13) /* ensure we are soft-disabled */ +#ifdef CONFIG_TRACE_IRQFLAGS + bl .trace_hardirqs_off + mfmsr r10 +#endif ori r10,r10,MSR_EE mtmsrd r10 /* hard-enable again */ addi r3,r1,STACK_FRAME_OVERHEAD @@ -512,7 +526,7 @@ BEGIN_FW_FTR_SECTION 4: END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) #endif - stb r5,PACASOFTIRQEN(r13) + TRACE_AND_RESTORE_IRQ(r5); /* extract EE bit and use it to restore paca->hard_enabled */ ld r3,_MSR(r1) @@ -580,6 +594,16 @@ do_work: bne restore /* here we are preempting the current task */ 1: +#ifdef CONFIG_TRACE_IRQFLAGS + bl .trace_hardirqs_on + /* Note: we just clobbered r10 which used to contain the previous + * MSR before the hard-disabling done by the caller of do_work. + * We don't have that value anymore, but it doesn't matter as + * we will hard-enable unconditionally, we can just reload the + * current MSR into r10 + */ + mfmsr r10 +#endif /* CONFIG_TRACE_IRQFLAGS */ li r0,1 stb r0,PACASOFTIRQEN(r13) stb r0,PACAHARDIRQEN(r13) diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S index 0f4fac512020..785af9b56591 100644 --- a/arch/powerpc/kernel/head_32.S +++ b/arch/powerpc/kernel/head_32.S @@ -30,6 +30,7 @@ #include <asm/thread_info.h> #include <asm/ppc_asm.h> #include <asm/asm-offsets.h> +#include <asm/ptrace.h> /* 601 only have IBAT; cr0.eq is set on 601 when using this macro */ #define LOAD_BAT(n, reg, RA, RB) \ @@ -268,8 +269,8 @@ __secondary_hold_acknowledge: li r10,MSR_KERNEL & ~(MSR_IR|MSR_DR); /* can take exceptions */ \ MTMSRD(r10); /* (except for mach check in rtas) */ \ stw r0,GPR0(r11); \ - lis r10,0x7265; /* put exception frame marker */ \ - addi r10,r10,0x6773; \ + lis r10,STACK_FRAME_REGS_MARKER@ha; /* exception frame marker */ \ + addi r10,r10,STACK_FRAME_REGS_MARKER@l; \ stw r10,8(r11); \ SAVE_4GPRS(3, r11); \ SAVE_2GPRS(7, r11) @@ -763,23 +764,6 @@ load_up_altivec: b fast_exception_return /* - * AltiVec unavailable trap from kernel - print a message, but let - * the task use AltiVec in the kernel until it returns to user mode. - */ -KernelAltiVec: - lwz r3,_MSR(r1) - oris r3,r3,MSR_VEC@h - stw r3,_MSR(r1) /* enable use of AltiVec after return */ - lis r3,87f@h - ori r3,r3,87f@l - mr r4,r2 /* current */ - lwz r5,_NIP(r1) - bl printk - b ret_from_except -87: .string "AltiVec used in kernel (task=%p, pc=%x) \n" - .align 4,0 - -/* * giveup_altivec(tsk) * Disable AltiVec for the task given as the argument, * and save the AltiVec registers in its thread_struct. diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S index ad071a146a8d..b84ec6a2fc94 100644 --- a/arch/powerpc/kernel/head_44x.S +++ b/arch/powerpc/kernel/head_44x.S @@ -211,7 +211,7 @@ skpinv: addi r4,r4,1 /* Increment */ SET_IVOR(12, WatchdogTimer); SET_IVOR(13, DataTLBError); SET_IVOR(14, InstructionTLBError); - SET_IVOR(15, Debug); + SET_IVOR(15, DebugCrit); /* Establish the interrupt vector base */ lis r4,interrupt_base@h /* IVPR only uses the high 16-bits */ @@ -578,7 +578,7 @@ interrupt_base: b InstructionStorage /* Debug Interrupt */ - DEBUG_EXCEPTION + DEBUG_CRIT_EXCEPTION /* * Local functions diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index d3aee08e6814..215973a2c8d5 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -36,8 +36,7 @@ #include <asm/firmware.h> #include <asm/page_64.h> #include <asm/exception.h> - -#define DO_SOFT_DISABLE +#include <asm/irqflags.h> /* * We layout physical memory as follows: @@ -450,8 +449,8 @@ bad_stack: */ fast_exc_return_irq: /* restores irq state too */ ld r3,SOFTE(r1) + TRACE_AND_RESTORE_IRQ(r3); ld r12,_MSR(r1) - stb r3,PACASOFTIRQEN(r13) /* restore paca->soft_enabled */ rldicl r4,r12,49,63 /* get MSR_EE to LSB */ stb r4,PACAHARDIRQEN(r13) /* restore paca->hard_enabled */ b 1f @@ -621,7 +620,7 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) mtlr r10 andi. r10,r12,MSR_RI /* check for unrecoverable exception */ - beq- unrecov_slb + beq- 2f .machine push .machine "power4" @@ -643,6 +642,22 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) rfid b . /* prevent speculative execution */ +2: +#ifdef CONFIG_PPC_ISERIES +BEGIN_FW_FTR_SECTION + b unrecov_slb +END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) +#endif /* CONFIG_PPC_ISERIES */ + mfspr r11,SPRN_SRR0 + clrrdi r10,r13,32 + LOAD_HANDLER(r10,unrecov_slb) + mtspr SPRN_SRR0,r10 + mfmsr r10 + ori r10,r10,MSR_IR|MSR_DR|MSR_RI + mtspr SPRN_SRR1,r10 + rfid + b . + unrecov_slb: EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB) DISABLE_INTS @@ -808,7 +823,7 @@ _STATIC(load_up_altivec) * Hash table stuff */ .align 7 -_GLOBAL(do_hash_page) +_STATIC(do_hash_page) std r3,_DAR(r1) std r4,_DSISR(r1) @@ -820,6 +835,27 @@ BEGIN_FTR_SECTION END_FTR_SECTION_IFCLR(CPU_FTR_SLB) /* + * On iSeries, we soft-disable interrupts here, then + * hard-enable interrupts so that the hash_page code can spin on + * the hash_table_lock without problems on a shared processor. + */ + DISABLE_INTS + + /* + * Currently, trace_hardirqs_off() will be called by DISABLE_INTS + * and will clobber volatile registers when irq tracing is enabled + * so we need to reload them. It may be possible to be smarter here + * and move the irq tracing elsewhere but let's keep it simple for + * now + */ +#ifdef CONFIG_TRACE_IRQFLAGS + ld r3,_DAR(r1) + ld r4,_DSISR(r1) + ld r5,_TRAP(r1) + ld r12,_MSR(r1) + clrrdi r5,r5,4 +#endif /* CONFIG_TRACE_IRQFLAGS */ + /* * We need to set the _PAGE_USER bit if MSR_PR is set or if we are * accessing a userspace segment (even from the kernel). We assume * kernel addresses always have the high bit set. @@ -832,13 +868,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB) rlwimi r4,r5,22+2,31-2,31-2 /* Set _PAGE_EXEC if trap is 0x400 */ /* - * On iSeries, we soft-disable interrupts here, then - * hard-enable interrupts so that the hash_page code can spin on - * the hash_table_lock without problems on a shared processor. - */ - DISABLE_INTS - - /* * r3 contains the faulting address * r4 contains the required access permissions * r5 contains the trap number @@ -848,7 +877,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB) bl .hash_page /* build HPTE if possible */ cmpdi r3,0 /* see if hash_page succeeded */ -#ifdef DO_SOFT_DISABLE BEGIN_FW_FTR_SECTION /* * If we had interrupts soft-enabled at the point where the @@ -860,7 +888,7 @@ BEGIN_FW_FTR_SECTION */ beq 13f END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) -#endif + BEGIN_FW_FTR_SECTION /* * Here we have interrupts hard-disabled, so it is sufficient @@ -874,11 +902,12 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES) /* * hash_page couldn't handle it, set soft interrupt enable back - * to what it was before the trap. Note that .local_irq_restore + * to what it was before the trap. Note that .raw_local_irq_restore * handles any interrupts pending at this point. */ ld r3,SOFTE(r1) - bl .local_irq_restore + TRACE_AND_RESTORE_IRQ_PARTIAL(r3, 11f) + bl .raw_local_irq_restore b 11f /* Here we have a page fault that hash_page can't handle. */ @@ -1477,6 +1506,10 @@ _INIT_STATIC(start_here_multiplatform) addi r2,r2,0x4000 add r2,r2,r26 + /* Set initial ptr to current */ + LOAD_REG_IMMEDIATE(r4, init_task) + std r4,PACACURRENT(r13) + /* Do very early kernel initializations, including initial hash table, * stab and slb setup before we turn on relocation. */ @@ -1505,10 +1538,6 @@ _INIT_GLOBAL(start_here_common) li r0,0 stdu r0,-STACK_FRAME_OVERHEAD(r1) - /* ptr to current */ - LOAD_REG_IMMEDIATE(r4, init_task) - std r4,PACACURRENT(r13) - /* Load the TOC */ ld r2,PACATOC(r13) std r1,PACAKSAVE(r13) diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h index ba9393f8e77a..aefafc6330c9 100644 --- a/arch/powerpc/kernel/head_booke.h +++ b/arch/powerpc/kernel/head_booke.h @@ -56,8 +56,17 @@ * is necessary since the MMU is always on, for Book-E parts, and the stacks * are offset from KERNELBASE. * + * There is some space optimization to be had here if desired. However + * to allow for a common kernel with support for debug exceptions either + * going to critical or their own debug level we aren't currently + * providing configurations that micro-optimize space usage. */ -#define BOOKE_EXCEPTION_STACK_SIZE (8192) +#ifdef CONFIG_44x +#define NUM_EXCEPTION_LVLS 2 +#else +#define NUM_EXCEPTION_LVLS 3 +#endif +#define BOOKE_EXCEPTION_STACK_SIZE (4096 * NUM_EXCEPTION_LVLS) /* CRIT_SPRG only used in critical exception handling */ #define CRIT_SPRG SPRN_SPRG2 @@ -68,7 +77,7 @@ #define CRIT_STACK_TOP (exception_stack_top) /* only on e200 for now */ -#define DEBUG_STACK_TOP (exception_stack_top - 4096) +#define DEBUG_STACK_TOP (exception_stack_top - 8192) #define DEBUG_SPRG SPRN_SPRG6W #ifdef CONFIG_SMP @@ -212,9 +221,8 @@ label: * save (and later restore) the MSR via SPRN_CSRR1, which will still have * the MSR_DE bit set. */ -#ifdef CONFIG_E200 -#define DEBUG_EXCEPTION \ - START_EXCEPTION(Debug); \ +#define DEBUG_DEBUG_EXCEPTION \ + START_EXCEPTION(DebugDebug); \ DEBUG_EXCEPTION_PROLOG; \ \ /* \ @@ -234,8 +242,8 @@ label: cmplw r12,r10; \ blt+ 2f; /* addr below exception vectors */ \ \ - lis r10,Debug@h; \ - ori r10,r10,Debug@l; \ + lis r10,DebugDebug@h; \ + ori r10,r10,DebugDebug@l; \ cmplw r12,r10; \ bgt+ 2f; /* addr above exception vectors */ \ \ @@ -265,9 +273,9 @@ label: 2: mfspr r4,SPRN_DBSR; \ addi r3,r1,STACK_FRAME_OVERHEAD; \ EXC_XFER_TEMPLATE(DebugException, 0x2002, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), NOCOPY, debug_transfer_to_handler, ret_from_debug_exc) -#else -#define DEBUG_EXCEPTION \ - START_EXCEPTION(Debug); \ + +#define DEBUG_CRIT_EXCEPTION \ + START_EXCEPTION(DebugCrit); \ CRITICAL_EXCEPTION_PROLOG; \ \ /* \ @@ -287,8 +295,8 @@ label: cmplw r12,r10; \ blt+ 2f; /* addr below exception vectors */ \ \ - lis r10,Debug@h; \ - ori r10,r10,Debug@l; \ + lis r10,DebugCrit@h; \ + ori r10,r10,DebugCrit@l; \ cmplw r12,r10; \ bgt+ 2f; /* addr above exception vectors */ \ \ @@ -318,7 +326,6 @@ label: 2: mfspr r4,SPRN_DBSR; \ addi r3,r1,STACK_FRAME_OVERHEAD; \ EXC_XFER_TEMPLATE(DebugException, 0x2002, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), NOCOPY, crit_transfer_to_handler, ret_from_crit_exc) -#endif #define INSTRUCTION_STORAGE_EXCEPTION \ START_EXCEPTION(InstructionStorage) \ diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index d9cc2c288d9e..4ff744143566 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -68,7 +68,9 @@ _ENTRY(_start); mr r29,r5 mr r28,r6 mr r27,r7 + li r25,0 /* phys kernel start (low) */ li r24,0 /* CPU number */ + li r23,0 /* phys kernel start (high) */ /* We try to not make any assumptions about how the boot loader * setup or used the TLBs. We invalidate all mappings from the @@ -167,7 +169,28 @@ skpinv: addi r6,r6,1 /* Increment */ mtspr SPRN_MAS0,r7 tlbre - /* Just modify the entry ID, EPN and RPN for the temp mapping */ + /* grab and fixup the RPN */ + mfspr r6,SPRN_MAS1 /* extract MAS1[SIZE] */ + rlwinm r6,r6,25,27,30 + li r8,-1 + addi r6,r6,10 + slw r6,r8,r6 /* convert to mask */ + + bl 1f /* Find our address */ +1: mflr r7 + + mfspr r8,SPRN_MAS3 +#ifdef CONFIG_PHYS_64BIT + mfspr r23,SPRN_MAS7 +#endif + and r8,r6,r8 + subfic r9,r6,-4096 + and r9,r9,r7 + + or r25,r8,r9 + ori r8,r25,(MAS3_SX|MAS3_SW|MAS3_SR) + + /* Just modify the entry ID and EPN for the temp mapping */ lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */ mtspr SPRN_MAS0,r7 @@ -177,12 +200,10 @@ skpinv: addi r6,r6,1 /* Increment */ ori r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_4K))@l mtspr SPRN_MAS1,r6 mfspr r6,SPRN_MAS2 - lis r7,PHYSICAL_START@h + li r7,0 /* temp EPN = 0 */ rlwimi r7,r6,0,20,31 mtspr SPRN_MAS2,r7 - mfspr r6,SPRN_MAS3 - rlwimi r7,r6,0,20,31 - mtspr SPRN_MAS3,r7 + mtspr SPRN_MAS3,r8 tlbwe xori r6,r4,1 @@ -232,8 +253,7 @@ skpinv: addi r6,r6,1 /* Increment */ ori r6,r6,PAGE_OFFSET@l rlwimi r6,r7,0,20,31 mtspr SPRN_MAS2,r6 - li r7,(MAS3_SX|MAS3_SW|MAS3_SR) - mtspr SPRN_MAS3,r7 + mtspr SPRN_MAS3,r8 tlbwe /* 7. Jump to KERNELBASE mapping */ @@ -283,7 +303,10 @@ skpinv: addi r6,r6,1 /* Increment */ SET_IVOR(12, WatchdogTimer); SET_IVOR(13, DataTLBError); SET_IVOR(14, InstructionTLBError); - SET_IVOR(15, Debug); + SET_IVOR(15, DebugDebug); +#if defined(CONFIG_E500) + SET_IVOR(15, DebugCrit); +#endif SET_IVOR(32, SPEUnavailable); SET_IVOR(33, SPEFloatingPointData); SET_IVOR(34, SPEFloatingPointRound); @@ -718,7 +741,10 @@ interrupt_base: /* Debug Interrupt */ - DEBUG_EXCEPTION + DEBUG_DEBUG_EXCEPTION +#if defined(CONFIG_E500) + DEBUG_CRIT_EXCEPTION +#endif /* * Local functions diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index 2f50bb5d00f9..9971159c8040 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c @@ -183,7 +183,7 @@ static int ibmebus_create_devices(const struct of_device_id *matches) ret = ibmebus_create_device(child); if (ret) { printk(KERN_ERR "%s: failed to create device (%i)", - __FUNCTION__, ret); + __func__, ret); of_node_put(child); break; } @@ -269,7 +269,7 @@ static ssize_t ibmebus_store_probe(struct bus_type *bus, if (bus_find_device(&ibmebus_bus_type, NULL, path, ibmebus_match_path)) { printk(KERN_WARNING "%s: %s has already been probed\n", - __FUNCTION__, path); + __func__, path); rc = -EEXIST; |