Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 24 Dec 2014 18:54:32 +0000 (UTC)
From:      Ian Lepore <ian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r276190 - in head: gnu/usr.bin/gdb/kgdb sys/arm/arm sys/arm/include
Message-ID:  <201412241854.sBOIsWIo087516@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ian
Date: Wed Dec 24 18:54:31 2014
New Revision: 276190
URL: https://svnweb.freebsd.org/changeset/base/276190

Log:
  Cleanup up ARM *frame structures...
  
   - Eliminate unused irqframe
   - Eliminate unused saframe
   - Instead of splitting r4-sp storage between the stack and switchframe,
     just put all the registers in switchframe and eliminate the un_32 struct.
  
  Submitted by:	Svatopluk Kraus <onwahe@gmail.com>,
  		Michal Meloun <meloun@miracle.cz>

Modified:
  head/gnu/usr.bin/gdb/kgdb/trgt_arm.c
  head/sys/arm/arm/db_trace.c
  head/sys/arm/arm/gdb_machdep.c
  head/sys/arm/arm/genassym.c
  head/sys/arm/arm/machdep.c
  head/sys/arm/arm/stack_machdep.c
  head/sys/arm/arm/swtch.S
  head/sys/arm/arm/trap.c
  head/sys/arm/arm/vm_machdep.c
  head/sys/arm/include/db_machdep.h
  head/sys/arm/include/frame.h
  head/sys/arm/include/pcb.h

Modified: head/gnu/usr.bin/gdb/kgdb/trgt_arm.c
==============================================================================
--- head/gnu/usr.bin/gdb/kgdb/trgt_arm.c	Wed Dec 24 18:51:25 2014	(r276189)
+++ head/gnu/usr.bin/gdb/kgdb/trgt_arm.c	Wed Dec 24 18:54:31 2014	(r276190)
@@ -72,20 +72,12 @@ kgdb_trgt_fetch_registers(int regno __un
 		warnx("kvm_read: %s", kvm_geterr(kvm));
 		memset(&pcb, 0, sizeof(pcb));
 	}
-	for (i = ARM_A1_REGNUM + 8; i <= ARM_SP_REGNUM; i++) {
-		supply_register(i, (char *)&pcb.un_32.pcb32_r8 +
-		    (i - (ARM_A1_REGNUM + 8 )) * 4);
-	}
-	if (pcb.un_32.pcb32_sp != 0) {
-		for (i = 0; i < 4; i++) {
-			if (kvm_read(kvm, pcb.un_32.pcb32_sp + (i) * 4,
-			    &reg, 4) != 4) {
-				warnx("kvm_read: %s", kvm_geterr(kvm));
-				break;
-			}
-			supply_register(ARM_A1_REGNUM + 4 + i, (char *)&reg);
-		}
-		if (kvm_read(kvm, pcb.un_32.pcb32_sp + 4 * 4, &reg, 4) != 4)
+	for (i = ARM_A1_REGNUM + 4; i <= ARM_SP_REGNUM; i++) {
+		supply_register(i, (char *)&pcb.pcb_regs.sf_r4 +
+		    (i - (ARM_A1_REGNUM + 4 )) * 4);
+	}
+	if (pcb.pcb_regs.sf_sp != 0) {
+		if (kvm_read(kvm, pcb.pcb_regs.sf_sp + 4 * 4, &reg, 4) != 4)
 			warnx("kvm_read :%s", kvm_geterr(kvm));
 		else
 			supply_register(ARM_PC_REGNUM, (char *)&reg);

Modified: head/sys/arm/arm/db_trace.c
==============================================================================
--- head/sys/arm/arm/db_trace.c	Wed Dec 24 18:51:25 2014	(r276189)
+++ head/sys/arm/arm/db_trace.c	Wed Dec 24 18:54:31 2014	(r276190)
@@ -609,14 +609,14 @@ db_trace_thread(struct thread *thr, int 
 		ctx = kdb_thr_ctx(thr);
 
 #ifdef __ARM_EABI__
-		state.registers[FP] = ctx->un_32.pcb32_r11;
-		state.registers[SP] = ctx->un_32.pcb32_sp;
-		state.registers[LR] = ctx->un_32.pcb32_lr;
-		state.registers[PC] = ctx->un_32.pcb32_pc;
+		state.registers[FP] = ctx->pcb_regs.sf_r11;
+		state.registers[SP] = ctx->pcb_regs.sf_sp;
+		state.registers[LR] = ctx->pcb_regs.sf_lr;
+		state.registers[PC] = ctx->pcb_regs.sf_pc;
 
 		db_stack_trace_cmd(&state);
 #else
-		db_stack_trace_cmd(ctx->un_32.pcb32_r11, -1, TRUE);
+		db_stack_trace_cmd(ctx->pcb_regs.sf_r11, -1, TRUE);
 #endif
 	} else
 		db_trace_self();

Modified: head/sys/arm/arm/gdb_machdep.c
==============================================================================
--- head/sys/arm/arm/gdb_machdep.c	Wed Dec 24 18:51:25 2014	(r276189)
+++ head/sys/arm/arm/gdb_machdep.c	Wed Dec 24 18:54:31 2014	(r276190)
@@ -67,22 +67,26 @@ gdb_cpu_getreg(int regnum, size_t *regsz
 	}
 
 	switch (regnum) {
-	case 8:  return (&kdb_thrctx->un_32.pcb32_r8);
-	case 9:  return (&kdb_thrctx->un_32.pcb32_r9);
-	case 10:  return (&kdb_thrctx->un_32.pcb32_r10);
-	case 11:  return (&kdb_thrctx->un_32.pcb32_r11);
-	case 12:  return (&kdb_thrctx->un_32.pcb32_r12);
-	case 13:  stacktest = kdb_thrctx->un_32.pcb32_sp + 5 * 4;
+	case 4:  return (&kdb_thrctx->pcb_regs.sf_r4);
+	case 5:  return (&kdb_thrctx->pcb_regs.sf_r5);
+	case 6:  return (&kdb_thrctx->pcb_regs.sf_r6);
+	case 7:  return (&kdb_thrctx->pcb_regs.sf_r7);
+	case 8:  return (&kdb_thrctx->pcb_regs.sf_r8);
+	case 9:  return (&kdb_thrctx->pcb_regs.sf_r9);
+	case 10:  return (&kdb_thrctx->pcb_regs.sf_r10);
+	case 11:  return (&kdb_thrctx->pcb_regs.sf_r11);
+	case 12:  return (&kdb_thrctx->pcb_regs.sf_r12);
+	case 13:  stacktest = kdb_thrctx->pcb_regs.sf_sp + 5 * 4;
 		  return (&stacktest);
 	case 15:
 		  /*
 		   * On context switch, the PC is not put in the PCB, but
 		   * we can retrieve it from the stack.
 		   */
-		  if (kdb_thrctx->un_32.pcb32_sp > KERNBASE) {
-			  kdb_thrctx->un_32.pcb32_pc = *(register_t *)
-			      (kdb_thrctx->un_32.pcb32_sp + 4 * 4);
-			  return (&kdb_thrctx->un_32.pcb32_pc);
+		  if (kdb_thrctx->pcb_regs.sf_sp > KERNBASE) {
+			  kdb_thrctx->pcb_regs.sf_pc = *(register_t *)
+			      (kdb_thrctx->pcb_regs.sf_sp + 4 * 4);
+			  return (&kdb_thrctx->pcb_regs.sf_pc);
 		  }
 	}
 

Modified: head/sys/arm/arm/genassym.c
==============================================================================
--- head/sys/arm/arm/genassym.c	Wed Dec 24 18:51:25 2014	(r276189)
+++ head/sys/arm/arm/genassym.c	Wed Dec 24 18:54:31 2014	(r276190)
@@ -63,13 +63,18 @@ ASSYM(PCB_FLAGS, offsetof(struct pcb, pc
 ASSYM(PCB_PAGEDIR, offsetof(struct pcb, pcb_pagedir));
 ASSYM(PCB_L1VEC, offsetof(struct pcb, pcb_l1vec));
 ASSYM(PCB_PL1VEC, offsetof(struct pcb, pcb_pl1vec));
-ASSYM(PCB_R8, offsetof(struct pcb, un_32.pcb32_r8));
-ASSYM(PCB_R9, offsetof(struct pcb, un_32.pcb32_r9));
-ASSYM(PCB_R10, offsetof(struct pcb, un_32.pcb32_r10));
-ASSYM(PCB_R11, offsetof(struct pcb, un_32.pcb32_r11));
-ASSYM(PCB_R12, offsetof(struct pcb, un_32.pcb32_r12));
-ASSYM(PCB_PC, offsetof(struct pcb, un_32.pcb32_pc));
-ASSYM(PCB_SP, offsetof(struct pcb, un_32.pcb32_sp));
+ASSYM(PCB_R4, offsetof(struct pcb, pcb_regs.sf_r4));
+ASSYM(PCB_R5, offsetof(struct pcb, pcb_regs.sf_r5));
+ASSYM(PCB_R6, offsetof(struct pcb, pcb_regs.sf_r6));
+ASSYM(PCB_R7, offsetof(struct pcb, pcb_regs.sf_r7));
+ASSYM(PCB_R8, offsetof(struct pcb, pcb_regs.sf_r8));
+ASSYM(PCB_R9, offsetof(struct pcb, pcb_regs.sf_r9));
+ASSYM(PCB_R10, offsetof(struct pcb, pcb_regs.sf_r10));
+ASSYM(PCB_R11, offsetof(struct pcb, pcb_regs.sf_r11));
+ASSYM(PCB_R12, offsetof(struct pcb, pcb_regs.sf_r12));
+ASSYM(PCB_SP, offsetof(struct pcb, pcb_regs.sf_sp));
+ASSYM(PCB_LR, offsetof(struct pcb, pcb_regs.sf_lr));
+ASSYM(PCB_PC, offsetof(struct pcb, pcb_regs.sf_pc));
 
 ASSYM(PC_CURPCB, offsetof(struct pcpu, pc_curpcb));
 ASSYM(PC_CURTHREAD, offsetof(struct pcpu, pc_curthread));

Modified: head/sys/arm/arm/machdep.c
==============================================================================
--- head/sys/arm/arm/machdep.c	Wed Dec 24 18:51:25 2014	(r276189)
+++ head/sys/arm/arm/machdep.c	Wed Dec 24 18:54:31 2014	(r276190)
@@ -378,7 +378,7 @@ cpu_startup(void *dummy)
 
 	bufinit();
 	vm_pager_bufferinit();
-	pcb->un_32.pcb32_sp = (u_int)thread0.td_kstack +
+	pcb->pcb_regs.sf_sp = (u_int)thread0.td_kstack +
 	    USPACE_SVC_STACK_TOP;
 	vector_page_setprot(VM_PROT_READ);
 	pmap_set_pcb_pagedir(pmap_kernel(), pcb);
@@ -770,14 +770,18 @@ sys_sigreturn(td, uap)
 void
 makectx(struct trapframe *tf, struct pcb *pcb)
 {
-	pcb->un_32.pcb32_r8 = tf->tf_r8;
-	pcb->un_32.pcb32_r9 = tf->tf_r9;
-	pcb->un_32.pcb32_r10 = tf->tf_r10;
-	pcb->un_32.pcb32_r11 = tf->tf_r11;
-	pcb->un_32.pcb32_r12 = tf->tf_r12;
-	pcb->un_32.pcb32_pc = tf->tf_pc;
-	pcb->un_32.pcb32_lr = tf->tf_usr_lr;
-	pcb->un_32.pcb32_sp = tf->tf_usr_sp;
+	pcb->pcb_regs.sf_r4 = tf->tf_r4;
+	pcb->pcb_regs.sf_r5 = tf->tf_r5;
+	pcb->pcb_regs.sf_r6 = tf->tf_r6;
+	pcb->pcb_regs.sf_r7 = tf->tf_r7;
+	pcb->pcb_regs.sf_r8 = tf->tf_r8;
+	pcb->pcb_regs.sf_r9 = tf->tf_r9;
+	pcb->pcb_regs.sf_r10 = tf->tf_r10;
+	pcb->pcb_regs.sf_r11 = tf->tf_r11;
+	pcb->pcb_regs.sf_r12 = tf->tf_r12;
+	pcb->pcb_regs.sf_pc = tf->tf_pc;
+	pcb->pcb_regs.sf_lr = tf->tf_usr_lr;
+	pcb->pcb_regs.sf_sp = tf->tf_usr_sp;
 }
 
 /*

Modified: head/sys/arm/arm/stack_machdep.c
==============================================================================
--- head/sys/arm/arm/stack_machdep.c	Wed Dec 24 18:51:25 2014	(r276189)
+++ head/sys/arm/arm/stack_machdep.c	Wed Dec 24 18:54:31 2014	(r276190)
@@ -76,7 +76,7 @@ stack_save_td(struct stack *st, struct t
 	 * as it doesn't have a frame pointer, however it's value is not used
 	 * when building for EABI.
 	 */
-	frame = (u_int32_t *)td->td_pcb->un_32.pcb32_r11;
+	frame = (u_int32_t *)td->td_pcb->pcb_regs.sf_r11;
 	stack_zero(st);
 	stack_capture(st, frame);
 }

Modified: head/sys/arm/arm/swtch.S
==============================================================================
--- head/sys/arm/arm/swtch.S	Wed Dec 24 18:51:25 2014	(r276189)
+++ head/sys/arm/arm/swtch.S	Wed Dec 24 18:54:31 2014	(r276190)
@@ -116,6 +116,14 @@ __FBSDID("$FreeBSD$");
 .Lblocked_lock:
 	.word	_C_LABEL(blocked_lock)
 
+/*
+ * cpu_throw(oldtd, newtd)
+ *
+ * Remove current thread state, then select the next thread to run
+ * and load its state.
+ * r0 = oldtd
+ * r1 = newtd
+ */
 ENTRY(cpu_throw)
 	mov	r5, r1
 
@@ -144,7 +152,6 @@ ENTRY(cpu_throw)
 	 * r0 = Pointer to L1 slot for vector_page (or NULL)
 	 * r1 = lwp0's DACR
 	 * r5 = lwp0
-	 * r6 = exit func
 	 * r7 = lwp0's PCB
 	 * r9 = cpufuncs
 	 */
@@ -181,25 +188,11 @@ ENTRY(cpu_throw)
 	mov	lr, pc
 	ldr	pc, [r9, #CF_CONTEXT_SWITCH]
 
-	/* Restore all the save registers */
-#ifndef _ARM_ARCH_5E
-	add	r1, r7, #PCB_R8
-	ldmia	r1, {r8-r13}
-#else
-	ldr	r8, [r7, #(PCB_R8)]
-	ldr	r9, [r7, #(PCB_R9)]
-	ldr	r10, [r7, #(PCB_R10)]
-	ldr	r11, [r7, #(PCB_R11)]
-	ldr	r12, [r7, #(PCB_R12)]
-	ldr	r13, [r7, #(PCB_SP)]
-#endif
-
 	GET_PCPU(r6, r4)
 	/* Hook in a new pcb */
 	str	r7, [r6, #PC_CURPCB]
 	/* We have a new curthread now so make a note it */
-	add	r6, r6, #PC_CURTHREAD
-	str	r5, [r6]
+	str	r5, [r6, #PC_CURTHREAD]
 #ifndef ARM_TP_ADDRESS
 	mcr	p15, 0, r5, c13, c0, 4
 #endif
@@ -215,22 +208,31 @@ ENTRY(cpu_throw)
 #else
 	mcr p15, 0, r6, c13, c0, 3
 #endif
-
-	add	sp, sp, #4;
-	ldmfd	sp!, {r4-r7, pc}
+	/* Restore all the saved registers and exit */
+	add	r3, r7, #PCB_R4
+	ldmia	r3, {r4-r12, sp, pc}
 END(cpu_throw)
 
+/*
+ * cpu_switch(oldtd, newtd, lock)
+ *
+ * Save the current thread state, then select the next thread to run
+ * and load its state.
+ * r0 = oldtd
+ * r1 = newtd
+ * r2 = lock (new lock for old thread)
+ */
 ENTRY(cpu_switch)
-	stmfd	sp!, {r4-r7, lr}
-	sub	sp, sp, #4;
-#ifdef __ARM_EABI__
-	.save	{r4-r7, lr}
-	.pad	#4
-#endif
+	/* Interrupts are disabled. */
+	/* Save all the registers in the old thread's pcb. */
+	ldr	r3, [r0, #(TD_PCB)]
+
+	/* Restore all the saved registers and exit */
+	add	r3, #(PCB_R4)
+	stmia	r3, {r4-r12, sp, lr, pc}
 
 	mov	r6, r2 /* Save the mutex */
 
-.Lswitch_resume:
 	/* rem: r0 = old lwp */
 	/* rem: interrupts are disabled */
 
@@ -246,30 +248,12 @@ ENTRY(cpu_switch)
 	ldr	r2, [r1, #TD_PCB]
 	str	r2, [r7, #PC_CURPCB]
 
-	/* rem: r1 = new process */
-	/* rem: interrupts are enabled */
-
 	/* Stage two : Save old context */
 
 	/* Get the user structure for the old thread. */
 	ldr	r2, [r0, #(TD_PCB)]
 	mov	r4, r0 /* Save the old thread. */
 
-	/* Save all the registers in the old thread's pcb */
-#ifndef _ARM_ARCH_5E
-	add	r7, r2, #(PCB_R8)
-	stmia	r7, {r8-r13}
-#else
-	strd	r8, [r2, #(PCB_R8)]
-	strd	r10, [r2, #(PCB_R10)]
-	strd	r12, [r2, #(PCB_R12)]
-#endif
-	str	pc, [r2, #(PCB_PC)]
-
-	/*
-	 * NOTE: We can now use r8-r13 until it is time to restore
-	 * them for the new process.
-	 */
 #ifdef ARM_TP_ADDRESS
 	/* Store the old tp */
 	ldr	r3, =ARM_TP_ADDRESS
@@ -318,7 +302,6 @@ ENTRY(cpu_switch)
 
 	/* rem: r2 = old PCB */
 	/* rem: r9 = new PCB */
-	/* rem: interrupts are enabled */
 
 	ldr	r5, [r9, #(PCB_DACR)]		/* r5 = new DACR */
 	mov	r2, #DOMAIN_CLIENT
@@ -336,7 +319,6 @@ ENTRY(cpu_switch)
 	mrc	p15, 0, r10, c2, c0, 0		/* r10 = old L1 */
 	ldr	r11, [r9, #(PCB_PAGEDIR)]	/* r11 = new L1 */
 
-
 	teq	r10, r11			/* Same L1? */
 	cmpeq	r0, r5				/* Same DACR? */
 	beq	.Lcs_context_switched		/* yes! */
@@ -426,54 +408,18 @@ ENTRY(cpu_switch)
 
 	/* rem: r9 = new PCB */
 
-	/* Restore all the save registers */
-#ifndef _ARM_ARCH_5E
-	add	r7, r9, #PCB_R8
-	ldmia	r7, {r8-r13}
-	sub	r7, r7, #PCB_R8		/* restore PCB pointer */
-#else
-	mov	r7, r9
-	ldr	r8, [r7, #(PCB_R8)]
-	ldr	r9, [r7, #(PCB_R9)]
-	ldr	r10, [r7, #(PCB_R10)]
-	ldr	r11, [r7, #(PCB_R11)]
-	ldr	r12, [r7, #(PCB_R12)]
-	ldr	r13, [r7, #(PCB_SP)]
-#endif
-
-	/* rem: r5 = new lwp's proc */
-	/* rem: r6 = lock */
-	/* rem: r7 = new PCB */
-
-.Lswitch_return:
-
-	/*
-	 * Pull the registers that got pushed when either savectx() or
-	 * cpu_switch() was called and return.
-	 */
-	add	sp, sp, #4;
-	ldmfd	sp!, {r4-r7, pc}
-#ifdef DIAGNOSTIC
-.Lswitch_bogons:
-	adr	r0, .Lswitch_panic_str
-	bl	_C_LABEL(panic)
-1:	nop
-	b	1b
-
-.Lswitch_panic_str:
-	.asciz	"cpu_switch: sched_qs empty with non-zero sched_whichqs!\n"
-#endif
+	/* Restore all the saved registers and exit */
+	add	r3, r9, #PCB_R4
+	ldmia	r3, {r4-r12, sp, pc}
 END(cpu_switch)
 
 ENTRY(savectx)
-	stmfd   sp!, {r4-r7, lr}
+	stmfd	sp!, {lr}
 	sub	sp, sp, #4
-	/*
-	 * r0 = pcb
-	 */
-	/* Store all the registers in the process's pcb */
-	add	r2, r0, #(PCB_R8)
-	stmia	r2, {r8-r13}
+	
+	/* Store all the registers in the thread's pcb */
+	add	r3, r0, #(PCB_R4)
+	stmia	r3, {r4-r12, sp, lr, pc}
 #ifdef VFP
 	fmrx	r2, fpexc		/* If the VFP is enabled */
 	tst	r2, #(VFPEXC_EN)	/* the current thread has */
@@ -482,7 +428,7 @@ ENTRY(savectx)
 	blne	_C_LABEL(vfp_store)	/* and disable the VFP. */
 #endif
 	add	sp, sp, #4;
-	ldmfd	sp!, {r4-r7, pc}
+	ldmfd	sp!, {pc}
 END(savectx)
 
 ENTRY(fork_trampoline)

Modified: head/sys/arm/arm/trap.c
==============================================================================
--- head/sys/arm/arm/trap.c	Wed Dec 24 18:51:25 2014	(r276189)
+++ head/sys/arm/arm/trap.c	Wed Dec 24 18:54:31 2014	(r276190)
@@ -545,7 +545,7 @@ dab_buserr(struct trapframe *tf, u_int f
 		 * If the current trapframe is at the top of the kernel stack,
 		 * the fault _must_ have come from user mode.
 		 */
-		if (tf != ((struct trapframe *)pcb->un_32.pcb32_sp) - 1) {
+		if (tf != ((struct trapframe *)pcb->pcb_regs.sf_sp) - 1) {
 			/*
 			 * Kernel mode. We're either about to die a
 			 * spectacular death, or pcb_onfault will come

Modified: head/sys/arm/arm/vm_machdep.c
==============================================================================
--- head/sys/arm/arm/vm_machdep.c	Wed Dec 24 18:51:25 2014	(r276189)
+++ head/sys/arm/arm/vm_machdep.c	Wed Dec 24 18:54:31 2014	(r276190)
@@ -79,7 +79,7 @@ __FBSDID("$FreeBSD$");
  * struct switchframe and trapframe must both be a multiple of 8
  * for correct stack alignment.
  */
-CTASSERT(sizeof(struct switchframe) == 24);
+CTASSERT(sizeof(struct switchframe) == 48);
 CTASSERT(sizeof(struct trapframe) == 80);
 
 /*
@@ -93,43 +93,55 @@ cpu_fork(register struct thread *td1, re
 {
 	struct pcb *pcb2;
 	struct trapframe *tf;
-	struct switchframe *sf;
 	struct mdproc *mdp2;
 
 	if ((flags & RFPROC) == 0)
 		return;
-	pcb2 = (struct pcb *)(td2->td_kstack + td2->td_kstack_pages * PAGE_SIZE) - 1;
+
+	/* Point the pcb to the top of the stack */
+	pcb2 = (struct pcb *)
+	    (td2->td_kstack + td2->td_kstack_pages * PAGE_SIZE) - 1;
 #ifdef __XSCALE__
 #ifndef CPU_XSCALE_CORE3
 	pmap_use_minicache(td2->td_kstack, td2->td_kstack_pages * PAGE_SIZE);
 #endif
 #endif
 	td2->td_pcb = pcb2;
+	
+	/* Clone td1's pcb */
 	bcopy(td1->td_pcb, pcb2, sizeof(*pcb2));
+	
+	/* Point to mdproc and then copy over td1's contents */
 	mdp2 = &p2->p_md;
 	bcopy(&td1->td_proc->p_md, mdp2, sizeof(*mdp2));
-	pcb2->un_32.pcb32_sp = td2->td_kstack +
-	    USPACE_SVC_STACK_TOP - sizeof(*pcb2);
+
+	/* Point the frame to the stack in front of pcb and copy td1's frame */
+	td2->td_frame = (struct trapframe *)pcb2 - 1;
+	*td2->td_frame = *td1->td_frame;
+
+	/*
+	 * Create a new fresh stack for the new process.
+	 * Copy the trap frame for the return to user mode as if from a
+	 * syscall.  This copies most of the user mode register values.
+	 */
+	pmap_set_pcb_pagedir(vmspace_pmap(p2->p_vmspace), pcb2);
+	pcb2->pcb_regs.sf_r4 = (register_t)fork_return;
+	pcb2->pcb_regs.sf_r5 = (register_t)td2;
+	pcb2->pcb_regs.sf_lr = (register_t)fork_trampoline;
+	pcb2->pcb_regs.sf_sp = STACKALIGN(td2->td_frame);
+
 	pcb2->pcb_vfpcpu = -1;
 	pcb2->pcb_vfpstate.fpscr = VFPSCR_DN | VFPSCR_FZ;
-	pmap_activate(td2);
-	td2->td_frame = tf = (struct trapframe *)STACKALIGN(
-	    pcb2->un_32.pcb32_sp - sizeof(struct trapframe));
-	*tf = *td1->td_frame;
-	sf = (struct switchframe *)tf - 1;
-	sf->sf_r4 = (u_int)fork_return;
-	sf->sf_r5 = (u_int)td2;
-	sf->sf_pc = (u_int)fork_trampoline;
+	
+	tf = td2->td_frame;
 	tf->tf_spsr &= ~PSR_C;
 	tf->tf_r0 = 0;
 	tf->tf_r1 = 0;
-	pcb2->un_32.pcb32_sp = (u_int)sf;
-	KASSERT((pcb2->un_32.pcb32_sp & 7) == 0,
-	    ("cpu_fork: Incorrect stack alignment"));
+
 
 	/* Setup to release spin count in fork_exit(). */
 	td2->td_md.md_spinlock_count = 1;
-	td2->td_md.md_saved_cspr = 0;
+	td2->td_md.md_saved_cspr = PSR_SVC32_MODE;;
 #ifdef ARM_TP_ADDRESS
 	td2->td_md.md_tp = *(register_t *)ARM_TP_ADDRESS;
 #else
@@ -218,25 +230,21 @@ cpu_set_syscall_retval(struct thread *td
 void
 cpu_set_upcall(struct thread *td, struct thread *td0)
 {
-	struct trapframe *tf;
-	struct switchframe *sf;
 
 	bcopy(td0->td_frame, td->td_frame, sizeof(struct trapframe));
 	bcopy(td0->td_pcb, td->td_pcb, sizeof(struct pcb));
-	tf = td->td_frame;
-	sf = (struct switchframe *)tf - 1;
-	sf->sf_r4 = (u_int)fork_return;
-	sf->sf_r5 = (u_int)td;
-	sf->sf_pc = (u_int)fork_trampoline;
-	tf->tf_spsr &= ~PSR_C;
-	tf->tf_r0 = 0;
-	td->td_pcb->un_32.pcb32_sp = (u_int)sf;
-	KASSERT((td->td_pcb->un_32.pcb32_sp & 7) == 0,
-	    ("cpu_set_upcall: Incorrect stack alignment"));
+
+	td->td_pcb->pcb_regs.sf_r4 = (register_t)fork_return;
+	td->td_pcb->pcb_regs.sf_r5 = (register_t)td;
+	td->td_pcb->pcb_regs.sf_lr = (register_t)fork_trampoline;
+	td->td_pcb->pcb_regs.sf_sp = STACKALIGN(td->td_frame);
+
+	td->td_frame->tf_spsr &= ~PSR_C;
+	td->td_frame->tf_r0 = 0;
 
 	/* Setup to release spin count in fork_exit(). */
 	td->td_md.md_spinlock_count = 1;
-	td->td_md.md_saved_cspr = 0;
+	td->td_md.md_saved_cspr = PSR_SVC32_MODE;
 }
 
 /*
@@ -250,8 +258,7 @@ cpu_set_upcall_kse(struct thread *td, vo
 {
 	struct trapframe *tf = td->td_frame;
 
-	tf->tf_usr_sp = STACKALIGN((int)stack->ss_sp + stack->ss_size
-	    - sizeof(struct trapframe));
+	tf->tf_usr_sp = STACKALIGN((int)stack->ss_sp + stack->ss_size);
 	tf->tf_pc = (int)entry;
 	tf->tf_r0 = (int)arg;
 	tf->tf_spsr = PSR_USR32_MODE;
@@ -289,9 +296,8 @@ cpu_thread_alloc(struct thread *td)
 	 * placed into the stack pointer which must be 8 byte aligned in
 	 * the ARM EABI.
 	 */
-	td->td_frame = (struct trapframe *)STACKALIGN((u_int)td->td_kstack +
-	    USPACE_SVC_STACK_TOP - sizeof(struct pcb) -
-	    sizeof(struct trapframe));
+	td->td_frame = (struct trapframe *)((caddr_t)td->td_pcb) - 1;
+
 #ifdef __XSCALE__
 #ifndef CPU_XSCALE_CORE3
 	pmap_use_minicache(td->td_kstack, td->td_kstack_pages * PAGE_SIZE);
@@ -318,16 +324,8 @@ cpu_thread_clean(struct thread *td)
 void
 cpu_set_fork_handler(struct thread *td, void (*func)(void *), void *arg)
 {
-	struct switchframe *sf;
-	struct trapframe *tf;
-	
-	tf = td->td_frame;
-	sf = (struct switchframe *)tf - 1;
-	sf->sf_r4 = (u_int)func;
-	sf->sf_r5 = (u_int)arg;
-	td->td_pcb->un_32.pcb32_sp = (u_int)sf;
-	KASSERT((td->td_pcb->un_32.pcb32_sp & 7) == 0,
-	    ("cpu_set_fork_handler: Incorrect stack alignment"));
+	td->td_pcb->pcb_regs.sf_r4 = (register_t)func;	/* function */
+	td->td_pcb->pcb_regs.sf_r5 = (register_t)arg;	/* first arg */
 }
 
 /*

Modified: head/sys/arm/include/db_machdep.h
==============================================================================
--- head/sys/arm/include/db_machdep.h	Wed Dec 24 18:51:25 2014	(r276189)
+++ head/sys/arm/include/db_machdep.h	Wed Dec 24 18:54:31 2014	(r276190)
@@ -38,7 +38,7 @@
 typedef vm_offset_t	db_addr_t;
 typedef int		db_expr_t;
 
-#define	PC_REGS()	((db_addr_t)kdb_thrctx->un_32.pcb32_pc)
+#define	PC_REGS()	((db_addr_t)kdb_thrctx->pcb_regs.sf_pc)
 
 #define	BKPT_INST	(KERNEL_BREAKPOINT)
 #define	BKPT_SIZE	(INSN_SIZE)

Modified: head/sys/arm/include/frame.h
==============================================================================
--- head/sys/arm/include/frame.h	Wed Dec 24 18:51:25 2014	(r276189)
+++ head/sys/arm/include/frame.h	Wed Dec 24 18:54:31 2014	(r276190)
@@ -86,57 +86,16 @@ struct trapframe {
 #define tf_r13 tf_usr_sp
 #define tf_r14 tf_usr_lr
 #define tf_r15 tf_pc
-/*
- *  * Scheduler activations upcall frame.  Pushed onto user stack before
- *   * calling an SA upcall.
- *    */
-
-struct saframe {
-#if 0 /* in registers on entry to upcall */
-	int             sa_type;
-	struct sa_t **  sa_sas;
-	int             sa_events;
-	int             sa_interrupted;
-#endif
-	void *          sa_arg;
-};
 
 /*
- *  * Signal frame.  Pushed onto user stack before calling sigcode.
- *   */
-
-/* the pointers are use in the trampoline code to locate the ucontext */
+ * Signal frame.  Pushed onto user stack before calling sigcode.
+ * The pointers are used in the trampoline code to locate the ucontext.
+ */
 struct sigframe {
-       	siginfo_t       sf_si;          /* actual saved siginfo */
+	siginfo_t       sf_si;          /* actual saved siginfo */
 	ucontext_t      sf_uc;          /* actual saved ucontext */
 };
 
-/*
- * System stack frames.
- */
-
-
-typedef struct irqframe {
-	unsigned int if_spsr;
-	unsigned int if_r0;
-	unsigned int if_r1;
-	unsigned int if_r2;
-	unsigned int if_r3;
-	unsigned int if_r4;
-	unsigned int if_r5;
-	unsigned int if_r6;
-	unsigned int if_r7;
-	unsigned int if_r8;
-	unsigned int if_r9;
-	unsigned int if_r10;
-	unsigned int if_r11;
-	unsigned int if_r12;
-	unsigned int if_usr_sp;
-	unsigned int if_usr_lr;
-	unsigned int if_svc_sp;
-	unsigned int if_svc_lr;
-	unsigned int if_pc;
-} irqframe_t;
 
 /*
  * Switch frame.
@@ -144,16 +103,23 @@ typedef struct irqframe {
  * It is important this is a multiple of 8 bytes so the stack is correctly
  * aligned when we create new threads.
  */
-
-struct switchframe {
-	u_int	pad;	/* Used to pad the struct to a multiple of 8-bytes */
-	u_int	sf_r4;
-	u_int	sf_r5;
-	u_int	sf_r6;
-	u_int	sf_r7;
-	u_int	sf_pc;
+struct switchframe
+{
+        register_t sf_r4;
+        register_t sf_r5;
+        register_t sf_r6;
+        register_t sf_r7;
+        register_t sf_r8;
+        register_t sf_r9;
+        register_t sf_r10;
+        register_t sf_r11;
+        register_t sf_r12;
+        register_t sf_sp;
+        register_t sf_lr;
+        register_t sf_pc;
 };
 
+
 /*
  * Stack frame. Used during stack traces (db_trace.c)
  */

Modified: head/sys/arm/include/pcb.h
==============================================================================
--- head/sys/arm/include/pcb.h	Wed Dec 24 18:51:25 2014	(r276189)
+++ head/sys/arm/include/pcb.h	Wed Dec 24 18:54:31 2014	(r276190)
@@ -39,50 +39,29 @@
 #define	_MACHINE_PCB_H_
 
 #include <machine/fp.h>
+#include <machine/frame.h>
 
 
-struct trapframe;
-
-struct pcb_arm32 {
-	vm_offset_t	pcb32_pagedir;		/* PT hooks */
-	uint32_t *pcb32_pl1vec;		/* PTR to vector_base L1 entry*/
-	uint32_t pcb32_l1vec;			/* Value to stuff on ctx sw */
-	u_int	pcb32_dacr;			/* Domain Access Control Reg */
-	/*
-	 * WARNING!
-	 * cpuswitch.S relies on pcb32_r8 being quad-aligned in struct pcb
-	 * (due to the use of "strd" when compiled for XSCALE)
-	 */
-	u_int	pcb32_r8;			/* used */
-	u_int	pcb32_r9;			/* used */
-	u_int	pcb32_r10;			/* used */
-	u_int	pcb32_r11;			/* used */
-	u_int	pcb32_r12;			/* used */
-	u_int	pcb32_sp;			/* used */
-	u_int	pcb32_lr;
-	u_int	pcb32_pc;
-};
-#define	pcb_pagedir	un_32.pcb32_pagedir
-#define	pcb_pl1vec	un_32.pcb32_pl1vec
-#define	pcb_l1vec	un_32.pcb32_l1vec
-#define	pcb_dacr	un_32.pcb32_dacr
-#define	pcb_cstate	un_32.pcb32_cstate
-
 /*
  * WARNING!
- * See warning for struct pcb_arm32, above, before changing struct pcb!
+ * Keep pcb_regs first for faster access in switch.S
  */
 struct pcb {
+	struct switchframe pcb_regs;		/* CPU state */
 	u_int	pcb_flags;
 #define	PCB_OWNFPU	0x00000001
 #define PCB_NOALIGNFLT	0x00000002
 	caddr_t	pcb_onfault;			/* On fault handler */
-	struct	pcb_arm32 un_32;
+	vm_offset_t	pcb_pagedir;		/* PT hooks */
+	uint32_t *pcb_pl1vec;			/* PTR to vector_base L1 entry*/
+	uint32_t pcb_l1vec;			/* Value to stuff on ctx sw */
+	u_int	pcb_dacr;			/* Domain Access Control Reg */
+
 	struct vfp_state pcb_vfpstate;          /* VP/NEON state */
 	u_int pcb_vfpcpu;                       /* VP/NEON last cpu */
 } __aligned(8); /* 
 		 * We need the PCB to be aligned on 8 bytes, as we may
-		 * access it using ldrd/strd, and some CPUs require it
+		 * access it using ldrd/strd, and ARM ABI require it
 		 * to by aligned on 8 bytes.
 		 */
 



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