Date: Fri, 8 May 2009 02:54:00 GMT From: Arnar Mar Sig <antab@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 161759 for review Message-ID: <200905080254.n482s00f043393@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=161759 Change 161759 by antab@antab_farm on 2009/05/08 02:53:14 Rework pcb and context switching, r8-r12 do not have to be preserved and the ldm usage had undefined results Affected files ... .. //depot/projects/avr32/src/sys/avr32/avr32/db_trace.c#6 edit .. //depot/projects/avr32/src/sys/avr32/avr32/locore.S#3 edit .. //depot/projects/avr32/src/sys/avr32/avr32/machdep.c#12 edit .. //depot/projects/avr32/src/sys/avr32/avr32/switch.S#12 edit .. //depot/projects/avr32/src/sys/avr32/avr32/vm_machdep.c#10 edit .. //depot/projects/avr32/src/sys/avr32/include/db_machdep.h#6 edit .. //depot/projects/avr32/src/sys/avr32/include/pcb.h#5 edit Differences ... ==== //depot/projects/avr32/src/sys/avr32/avr32/db_trace.c#6 (text+ko) ==== @@ -79,12 +79,12 @@ struct pcb *ctx; ctx = kdb_thr_ctx(thr); - if (ctx->pcb_regs.regs.pc != 0) { - firstframe.fp = (struct db_frame *)ctx->pcb_regs.regs.r7; - firstframe.lr = ctx->pcb_regs.regs.pc; + if (ctx->pc != 0) { + firstframe.fp = (struct db_frame *)ctx->r7; + firstframe.lr = ctx->pc; frame = &firstframe; } else { - frame = (struct db_frame *)ctx->pcb_regs.regs.r7; + frame = (struct db_frame *)ctx->r7; } db_backtrace(thr, frame, count); ==== //depot/projects/avr32/src/sys/avr32/avr32/locore.S#3 (text+ko) ==== @@ -92,8 +92,8 @@ proc0_stack_ptr: .long proc0_stack_end +.align 4 GLOBAL(proc0_stack) .space KSTACK_SIZE - .align 4 proc0_stack_end: ==== //depot/projects/avr32/src/sys/avr32/avr32/machdep.c#12 (text+ko) ==== @@ -80,6 +80,7 @@ struct pcpu __pcpu; struct pcpu *pcpup = &__pcpu; struct pcb proc0_pcb; +static struct trapframe proc0_tf; extern vm_offset_t proc0_stack; extern uint64_t clock_cpu_frequency; @@ -112,11 +113,10 @@ static void avr32_init_proc0() { - proc_linkup(&proc0, &thread0); + proc_linkup0(&proc0, &thread0); thread0.td_kstack = (vm_offset_t)&proc0_stack; - thread0.td_kstack_pages = KSTACK_PAGES - 1; thread0.td_pcb = &proc0_pcb; - thread0.td_frame = &thread0.td_pcb->pcb_regs; + thread0.td_frame = &proc0_tf; pcpu_init(pcpup, 0, sizeof(struct pcpu)); PCPU_SET(curthread, &thread0); @@ -279,7 +279,16 @@ void makectx(struct trapframe *tf, struct pcb *pcb) { - bcopy(&tf->regs, &pcb->pcb_regs, sizeof(struct trapframe)); + pcb->pc = tf->regs.pc; + pcb->sp = tf->regs.sp; + pcb->r7 = tf->regs.r7; + pcb->r6 = tf->regs.r6; + pcb->r5 = tf->regs.r5; + pcb->r4 = tf->regs.r4; + pcb->r3 = tf->regs.r3; + pcb->r2 = tf->regs.r2; + pcb->r1 = tf->regs.r1; + pcb->r0 = tf->regs.r0; } u_int32_t ==== //depot/projects/avr32/src/sys/avr32/avr32/switch.S#12 (text+ko) ==== @@ -34,21 +34,22 @@ __FBSDID("$FreeBSD: $"); /** - * r11: td - * r10: td frame - * r9: callout + * r7: callout + * r6: td + * r5: td frame */ ENTRY(fork_trampoline) - mov r12, r9 /* Callout is first argument to fork_exit */ - mov r6, r10 /* Save r10 for later use */ + mov r12, r7 + mov r11, r6 + mov r10, r5 call fork_exit /* Call fork_exit */ /* Return to usermode */ - ld.w r9, r6++ /* Load status register */ + ld.w r9, r5++ /* Load status register */ mtsr AT32_SYS_RSR_SUP, r9 /* Return status register */ - ld.w r9, r6++ /* Load program count */ + ld.w r9, r5++ /* Load program count */ mtsr AT32_SYS_RAR_SUP, r9 /* Return address register */ - ldmts r6, r0-r12,sp,lr /* Load rest to user register context */ + ldmts r5, r0-r12,sp,lr /* Load rest to user register context */ frs /* Flush the return stack */ sub pc, -2 /* Flush the pipeline */ @@ -62,9 +63,7 @@ ENTRY(savectx) mustr r11 /* Get status register */ st.w r12++, r11 /* Store status register */ - sub r12, -4 /* Skip PC */ - stm r12, r0-r12,sp,lr /* Store rest */ - mov lr, r8 + stm r12, r0-r7,sp,lr /* Store rest */ retal sp /* return 0 */ END(savectx) @@ -77,48 +76,45 @@ ENTRY(restorectx) /* * Lock kernel stack in tlb - * r10: KStack * r9: Pointer to kernel PTE - * r8: Iterator + * r8: Address of PCB * r7: * Frame Pointer not used * r6: PTE * r5: MMUCR * r4: Misc * r3: tlbehi save - * r2: Address of PCB - * r1: Saved SR + * r2: Iterator + * r1: KStack */ - mov r1, r10 - /* Load PCB and PD address */ - ld.w r2, r12[TD_PCB] + ld.w r8, r12[TD_PCB] /* Add ASID and V flag to kstack value */ - ld.w r10, r12[TD_KSTACK] + ld.w r1, r12[TD_KSTACK] ld.w r4, r11[PMAP_ASID] - add r10, r4 - sbr r10, AT32_SYS_TLBEHI_V + add r1, r4 + sbr r1, AT32_SYS_TLBEHI_V ld.w r11, r11[PMAP_PD] /* Point r11 to page directory */ /* Check if stack is in P3 */ - mov r9, r10 + mov r9, r1 lsr r9, 29 cp r9, 0x6 brne restore_finish sub r9, r12, -(TD_KPTE) /* Add KPTE offset to thread struct pointer */ - mov r8, KSTACK_PAGES /* Iterate thru thru all kstack pages */ + mov r2, KSTACK_PAGES /* Iterate thru thru all kstack pages */ mfsr r3, AT32_SYS_TLBEHI -1: sub r8, 1 /* Decrease iterator */ +1: sub r2, 1 /* Decrease iterator */ mtsr AT32_SYS_TLBEHI, r3 /* Set TLBEHI to old to load pte */ nop /* Wait for mtsr */ ld.w r6, r9++ /* Load PTE */ /* Search for entry in tlb and invalidate it if its there */ - mtsr AT32_SYS_TLBEHI, r10 /* Set TLBEHI to kstack tlbehi */ + mtsr AT32_SYS_TLBEHI, r1 /* Set TLBEHI to kstack tlbehi */ nop /* Wait for mtsr */ tlbs /* Search for entry */ sub pc, -2 /* Flush pipeline */ @@ -135,10 +131,10 @@ sub pc, -2 /* Flush pipline */ 2: - mtsr AT32_SYS_TLBEHI, r10 /* Set TLBEHI to kstack tlbehi */ + mtsr AT32_SYS_TLBEHI, r1 /* Set TLBEHI to kstack tlbehi */ mtsr AT32_SYS_TLBELO, r6 /* Set TLBELO to PTE */ mfsr r5, AT32_SYS_MMUCR /* Get MMUCR */ - bfins r5, r8, AT32_SYS_MMUCR_DRP, AT32_SYS_MMUCR_DRP_SIZE /* Set entry to insert to */ + bfins r5, r2, AT32_SYS_MMUCR_DRP, AT32_SYS_MMUCR_DRP_SIZE /* Set entry to insert to */ mtsr AT32_SYS_MMUCR, r5 /* Set MMUCR */ nop /* Wait for mtsr to leave the pipeline */ @@ -146,19 +142,20 @@ sub pc, -2 /* Flush pipeline */ /* Are we done? */ - sub r10, -4096 /* Add PAGE_SIZE to kstack address */ - cp.w r8, 0 /* Done? */ + sub r1, -4096 /* Add PAGE_SIZE to kstack address */ + cp.w r2, 0 /* Done? */ brne 1b /* Or not */ restore_finish: mtsr AT32_SYS_PTBR, r11 /* Point lookups to new pmap */ - mtsr AT32_SYS_TLBEHI, r10 /* Set TLBEHI (ASID for new td) */ + mtsr AT32_SYS_TLBEHI, r1 /* Set TLBEHI (ASID for new td) */ nop /* Wait for mtsr */ - mtsr AT32_SYS_SR, r1 /* Restore saved SR */ - ld.w r4, r2++ /* Load status register */ - musfr r4 /* Set status register */ - sub r2, -4 /* Skip PC */ - ldm r2, r0-r12,sp,lr /* Load rest */ + + ld.w r9, r8++ /* Load status register */ + ldm r8, r0-r7,sp,lr /* Load rest */ + + mtsr AT32_SYS_SR, r10 /* Restore saved SR */ + musfr r9 /* Set status register */ frs /* Flush the return stack */ sub pc, -2 /* Flush the pipeline */ ==== //depot/projects/avr32/src/sys/avr32/avr32/vm_machdep.c#10 (text+ko) ==== @@ -65,15 +65,30 @@ return; } - /* Copy p1's pcb to p2 */ + /* Point the pcb and td_frame to the top of the stack */ + td2->td_pcb = (struct pcb *)(td2->td_kstack + td2->td_kstack_pages + * PAGE_SIZE) - 1; + td2->td_frame = (struct trapframe *)td2->td_pcb - 1; + + + /* + * Copy p1's pcb to p2 and set kernel registers for trampoline + */ bcopy(td1->td_pcb, td2->td_pcb, sizeof(struct pcb)); + td2->td_pcb->r7 = (register_t)fork_return; + td2->td_pcb->r6 = (register_t)td2; + td2->td_pcb->r5 = (register_t)td2->td_frame; + td2->td_pcb->sp = (register_t)td2->td_frame - sizeof(void *); + td2->td_pcb->pc = (register_t)fork_trampoline; + + /* + * Copy p1's td_frame to p2 and set registers as if from a syscall + */ + bcopy(td1->td_frame, td2->td_frame, sizeof(struct trapframe)); + td2->td_frame->regs.r11 = 0; + td2->td_frame->regs.r12 = 0; + td2->td_frame->regs.sr &= ~bit_mask(SYS, SR, C); - /* Sets regs (need to look into this better later on) */ - td2->td_pcb->pcb_regs.regs.r9 = (register_t)fork_return; - td2->td_pcb->pcb_regs.regs.r11 = (register_t)td2; - td2->td_pcb->pcb_regs.regs.r10 = (register_t)td2->td_frame; - td2->td_pcb->pcb_regs.regs.sp = (register_t)td2->td_frame - sizeof(void *); - td2->td_pcb->pcb_regs.regs.lr = (register_t)fork_trampoline; td2->td_md.md_saved_intr = 0; /* TODO: probably not right. */ td2->td_md.md_spinlock_count = 1; @@ -88,8 +103,8 @@ void cpu_set_fork_handler(struct thread *td, void (*func) __P((void *)), void *arg) { - td->td_pcb->pcb_regs.regs.r9 = (register_t)func; - td->td_pcb->pcb_regs.regs.r11 = (register_t)arg; + td->td_pcb->r7 = (register_t)func; + td->td_pcb->r6 = (register_t)arg; } void @@ -135,7 +150,7 @@ td->td_pcb = (struct pcb *)(td->td_kstack + td->td_kstack_pages * PAGE_SIZE) - 1; - td->td_frame = &td->td_pcb->pcb_regs; + td->td_frame = (struct trapframe *)td->td_pcb - 1; pte = pmap_pte(kernel_pmap, td->td_kstack); if (pte == NULL) { @@ -157,15 +172,16 @@ void cpu_set_upcall(struct thread *td, struct thread *td0) { - /* Copy td's pcb to td0 */ + /* Copy td's pcb and frame */ bcopy(td0->td_pcb, td->td_pcb, sizeof(struct pcb)); + bcopy(td0->td_frame, td->td_frame, sizeof(struct trapframe)); /* Sets regs (need to look into this better later on) */ - td->td_pcb->pcb_regs.regs.r9 = (register_t)fork_return; - td->td_pcb->pcb_regs.regs.r11 = (register_t)td; - td->td_pcb->pcb_regs.regs.r10 = (register_t)td->td_frame; - td->td_pcb->pcb_regs.regs.sp = (register_t)td->td_frame - sizeof(void *); - td->td_pcb->pcb_regs.regs.lr = (register_t)fork_trampoline; + td->td_pcb->r7 = (register_t)fork_return; + td->td_pcb->r6 = (register_t)td; + td->td_pcb->r5 = (register_t)td->td_frame; + td->td_pcb->sp = (register_t)td->td_frame - sizeof(void *); + td->td_pcb->pc = (register_t)fork_trampoline; td->td_md.md_saved_intr = 0; /* TODO: probably not right. */ td->td_md.md_spinlock_count = 1; ==== //depot/projects/avr32/src/sys/avr32/include/db_machdep.h#6 (text+ko) ==== @@ -37,7 +37,7 @@ typedef vm_offset_t db_addr_t; typedef int db_expr_t; -#define PC_REGS() ((db_addr_t)kdb_thrctx->pcb_regs.regs.pc) +#define PC_REGS() ((db_addr_t)kdb_thrctx->pc) #define BKPT_INST (0xD673) #define BKPT_SIZE (2) ==== //depot/projects/avr32/src/sys/avr32/include/pcb.h#5 (text+ko) ==== @@ -35,7 +35,17 @@ * AVR32 process control block */ struct pcb { - struct trapframe pcb_regs; /* saved CPU and registers */ + register_t sr; /* Status register */ + register_t pc; /* Program counter */ + register_t sp; + register_t r7; + register_t r6; + register_t r5; + register_t r4; + register_t r3; + register_t r2; + register_t r1; + register_t r0; }; #ifdef _KERNEL
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905080254.n482s00f043393>