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