Nucleus
Barry Per-CPU Scheduler bb0cb77 (3 years, 2 months ago)
diff --git a/include/nucleus/cpu.h b/include/nucleus/cpu.h
index f4d7175..2a8c52b 100644
--- a/include/nucleus/cpu.h
+++ b/include/nucleus/cpu.h
@@ -2,14 +2,20 @@
#define _NUCLEUS_CPU_H
#include <stdint.h>
+#include <stddef.h>
#include <nucleus/types.h>
typedef unsigned int cpu_t;
+typedef struct Processor Processor;
/* Structure for CPU specific data */
-struct CPUData {
+struct Processor {
+ Processor *self;
cpu_t id;
- Task *task;
+ uint32_t inCriticalSection;
+ uint32_t critFlags;
+ Scheduler *scheduler;
+ struct IPIQueue *ipiq;
};
/* Structure for an Interrupt Frame */
@@ -20,12 +26,22 @@ struct InterruptFrame {
uint32_t eip, cs, eflags, useresp, ss;
};
-typedef void (*exc_handler_t)(struct InterruptFrame *);
-typedef void (*int_handler_t)(struct InterruptFrame *);
+/* Flags for IPI Queue Messages */
+enum IPIQFlag {
+ IPIQ_ASYNC,
+ IPIQ_SYNC,
+ IPIQ_DONE,
+};
-extern struct CPUData __seg_gs *cpu;
+typedef void (*int_handler_t)(struct InterruptFrame *);
+typedef void (*ipiq_func_t)(void *);
+extern Processor __seg_gs *const cpu;
+extern Processor *cpus[];
+extern size_t ncpus;
extern int apic;
+#define for_each_cpu(c) for (cpu_t __i_ ## c = 0; ((c) = cpus[__i_ ## c]) && \
+ __i_ ## c < ncpus; __i_ ## c++)
extern uintptr_t lapicPtr, ioapicPtr;
#define LAPIC(off) (*((uint32_t *) ((uint32_t) lapicPtr + (off))))
@@ -35,8 +51,38 @@ extern cpu_t lapicNums[];
#define CPUID (apic ? lapicNums[(cpu_t) (LAPIC(0x20) >> 24)] : 0)
#define MAX_CPUS 2
-void register_exception(int num, exc_handler_t addr);
-void register_interrupt(int num, int_handler_t addr);
+/* Enter a critical section */
+static inline void
+enter_critical_section(void)
+{
+ uint32_t *ics = &cpu->self->inCriticalSection;
+ if (__atomic_fetch_add(ics, 1, __ATOMIC_RELAXED) == 0)
+ asm volatile (
+ "pushf;"
+ "cli;"
+ "pop %0"
+ : "=r" (cpu->critFlags)
+ : : "memory"
+ );
+}
+/* Exit a critical section */
+static inline void
+exit_critical_section(void)
+{
+ uint32_t *ics = &cpu->self->inCriticalSection;
+ if (__atomic_sub_fetch(ics, 1, __ATOMIC_RELAXED) == 0)
+ asm volatile (
+ "push %0;"
+ "popf"
+ : : "rm" (cpu->critFlags)
+ : "memory","cc"
+ );
+}
+
+void register_exception(uint8_t num, int_handler_t addr);
+void register_interrupt(uint8_t num, int_handler_t addr);
+void register_ipi(uint8_t num, int_handler_t addr);
+void send_ipiq(cpu_t targid, ipiq_func_t func, void *arg, enum IPIQFlag flags);
void set_fs_base(uintptr_t base);
void set_gs_base(uintptr_t base);