BarryServer : Git

All the code for all my projects
// BarryServer : Git / Nucleus / blob / master / include / nucleus / cpu.h

// Related

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