Nucleus
Barry Kernel threads + threads share address space 6217f0d (3 years, 1 month ago)
#ifndef _NUCLEUS_CPU_H
#define _NUCLEUS_CPU_H
#include <stddef.h>
#include <stdint.h>
#include <nucleus/types.h>
typedef unsigned int cpu_t;
typedef struct Processor Processor;
/* Structure for CPU specific data */
struct Processor {
Processor *self;
cpu_t id;
uint32_t inCriticalSection;
uint32_t critFlags;
struct InterruptFrame *frame;
Scheduler *scheduler;
struct IPIQueue *ipiq;
};
/* Structure for an Interrupt Frame */
struct InterruptFrame {
uint32_t ds;
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax;
uint32_t intnum, err;
uint32_t eip, cs, eflags, useresp, ss;
};
/* Flags for IPI Queue Messages */
enum IPIQFlag {
IPIQ_ASYNC,
IPIQ_SYNC,
IPIQ_DONE,
};
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))))
#define IOAPIC(off) (*((uint32_t *) ((uint32_t) ioapicPtr + (off))))
extern cpu_t lapicNums[];
#define CPUID (apic ? lapicNums[(cpu_t) (LAPIC(0x20) >> 24)] : 0)
#define MAX_CPUS 2
/* 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);
void set_kernel_stack(uintptr_t top);
#endif