Date: Wed, 11 Feb 2009 20:05:53 GMT From: Arnar Mar Sig <antab@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 157567 for review Message-ID: <200902112005.n1BK5r9Y088729@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=157567 Change 157567 by antab@antab_farm on 2009/02/11 20:05:41 Misc changes to get cpu_switch() working, still does not work. Affected files ... .. //depot/projects/avr32/src/share/man/man9/mi_switch.9#2 edit .. //depot/projects/avr32/src/sys/avr32/avr32/db_interface.c#3 edit .. //depot/projects/avr32/src/sys/avr32/avr32/genassym.c#2 edit .. //depot/projects/avr32/src/sys/avr32/avr32/machdep.c#5 edit .. //depot/projects/avr32/src/sys/avr32/avr32/pm_machdep.c#4 edit .. //depot/projects/avr32/src/sys/avr32/avr32/switch.S#2 edit .. //depot/projects/avr32/src/sys/avr32/avr32/trap.c#3 edit .. //depot/projects/avr32/src/sys/avr32/avr32/vm_machdep.c#4 edit .. //depot/projects/avr32/src/sys/avr32/conf/NGW100#5 edit .. //depot/projects/avr32/src/sys/avr32/include/pcb.h#3 edit .. //depot/projects/avr32/src/sys/avr32/include/reg.h#4 edit Differences ... ==== //depot/projects/avr32/src/share/man/man9/mi_switch.9#2 (text+ko) ==== @@ -48,11 +48,11 @@ .In sys/param.h .In sys/proc.h .Ft void -.Fn mi_switch "void" +.Fn mi_switch "int flags" "struct thread *newtd" .Ft void -.Fn cpu_switch "void" +.Fn cpu_switch "struct thread *old" "struct thread *new" "struct mtx *lock" .Ft void -.Fn cpu_throw "void" +.Fn cpu_throw "struct thread *old" "struct thread *new" .Sh DESCRIPTION The .Fn mi_switch @@ -132,12 +132,8 @@ which will perform the actual thread context switch. .Pp .Fn cpu_switch -first saves the context of the current thread. -Next, it calls -.Fn choosethread -to determine which thread to run next. -Finally, it reads in the saved context of the new thread and starts to -execute the new thread. +first saves the context of the old thread, then it reads in the saved +context of the new thread and starts to execute the new thread. .Pp .Fn cpu_throw is similar to ==== //depot/projects/avr32/src/sys/avr32/avr32/db_interface.c#3 (text+ko) ==== @@ -58,13 +58,24 @@ static db_varfcn_t db_frame; #define DB_OFFSET(x) (db_expr_t *)(offsetof(struct trapframe, regs) + offsetof(struct reg, x)) -#define DB_OFFSET_REG(x, r) (db_expr_t *)(offsetof(struct trapframe, regs) + offsetof(struct reg, x) + (r * sizeof(int))) struct db_variable db_regs[] = { - { "r0", DB_OFFSET_REG(r, 0), db_frame }, - { "sp", DB_OFFSET(sp), db_frame }, - { "lr", DB_OFFSET(lr), db_frame }, - { "pc", DB_OFFSET(pc), db_frame }, - { "sr", DB_OFFSET(sr), db_frame }, + { "r0", DB_OFFSET(r0), db_frame }, + { "r1", DB_OFFSET(r1), db_frame }, + { "r2", DB_OFFSET(r2), db_frame }, + { "r3", DB_OFFSET(r3), db_frame }, + { "r4", DB_OFFSET(r4), db_frame }, + { "r5", DB_OFFSET(r5), db_frame }, + { "r6", DB_OFFSET(r6), db_frame }, + { "r7", DB_OFFSET(r7), db_frame }, + { "r8", DB_OFFSET(r8), db_frame }, + { "r9", DB_OFFSET(r9), db_frame }, + { "r10", DB_OFFSET(r10), db_frame }, + { "r11", DB_OFFSET(r11), db_frame }, + { "r12", DB_OFFSET(r12), db_frame }, + { "sp", DB_OFFSET(sp), db_frame }, + { "lr", DB_OFFSET(lr), db_frame }, + { "pc", DB_OFFSET(pc), db_frame }, + { "sr", DB_OFFSET(sr), db_frame }, }; struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]); ==== //depot/projects/avr32/src/sys/avr32/avr32/genassym.c#2 (text+ko) ==== @@ -35,5 +35,8 @@ #include <sys/vmmeter.h> #include <vm/vm.h> #include <vm/pmap.h> +#include <machine/frame.h> ASSYM(P_VMSPACE, offsetof(struct proc, p_vmspace)); +ASSYM(TD_PCB, offsetof(struct thread, td_pcb)); +ASSYM(TD_PCB_SIZE, sizeof(struct trapframe)); ==== //depot/projects/avr32/src/sys/avr32/avr32/machdep.c#5 (text+ko) ==== @@ -269,14 +269,6 @@ printf("Kernel dumps not implemented on this architecture\n"); } - -int -savectx(struct pcb *pcb) -{ - avr32_impl(); - return (0); -} - void makectx(struct trapframe *tf, struct pcb *pcb) { ==== //depot/projects/avr32/src/sys/avr32/avr32/pm_machdep.c#4 (text+ko) ==== @@ -78,10 +78,6 @@ return (0); } -void cpu_switch(struct thread *td, struct thread *newtd, struct mtx *lock) { - avr32_impl(); -} - /* * System call to cleanup state after a signal * has been taken. Reset signal mask and ==== //depot/projects/avr32/src/sys/avr32/avr32/switch.S#2 (text+ko) ==== @@ -26,12 +26,45 @@ */ #include <machine/asm.h> +#include <machine/reg.h> #include <machine/reg_sys.h> #include "assym.s" __FBSDID("$FreeBSD: $"); ENTRY(fork_trampoline) + breakpoint sub r12, pc, (. - 2f) bral panic 2: .asciz "fork_trampoline needed\n" + + +/** + * r12: Pointer to where to save context + */ +ENTRY(savectx) + mustr r11 # Get status register + st.w r12++, r11 # Store status register + sub r12, -4 # Skip PC + stm r12, r0-lr # Store rest + mov lr, r8 + retal sp # return 0 + +/** + * r12: Pointer to where to restore context from + */ +ENTRY(restorectx) + ld.w r11, r12++ # Load status register + musfr r11 # Set status register + sub r12, -4 # Skip PC + ldm r12, r0-lr # Load rest + + frs # Flush the return stack + sub pc, -2 # Flush the pipeline + + # everything looks good in gdb here, but when retal is executed something + # freaky happens and everything is lost + breakpoint + + retal pc # return 1 + ==== //depot/projects/avr32/src/sys/avr32/avr32/trap.c#3 (text+ko) ==== @@ -61,13 +61,15 @@ #include <machine/reg.h> #include <machine/reg_sys.h> -static void +void trapframe_dump(struct trapframe *frame) { + register_t *reg; int i; for (i = 0; i <= 12; i++) { - printf("r%-2d = %08x ", i, frame->regs.r[i]); + reg = (register_t *)((size_t)&frame->regs.r0 - (i * sizeof(register_t))); + printf("r%-2d = %08x ", i, *reg); if (!((i+1) % 4)) { printf("\n"); } ==== //depot/projects/avr32/src/sys/avr32/avr32/vm_machdep.c#4 (text+ko) ==== @@ -67,11 +67,11 @@ bcopy(td1->td_pcb, td2->td_pcb, sizeof(struct pcb)); /* Sets regs (need to look into this better later on) */ - td2->td_pcb->pcb_regs.regs.r[10] = (register_t)fork_return; - td2->td_pcb->pcb_regs.regs.r[11] = (register_t)td2; - td2->td_pcb->pcb_regs.regs.r[12] = (register_t)td2->td_frame; - // TODO: STACK POINTER - td2->td_pcb->pcb_regs.regs.pc = (register_t)fork_trampoline; + td2->td_pcb->pcb_regs.regs.r10 = (register_t)fork_return; + td2->td_pcb->pcb_regs.regs.r11 = (register_t)td2; + td2->td_pcb->pcb_regs.regs.r12 = (register_t)td2->td_frame; + td2->td_pcb->pcb_regs.regs.sp = (register_t)td2->td_frame - sizeof(struct trapframe); + 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; @@ -86,8 +86,8 @@ void cpu_set_fork_handler(struct thread *td, void (*func) __P((void *)), void *arg) { - td->td_pcb->pcb_regs.regs.r[10] = (register_t)func; - td->td_pcb->pcb_regs.regs.r[11] = (register_t)arg; + td->td_pcb->pcb_regs.regs.r10 = (register_t)func; + td->td_pcb->pcb_regs.regs.r11 = (register_t)arg; } void @@ -147,10 +147,10 @@ bcopy(td0->td_pcb, td->td_pcb, sizeof(struct pcb)); /* Sets regs (need to look into this better later on) */ - td->td_pcb->pcb_regs.regs.r[10] = (register_t)fork_return; - td->td_pcb->pcb_regs.regs.r[11] = (register_t)td; - td->td_pcb->pcb_regs.regs.r[12] = (register_t)td->td_frame; - // TODO: STACK POINTER + td->td_pcb->pcb_regs.regs.r10 = (register_t)fork_return; + td->td_pcb->pcb_regs.regs.r11 = (register_t)td; + td->td_pcb->pcb_regs.regs.r12 = (register_t)td->td_frame; + td->td_pcb->pcb_regs.regs.sp = (register_t)td->td_frame - sizeof(struct trapframe); td->td_pcb->pcb_regs.regs.pc = (register_t)fork_trampoline; td->td_md.md_saved_intr = 0; /* TODO: probably not right. */ @@ -190,3 +190,24 @@ { avr32_impl(); } + +void +cpu_switch(struct thread *old, struct thread *new, struct mtx *mtx) +{ + struct pcb *oldpcb, *newpcb; + + oldpcb = old->td_pcb; + if (!savectx(oldpcb)) { + trapframe_dump(oldpcb); + avr32_debug("in from savectx\n"); + old->td_lock = mtx; + newpcb = new->td_pcb; + PCPU_SET(curthread, new); + trapframe_dump(newpcb); + restorectx(newpcb); + /* We should not get here. */ + panic("cpu_switch: restorectx() returned"); + } + panic("end of cpu_switch, return from another thread?"); +} + ==== //depot/projects/avr32/src/sys/avr32/conf/NGW100#5 (text+ko) ==== @@ -12,9 +12,9 @@ makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols #options VERBOSE_SYSINIT -#options DDB +options DDB options KDB -#options GDB +options GDB options SCHED_4BSD #4BSD scheduler #options INET #InterNETworking ==== //depot/projects/avr32/src/sys/avr32/include/pcb.h#3 (text+ko) ==== @@ -43,6 +43,8 @@ void makectx(struct trapframe *, struct pcb *); int savectx(struct pcb *); +void restorectx(struct pcb *); + #endif #endif /* !_MACHINE_PCB_H_ */ ==== //depot/projects/avr32/src/sys/avr32/include/reg.h#4 (text+ko) ==== @@ -3,12 +3,25 @@ #ifndef MACHINE_REG_H #define MACHINE_REG_H +#ifndef LOCORE struct reg { - register_t sr; // Status register - register_t pc; // Program counter - register_t lr; - register_t sp; - register_t r[13]; + register_t sr; /* Status register */ + register_t pc; /* Program counter */ + register_t lr; + register_t sp; + register_t r12; + register_t r11; + register_t r10; + register_t r9; + register_t r8; + register_t r7; + register_t r6; + register_t r5; + register_t r4; + register_t r3; + register_t r2; + register_t r1; + register_t r0; }; struct fpreg { @@ -61,8 +74,7 @@ static inline void __raw_write(volatile void *addr, uint32_t value) { *(volatile uint32_t *)addr = value; } - - +#endif #endif #endif /* !MACHINE_REG_H */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200902112005.n1BK5r9Y088729>