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, - ®, 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) + 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, ®, 4) != 4) warnx("kvm_read :%s", kvm_geterr(kvm)); else supply_register(ARM_PC_REGNUM, (char *)®); 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>