svn commit: r268334 - in projects/arm64/sys/arm64: arm64 include

Andrew Turner andrew at FreeBSD.org
Sun Jul 6 22:09:51 UTC 2014


Author: andrew
Date: Sun Jul  6 22:09:50 2014
New Revision: 268334
URL: http://svnweb.freebsd.org/changeset/base/268334

Log:
  Implement cpu_switch. It's missing things like cache flushing and SMP
  support, however neigher of these are needed at this point.

Modified:
  projects/arm64/sys/arm64/arm64/swtch.S
  projects/arm64/sys/arm64/arm64/vm_machdep.c
  projects/arm64/sys/arm64/include/pcb.h

Modified: projects/arm64/sys/arm64/arm64/swtch.S
==============================================================================
--- projects/arm64/sys/arm64/arm64/swtch.S	Sun Jul  6 22:08:06 2014	(r268333)
+++ projects/arm64/sys/arm64/arm64/swtch.S	Sun Jul  6 22:09:50 2014	(r268334)
@@ -31,6 +31,10 @@
 
 __FBSDID("$FreeBSD$");
 
+.Lcurpcpu:
+	.quad	_C_LABEL(__pcpu)
+	.quad	PCPU_SIZE
+
 /*
  * void cpu_throw(struct thread *old, struct thread *new)
  */
@@ -44,14 +48,98 @@ END(cpu_throw)
 
 /*
  * void cpu_switch(struct thread *old, struct thread *new, struct mtx *mtx)
+ *
+ * x0 = old
+ * x1 = new
+ * x2 = mtx
+ * x3 to x7, x16 and x17 are caller saved
  */
 ENTRY(cpu_switch)
-	adr	x0, .Lcpu_switch_panic_str
-	bl	_C_LABEL(panic)
+#ifdef SMP
+#error cpu_switch needs to be ported to support SMP
+#endif
+
+	/* Load the PCPU area */
+	/* TODO: Adjust for the core we are on */
+	ldr	x3, .Lcurpcpu
+
+	/* Store the new curthread */
+	msr	tpidr_el1, x1
+	/* And the new pcb */
+	ldr	x4, [x1, #TD_PCB]
+	str	x4, [x3, #PC_CURPCB]
+
+	/*
+	 * Save the old context.
+	 */
+	ldr	x4, [x0, #TD_PCB]
+
+	/* Store the callee-saved registers */
+	stp	x8, x9, [x4, #PCB_REGS + 8 * 8]
+	stp	x10, x11, [x4, #PCB_REGS + 10 * 8]
+	stp	x12, x13, [x4, #PCB_REGS + 12 * 8]
+	stp	x14, x15, [x4, #PCB_REGS + 14 * 8]
+	stp	x16, x17, [x4, #PCB_REGS + 16 * 8]
+	stp	x18, x19, [x4, #PCB_REGS + 18 * 8]
+	stp	x20, x21, [x4, #PCB_REGS + 20 * 8]
+	stp	x22, x23, [x4, #PCB_REGS + 22 * 8]
+	stp	x24, x25, [x4, #PCB_REGS + 24 * 8]
+	stp	x26, x27, [x4, #PCB_REGS + 26 * 8]
+	stp	x28, x29, [x4, #PCB_REGS + 28 * 8]
+	str	x30, [x4, #PCB_REGS + 30 * 8]
+	/* And the old stack pointer */
+	mov	x5, sp
+	str	x5, [x4, #PCB_SP]
+
+	/* TODO: Save/restore the tls thread pointer */
+
+	/*
+	 * Restore the saved context.
+	 */
+	ldr	x4, [x1, #TD_PCB]
+
+	/*
+	 * TODO: We may need to flush the cache here if switching
+	 * to a user process.
+	 */
+
+	/* Release the old thread */
+	str	x2, [x0, #TD_LOCK]
+#if defined(SCHED_ULE) && defined(SMP)
+#error We may need to wait for the lock here
+#endif
+
+	/* Restore the registers */
+	ldr	x5, [x4, #PCB_SP]
+	mov	sp, x5
+	ldp	x8, x9, [x4, #PCB_REGS + 8 * 8]
+	ldp	x10, x11, [x4, #PCB_REGS + 10 * 8]
+	ldp	x12, x13, [x4, #PCB_REGS + 12 * 8]
+	ldp	x14, x15, [x4, #PCB_REGS + 14 * 8]
+	ldp	x16, x17, [x4, #PCB_REGS + 16 * 8]
+	ldp	x18, x19, [x4, #PCB_REGS + 18 * 8]
+	ldp	x20, x21, [x4, #PCB_REGS + 20 * 8]
+	ldp	x22, x23, [x4, #PCB_REGS + 22 * 8]
+	ldp	x24, x25, [x4, #PCB_REGS + 24 * 8]
+	ldp	x26, x27, [x4, #PCB_REGS + 26 * 8]
+	ldp	x28, x29, [x4, #PCB_REGS + 28 * 8]
+	ldr	x30, [x4, #PCB_REGS + 30 * 8]
+
+	str	xzr, [x4, #PCB_REGS + 18 * 8]
 	ret
 .Lcpu_switch_panic_str:
-	.asciz "cpu_switch\0"
-END(cpu_throw)
+	.asciz "cpu_switch: %p\0"
+END(cpu_switch)
+
+ENTRY(fork_trampoline)
+	mov	x0, x8
+	mov	x1, x9
+	mov	x2, sp
+	bl	_C_LABEL(fork_exit)
+
+	brk 1
+	
+END(fork_trampoline)
 
 ENTRY(savectx)
 	adr	x0, .Lsavectx_panic_str

Modified: projects/arm64/sys/arm64/arm64/vm_machdep.c
==============================================================================
--- projects/arm64/sys/arm64/arm64/vm_machdep.c	Sun Jul  6 22:08:06 2014	(r268333)
+++ projects/arm64/sys/arm64/arm64/vm_machdep.c	Sun Jul  6 22:09:50 2014	(r268334)
@@ -64,9 +64,14 @@ cpu_fork(struct thread *td1, struct proc
 	bcopy(td1->td_pcb, pcb2, sizeof(*pcb2));
 
 	/* Set the return value registers for fork() */
-	td1->td_frame->tf_x[0] = 0;
-
-	printf("TODO: cpu_fork");
+	td1->td_pcb->pcb_x[8] = (uintptr_t)fork_return;
+	td1->td_pcb->pcb_x[9] = (uintptr_t)td2;
+	td1->td_pcb->pcb_x[PCB_LR] = (uintptr_t)fork_trampoline;
+	td1->td_pcb->pcb_sp = (uintptr_t)td1->td_frame;
+
+	/* Setup to release spin count in fork_exit(). */
+	td1->td_md.md_spinlock_count = 1;
+	td1->td_md.md_saved_daif = 0;
 }
 
 void
@@ -103,8 +108,17 @@ cpu_set_syscall_retval(struct thread *td
 void
 cpu_set_upcall(struct thread *td, struct thread *td0)
 {
+	bcopy(td0->td_frame, td->td_frame, sizeof(struct trapframe));
+	bcopy(td0->td_pcb, td->td_pcb, sizeof(struct pcb));
 
-	panic("cpu_set_upcall");
+	td->td_pcb->pcb_x[8] = (uintptr_t)fork_return;
+	td->td_pcb->pcb_x[9] = (uintptr_t)td;
+	td->td_pcb->pcb_x[PCB_LR] = (uintptr_t)fork_trampoline;
+	td->td_pcb->pcb_sp = (uintptr_t)td->td_frame;
+
+	/* Setup to release spin count in fork_exit(). */
+	td->td_md.md_spinlock_count = 1;
+	td->td_md.md_saved_daif = 0;
 }
 
 /*
@@ -162,7 +176,10 @@ void
 cpu_set_fork_handler(struct thread *td, void (*func)(void *), void *arg)
 {
 
-	panic("cpu_set_fork_handler");
+	td->td_pcb->pcb_x[8] = (uintptr_t)func;
+	td->td_pcb->pcb_x[9] = (uintptr_t)arg;
+	td->td_pcb->pcb_x[PCB_LR] = (uintptr_t)fork_trampoline;
+	td->td_pcb->pcb_sp = (uintptr_t)td->td_frame;
 }
 
 void

Modified: projects/arm64/sys/arm64/include/pcb.h
==============================================================================
--- projects/arm64/sys/arm64/include/pcb.h	Sun Jul  6 22:08:06 2014	(r268333)
+++ projects/arm64/sys/arm64/include/pcb.h	Sun Jul  6 22:09:50 2014	(r268334)
@@ -33,10 +33,10 @@
 
 struct trapframe;
 
+#define	PCB_LR		30
 struct pcb {
 	uint64_t	pcb_x[31];
 	uint64_t	pcb_sp;
-	uint64_t	pcb_pc;
 } __aligned(64);
 
 #ifdef _KERNEL


More information about the svn-src-projects mailing list