Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 8 May 2009 02:54:00 GMT
From:      Arnar Mar Sig <antab@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 161759 for review
Message-ID:  <200905080254.n482s00f043393@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=161759

Change 161759 by antab@antab_farm on 2009/05/08 02:53:14

	Rework pcb and context switching, r8-r12 do not have to be preserved and the ldm usage had undefined results

Affected files ...

.. //depot/projects/avr32/src/sys/avr32/avr32/db_trace.c#6 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/locore.S#3 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/machdep.c#12 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/switch.S#12 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/vm_machdep.c#10 edit
.. //depot/projects/avr32/src/sys/avr32/include/db_machdep.h#6 edit
.. //depot/projects/avr32/src/sys/avr32/include/pcb.h#5 edit

Differences ...

==== //depot/projects/avr32/src/sys/avr32/avr32/db_trace.c#6 (text+ko) ====

@@ -79,12 +79,12 @@
 	struct pcb *ctx;
 
 	ctx = kdb_thr_ctx(thr);
-	if (ctx->pcb_regs.regs.pc != 0) {
-		firstframe.fp = (struct db_frame *)ctx->pcb_regs.regs.r7;
-		firstframe.lr = ctx->pcb_regs.regs.pc;
+	if (ctx->pc != 0) {
+		firstframe.fp = (struct db_frame *)ctx->r7;
+		firstframe.lr = ctx->pc;
 		frame = &firstframe;
 	} else {
-		frame = (struct db_frame *)ctx->pcb_regs.regs.r7;
+		frame = (struct db_frame *)ctx->r7;
 	}
 
 	db_backtrace(thr, frame, count);

==== //depot/projects/avr32/src/sys/avr32/avr32/locore.S#3 (text+ko) ====

@@ -92,8 +92,8 @@
 proc0_stack_ptr:
 	.long proc0_stack_end
 
+.align 4
 GLOBAL(proc0_stack)
 	.space KSTACK_SIZE
-	.align 4
 proc0_stack_end:
 

==== //depot/projects/avr32/src/sys/avr32/avr32/machdep.c#12 (text+ko) ====

@@ -80,6 +80,7 @@
 struct pcpu __pcpu;
 struct pcpu *pcpup = &__pcpu;
 struct pcb proc0_pcb;
+static struct trapframe proc0_tf;
 extern vm_offset_t proc0_stack;
 extern uint64_t clock_cpu_frequency;
 
@@ -112,11 +113,10 @@
 static void
 avr32_init_proc0()
 {
-	proc_linkup(&proc0, &thread0);
+	proc_linkup0(&proc0, &thread0);
 	thread0.td_kstack = (vm_offset_t)&proc0_stack;
-	thread0.td_kstack_pages = KSTACK_PAGES - 1;
 	thread0.td_pcb = &proc0_pcb;
-	thread0.td_frame = &thread0.td_pcb->pcb_regs;
+	thread0.td_frame = &proc0_tf;
 
 	pcpu_init(pcpup, 0, sizeof(struct pcpu));
 	PCPU_SET(curthread, &thread0);
@@ -279,7 +279,16 @@
 void
 makectx(struct trapframe *tf, struct pcb *pcb)
 {
-	bcopy(&tf->regs, &pcb->pcb_regs, sizeof(struct trapframe));
+	pcb->pc = tf->regs.pc;
+	pcb->sp = tf->regs.sp;
+	pcb->r7 = tf->regs.r7;
+	pcb->r6 = tf->regs.r6;
+	pcb->r5 = tf->regs.r5;
+	pcb->r4 = tf->regs.r4;
+	pcb->r3 = tf->regs.r3;
+	pcb->r2 = tf->regs.r2;
+	pcb->r1 = tf->regs.r1;
+	pcb->r0 = tf->regs.r0;
 }
 
 u_int32_t

==== //depot/projects/avr32/src/sys/avr32/avr32/switch.S#12 (text+ko) ====

@@ -34,21 +34,22 @@
 __FBSDID("$FreeBSD: $");
 
 /**
- * r11:	td
- * r10:	td frame
- * r9:	callout
+ * r7:	callout
+ * r6:	td
+ * r5:	td frame
  */
 ENTRY(fork_trampoline)
-	mov	r12, r9				/* Callout is first argument to fork_exit */
-	mov	r6, r10				/* Save r10 for later use */
+	mov	r12, r7
+	mov	r11, r6
+	mov	r10, r5
 	call	fork_exit			/* Call fork_exit */
 
 	/* Return to usermode */
-	ld.w	r9, r6++			/* Load status register */
+	ld.w	r9, r5++			/* Load status register */
 	mtsr	AT32_SYS_RSR_SUP, r9		/* Return status register */
-	ld.w	r9, r6++			/* Load program count */
+	ld.w	r9, r5++			/* Load program count */
 	mtsr	AT32_SYS_RAR_SUP, r9		/* Return address register */
-	ldmts	r6, r0-r12,sp,lr		/* Load rest to user register context */
+	ldmts	r5, r0-r12,sp,lr		/* Load rest to user register context */
 
 	frs					/* Flush the return stack */
 	sub	pc, -2				/* Flush the pipeline */
@@ -62,9 +63,7 @@
 ENTRY(savectx)
 	mustr	r11				/* Get status register */
 	st.w	r12++, r11			/* Store status register */
-	sub	r12, -4				/* Skip PC */
-	stm	r12, r0-r12,sp,lr		/* Store rest */
-	mov	lr, r8
+	stm	r12, r0-r7,sp,lr		/* Store rest */
 	retal	sp				/* return 0 */
 END(savectx)
 
@@ -77,48 +76,45 @@
 ENTRY(restorectx)
 	/*
 	 * Lock kernel stack in tlb
-	 * r10: KStack
 	 * r9:	Pointer to kernel PTE
-	 * r8:	Iterator
+	 * r8:  Address of PCB
 	 * r7:  * Frame Pointer not used
 	 * r6:	PTE
 	 * r5:	MMUCR
 	 * r4:  Misc
 	 * r3:	tlbehi save
-	 * r2:  Address of PCB
-	 * r1:  Saved SR
+	 * r2:	Iterator
+	 * r1:	KStack
 	 */
 
-	mov	r1, r10
-
 	/* Load PCB and PD address */
-	ld.w	r2, r12[TD_PCB]
+	ld.w	r8, r12[TD_PCB]
 
 	/* Add ASID and V flag to kstack value */
-	ld.w	r10, r12[TD_KSTACK]
+	ld.w	r1, r12[TD_KSTACK]
 	ld.w	r4, r11[PMAP_ASID]
-	add	r10, r4
-	sbr	r10, AT32_SYS_TLBEHI_V
+	add	r1, r4
+	sbr	r1, AT32_SYS_TLBEHI_V
 	ld.w	r11, r11[PMAP_PD]		/* Point r11 to page directory */
 
 	/* Check if stack is in P3 */
-	mov	r9, r10
+	mov	r9, r1
 	lsr	r9, 29
 	cp	r9, 0x6
 	brne	restore_finish
 
 	sub	r9, r12, -(TD_KPTE)		/* Add KPTE offset to thread struct pointer */
-	mov	r8, KSTACK_PAGES		/* Iterate thru thru all kstack pages */
+	mov	r2, KSTACK_PAGES		/* Iterate thru thru all kstack pages */
 
 	mfsr	r3, AT32_SYS_TLBEHI
 
-1:	sub	r8, 1				/* Decrease iterator */
+1:	sub	r2, 1				/* Decrease iterator */
 	mtsr	AT32_SYS_TLBEHI, r3		/* Set TLBEHI to old to load pte */
 	nop					/* Wait for mtsr */
 	ld.w	r6, r9++			/* Load PTE */
 
 	/* Search for entry in tlb and invalidate it if its there */
-	mtsr	AT32_SYS_TLBEHI, r10		/* Set TLBEHI to kstack tlbehi */
+	mtsr	AT32_SYS_TLBEHI, r1		/* Set TLBEHI to kstack tlbehi */
 	nop					/* Wait for mtsr */
 	tlbs					/* Search for entry */
 	sub	pc, -2				/* Flush pipeline */
@@ -135,10 +131,10 @@
 	sub	pc, -2				/* Flush pipline */
 
 2:
-	mtsr	AT32_SYS_TLBEHI, r10		/* Set TLBEHI to kstack tlbehi */
+	mtsr	AT32_SYS_TLBEHI, r1		/* Set TLBEHI to kstack tlbehi */
 	mtsr	AT32_SYS_TLBELO, r6		/* Set TLBELO to PTE */
 	mfsr	r5, AT32_SYS_MMUCR		/* Get MMUCR */
-	bfins	r5, r8, AT32_SYS_MMUCR_DRP, AT32_SYS_MMUCR_DRP_SIZE	/* Set entry to insert to */
+	bfins	r5, r2, AT32_SYS_MMUCR_DRP, AT32_SYS_MMUCR_DRP_SIZE	/* Set entry to insert to */
 	mtsr	AT32_SYS_MMUCR, r5		/* Set MMUCR */
 	nop					/* Wait for mtsr to leave the pipeline */
 
@@ -146,19 +142,20 @@
 	sub	pc, -2				/* Flush pipeline */
 
 	/* Are we done? */
-	sub	r10, -4096			/* Add PAGE_SIZE to kstack address */
-	cp.w	r8, 0				/* Done? */
+	sub	r1, -4096			/* Add PAGE_SIZE to kstack address */
+	cp.w	r2, 0				/* Done? */
 	brne	1b				/* Or not */
 
 restore_finish:
 	mtsr	AT32_SYS_PTBR, r11		/* Point lookups to new pmap */
-	mtsr	AT32_SYS_TLBEHI, r10		/* Set TLBEHI (ASID for new td) */
+	mtsr	AT32_SYS_TLBEHI, r1		/* Set TLBEHI (ASID for new td) */
 	nop					/* Wait for mtsr */
-	mtsr	AT32_SYS_SR, r1			/* Restore saved SR */
-	ld.w	r4, r2++			/* Load status register */
-	musfr	r4				/* Set status register */
-	sub	r2, -4				/* Skip PC */
-	ldm	r2, r0-r12,sp,lr		/* Load rest */
+
+	ld.w	r9, r8++			/* Load status register */
+	ldm	r8, r0-r7,sp,lr			/* Load rest */
+
+	mtsr	AT32_SYS_SR, r10		/* Restore saved SR */
+	musfr	r9				/* Set status register */
 
 	frs					/* Flush the return stack */
 	sub	pc, -2				/* Flush the pipeline */

==== //depot/projects/avr32/src/sys/avr32/avr32/vm_machdep.c#10 (text+ko) ====

@@ -65,15 +65,30 @@
 		return;
 	}
 
-	/* Copy p1's pcb to p2 */
+	/* Point the pcb and td_frame to the top of the stack */
+        td2->td_pcb = (struct pcb *)(td2->td_kstack + td2->td_kstack_pages
+	    * PAGE_SIZE) - 1;
+	td2->td_frame = (struct trapframe *)td2->td_pcb - 1;
+
+
+	/*
+	 * Copy p1's pcb to p2 and set kernel registers for trampoline
+	 */
 	bcopy(td1->td_pcb, td2->td_pcb, sizeof(struct pcb));
+	td2->td_pcb->r7 = (register_t)fork_return;
+	td2->td_pcb->r6 = (register_t)td2;
+	td2->td_pcb->r5 = (register_t)td2->td_frame;
+	td2->td_pcb->sp = (register_t)td2->td_frame - sizeof(void *);
+	td2->td_pcb->pc = (register_t)fork_trampoline;
+
+	/*
+	 * Copy p1's td_frame to p2 and set registers as if from a syscall
+	 */
+	bcopy(td1->td_frame, td2->td_frame, sizeof(struct trapframe));
+	td2->td_frame->regs.r11 = 0;
+	td2->td_frame->regs.r12 = 0;
+	td2->td_frame->regs.sr &= ~bit_mask(SYS, SR, C);
 
-	/* Sets regs (need to look into this better later on) */
-	td2->td_pcb->pcb_regs.regs.r9 = (register_t)fork_return;
-	td2->td_pcb->pcb_regs.regs.r11 = (register_t)td2;
-	td2->td_pcb->pcb_regs.regs.r10 = (register_t)td2->td_frame;
-	td2->td_pcb->pcb_regs.regs.sp = (register_t)td2->td_frame - sizeof(void *);
-	td2->td_pcb->pcb_regs.regs.lr = (register_t)fork_trampoline;
 
 	td2->td_md.md_saved_intr = 0;		/* TODO: probably not right. */
 	td2->td_md.md_spinlock_count = 1;
@@ -88,8 +103,8 @@
 void
 cpu_set_fork_handler(struct thread *td, void (*func) __P((void *)), void *arg)
 {
-	td->td_pcb->pcb_regs.regs.r9 = (register_t)func;
-	td->td_pcb->pcb_regs.regs.r11 = (register_t)arg;
+	td->td_pcb->r7 = (register_t)func;
+	td->td_pcb->r6 = (register_t)arg;
 }
 
 void
@@ -135,7 +150,7 @@
 
 	td->td_pcb = (struct pcb *)(td->td_kstack + td->td_kstack_pages *
 	    PAGE_SIZE) - 1;
-	td->td_frame = &td->td_pcb->pcb_regs;
+	td->td_frame = (struct trapframe *)td->td_pcb - 1;
 
 	pte = pmap_pte(kernel_pmap, td->td_kstack);
 	if (pte == NULL) {
@@ -157,15 +172,16 @@
 void
 cpu_set_upcall(struct thread *td, struct thread *td0)
 {
-	/* Copy td's pcb to td0 */
+	/* Copy td's pcb and frame */
 	bcopy(td0->td_pcb, td->td_pcb, sizeof(struct pcb));
+	bcopy(td0->td_frame, td->td_frame, sizeof(struct trapframe));
 
 	/* Sets regs (need to look into this better later on) */
-	td->td_pcb->pcb_regs.regs.r9 = (register_t)fork_return;
-	td->td_pcb->pcb_regs.regs.r11 = (register_t)td;
-	td->td_pcb->pcb_regs.regs.r10 = (register_t)td->td_frame;
-	td->td_pcb->pcb_regs.regs.sp = (register_t)td->td_frame - sizeof(void *);
-	td->td_pcb->pcb_regs.regs.lr = (register_t)fork_trampoline;
+	td->td_pcb->r7 = (register_t)fork_return;
+	td->td_pcb->r6 = (register_t)td;
+	td->td_pcb->r5 = (register_t)td->td_frame;
+	td->td_pcb->sp = (register_t)td->td_frame - sizeof(void *);
+	td->td_pcb->pc = (register_t)fork_trampoline;
 
 	td->td_md.md_saved_intr = 0;		/* TODO: probably not right. */
 	td->td_md.md_spinlock_count = 1;

==== //depot/projects/avr32/src/sys/avr32/include/db_machdep.h#6 (text+ko) ====

@@ -37,7 +37,7 @@
 typedef vm_offset_t	db_addr_t;
 typedef int		db_expr_t;
 
-#define	PC_REGS()	((db_addr_t)kdb_thrctx->pcb_regs.regs.pc)
+#define	PC_REGS()	((db_addr_t)kdb_thrctx->pc)
 
 #define	BKPT_INST		(0xD673)
 #define	BKPT_SIZE		(2)

==== //depot/projects/avr32/src/sys/avr32/include/pcb.h#5 (text+ko) ====

@@ -35,7 +35,17 @@
  * AVR32 process control block
  */
 struct pcb {
-	struct trapframe pcb_regs;	/* saved CPU and registers */
+	register_t sr;	/* Status register */
+	register_t pc;	/* Program counter */
+	register_t sp;
+	register_t r7;
+	register_t r6;
+	register_t r5;
+	register_t r4;
+	register_t r3;
+	register_t r2;
+	register_t r1;
+	register_t r0;
 };
 
 #ifdef _KERNEL



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905080254.n482s00f043393>