summaryrefslogtreecommitdiffstats
path: root/sys/arm
diff options
context:
space:
mode:
authorian <ian@FreeBSD.org>2014-12-24 18:54:31 +0000
committerian <ian@FreeBSD.org>2014-12-24 18:54:31 +0000
commitbd1ca6b379a2ae02c2df7950a43c483498c0b73f (patch)
tree6a728a706cb7fe2d6b35a18dd216908ce7391af7 /sys/arm
parent3c6d556e1216aee1059f9044d4c3f3f8456cdca2 (diff)
downloadFreeBSD-src-bd1ca6b379a2ae02c2df7950a43c483498c0b73f.zip
FreeBSD-src-bd1ca6b379a2ae02c2df7950a43c483498c0b73f.tar.gz
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>
Diffstat (limited to 'sys/arm')
-rw-r--r--sys/arm/arm/db_trace.c10
-rw-r--r--sys/arm/arm/gdb_machdep.c24
-rw-r--r--sys/arm/arm/genassym.c19
-rw-r--r--sys/arm/arm/machdep.c22
-rw-r--r--sys/arm/arm/stack_machdep.c2
-rw-r--r--sys/arm/arm/swtch.S128
-rw-r--r--sys/arm/arm/trap.c2
-rw-r--r--sys/arm/arm/vm_machdep.c88
-rw-r--r--sys/arm/include/db_machdep.h2
-rw-r--r--sys/arm/include/frame.h72
-rw-r--r--sys/arm/include/pcb.h39
11 files changed, 155 insertions, 253 deletions
diff --git a/sys/arm/arm/db_trace.c b/sys/arm/arm/db_trace.c
index 0f06486..04ab565 100644
--- a/sys/arm/arm/db_trace.c
+++ b/sys/arm/arm/db_trace.c
@@ -609,14 +609,14 @@ db_trace_thread(struct thread *thr, int count)
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();
diff --git a/sys/arm/arm/gdb_machdep.c b/sys/arm/arm/gdb_machdep.c
index 11b9c0d..8cc7a19 100644
--- a/sys/arm/arm/gdb_machdep.c
+++ b/sys/arm/arm/gdb_machdep.c
@@ -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);
}
}
diff --git a/sys/arm/arm/genassym.c b/sys/arm/arm/genassym.c
index ab0be4c..ce7b88d 100644
--- a/sys/arm/arm/genassym.c
+++ b/sys/arm/arm/genassym.c
@@ -63,13 +63,18 @@ ASSYM(PCB_FLAGS, offsetof(struct pcb, pcb_flags));
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));
diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c
index 341ea4a..f3e75d5 100644
--- a/sys/arm/arm/machdep.c
+++ b/sys/arm/arm/machdep.c
@@ -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;
}
/*
diff --git a/sys/arm/arm/stack_machdep.c b/sys/arm/arm/stack_machdep.c
index f1708f5..9c984a9 100644
--- a/sys/arm/arm/stack_machdep.c
+++ b/sys/arm/arm/stack_machdep.c
@@ -76,7 +76,7 @@ stack_save_td(struct stack *st, struct thread *td)
* 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);
}
diff --git a/sys/arm/arm/swtch.S b/sys/arm/arm/swtch.S
index 610d575..e9d6f61 100644
--- a/sys/arm/arm/swtch.S
+++ b/sys/arm/arm/swtch.S
@@ -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)
diff --git a/sys/arm/arm/trap.c b/sys/arm/arm/trap.c
index ec14feb..eaabf4f 100644
--- a/sys/arm/arm/trap.c
+++ b/sys/arm/arm/trap.c
@@ -545,7 +545,7 @@ dab_buserr(struct trapframe *tf, u_int fsr, u_int far, struct thread *td,
* 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
diff --git a/sys/arm/arm/vm_machdep.c b/sys/arm/arm/vm_machdep.c
index 7758a22..42587f5 100644
--- a/sys/arm/arm/vm_machdep.c
+++ b/sys/arm/arm/vm_machdep.c
@@ -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, register struct proc *p2,
{
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, int error)
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, void (*entry)(void *), void *arg,
{
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 */
}
/*
diff --git a/sys/arm/include/db_machdep.h b/sys/arm/include/db_machdep.h
index da3b30e..741cae9 100644
--- a/sys/arm/include/db_machdep.h
+++ b/sys/arm/include/db_machdep.h
@@ -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)
diff --git a/sys/arm/include/frame.h b/sys/arm/include/frame.h
index 1e6f43a..7655d89 100644
--- a/sys/arm/include/frame.h
+++ b/sys/arm/include/frame.h
@@ -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)
*/
diff --git a/sys/arm/include/pcb.h b/sys/arm/include/pcb.h
index 252d94e..b5ed607 100644
--- a/sys/arm/include/pcb.h
+++ b/sys/arm/include/pcb.h
@@ -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.
*/
OpenPOWER on IntegriCloud