PERFORCE change 157567 for review
Arnar Mar Sig
antab at FreeBSD.org
Wed Feb 11 12:05:55 PST 2009
http://perforce.freebsd.org/chv.cgi?CH=157567
Change 157567 by antab at 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 */
More information about the p4-projects
mailing list