summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/amd64/amd64/cpu.c11
-rw-r--r--sys/arch/amd64/amd64/cpu_mp.c133
-rw-r--r--sys/include/arch/amd64/cpu.h28
-rw-r--r--sys/include/arch/amd64/cpu_mp.h40
-rw-r--r--sys/include/arch/amd64/msr.h3
-rw-r--r--sys/include/sys/proc.h47
-rw-r--r--sys/include/sys/sched.h42
-rw-r--r--sys/include/sys/sched_state.h44
-rw-r--r--sys/include/sys/types.h1
-rw-r--r--sys/kern/init_main.c13
-rw-r--r--sys/kern/kern_sched.c97
11 files changed, 454 insertions, 5 deletions
diff --git a/sys/arch/amd64/amd64/cpu.c b/sys/arch/amd64/amd64/cpu.c
index 8763b51..0c59730 100644
--- a/sys/arch/amd64/amd64/cpu.c
+++ b/sys/arch/amd64/amd64/cpu.c
@@ -27,7 +27,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <machine/cpu.h>
+#include <machine/cpu_mp.h>
#include <sys/cdefs.h>
__KERNEL_META("$Hyra$: cpu.c, Ian Marco Moffett, "
@@ -49,5 +49,12 @@ amd64_get_bsp(void)
struct cpu_info *
amd64_this_cpu(void)
{
- return amd64_get_bsp();
+ struct cpu_ctx *cctx;
+
+ if (!mp_supported()) {
+ return amd64_get_bsp();
+ }
+
+ cctx = (void *)read_gs_base();
+ return cctx->ci;
}
diff --git a/sys/arch/amd64/amd64/cpu_mp.c b/sys/arch/amd64/amd64/cpu_mp.c
new file mode 100644
index 0000000..c382439
--- /dev/null
+++ b/sys/arch/amd64/amd64/cpu_mp.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <machine/cpu_mp.h>
+#include <sys/machdep.h>
+#include <sys/limine.h>
+#include <sys/types.h>
+#include <sys/syslog.h>
+#include <sys/sched.h>
+#include <sys/cpu.h>
+#include <vm/dynalloc.h>
+#include <assert.h>
+
+__MODULE_NAME("cpu_mp");
+__KERNEL_META("$Hyra$: cpu_mp.c, Ian Marco Moffett, "
+ "SMP related code");
+
+static volatile struct limine_smp_request g_smp_req = {
+ .id = LIMINE_SMP_REQUEST,
+ .revision = 0
+};
+
+static bool is_mp_supported = false;
+
+static void
+ap_create_cctx(struct cpu_info *ci)
+{
+ struct cpu_ctx *cctx;
+
+ cctx = dynalloc(sizeof(struct cpu_ctx));
+ __assert(cctx != NULL);
+
+ cctx->ci = ci;
+
+ /* Set *our* %GS now... */
+ wrmsr(IA32_KERNEL_GS_BASE, (uintptr_t)cctx);
+
+ if (!is_mp_supported) {
+ is_mp_supported = true;
+ }
+}
+
+static void
+ap_trampoline(struct limine_smp_info *si)
+{
+ struct cpu_info *ci;
+
+ ci = (void *)si->extra_argument;
+
+ pre_init();
+ ap_create_cctx(ci);
+ processor_init();
+
+ sched_init_processor(ci);
+
+ /* Should not be reached */
+ __assert(0);
+ __builtin_unreachable();
+}
+
+/*
+ * Returns true if SMP is supported.
+ */
+bool
+mp_supported(void)
+{
+ return is_mp_supported;
+}
+
+void
+ap_bootstrap(struct cpu_info *ci)
+{
+ struct limine_smp_response *resp = g_smp_req.response;
+ struct limine_smp_info **cpus;
+ struct cpu_info *ap_ci = NULL;
+ size_t cpu_init_counter;
+
+ /* Should not happen */
+ __assert(resp != NULL);
+
+ cpus = resp->cpus;
+ cpu_init_counter = resp->cpu_count - 1;
+
+ if (resp->cpu_count == 1) {
+ /* TODO: Allow single core processing */
+ panic("System only has 1 core!\n");
+ }
+
+ /* Create processor context */
+ ap_create_cctx(ci);
+
+ KINFO("Bootstrapping %d cores...\n", cpu_init_counter);
+ for (size_t i = 0; i < resp->cpu_count; ++i) {
+ if (ci->id == cpus[i]->lapic_id) {
+ KINFO("Skip %d (BSP)... continue\n", ci->id);
+ continue;
+ }
+
+ ap_ci = dynalloc(sizeof(struct cpu_info));
+ __assert(ap_ci != NULL);
+ cpu_attach(ap_ci);
+
+ cpus[i]->extra_argument = (uintptr_t)dynalloc(sizeof(struct cpu_info));
+ cpus[i]->goto_address = ap_trampoline;
+ }
+ KINFO("AP bootstrap done for all cores\n");
+}
diff --git a/sys/include/arch/amd64/cpu.h b/sys/include/arch/amd64/cpu.h
index 37ad69d..c72c106 100644
--- a/sys/include/arch/amd64/cpu.h
+++ b/sys/include/arch/amd64/cpu.h
@@ -33,7 +33,10 @@
#include <sys/types.h>
#include <sys/cdefs.h>
#include <sys/spinlock.h>
+#include <sys/sched_state.h>
+#include <sys/queue.h>
#include <machine/tss.h>
+#include <machine/msr.h>
#define this_cpu() amd64_this_cpu()
#define get_bsp() amd64_get_bsp()
@@ -52,7 +55,10 @@ struct cpu_info {
/* Per-arch fields */
void *pmap; /* Current pmap */
uint32_t id;
+ uint32_t idx;
struct spinlock lock;
+ struct sched_state sched_state;
+ TAILQ_ENTRY(cpu_info) link;
/* AMD64 */
volatile size_t lapic_tmr_freq;
@@ -62,6 +68,16 @@ struct cpu_info {
};
/*
+ * Contains information for the current
+ * core. Stored in %GS.
+ *
+ * MUST REMAIN IN ORDER!!!
+ */
+struct cpu_ctx {
+ struct cpu_info *ci;
+};
+
+/*
* Returns true for this core if maskable
* interrupts are masked (CLI) and false if
* they aren't (STI).
@@ -75,6 +91,18 @@ amd64_is_intr_mask(void)
return __TEST(flags, 1 << 9);
}
+static inline void
+write_gs_base(uintptr_t val)
+{
+ wrmsr(IA32_KERNEL_GS_BASE, val);
+}
+
+static inline uintptr_t
+read_gs_base(void)
+{
+ return rdmsr(IA32_KERNEL_GS_BASE);
+}
+
struct cpu_info *amd64_this_cpu(void);
struct cpu_info *amd64_get_bsp(void);
diff --git a/sys/include/arch/amd64/cpu_mp.h b/sys/include/arch/amd64/cpu_mp.h
new file mode 100644
index 0000000..4047f3b
--- /dev/null
+++ b/sys/include/arch/amd64/cpu_mp.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SYS_CPU_AP_H_
+#define _SYS_CPU_AP_H_
+
+#include <machine/cpu.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+__weak void ap_bootstrap(struct cpu_info *ci);
+__weak bool mp_supported(void);
+
+#endif /* !_SYS_CPU_AP_H_ */
diff --git a/sys/include/arch/amd64/msr.h b/sys/include/arch/amd64/msr.h
index 64a790c..d36548b 100644
--- a/sys/include/arch/amd64/msr.h
+++ b/sys/include/arch/amd64/msr.h
@@ -33,7 +33,8 @@
#include <sys/types.h>
#include <sys/cdefs.h>
-#define IA32_SPEC_CTL 0x00000048
+#define IA32_SPEC_CTL 0x00000048
+#define IA32_KERNEL_GS_BASE 0xC0000102
static inline uint64_t
rdmsr(uint32_t msr_addr)
diff --git a/sys/include/sys/proc.h b/sys/include/sys/proc.h
new file mode 100644
index 0000000..1c0e389
--- /dev/null
+++ b/sys/include/sys/proc.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SYS_PROC_H_
+#define _SYS_PROC_H_
+
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <machine/cpu.h>
+
+/*
+ * A task running on the CPU e.g., a process or
+ * a thread.
+ */
+struct proc {
+ pid_t pid;
+ struct cpu_info *cpu;
+ TAILQ_ENTRY(tailq_entry) entries;
+};
+
+#endif /* !_SYS_PROC_H_ */
diff --git a/sys/include/sys/sched.h b/sys/include/sys/sched.h
new file mode 100644
index 0000000..4fdf065
--- /dev/null
+++ b/sys/include/sys/sched.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SYS_SCHED_H_
+#define _SYS_SCHED_H_
+
+#include <sys/proc.h>
+#include <sys/queue.h>
+#include <sys/types.h>
+#include <sys/spinlock.h>
+#include <machine/cpu.h>
+
+__noreturn
+void sched_init_processor(struct cpu_info *ci);
+
+#endif /* !_SYS_SCHED_H_ */
diff --git a/sys/include/sys/sched_state.h b/sys/include/sys/sched_state.h
new file mode 100644
index 0000000..03a55dd
--- /dev/null
+++ b/sys/include/sys/sched_state.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SYS_SCHED_STATE_H_
+#define _SYS_SCHED_STATE_H_
+
+#include <sys/types.h>
+#include <sys/queue.h>
+
+/*
+ * Scheduler state, per CPU.
+ */
+struct sched_state {
+ TAILQ_HEAD(, proc) queue;
+ size_t queue_nrun; /* Number of processes in the run queue */
+};
+
+#endif /* !_SYS_SCHED_STATE_H_ */
diff --git a/sys/include/sys/types.h b/sys/include/sys/types.h
index 29f4421..388458c 100644
--- a/sys/include/sys/types.h
+++ b/sys/include/sys/types.h
@@ -65,6 +65,7 @@ typedef int32_t ssize_t; /* Byte count or error */
typedef _Bool bool;
typedef ssize_t off_t;
typedef size_t uintptr_t;
+typedef int pid_t;
#if defined(_KERNEL)
typedef uintptr_t vaddr_t; /* Virtual address */
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index 99f1e87..2fe84ed 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -32,6 +32,8 @@
#include <sys/syslog.h>
#include <sys/machdep.h>
#include <sys/timer.h>
+#include <sys/sched.h>
+#include <machine/cpu_mp.h>
#include <firmware/acpi/acpi.h>
#include <vm/physseg.h>
#include <logo.h>
@@ -72,6 +74,8 @@ list_timers(void)
void
main(void)
{
+ struct cpu_info *ci;
+
pre_init();
tty_init();
syslog_init();
@@ -86,6 +90,11 @@ main(void)
processor_init();
list_timers();
- /* We're done here, halt the processor */
- __ASMV("cli; hlt");
+ ci = this_cpu();
+ if (ap_bootstrap != NULL) {
+ ap_bootstrap(ci);
+ }
+
+ sched_init_processor(ci);
+ __builtin_unreachable();
}
diff --git a/sys/kern/kern_sched.c b/sys/kern/kern_sched.c
new file mode 100644
index 0000000..da4c6c5
--- /dev/null
+++ b/sys/kern/kern_sched.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/sched.h>
+#include <sys/sched_state.h>
+#include <sys/types.h>
+#include <sys/cdefs.h>
+#include <sys/spinlock.h>
+#include <assert.h>
+
+/*
+ * This is the processor ready list, processors
+ * (cores) that have no task assigned live here.
+ *
+ * Assigning a task to a core is done by popping from
+ * this list. However, it must be done carefully and
+ * must be serialized. You *must* acquire ci_ready_lock
+ * before performing *any* operations on ci_ready_list!!!
+ */
+static TAILQ_HEAD(, cpu_info) ci_ready_list;
+static struct spinlock ci_ready_lock = {0};
+
+/*
+ * Push a processor into the ready list.
+ */
+static void
+sched_enqueue_ci(struct cpu_info *ci)
+{
+ spinlock_acquire(&ci_ready_lock);
+ TAILQ_INSERT_TAIL(&ci_ready_list, ci, link);
+ spinlock_release(&ci_ready_lock);
+}
+
+/*
+ * Processor awaiting tasks to be assigned will be here spinning.
+ *
+ * XXX: We are not using the PAUSE instruction for the sake of
+ * ensuring compatibility... PAUSE is F3 90, REP NOP is
+ * F3 90... REP NOP will be read as a PAUSE on processors
+ * that support it.
+ */
+__noreturn static void
+sched_enter(void)
+{
+ for (;;) {
+ __ASMV("rep; nop");
+ }
+}
+
+/*
+ * Setup scheduler related things and enqueue AP.
+ */
+void
+sched_init_processor(struct cpu_info *ci)
+{
+ struct sched_state *sched_state = &ci->sched_state;
+ static bool is_init = true;
+
+ if (is_init) {
+ /* Setup ready list if first call */
+ TAILQ_INIT(&ci_ready_list);
+ is_init = false;
+ }
+
+ TAILQ_INIT(&sched_state->queue);
+ sched_enqueue_ci(ci);
+
+ sched_enter();
+
+ __builtin_unreachable();
+}