Skip site navigation (1)Skip section navigation (2)
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>