From 8f4688468b960e1e3d9b12db23ff29195885d48c Mon Sep 17 00:00:00 2001 From: ian Date: Thu, 12 Feb 2015 04:15:55 +0000 Subject: [PATCH] MFC r276187, r276190, r271422: Rename pmap_kenter_temp to pmap_kenter_temporary to be consistent with the other architectures with this function. Eliminate unnecessary references to pte.h internals by using the standard pmap_kenter_temporary() to map pages while dumping. Cleanup up ARM *frame structures. git-svn-id: svn://svn.freebsd.org/base/stable/10@278614 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- gnu/usr.bin/gdb/kgdb/trgt_arm.c | 18 ++--- sys/arm/arm/db_trace.c | 10 +-- sys/arm/arm/dump_machdep.c | 16 ++-- sys/arm/arm/gdb_machdep.c | 24 +++--- sys/arm/arm/genassym.c | 19 +++-- sys/arm/arm/machdep.c | 22 +++--- sys/arm/arm/minidump_machdep.c | 4 +- sys/arm/arm/pmap-v6.c | 2 +- sys/arm/arm/pmap.c | 2 +- sys/arm/arm/stack_machdep.c | 2 +- sys/arm/arm/swtch.S | 128 +++++++++----------------------- sys/arm/arm/trap.c | 2 +- sys/arm/arm/vm_machdep.c | 88 +++++++++++----------- sys/arm/include/db_machdep.h | 2 +- sys/arm/include/frame.h | 72 +++++------------- sys/arm/include/pcb.h | 39 +++------- sys/arm/include/pmap.h | 2 +- 17 files changed, 173 insertions(+), 279 deletions(-) diff --git a/gnu/usr.bin/gdb/kgdb/trgt_arm.c b/gnu/usr.bin/gdb/kgdb/trgt_arm.c index ca18ae369..1bb3f41de 100644 --- a/gnu/usr.bin/gdb/kgdb/trgt_arm.c +++ b/gnu/usr.bin/gdb/kgdb/trgt_arm.c @@ -68,20 +68,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, - ®, 4) != 4) { - warnx("kvm_read: %s", kvm_geterr(kvm)); - break; - } - supply_register(ARM_A1_REGNUM + 4 + i, (char *)®); - } - if (kvm_read(kvm, pcb.un_32.pcb32_sp + 4 * 4, ®, 4) != 4) + if (pcb.pcb_regs.sf_sp != 0) { + if (kvm_read(kvm, pcb.pcb_regs.sf_sp + 4 * 4, ®, 4) != 4) warnx("kvm_read :%s", kvm_geterr(kvm)); else supply_register(ARM_PC_REGNUM, (char *)®); diff --git a/sys/arm/arm/db_trace.c b/sys/arm/arm/db_trace.c index af661f310..388edb935 100644 --- a/sys/arm/arm/db_trace.c +++ b/sys/arm/arm/db_trace.c @@ -603,14 +603,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/dump_machdep.c b/sys/arm/arm/dump_machdep.c index b0e4b1bbf..cdf2e4cf5 100644 --- a/sys/arm/arm/dump_machdep.c +++ b/sys/arm/arm/dump_machdep.c @@ -161,11 +161,13 @@ static int cb_dumpdata(struct md_pa *mdp, int seqnr, void *arg) { struct dumperinfo *di = (struct dumperinfo*)arg; - vm_paddr_t pa; + vm_paddr_t a, pa; + void *va; uint32_t pgs; size_t counter, sz, chunk; - int c, error; + int i, c, error; + va = 0; error = 0; /* catch case in which chunk size is 0 */ counter = 0; pgs = mdp->md_size / PAGE_SIZE; @@ -195,16 +197,14 @@ cb_dumpdata(struct md_pa *mdp, int seqnr, void *arg) printf(" %d", pgs * PAGE_SIZE); counter &= (1<<24) - 1; } - if (pa == (pa & L1_ADDR_BITS)) { - pmap_kenter_section(0, pa & L1_ADDR_BITS, 0); - cpu_tlb_flushID_SE(0); - cpu_cpwait(); + for (i = 0; i < chunk; i++) { + a = pa + i * PAGE_SIZE; + va = pmap_kenter_temporary(trunc_page(a), i); } #ifdef SW_WATCHDOG wdog_kern_pat(WD_LASTVAL); #endif - error = dump_write(di, - (void *)(pa - (pa & L1_ADDR_BITS)),0, dumplo, sz); + error = dump_write(di, va, 0, dumplo, sz); if (error) break; dumplo += sz; diff --git a/sys/arm/arm/gdb_machdep.c b/sys/arm/arm/gdb_machdep.c index 11b9c0d2d..8cc7a198b 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 ab0be4ca1..ce7b88d74 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 22425ff0c..685a0592c 100644 --- a/sys/arm/arm/machdep.c +++ b/sys/arm/arm/machdep.c @@ -376,7 +376,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); @@ -768,14 +768,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/minidump_machdep.c b/sys/arm/arm/minidump_machdep.c index 85ea2827c..13f32428b 100644 --- a/sys/arm/arm/minidump_machdep.c +++ b/sys/arm/arm/minidump_machdep.c @@ -154,7 +154,7 @@ blk_write(struct dumperinfo *di, char *ptr, vm_paddr_t pa, size_t sz) sz -= len; } else { for (i = 0; i < len; i += PAGE_SIZE) - dump_va = pmap_kenter_temp(pa + i, + dump_va = pmap_kenter_temporary(pa + i, (i + fragsz) >> PAGE_SHIFT); fragsz += len; pa += len; @@ -244,7 +244,7 @@ minidumpsys(struct dumperinfo *di) } if (pmap_pde_v(pdp) && pmap_pde_page(pdp)) { /* Set bit for each valid page in this 1MB block */ - addr = pmap_kenter_temp(*pdp & L1_C_ADDR_MASK, 0); + addr = pmap_kenter_temporary(*pdp & L1_C_ADDR_MASK, 0); pt = (pt_entry_t*)(addr + (((uint32_t)*pdp & L1_C_ADDR_MASK) & PAGE_MASK)); for (k = 0; k < 256; k++) { diff --git a/sys/arm/arm/pmap-v6.c b/sys/arm/arm/pmap-v6.c index 3df1c8a24..dc7382f24 100644 --- a/sys/arm/arm/pmap-v6.c +++ b/sys/arm/arm/pmap-v6.c @@ -2371,7 +2371,7 @@ pmap_kenter_section(vm_offset_t va, vm_offset_t pa, int flags) * to be used for panic dumps. */ void * -pmap_kenter_temp(vm_paddr_t pa, int i) +pmap_kenter_temporary(vm_paddr_t pa, int i) { vm_offset_t va; diff --git a/sys/arm/arm/pmap.c b/sys/arm/arm/pmap.c index f4e44d718..f438816da 100644 --- a/sys/arm/arm/pmap.c +++ b/sys/arm/arm/pmap.c @@ -2666,7 +2666,7 @@ pmap_kenter_section(vm_offset_t va, vm_offset_t pa, int flags) * to be used for panic dumps. */ void * -pmap_kenter_temp(vm_paddr_t pa, int i) +pmap_kenter_temporary(vm_paddr_t pa, int i) { vm_offset_t va; diff --git a/sys/arm/arm/stack_machdep.c b/sys/arm/arm/stack_machdep.c index f1708f5bf..9c984a9b4 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 610d57537..e9d6f6159 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 cb589bb6e..6649d8849 100644 --- a/sys/arm/arm/trap.c +++ b/sys/arm/arm/trap.c @@ -565,7 +565,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 72a374de9..9f730d435 100644 --- a/sys/arm/arm/vm_machdep.c +++ b/sys/arm/arm/vm_machdep.c @@ -80,7 +80,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); #ifndef NSFBUFS @@ -130,43 +130,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 @@ -355,25 +367,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; } /* @@ -387,8 +395,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; @@ -426,9 +433,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); @@ -455,16 +461,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 da3b30e4f..741cae999 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 1e6f43a5b..7655d89ca 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 252d94e45..b5ed607fc 100644 --- a/sys/arm/include/pcb.h +++ b/sys/arm/include/pcb.h @@ -39,50 +39,29 @@ #define _MACHINE_PCB_H_ #include +#include -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. */ diff --git a/sys/arm/include/pmap.h b/sys/arm/include/pmap.h index 70c337a9d..3f0b9e984 100644 --- a/sys/arm/include/pmap.h +++ b/sys/arm/include/pmap.h @@ -256,7 +256,7 @@ int pmap_change_attr(vm_offset_t, vm_size_t, int); void pmap_kenter(vm_offset_t va, vm_paddr_t pa); void pmap_kenter_nocache(vm_offset_t va, vm_paddr_t pa); void pmap_kenter_device(vm_offset_t va, vm_paddr_t pa); -void *pmap_kenter_temp(vm_paddr_t pa, int i); +void *pmap_kenter_temporary(vm_paddr_t pa, int i); void pmap_kenter_user(vm_offset_t va, vm_paddr_t pa); vm_paddr_t pmap_kextract(vm_offset_t va); void pmap_kremove(vm_offset_t); -- 2.45.0