Skip site navigation (1)Skip section navigation (2)
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>