Date: Sun, 2 Aug 2009 21:16:01 +0000 (UTC) From: Nathan Whitehorn <nwhitehorn@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r196040 - in projects/ppc64/sys/powerpc: aim aim64 include powerpc Message-ID: <200908022116.n72LG1bq024981@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: nwhitehorn Date: Sun Aug 2 21:16:01 2009 New Revision: 196040 URL: http://svn.freebsd.org/changeset/base/196040 Log: Fix trap handling by using the correct stack frame definition on PPC64 and removing a typo that prevented link register restore from working (mtlr was in the wrong place). These bugs could cause corruption of LR and R3 while taking a trap. The kernel now can load a fake init from disk, and starts trying to execute it. Remaining steps to get init going: - Fix RESTORE_USER_SRS in trap_subr.S, which cannot work right now. - Teach aim64/machdep.c about function descriptors and TOCs, so that it starts trying to execute code instead of part of the data section. Modified: projects/ppc64/sys/powerpc/aim/trap.c projects/ppc64/sys/powerpc/aim64/swtch.S projects/ppc64/sys/powerpc/aim64/trap_subr.S projects/ppc64/sys/powerpc/include/frame.h projects/ppc64/sys/powerpc/include/pte.h projects/ppc64/sys/powerpc/include/sr.h projects/ppc64/sys/powerpc/powerpc/genassym.c Modified: projects/ppc64/sys/powerpc/aim/trap.c ============================================================================== --- projects/ppc64/sys/powerpc/aim/trap.c Sun Aug 2 19:43:32 2009 (r196039) +++ projects/ppc64/sys/powerpc/aim/trap.c Sun Aug 2 21:16:01 2009 (r196040) @@ -544,7 +544,7 @@ trap_pfault(struct trapframe *frame, int : "=r"(user_sr) : "r"(USER_SR)); - user_sr >>= SLBV_VSID_SHIFT; + user_sr = (user_sr & SLBV_VSID_MASK) >> SLBV_VSID_SHIFT; user_sr = slb_esid_lookup(&p->p_vmspace->vm_pmap, user_sr); #else Modified: projects/ppc64/sys/powerpc/aim64/swtch.S ============================================================================== --- projects/ppc64/sys/powerpc/aim64/swtch.S Sun Aug 2 19:43:32 2009 (r196039) +++ projects/ppc64/sys/powerpc/aim64/swtch.S Sun Aug 2 21:16:01 2009 (r196040) @@ -259,4 +259,5 @@ ENTRY(fork_trampoline) trapframe to simulate FRAME_SETUP does when allocating space for a frame pointer/saved LR */ - b trapexit + b .trapexit + nop Modified: projects/ppc64/sys/powerpc/aim64/trap_subr.S ============================================================================== --- projects/ppc64/sys/powerpc/aim64/trap_subr.S Sun Aug 2 19:43:32 2009 (r196039) +++ projects/ppc64/sys/powerpc/aim64/trap_subr.S Sun Aug 2 21:16:01 2009 (r196040) @@ -111,46 +111,46 @@ nslb: isync; \ mfsprg1 %r31; /* get saved SP */ \ stdu %r31,-FRAMELEN(%r1); /* save it in the callframe */ \ - std %r0, FRAME_0+16(%r1); /* save r0 in the trapframe */ \ - std %r31,FRAME_1+16(%r1); /* save SP " " */ \ - std %r2, FRAME_2+16(%r1); /* save r2 " " */ \ - std %r28,FRAME_LR+16(%r1); /* save LR " " */ \ - std %r29,FRAME_CR+16(%r1); /* save CR " " */ \ + std %r0, FRAME_0+48(%r1); /* save r0 in the trapframe */ \ + std %r31,FRAME_1+48(%r1); /* save SP " " */ \ + std %r2, FRAME_2+48(%r1); /* save r2 " " */ \ + std %r28,FRAME_LR+48(%r1); /* save LR " " */ \ + std %r29,FRAME_CR+48(%r1); /* save CR " " */ \ GET_CPUINFO(%r2); \ ld %r27,(savearea+CPUSAVE_R27)(%r2); /* get saved r27 */ \ ld %r28,(savearea+CPUSAVE_R28)(%r2); /* get saved r28 */ \ ld %r29,(savearea+CPUSAVE_R29)(%r2); /* get saved r29 */ \ ld %r30,(savearea+CPUSAVE_R30)(%r2); /* get saved r30 */ \ ld %r31,(savearea+CPUSAVE_R31)(%r2); /* get saved r31 */ \ - std %r3, FRAME_3+16(%r1); /* save r3-r31 */ \ - std %r4, FRAME_4+16(%r1); \ - std %r5, FRAME_5+16(%r1); \ - std %r6, FRAME_6+16(%r1); \ - std %r7, FRAME_7+16(%r1); \ - std %r8, FRAME_8+16(%r1); \ - std %r9, FRAME_9+16(%r1); \ - std %r10, FRAME_10+16(%r1); \ - std %r11, FRAME_11+16(%r1); \ - std %r12, FRAME_12+16(%r1); \ - std %r13, FRAME_13+16(%r1); \ - std %r14, FRAME_14+16(%r1); \ - std %r15, FRAME_15+16(%r1); \ - std %r16, FRAME_16+16(%r1); \ - std %r17, FRAME_17+16(%r1); \ - std %r18, FRAME_18+16(%r1); \ - std %r19, FRAME_19+16(%r1); \ - std %r20, FRAME_20+16(%r1); \ - std %r21, FRAME_21+16(%r1); \ - std %r22, FRAME_22+16(%r1); \ - std %r23, FRAME_23+16(%r1); \ - std %r24, FRAME_24+16(%r1); \ - std %r25, FRAME_25+16(%r1); \ - std %r26, FRAME_26+16(%r1); \ - std %r27, FRAME_27+16(%r1); \ - std %r28, FRAME_28+16(%r1); \ - std %r29, FRAME_29+16(%r1); \ - std %r30, FRAME_30+16(%r1); \ - std %r31, FRAME_31+16(%r1); \ + std %r3, FRAME_3+48(%r1); /* save r3-r31 */ \ + std %r4, FRAME_4+48(%r1); \ + std %r5, FRAME_5+48(%r1); \ + std %r6, FRAME_6+48(%r1); \ + std %r7, FRAME_7+48(%r1); \ + std %r8, FRAME_8+48(%r1); \ + std %r9, FRAME_9+48(%r1); \ + std %r10, FRAME_10+48(%r1); \ + std %r11, FRAME_11+48(%r1); \ + std %r12, FRAME_12+48(%r1); \ + std %r13, FRAME_13+48(%r1); \ + std %r14, FRAME_14+48(%r1); \ + std %r15, FRAME_15+48(%r1); \ + std %r16, FRAME_16+48(%r1); \ + std %r17, FRAME_17+48(%r1); \ + std %r18, FRAME_18+48(%r1); \ + std %r19, FRAME_19+48(%r1); \ + std %r20, FRAME_20+48(%r1); \ + std %r21, FRAME_21+48(%r1); \ + std %r22, FRAME_22+48(%r1); \ + std %r23, FRAME_23+48(%r1); \ + std %r24, FRAME_24+48(%r1); \ + std %r25, FRAME_25+48(%r1); \ + std %r26, FRAME_26+48(%r1); \ + std %r27, FRAME_27+48(%r1); \ + std %r28, FRAME_28+48(%r1); \ + std %r29, FRAME_29+48(%r1); \ + std %r30, FRAME_30+48(%r1); \ + std %r31, FRAME_31+48(%r1); \ ld %r28,(savearea+CPUSAVE_AIM_DAR)(%r2); /* saved DAR */ \ ld %r29,(savearea+CPUSAVE_AIM_DSISR)(%r2);/* saved DSISR */\ ld %r30,(savearea+CPUSAVE_SRR0)(%r2); /* saved SRR0 */ \ @@ -158,61 +158,61 @@ nslb: mfxer %r3; \ mfctr %r4; \ mfsprg3 %r5; \ - mtlr %r6; \ - std %r3, FRAME_XER+16(1); /* save xer/ctr/exc */ \ - std %r4, FRAME_CTR+16(1); \ - std %r5, FRAME_EXC+16(1); \ - std %r28,FRAME_AIM_DAR+16(1); \ - std %r29,FRAME_AIM_DSISR+16(1); /* save dsisr/srr0/srr1 */ \ - std %r30,FRAME_SRR0+16(1); \ - std %r31,FRAME_SRR1+16(1) + std %r3, FRAME_XER+48(1); /* save xer/ctr/exc */ \ + std %r4, FRAME_CTR+48(1); \ + std %r5, FRAME_EXC+48(1); \ + std %r28,FRAME_AIM_DAR+48(1); \ + std %r29,FRAME_AIM_DSISR+48(1); /* save dsisr/srr0/srr1 */ \ + std %r30,FRAME_SRR0+48(1); \ + std %r31,FRAME_SRR1+48(1) #define FRAME_LEAVE(savearea) \ /* Now restore regs: */ \ - ld %r2,FRAME_SRR0+16(%r1); \ - ld %r3,FRAME_SRR1+16(%r1); \ - ld %r4,FRAME_CTR+16(%r1); \ - ld %r5,FRAME_XER+16(%r1); \ - ld %r6,FRAME_LR+16(%r1); \ + ld %r2,FRAME_SRR0+48(%r1); \ + ld %r3,FRAME_SRR1+48(%r1); \ + ld %r4,FRAME_CTR+48(%r1); \ + ld %r5,FRAME_XER+48(%r1); \ + ld %r6,FRAME_LR+48(%r1); \ GET_CPUINFO(%r7); \ std %r2,(savearea+CPUSAVE_SRR0)(%r7); /* save SRR0 */ \ std %r3,(savearea+CPUSAVE_SRR1)(%r7); /* save SRR1 */ \ - ld %r7,FRAME_CR+16(%r1); \ + ld %r7,FRAME_CR+48(%r1); \ mtctr %r4; \ mtxer %r5; \ + mtlr %r6; \ mtsprg1 %r7; /* save cr */ \ - ld %r31,FRAME_31+16(%r1); /* restore r0-31 */ \ - ld %r30,FRAME_30+16(%r1); \ - ld %r29,FRAME_29+16(%r1); \ - ld %r28,FRAME_28+16(%r1); \ - ld %r27,FRAME_27+16(%r1); \ - ld %r26,FRAME_26+16(%r1); \ - ld %r25,FRAME_25+16(%r1); \ - ld %r24,FRAME_24+16(%r1); \ - ld %r23,FRAME_23+16(%r1); \ - ld %r22,FRAME_22+16(%r1); \ - ld %r21,FRAME_21+16(%r1); \ - ld %r20,FRAME_20+16(%r1); \ - ld %r19,FRAME_19+16(%r1); \ - ld %r18,FRAME_18+16(%r1); \ - ld %r17,FRAME_17+16(%r1); \ - ld %r16,FRAME_16+16(%r1); \ - ld %r15,FRAME_15+16(%r1); \ - ld %r14,FRAME_14+16(%r1); \ - ld %r13,FRAME_13+16(%r1); \ - ld %r12,FRAME_12+16(%r1); \ - ld %r11,FRAME_11+16(%r1); \ - ld %r10,FRAME_10+16(%r1); \ - ld %r9, FRAME_9+16(%r1); \ - ld %r8, FRAME_8+16(%r1); \ - ld %r7, FRAME_7+16(%r1); \ - ld %r6, FRAME_6+16(%r1); \ - ld %r5, FRAME_5+16(%r1); \ - ld %r4, FRAME_4+16(%r1); \ - ld %r3, FRAME_3+16(%r1); \ - ld %r2, FRAME_2+16(%r1); \ - ld %r0, FRAME_0+16(%r1); \ - ld %r1, FRAME_1+16(%r1); \ + ld %r31,FRAME_31+48(%r1); /* restore r0-31 */ \ + ld %r30,FRAME_30+48(%r1); \ + ld %r29,FRAME_29+48(%r1); \ + ld %r28,FRAME_28+48(%r1); \ + ld %r27,FRAME_27+48(%r1); \ + ld %r26,FRAME_26+48(%r1); \ + ld %r25,FRAME_25+48(%r1); \ + ld %r24,FRAME_24+48(%r1); \ + ld %r23,FRAME_23+48(%r1); \ + ld %r22,FRAME_22+48(%r1); \ + ld %r21,FRAME_21+48(%r1); \ + ld %r20,FRAME_20+48(%r1); \ + ld %r19,FRAME_19+48(%r1); \ + ld %r18,FRAME_18+48(%r1); \ + ld %r17,FRAME_17+48(%r1); \ + ld %r16,FRAME_16+48(%r1); \ + ld %r15,FRAME_15+48(%r1); \ + ld %r14,FRAME_14+48(%r1); \ + ld %r13,FRAME_13+48(%r1); \ + ld %r12,FRAME_12+48(%r1); \ + ld %r11,FRAME_11+48(%r1); \ + ld %r10,FRAME_10+48(%r1); \ + ld %r9, FRAME_9+48(%r1); \ + ld %r8, FRAME_8+48(%r1); \ + ld %r7, FRAME_7+48(%r1); \ + ld %r6, FRAME_6+48(%r1); \ + ld %r5, FRAME_5+48(%r1); \ + ld %r4, FRAME_4+48(%r1); \ + ld %r3, FRAME_3+48(%r1); \ + ld %r2, FRAME_2+48(%r1); \ + ld %r0, FRAME_0+48(%r1); \ + ld %r1, FRAME_1+48(%r1); \ /* Can't touch %r1 from here on */ \ mtsprg2 %r2; /* save r2 & r3 */ \ mtsprg3 %r3; \ @@ -234,11 +234,6 @@ nslb: ld %r3,(savearea+CPUSAVE_SRR0)(%r2); /* restore srr0 */ \ mtsrr0 %r3; \ ld %r3,(savearea+CPUSAVE_SRR1)(%r2); /* restore srr1 */ \ - \ - /* Make sure HV bit of MSR propagated to SRR1 */ \ - mfmsr %r2; \ - or %r3,%r2,%r3; \ - \ mtsrr1 %r3; \ mfsprg2 %r2; /* restore r2 & r3 */ \ mfsprg3 %r3 @@ -465,7 +460,7 @@ k_trap: trapagain: lis %r3,tocbase@ha ld %r2,tocbase@l(%r3) - addi %r3,%r1,16 + addi %r3,%r1,48 bl CNAME(.powerpc_interrupt) nop bl CNAME(.trapexit) @@ -540,13 +535,13 @@ dbtrap: /* Call C trap code: */ lis %r3,tocbase@ha ld %r2,tocbase@l(%r3) - addi %r3,%r1,16 + addi %r3,%r1,48 bl CNAME(.db_trap_glue) nop or. %r3,%r3,%r3 bne dbleave /* This wasn't for KDB, so switch to real trap: */ - ld %r3,FRAME_EXC+16(%r1) /* save exception */ + ld %r3,FRAME_EXC+48(%r1) /* save exception */ GET_CPUINFO(%r4) std %r3,(PC_DBSAVE+CPUSAVE_R31)(%r4) FRAME_LEAVE(PC_DBSAVE) Modified: projects/ppc64/sys/powerpc/include/frame.h ============================================================================== --- projects/ppc64/sys/powerpc/include/frame.h Sun Aug 2 19:43:32 2009 (r196039) +++ projects/ppc64/sys/powerpc/include/frame.h Sun Aug 2 21:16:01 2009 (r196040) @@ -71,9 +71,13 @@ struct trapframe { }; /* - * This is to ensure alignment of the stackpointer + * FRAMELEN is the size of the stack region used by the low-level trap + * handler. It is the size of its data (trapframe) plus the callframe + * header (sizeof(struct callframe) - 3 register widths). It must also + * be 16-byte aligned. */ -#define FRAMELEN roundup(sizeof(struct trapframe) + 8, 16) +#define FRAMELEN roundup(sizeof(struct trapframe) + \ + sizeof(struct callframe) - 3*sizeof(register_t), 16) #define trapframe(td) ((td)->td_frame) /* Modified: projects/ppc64/sys/powerpc/include/pte.h ============================================================================== --- projects/ppc64/sys/powerpc/include/pte.h Sun Aug 2 19:43:32 2009 (r196039) +++ projects/ppc64/sys/powerpc/include/pte.h Sun Aug 2 21:16:01 2009 (r196040) @@ -128,11 +128,11 @@ typedef struct lpte lpte_t; * Extract bits from address */ #define ADDR_SR_SHFT 28 -#define ADDR_PIDX 0x0ffff000 +#define ADDR_PIDX 0x0ffff000UL #define ADDR_PIDX_SHFT 12 #define ADDR_API_SHFT 22 #define ADDR_API_SHFT64 16 -#define ADDR_POFF 0x00000fff +#define ADDR_POFF 0x00000fffUL /* * Bits in DSISR: Modified: projects/ppc64/sys/powerpc/include/sr.h ============================================================================== --- projects/ppc64/sys/powerpc/include/sr.h Sun Aug 2 19:43:32 2009 (r196039) +++ projects/ppc64/sys/powerpc/include/sr.h Sun Aug 2 21:16:01 2009 (r196040) @@ -50,7 +50,8 @@ #define KERNEL2_SEGMENT (0xfffff0 + KERNEL2_SR) #define EMPTY_SEGMENT 0xfffff0 #define USER_ADDR ((void *)((register_t)USER_SR << ADDR_SR_SHFT)) -#define SEGMENT_LENGTH 0x10000000 -#define SEGMENT_MASK 0xf0000000 +#define SEGMENT_LENGTH 0x10000000UL +#define SEGMENT_INVMASK 0x0fffffffUL +#define SEGMENT_MASK ~SEGMENT_INVMASK #endif /* !_MACHINE_SR_H_ */ Modified: projects/ppc64/sys/powerpc/powerpc/genassym.c ============================================================================== --- projects/ppc64/sys/powerpc/powerpc/genassym.c Sun Aug 2 19:43:32 2009 (r196039) +++ projects/ppc64/sys/powerpc/powerpc/genassym.c Sun Aug 2 21:16:01 2009 (r196040) @@ -117,7 +117,11 @@ ASSYM(PTE_FLAGS, offsetof(struct pte, fl ASSYM(TLB0_ENTRY_SIZE, sizeof(struct tlb_entry)); #endif +#ifdef __powerpc64__ +ASSYM(FSP, 48); +#else ASSYM(FSP, 8); +#endif ASSYM(FRAMELEN, FRAMELEN); ASSYM(FRAME_0, offsetof(struct trapframe, fixreg[0])); ASSYM(FRAME_1, offsetof(struct trapframe, fixreg[1]));
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200908022116.n72LG1bq024981>