PERFORCE change 161759 for review
Arnar Mar Sig
antab at FreeBSD.org
Fri May 8 02:54:02 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=161759
Change 161759 by antab at 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
More information about the p4-projects
mailing list