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>
This commit is contained in:
ian 2014-12-24 18:54:31 +00:00
parent 3c6d556e12
commit bd1ca6b379
12 changed files with 160 additions and 266 deletions

View File

@ -72,20 +72,12 @@ kgdb_trgt_fetch_registers(int regno __unused)
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);
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.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)
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);

View File

@ -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();

View File

@ -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);
}
}

View File

@ -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));

View File

@ -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;
}
/*

View File

@ -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);
}

View File

@ -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)

View File

@ -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

View File

@ -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 */
}
/*

View File

@ -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)

View File

@ -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)
*/

View File

@ -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.
*/