mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 06:58:22 +00:00
cpu: rename _cpu() to current_cpu()
This commit is contained in:
@@ -166,26 +166,26 @@ void arch_apic_initap() {
|
|||||||
interrupt_register(0xff, spurious, NULL, IPL_IGNORE);
|
interrupt_register(0xff, spurious, NULL, IPL_IGNORE);
|
||||||
writelapic(APIC_REG_SPURIOUS, 0x1FF);
|
writelapic(APIC_REG_SPURIOUS, 0x1FF);
|
||||||
|
|
||||||
_cpu()->id = readlapic(APIC_REG_ID) >> 24;
|
current_cpu()->id = readlapic(APIC_REG_ID) >> 24;
|
||||||
|
|
||||||
// get the acpi id for the local nmi sources
|
// get the acpi id for the local nmi sources
|
||||||
|
|
||||||
for (size_t i = 0; i < lapiccount; ++i) {
|
for (size_t i = 0; i < lapiccount; ++i) {
|
||||||
struct acpi_madt_lapic *current = getentry(ACPI_MADT_ENTRY_TYPE_LAPIC, i);
|
struct acpi_madt_lapic *current = getentry(ACPI_MADT_ENTRY_TYPE_LAPIC, i);
|
||||||
if (_cpu()->id == current->id) {
|
if (current_cpu()->id == current->id) {
|
||||||
_cpu()->acpiid = current->uid;
|
current_cpu()->acpiid = current->uid;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("processor id: %lu (APIC) %lu (ACPI)\n", _cpu()->id, _cpu()->acpiid);
|
printf("processor id: %lu (APIC) %lu (ACPI)\n", current_cpu()->id, current_cpu()->acpiid);
|
||||||
|
|
||||||
isr_t *nmiisr = interrupt_allocate(nmi, NULL, IPL_MAX); // MAX IPL because NMI
|
isr_t *nmiisr = interrupt_allocate(nmi, NULL, IPL_MAX); // MAX IPL because NMI
|
||||||
__assert(nmiisr);
|
__assert(nmiisr);
|
||||||
|
|
||||||
for (size_t i = 0; i < lapicnmicount; ++i) {
|
for (size_t i = 0; i < lapicnmicount; ++i) {
|
||||||
struct acpi_madt_lapic_nmi* current = getentry(ACPI_MADT_ENTRY_TYPE_LAPIC_NMI, i);
|
struct acpi_madt_lapic_nmi* current = getentry(ACPI_MADT_ENTRY_TYPE_LAPIC_NMI, i);
|
||||||
if (current->uid == _cpu()->acpiid || current->uid == 0xff)
|
if (current->uid == current_cpu()->acpiid || current->uid == 0xff)
|
||||||
writelapic(APIC_LVT_LINT0 + 0x10 * current->lint, (nmiisr->id & 0xff) | LVT_DELIVERY_NMI | (current->flags << 12));
|
writelapic(APIC_LVT_LINT0 + 0x10 * current->lint, (nmiisr->id & 0xff) | LVT_DELIVERY_NMI | (current->flags << 12));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -204,7 +204,7 @@ static time_t stoptimer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void timerisr(isr_t *isr, context_t *context) {
|
static void timerisr(isr_t *isr, context_t *context) {
|
||||||
timer_isr(_cpu()->timer, context);
|
timer_isr(current_cpu()->timer, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void armtimer(time_t ticks) {
|
static void armtimer(time_t ticks) {
|
||||||
@@ -233,12 +233,12 @@ void arch_apic_timerinit() {
|
|||||||
|
|
||||||
writelapic(APIC_TIMER_INITIALCOUNT, 0);
|
writelapic(APIC_TIMER_INITIALCOUNT, 0);
|
||||||
|
|
||||||
printf("cpu%lu: local apic timer calibrated at %lu ticks per us. ISR vector %lu\n", _cpu()->id, ticksperus, vec);
|
printf("cpu%lu: local apic timer calibrated at %lu ticks per us. ISR vector %lu\n", current_cpu()->id, ticksperus, vec);
|
||||||
|
|
||||||
writelapic(APIC_LVT_TIMER, vec);
|
writelapic(APIC_LVT_TIMER, vec);
|
||||||
|
|
||||||
_cpu()->timer = timer_new(ticksperus, armtimer, stoptimer);
|
current_cpu()->timer = timer_new(ticksperus, armtimer, stoptimer);
|
||||||
__assert(_cpu()->timer);
|
__assert(current_cpu()->timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void arch_apic_sendipi(uint8_t cpu, uint8_t vec, uint8_t dest, uint8_t mode, uint8_t level) {
|
void arch_apic_sendipi(uint8_t cpu, uint8_t vec, uint8_t dest, uint8_t mode, uint8_t level) {
|
||||||
|
|||||||
@@ -21,18 +21,18 @@ typedef struct {
|
|||||||
} __attribute__((packed)) gdtr_t;
|
} __attribute__((packed)) gdtr_t;
|
||||||
|
|
||||||
void arch_gdt_reload() {
|
void arch_gdt_reload() {
|
||||||
memcpy(_cpu()->gdt, template, sizeof(template));
|
memcpy(current_cpu()->gdt, template, sizeof(template));
|
||||||
uintptr_t istaddr = (uintptr_t)&_cpu()->ist;
|
uintptr_t istaddr = (uintptr_t)¤t_cpu()->ist;
|
||||||
|
|
||||||
// add ist to gdt
|
// add ist to gdt
|
||||||
_cpu()->gdt[5] |= ((istaddr & 0xff000000) << 32) | ((istaddr & 0xff0000) << 16) | ((istaddr & 0xffff) << 16) | sizeof(ist_t);
|
current_cpu()->gdt[5] |= ((istaddr & 0xff000000) << 32) | ((istaddr & 0xff0000) << 16) | ((istaddr & 0xffff) << 16) | sizeof(ist_t);
|
||||||
_cpu()->gdt[6] = (istaddr >> 32) & 0xffffffff;
|
current_cpu()->gdt[6] = (istaddr >> 32) & 0xffffffff;
|
||||||
|
|
||||||
// reload gdt and ist
|
// reload gdt and ist
|
||||||
|
|
||||||
gdtr_t gdtr = {
|
gdtr_t gdtr = {
|
||||||
.size = sizeof(template) - 1,
|
.size = sizeof(template) - 1,
|
||||||
.address = (uintptr_t)&_cpu()->gdt
|
.address = (uintptr_t)¤t_cpu()->gdt
|
||||||
};
|
};
|
||||||
|
|
||||||
asm volatile("lgdt (%%rax)" : : "a"(&gdtr) : "memory");
|
asm volatile("lgdt (%%rax)" : : "a"(&gdtr) : "memory");
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ void arch_idt_reload() {
|
|||||||
for (int i = 0; i < 32; ++i)
|
for (int i = 0; i < 32; ++i)
|
||||||
interrupt_register(i, exceptisr, NULL, IPL_IGNORE);
|
interrupt_register(i, exceptisr, NULL, IPL_IGNORE);
|
||||||
|
|
||||||
_cpu()->ipl = IPL_NORMAL;
|
current_cpu()->ipl = IPL_NORMAL;
|
||||||
interrupt_set(true);
|
interrupt_set(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -232,7 +232,7 @@ void arch_mmu_tlbshootdown(void *page) {
|
|||||||
mmupage = page;
|
mmupage = page;
|
||||||
remaining = arch_smp_cpusawake - 1;
|
remaining = arch_smp_cpusawake - 1;
|
||||||
|
|
||||||
arch_smp_sendipi(NULL, &_cpu()->isr[0xfe], ARCH_SMP_IPI_OTHERCPUS, false);
|
arch_smp_sendipi(NULL, ¤t_cpu()->isr[0xfe], ARCH_SMP_IPI_OTHERCPUS, false);
|
||||||
|
|
||||||
while (__atomic_load_n(&remaining, __ATOMIC_SEQ_CST)) CPU_PAUSE();
|
while (__atomic_load_n(&remaining, __ATOMIC_SEQ_CST)) CPU_PAUSE();
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ void arch_smp_sendipi(cpu_t *targcpu, isr_t *isr, int target, bool nmi) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void arch_smp_haltallothers() {
|
void arch_smp_haltallothers() {
|
||||||
arch_smp_sendipi(NULL, &_cpu()->isr[0xfd], ARCH_SMP_IPI_OTHERCPUS, true);
|
arch_smp_sendipi(NULL, ¤t_cpu()->isr[0xfd], ARCH_SMP_IPI_OTHERCPUS, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void arch_smp_wakeup() {
|
void arch_smp_wakeup() {
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ int arch_context_saveandcall(void (*fn)(context_t *context, void *argument), voi
|
|||||||
|
|
||||||
// kernelgsbase is set as user because they'll be swapped in the context switch
|
// kernelgsbase is set as user because they'll be swapped in the context switch
|
||||||
#define ARCH_CONTEXT_SWITCHTHREAD(x) \
|
#define ARCH_CONTEXT_SWITCHTHREAD(x) \
|
||||||
_cpu()->ist.rsp0 = (uint64_t)(x)->kernelstacktop; \
|
current_cpu()->ist.rsp0 = (uint64_t)(x)->kernelstacktop; \
|
||||||
wrmsr(MSR_KERNELGSBASE, (x)->extracontext.gsbase); \
|
wrmsr(MSR_KERNELGSBASE, (x)->extracontext.gsbase); \
|
||||||
wrmsr(MSR_FSBASE, (x)->extracontext.fsbase); \
|
wrmsr(MSR_FSBASE, (x)->extracontext.fsbase); \
|
||||||
asm("fxrstor (%%rax)" : : "a"(&(x)->extracontext.fx[0])); \
|
asm("fxrstor (%%rax)" : : "a"(&(x)->extracontext.fx[0])); \
|
||||||
@@ -99,7 +99,7 @@ int arch_context_saveandcall(void (*fn)(context_t *context, void *argument), voi
|
|||||||
|
|
||||||
#define ARCH_CONTEXT_THREADLOAD(t, c) \
|
#define ARCH_CONTEXT_THREADLOAD(t, c) \
|
||||||
memcpy(c, &(t)->context, sizeof(context_t)); \
|
memcpy(c, &(t)->context, sizeof(context_t)); \
|
||||||
_cpu()->ist.rsp0 = (uint64_t)(t)->kernelstacktop; \
|
current_cpu()->ist.rsp0 = (uint64_t)(t)->kernelstacktop; \
|
||||||
wrmsr(MSR_KERNELGSBASE, (t)->extracontext.gsbase); \
|
wrmsr(MSR_KERNELGSBASE, (t)->extracontext.gsbase); \
|
||||||
wrmsr(MSR_FSBASE, (t)->extracontext.fsbase); \
|
wrmsr(MSR_FSBASE, (t)->extracontext.fsbase); \
|
||||||
asm("fxrstor (%%rax)" : : "a"(&(t)->extracontext.fx[0])); \
|
asm("fxrstor (%%rax)" : : "a"(&(t)->extracontext.fx[0])); \
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ static inline thread_t *current_thread(void) {
|
|||||||
return thread;
|
return thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline cpu_t *_cpu(void) {
|
static inline cpu_t *current_cpu(void) {
|
||||||
cpu_t *cpu;
|
cpu_t *cpu;
|
||||||
asm volatile ("mov %%gs:8, %%rax" : "=a"(cpu) : : "memory");
|
asm volatile ("mov %%gs:8, %%rax" : "=a"(cpu) : : "memory");
|
||||||
return cpu;
|
return cpu;
|
||||||
|
|||||||
@@ -99,8 +99,8 @@ int poll_dowait(polldesc_t *desc, size_t ustimeout) {
|
|||||||
sched_preparesleep(true);
|
sched_preparesleep(true);
|
||||||
|
|
||||||
if (ustimeout != 0) {
|
if (ustimeout != 0) {
|
||||||
sched_targetcpu(_cpu());
|
sched_targetcpu(current_cpu());
|
||||||
timer_insert(_cpu()->timer, &sleepentry, timeout, desc, ustimeout, false);
|
timer_insert(current_cpu()->timer, &sleepentry, timeout, desc, ustimeout, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
spinlock_release(&desc->lock);
|
spinlock_release(&desc->lock);
|
||||||
@@ -116,7 +116,7 @@ int poll_dowait(polldesc_t *desc, size_t ustimeout) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ustimeout != 0 && ret != 1) {
|
if (ustimeout != 0 && ret != 1) {
|
||||||
timer_remove(_cpu()->timer, &sleepentry);
|
timer_remove(current_cpu()->timer, &sleepentry);
|
||||||
sched_targetcpu(NULL);
|
sched_targetcpu(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -436,7 +436,7 @@ static void writer() {
|
|||||||
timerentry_t timerentry;
|
timerentry_t timerentry;
|
||||||
// this will be inserted on some random cpu's timer, but it will always work after that
|
// this will be inserted on some random cpu's timer, but it will always work after that
|
||||||
interrupt_set(false);
|
interrupt_set(false);
|
||||||
timer_insert(_cpu()->timer, &timerentry, tick, NULL, (uintmax_t)WRITER_TICK_SECONDS * 1000000, true);
|
timer_insert(current_cpu()->timer, &timerentry, tick, NULL, (uintmax_t)WRITER_TICK_SECONDS * 1000000, true);
|
||||||
interrupt_set(true);
|
interrupt_set(true);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
HOLD_LOCK();
|
HOLD_LOCK();
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ static void remove(dpc_t *dpc) {
|
|||||||
if (dpc->prev)
|
if (dpc->prev)
|
||||||
dpc->prev->next = dpc->next;
|
dpc->prev->next = dpc->next;
|
||||||
else
|
else
|
||||||
_cpu()->dpcqueue = dpc->next;
|
current_cpu()->dpcqueue = dpc->next;
|
||||||
|
|
||||||
if (dpc->next)
|
if (dpc->next)
|
||||||
dpc->next->prev = dpc->prev;
|
dpc->next->prev = dpc->prev;
|
||||||
@@ -16,17 +16,17 @@ static void remove(dpc_t *dpc) {
|
|||||||
|
|
||||||
static void insert(dpc_t *dpc) {
|
static void insert(dpc_t *dpc) {
|
||||||
dpc->prev = NULL;
|
dpc->prev = NULL;
|
||||||
dpc->next = _cpu()->dpcqueue;
|
dpc->next = current_cpu()->dpcqueue;
|
||||||
|
|
||||||
if (dpc->next)
|
if (dpc->next)
|
||||||
dpc->next->prev = dpc;
|
dpc->next->prev = dpc;
|
||||||
|
|
||||||
_cpu()->dpcqueue = dpc;
|
current_cpu()->dpcqueue = dpc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void isrfn(isr_t *self, context_t *context) {
|
static void isrfn(isr_t *self, context_t *context) {
|
||||||
while (_cpu()->dpcqueue) {
|
while (current_cpu()->dpcqueue) {
|
||||||
dpc_t *dpc = _cpu()->dpcqueue;
|
dpc_t *dpc = current_cpu()->dpcqueue;
|
||||||
remove(dpc);
|
remove(dpc);
|
||||||
dpcarg_t arg = dpc->arg;
|
dpcarg_t arg = dpc->arg;
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ void dpc_enqueue(dpc_t *dpc, dpcfn_t fn, dpcarg_t arg) {
|
|||||||
dpc->arg = arg;
|
dpc->arg = arg;
|
||||||
dpc->enqueued = true;
|
dpc->enqueued = true;
|
||||||
insert(dpc);
|
insert(dpc);
|
||||||
interrupt_raise(_cpu()->dpcisr);
|
interrupt_raise(current_cpu()->dpcisr);
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
interrupt_set(entrystate);
|
interrupt_set(entrystate);
|
||||||
@@ -69,6 +69,6 @@ void dpc_dequeue(dpc_t *dpc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void dpc_init() {
|
void dpc_init() {
|
||||||
_cpu()->dpcisr = interrupt_allocate(isrfn, NULL, IPL_DPC);
|
current_cpu()->dpcisr = interrupt_allocate(isrfn, NULL, IPL_DPC);
|
||||||
__assert(_cpu()->dpcisr);
|
__assert(current_cpu()->dpcisr);
|
||||||
}
|
}
|
||||||
|
|||||||
+21
-21
@@ -13,7 +13,7 @@ static void removefromqueue(isr_t *isr) {
|
|||||||
if (isr->prev)
|
if (isr->prev)
|
||||||
isr->prev->next = isr->next;
|
isr->prev->next = isr->next;
|
||||||
else
|
else
|
||||||
_cpu()->isrqueue = isr->next;
|
current_cpu()->isrqueue = isr->next;
|
||||||
|
|
||||||
if (isr->next)
|
if (isr->next)
|
||||||
isr->next->prev = isr->prev;
|
isr->next->prev = isr->prev;
|
||||||
@@ -23,10 +23,10 @@ static void insertinqueue(isr_t *isr) {
|
|||||||
if (isr->pending)
|
if (isr->pending)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
isr->next = _cpu()->isrqueue;
|
isr->next = current_cpu()->isrqueue;
|
||||||
if (isr->next)
|
if (isr->next)
|
||||||
isr->next->prev = isr;
|
isr->next->prev = isr;
|
||||||
_cpu()->isrqueue = isr;
|
current_cpu()->isrqueue = isr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void runisr(isr_t *isr, context_t *ctx) {
|
static void runisr(isr_t *isr, context_t *ctx) {
|
||||||
@@ -43,16 +43,16 @@ static void runisr(isr_t *isr, context_t *ctx) {
|
|||||||
|
|
||||||
static void dopending(context_t *ctx, void *) {
|
static void dopending(context_t *ctx, void *) {
|
||||||
arch_interrupt_disable();
|
arch_interrupt_disable();
|
||||||
bool entrystatus = _cpu()->intstatus;
|
bool entrystatus = current_cpu()->intstatus;
|
||||||
_cpu()->intstatus = false;
|
current_cpu()->intstatus = false;
|
||||||
|
|
||||||
isr_t *list = NULL;
|
isr_t *list = NULL;
|
||||||
isr_t *iterator = _cpu()->isrqueue;
|
isr_t *iterator = current_cpu()->isrqueue;
|
||||||
|
|
||||||
// build a list of pending ISRs and remove them from the main queue
|
// build a list of pending ISRs and remove them from the main queue
|
||||||
while (iterator) {
|
while (iterator) {
|
||||||
isr_t *next = iterator->next;
|
isr_t *next = iterator->next;
|
||||||
if (_cpu()->ipl > iterator->priority) {
|
if (current_cpu()->ipl > iterator->priority) {
|
||||||
removefromqueue(iterator);
|
removefromqueue(iterator);
|
||||||
|
|
||||||
if (list)
|
if (list)
|
||||||
@@ -88,7 +88,7 @@ static void dopending(context_t *ctx, void *) {
|
|||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (entrystatus) {
|
if (entrystatus) {
|
||||||
_cpu()->intstatus = true;
|
current_cpu()->intstatus = true;
|
||||||
arch_interrupt_enable();
|
arch_interrupt_enable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -96,13 +96,13 @@ static void dopending(context_t *ctx, void *) {
|
|||||||
__attribute__((no_caller_saved_registers)) void sched_userspacecheck(context_t *context, bool syscall, uint64_t syscallret, uint64_t syscallerrno);
|
__attribute__((no_caller_saved_registers)) void sched_userspacecheck(context_t *context, bool syscall, uint64_t syscallret, uint64_t syscallerrno);
|
||||||
|
|
||||||
void interrupt_isr(int vec, context_t *ctx) {
|
void interrupt_isr(int vec, context_t *ctx) {
|
||||||
isr_t *isr = &_cpu()->isr[vec];
|
isr_t *isr = ¤t_cpu()->isr[vec];
|
||||||
_cpu()->intstatus = false;
|
current_cpu()->intstatus = false;
|
||||||
|
|
||||||
if (isr->func == NULL)
|
if (isr->func == NULL)
|
||||||
_panic("Unregistered interrupt", ctx);
|
_panic("Unregistered interrupt", ctx);
|
||||||
|
|
||||||
if (_cpu()->ipl > isr->priority) {
|
if (current_cpu()->ipl > isr->priority) {
|
||||||
runisr(isr, ctx);
|
runisr(isr, ctx);
|
||||||
dopending(ctx, NULL);
|
dopending(ctx, NULL);
|
||||||
} else {
|
} else {
|
||||||
@@ -116,7 +116,7 @@ void interrupt_isr(int vec, context_t *ctx) {
|
|||||||
if (ARCH_CONTEXT_ISUSER(ctx))
|
if (ARCH_CONTEXT_ISUSER(ctx))
|
||||||
sched_userspacecheck(ctx, false, 0, 0);
|
sched_userspacecheck(ctx, false, 0, 0);
|
||||||
|
|
||||||
_cpu()->intstatus = ARCH_CONTEXT_INTSTATUS(ctx);
|
current_cpu()->intstatus = ARCH_CONTEXT_INTSTATUS(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void interrupt_raise(isr_t *isr) {
|
void interrupt_raise(isr_t *isr) {
|
||||||
@@ -135,7 +135,7 @@ void interrupt_raise(isr_t *isr) {
|
|||||||
void interrupt_register(int vector, void (*func)(isr_t *self, context_t *ctx), void (*eoi)(isr_t *self), long priority) {
|
void interrupt_register(int vector, void (*func)(isr_t *self, context_t *ctx), void (*eoi)(isr_t *self), long priority) {
|
||||||
bool intstatus = interrupt_set(false);
|
bool intstatus = interrupt_set(false);
|
||||||
|
|
||||||
isr_t *isr = &_cpu()->isr[vector];
|
isr_t *isr = ¤t_cpu()->isr[vector];
|
||||||
isr->func = func;
|
isr->func = func;
|
||||||
isr->eoi = eoi;
|
isr->eoi = eoi;
|
||||||
isr->id = (uint64_t)current_cpu_id() | vector;
|
isr->id = (uint64_t)current_cpu_id() | vector;
|
||||||
@@ -150,8 +150,8 @@ isr_t *interrupt_allocate(void (*func)(isr_t *self, context_t *ctx), void (*eoi)
|
|||||||
isr_t *isr = NULL;
|
isr_t *isr = NULL;
|
||||||
|
|
||||||
for (int i = 0; i < MAX_ISR_COUNT; ++i) {
|
for (int i = 0; i < MAX_ISR_COUNT; ++i) {
|
||||||
if (_cpu()->isr[i].func == NULL) {
|
if (current_cpu()->isr[i].func == NULL) {
|
||||||
isr = &_cpu()->isr[i];
|
isr = ¤t_cpu()->isr[i];
|
||||||
interrupt_register(i, func, eoi, priority);
|
interrupt_register(i, func, eoi, priority);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -163,9 +163,9 @@ isr_t *interrupt_allocate(void (*func)(isr_t *self, context_t *ctx), void (*eoi)
|
|||||||
|
|
||||||
long interrupt_loweripl(long ipl) {
|
long interrupt_loweripl(long ipl) {
|
||||||
bool oldintstatus = interrupt_set(false);
|
bool oldintstatus = interrupt_set(false);
|
||||||
long oldipl = _cpu()->ipl;
|
long oldipl = current_cpu()->ipl;
|
||||||
if (oldipl < ipl)
|
if (oldipl < ipl)
|
||||||
_cpu()->ipl = ipl;
|
current_cpu()->ipl = ipl;
|
||||||
interrupt_set(oldintstatus);
|
interrupt_set(oldintstatus);
|
||||||
|
|
||||||
if (oldintstatus)
|
if (oldintstatus)
|
||||||
@@ -176,10 +176,10 @@ long interrupt_loweripl(long ipl) {
|
|||||||
|
|
||||||
long interrupt_raiseipl(long ipl) {
|
long interrupt_raiseipl(long ipl) {
|
||||||
bool oldintstatus = interrupt_set(false);
|
bool oldintstatus = interrupt_set(false);
|
||||||
long oldipl = _cpu()->ipl;
|
long oldipl = current_cpu()->ipl;
|
||||||
|
|
||||||
if (oldipl > ipl)
|
if (oldipl > ipl)
|
||||||
_cpu()->ipl = ipl;
|
current_cpu()->ipl = ipl;
|
||||||
|
|
||||||
interrupt_set(oldintstatus);
|
interrupt_set(oldintstatus);
|
||||||
|
|
||||||
@@ -188,8 +188,8 @@ long interrupt_raiseipl(long ipl) {
|
|||||||
|
|
||||||
bool interrupt_set(bool status) {
|
bool interrupt_set(bool status) {
|
||||||
arch_interrupt_disable();
|
arch_interrupt_disable();
|
||||||
bool old = _cpu()->intstatus;
|
bool old = current_cpu()->intstatus;
|
||||||
_cpu()->intstatus = status;
|
current_cpu()->intstatus = status;
|
||||||
|
|
||||||
if (status) {
|
if (status) {
|
||||||
arch_interrupt_enable();
|
arch_interrupt_enable();
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ static void itimer_dpc(context_t *context, dpcarg_t arg) {
|
|||||||
itimer->paused = itimer->repeatus == 0;
|
itimer->paused = itimer->repeatus == 0;
|
||||||
itimer->fn(context, itimer->arg);
|
itimer->fn(context, itimer->arg);
|
||||||
if (itimer->repeatus) {
|
if (itimer->repeatus) {
|
||||||
timer_insert(_cpu()->timer, &itimer->entry, itimer_dpc, itimer, itimer->remainingus, false);
|
timer_insert(current_cpu()->timer, &itimer->entry, itimer_dpc, itimer, itimer->remainingus, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
@@ -30,7 +30,7 @@ void itimer_pause(itimer_t *itimer, uintmax_t *remainingus, uintmax_t *repeatus)
|
|||||||
bool intstatus = interrupt_set(false);
|
bool intstatus = interrupt_set(false);
|
||||||
spinlock_acquire(&itimer->lock);
|
spinlock_acquire(&itimer->lock);
|
||||||
|
|
||||||
while (itimer->cpu && itimer->cpu != _cpu()) {
|
while (itimer->cpu && itimer->cpu != current_cpu()) {
|
||||||
// schedule on the itimer cpu
|
// schedule on the itimer cpu
|
||||||
sched_targetcpu(itimer->cpu);
|
sched_targetcpu(itimer->cpu);
|
||||||
spinlock_release(&itimer->lock);
|
spinlock_release(&itimer->lock);
|
||||||
@@ -47,7 +47,7 @@ void itimer_pause(itimer_t *itimer, uintmax_t *remainingus, uintmax_t *repeatus)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
itimer->cpu = NULL;
|
itimer->cpu = NULL;
|
||||||
itimer->remainingus = timer_remove(_cpu()->timer, &itimer->entry);
|
itimer->remainingus = timer_remove(current_cpu()->timer, &itimer->entry);
|
||||||
if (itimer->remainingus == 0) {
|
if (itimer->remainingus == 0) {
|
||||||
// while we were running in the cpu, the timer fired.
|
// while we were running in the cpu, the timer fired.
|
||||||
// the dpc won't be handled because the timer entry
|
// the dpc won't be handled because the timer entry
|
||||||
@@ -83,9 +83,9 @@ void itimer_resume(itimer_t *itimer) {
|
|||||||
spinlock_acquire(&itimer->lock);
|
spinlock_acquire(&itimer->lock);
|
||||||
|
|
||||||
__assert(itimer->paused && itimer->remainingus);
|
__assert(itimer->paused && itimer->remainingus);
|
||||||
itimer->cpu = _cpu();
|
itimer->cpu = current_cpu();
|
||||||
itimer->paused = false;
|
itimer->paused = false;
|
||||||
timer_insert(_cpu()->timer, &itimer->entry, itimer_dpc, itimer, itimer->remainingus, false);
|
timer_insert(current_cpu()->timer, &itimer->entry, itimer_dpc, itimer, itimer->remainingus, false);
|
||||||
|
|
||||||
spinlock_release(&itimer->lock);
|
spinlock_release(&itimer->lock);
|
||||||
interrupt_set(intstatus);
|
interrupt_set(intstatus);
|
||||||
|
|||||||
+33
-33
@@ -185,7 +185,7 @@ static thread_t *getinrunqueue(rqueue_t *rq) {
|
|||||||
thread_t *thread = rq->list;
|
thread_t *thread = rq->list;
|
||||||
|
|
||||||
while (thread) {
|
while (thread) {
|
||||||
if (thread->cputarget == NULL || thread->cputarget == _cpu())
|
if (thread->cputarget == NULL || thread->cputarget == current_cpu())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
thread = thread->next;
|
thread = thread->next;
|
||||||
@@ -233,13 +233,13 @@ static __attribute__((noreturn)) void switchthread(thread_t *thread) {
|
|||||||
interrupt_set(false);
|
interrupt_set(false);
|
||||||
thread_t* current = current_thread();
|
thread_t* current = current_thread();
|
||||||
|
|
||||||
_cpu()->thread = thread;
|
current_cpu()->thread = thread;
|
||||||
|
|
||||||
if(current == NULL || thread->vmmctx != current->vmmctx)
|
if(current == NULL || thread->vmmctx != current->vmmctx)
|
||||||
vmm_switchcontext(thread->vmmctx);
|
vmm_switchcontext(thread->vmmctx);
|
||||||
|
|
||||||
_cpu()->intstatus = ARCH_CONTEXT_INTSTATUS(&thread->context);
|
current_cpu()->intstatus = ARCH_CONTEXT_INTSTATUS(&thread->context);
|
||||||
thread->cpu = _cpu();
|
thread->cpu = current_cpu();
|
||||||
// XXX make the locking of the flags field better, candidate for a r/w lock
|
// XXX make the locking of the flags field better, candidate for a r/w lock
|
||||||
spinlock_acquire(&runqueuelock);
|
spinlock_acquire(&runqueuelock);
|
||||||
if (current)
|
if (current)
|
||||||
@@ -254,7 +254,7 @@ static __attribute__((noreturn)) void switchthread(thread_t *thread) {
|
|||||||
__assert((thread->flags & SCHED_THREAD_FLAGS_QUEUED) == 0);
|
__assert((thread->flags & SCHED_THREAD_FLAGS_QUEUED) == 0);
|
||||||
spinlock_release(&runqueuelock);
|
spinlock_release(&runqueuelock);
|
||||||
|
|
||||||
void *schedulerstack = _cpu()->schedulerstack;
|
void *schedulerstack = current_cpu()->schedulerstack;
|
||||||
__assert(!((void *)thread->context.rsp < schedulerstack && (void *)thread->context.rsp >= (schedulerstack - SCHEDULER_STACK_SIZE)));
|
__assert(!((void *)thread->context.rsp < schedulerstack && (void *)thread->context.rsp >= (schedulerstack - SCHEDULER_STACK_SIZE)));
|
||||||
|
|
||||||
ARCH_CONTEXT_SWITCHTHREAD(thread);
|
ARCH_CONTEXT_SWITCHTHREAD(thread);
|
||||||
@@ -300,7 +300,7 @@ __attribute__((noreturn)) void sched_stopcurrentthread() {
|
|||||||
|
|
||||||
thread_t *next = runqueuenext(0x0fffffff);
|
thread_t *next = runqueuenext(0x0fffffff);
|
||||||
if (next == NULL)
|
if (next == NULL)
|
||||||
next = _cpu()->idlethread;
|
next = current_cpu()->idlethread;
|
||||||
|
|
||||||
spinlock_release(&runqueuelock);
|
spinlock_release(&runqueuelock);
|
||||||
|
|
||||||
@@ -382,7 +382,7 @@ static void threadexit_internal(context_t *, void *) {
|
|||||||
// we don't need to access the current thread anymore, as any state will be ignored and we are running on the scheduler stack
|
// we don't need to access the current thread anymore, as any state will be ignored and we are running on the scheduler stack
|
||||||
// as well as not being preempted at all
|
// as well as not being preempted at all
|
||||||
interrupt_set(false);
|
interrupt_set(false);
|
||||||
_cpu()->thread = NULL;
|
current_cpu()->thread = NULL;
|
||||||
|
|
||||||
spinlock_acquire(&runqueuelock);
|
spinlock_acquire(&runqueuelock);
|
||||||
thread->flags |= SCHED_THREAD_FLAGS_DEAD;
|
thread->flags |= SCHED_THREAD_FLAGS_DEAD;
|
||||||
@@ -416,7 +416,7 @@ __attribute__((noreturn)) void sched_threadexit() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interrupt_set(false);
|
interrupt_set(false);
|
||||||
arch_context_saveandcall(threadexit_internal, _cpu()->schedulerstack, NULL);
|
arch_context_saveandcall(threadexit_internal, current_cpu()->schedulerstack, NULL);
|
||||||
__builtin_unreachable();
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -444,13 +444,13 @@ static void checktrampoline(context_t *context, void *_args) {
|
|||||||
__assert(ARCH_CONTEXT_INTSTATUS(context) == false);
|
__assert(ARCH_CONTEXT_INTSTATUS(context) == false);
|
||||||
checkargs_t *args = _args;
|
checkargs_t *args = _args;
|
||||||
userspacecheck(args);
|
userspacecheck(args);
|
||||||
_cpu()->intstatus = ARCH_CONTEXT_INTSTATUS(args->context);
|
current_cpu()->intstatus = ARCH_CONTEXT_INTSTATUS(args->context);
|
||||||
arch_context_switch(args->context);
|
arch_context_switch(args->context);
|
||||||
}
|
}
|
||||||
|
|
||||||
// called right before going back to userspace in the syscall handler, interrupt handler and arch_context_switch
|
// called right before going back to userspace in the syscall handler, interrupt handler and arch_context_switch
|
||||||
__attribute__((no_caller_saved_registers)) void sched_userspacecheck(context_t *context, bool syscall, uint64_t syscallerrno, uint64_t syscallret) {
|
__attribute__((no_caller_saved_registers)) void sched_userspacecheck(context_t *context, bool syscall, uint64_t syscallerrno, uint64_t syscallret) {
|
||||||
__assert(_cpu());
|
__assert(current_cpu());
|
||||||
if (current_thread() == NULL || ARCH_CONTEXT_ISUSER(context) == false)
|
if (current_thread() == NULL || ARCH_CONTEXT_ISUSER(context) == false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -466,13 +466,13 @@ __attribute__((no_caller_saved_registers)) void sched_userspacecheck(context_t *
|
|||||||
// return context is user mode, so its kernel stack is free
|
// return context is user mode, so its kernel stack is free
|
||||||
// if we are running on the scheduler stack, run on the kernel stack
|
// if we are running on the scheduler stack, run on the kernel stack
|
||||||
// so we don't risk stack corruption (as we have to turn on interrupts should the thread need to exit)
|
// so we don't risk stack corruption (as we have to turn on interrupts should the thread need to exit)
|
||||||
if (&args < (checkargs_t *)_cpu()->schedulerstack && &args >= (checkargs_t *)((uintptr_t)_cpu()->schedulerstack - SCHEDULER_STACK_SIZE)) {
|
if (&args < (checkargs_t *)current_cpu()->schedulerstack && &args >= (checkargs_t *)((uintptr_t)current_cpu()->schedulerstack - SCHEDULER_STACK_SIZE)) {
|
||||||
arch_context_saveandcall(checktrampoline, current_thread()->kernelstacktop, &args);
|
arch_context_saveandcall(checktrampoline, current_thread()->kernelstacktop, &args);
|
||||||
} else {
|
} else {
|
||||||
userspacecheck(&args);
|
userspacecheck(&args);
|
||||||
}
|
}
|
||||||
|
|
||||||
_cpu()->intstatus = intstatus;
|
current_cpu()->intstatus = intstatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sched_stopotherthreads() {
|
void sched_stopotherthreads() {
|
||||||
@@ -564,7 +564,7 @@ static void yield(context_t *context, void *) {
|
|||||||
runqueueinsert(thread);
|
runqueueinsert(thread);
|
||||||
|
|
||||||
if (next == NULL)
|
if (next == NULL)
|
||||||
next = _cpu()->idlethread;
|
next = current_cpu()->idlethread;
|
||||||
|
|
||||||
spinlock_release(&runqueuelock);
|
spinlock_release(&runqueuelock);
|
||||||
switchthread(next);
|
switchthread(next);
|
||||||
@@ -576,8 +576,8 @@ static void yield(context_t *context, void *) {
|
|||||||
int sched_yield() {
|
int sched_yield() {
|
||||||
bool sleeping = current_thread()->flags & SCHED_THREAD_FLAGS_SLEEP;
|
bool sleeping = current_thread()->flags & SCHED_THREAD_FLAGS_SLEEP;
|
||||||
bool old = sleeping ? current_thread()->sleepintstatus : interrupt_set(false);
|
bool old = sleeping ? current_thread()->sleepintstatus : interrupt_set(false);
|
||||||
arch_context_saveandcall(yield, _cpu()->schedulerstack, NULL);
|
arch_context_saveandcall(yield, current_cpu()->schedulerstack, NULL);
|
||||||
__assert(_cpu()->ipl == IPL_NORMAL);
|
__assert(current_cpu()->ipl == IPL_NORMAL);
|
||||||
interrupt_set(old);
|
interrupt_set(old);
|
||||||
return sleeping ? current_thread()->wakeupreason : 0;
|
return sleeping ? current_thread()->wakeupreason : 0;
|
||||||
}
|
}
|
||||||
@@ -684,12 +684,12 @@ static void timerhook(context_t *context, dpcarg_t arg) {
|
|||||||
ARCH_CONTEXT_THREADSAVE(current, context);
|
ARCH_CONTEXT_THREADSAVE(current, context);
|
||||||
|
|
||||||
CTX_INIT(context, false, false);
|
CTX_INIT(context, false, false);
|
||||||
CTX_SP(context) = (uintptr_t)_cpu()->schedulerstack;
|
CTX_SP(context) = (uintptr_t)current_cpu()->schedulerstack;
|
||||||
CTX_IP(context) = (uintptr_t)dopreempt;
|
CTX_IP(context) = (uintptr_t)dopreempt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cpuidlethread() {
|
static void cpuidlethread() {
|
||||||
sched_targetcpu(_cpu());
|
sched_targetcpu(current_cpu());
|
||||||
interrupt_set(true);
|
interrupt_set(true);
|
||||||
while (1) {
|
while (1) {
|
||||||
CPU_HALT();
|
CPU_HALT();
|
||||||
@@ -712,20 +712,20 @@ void sched_sleepus(size_t us) {
|
|||||||
timerentry_t sleepentry = {0};
|
timerentry_t sleepentry = {0};
|
||||||
sched_preparesleep(false);
|
sched_preparesleep(false);
|
||||||
|
|
||||||
timer_insert(_cpu()->timer, &sleepentry, timeout, current_thread(), us, false);
|
timer_insert(current_cpu()->timer, &sleepentry, timeout, current_thread(), us, false);
|
||||||
sched_yield();
|
sched_yield();
|
||||||
}
|
}
|
||||||
|
|
||||||
void sched_apentry() {
|
void sched_apentry() {
|
||||||
_cpu()->schedulerstack = vmm_map(NULL, SCHEDULER_STACK_SIZE, VMM_FLAGS_ALLOCATE, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, NULL);
|
current_cpu()->schedulerstack = vmm_map(NULL, SCHEDULER_STACK_SIZE, VMM_FLAGS_ALLOCATE, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, NULL);
|
||||||
__assert(_cpu()->schedulerstack);
|
__assert(current_cpu()->schedulerstack);
|
||||||
_cpu()->schedulerstack = (void *)((uintptr_t)_cpu()->schedulerstack + SCHEDULER_STACK_SIZE);
|
current_cpu()->schedulerstack = (void *)((uintptr_t)current_cpu()->schedulerstack + SCHEDULER_STACK_SIZE);
|
||||||
|
|
||||||
_cpu()->idlethread = sched_newthread(cpuidlethread, PAGE_SIZE * 4, 3, NULL, NULL);
|
current_cpu()->idlethread = sched_newthread(cpuidlethread, PAGE_SIZE * 4, 3, NULL, NULL);
|
||||||
__assert(_cpu()->idlethread);
|
__assert(current_cpu()->idlethread);
|
||||||
|
|
||||||
timer_insert(_cpu()->timer, &_cpu()->schedtimerentry, timerhook, NULL, QUANTUM_US, true);
|
timer_insert(current_cpu()->timer, ¤t_cpu()->schedtimerentry, timerhook, NULL, QUANTUM_US, true);
|
||||||
timer_resume(_cpu()->timer);
|
timer_resume(current_cpu()->timer);
|
||||||
sched_stopcurrentthread();
|
sched_stopcurrentthread();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -738,20 +738,20 @@ void sched_init() {
|
|||||||
__assert(hashtable_init(&pidtable, 100) == 0);
|
__assert(hashtable_init(&pidtable, 100) == 0);
|
||||||
MUTEX_INIT(&sched_pidtablemutex);
|
MUTEX_INIT(&sched_pidtablemutex);
|
||||||
|
|
||||||
_cpu()->schedulerstack = vmm_map(NULL, SCHEDULER_STACK_SIZE, VMM_FLAGS_ALLOCATE, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, NULL);
|
current_cpu()->schedulerstack = vmm_map(NULL, SCHEDULER_STACK_SIZE, VMM_FLAGS_ALLOCATE, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC, NULL);
|
||||||
__assert(_cpu()->schedulerstack);
|
__assert(current_cpu()->schedulerstack);
|
||||||
_cpu()->schedulerstack = (void *)((uintptr_t)_cpu()->schedulerstack + SCHEDULER_STACK_SIZE);
|
current_cpu()->schedulerstack = (void *)((uintptr_t)current_cpu()->schedulerstack + SCHEDULER_STACK_SIZE);
|
||||||
|
|
||||||
SPINLOCK_INIT(runqueuelock);
|
SPINLOCK_INIT(runqueuelock);
|
||||||
|
|
||||||
_cpu()->idlethread = sched_newthread(cpuidlethread, PAGE_SIZE * 4, 3, NULL, NULL);
|
current_cpu()->idlethread = sched_newthread(cpuidlethread, PAGE_SIZE * 4, 3, NULL, NULL);
|
||||||
__assert(_cpu()->idlethread);
|
__assert(current_cpu()->idlethread);
|
||||||
_cpu()->thread = sched_newthread(NULL, PAGE_SIZE * 32, 0, NULL, NULL);
|
current_cpu()->thread = sched_newthread(NULL, PAGE_SIZE * 32, 0, NULL, NULL);
|
||||||
__assert(current_thread());
|
__assert(current_thread());
|
||||||
|
|
||||||
timer_insert(_cpu()->timer, &_cpu()->schedtimerentry, timerhook, NULL, QUANTUM_US, true);
|
timer_insert(current_cpu()->timer, ¤t_cpu()->schedtimerentry, timerhook, NULL, QUANTUM_US, true);
|
||||||
// XXX move this resume to a more appropriate place
|
// XXX move this resume to a more appropriate place
|
||||||
timer_resume(_cpu()->timer);
|
timer_resume(current_cpu()->timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define STACK_TOP (void *)0x0000800000000000
|
#define STACK_TOP (void *)0x0000800000000000
|
||||||
|
|||||||
@@ -27,13 +27,13 @@ syscallret_t syscall_nanosleep(context_t *, timespec_t *utime, timespec_t *remai
|
|||||||
timerentry_t sleepentry;
|
timerentry_t sleepentry;
|
||||||
sched_preparesleep(true);
|
sched_preparesleep(true);
|
||||||
|
|
||||||
sched_targetcpu(_cpu());
|
sched_targetcpu(current_cpu());
|
||||||
timer_insert(_cpu()->timer, &sleepentry, timeout, current_thread(), time.s * 1000000 + time.ns / 1000, false);
|
timer_insert(current_cpu()->timer, &sleepentry, timeout, current_thread(), time.s * 1000000 + time.ns / 1000, false);
|
||||||
|
|
||||||
ret.errno = sched_yield() == SCHED_WAKEUP_REASON_INTERRUPTED ? EINTR : 0;
|
ret.errno = sched_yield() == SCHED_WAKEUP_REASON_INTERRUPTED ? EINTR : 0;
|
||||||
|
|
||||||
if (ret.errno && remaining) {
|
if (ret.errno && remaining) {
|
||||||
uintmax_t remainingus = timer_remove(_cpu()->timer, &sleepentry);
|
uintmax_t remainingus = timer_remove(current_cpu()->timer, &sleepentry);
|
||||||
time.ns = (remainingus % 1000000) * 1000;
|
time.ns = (remainingus % 1000000) * 1000;
|
||||||
time.s = (remainingus / 1000000);
|
time.s = (remainingus / 1000000);
|
||||||
ret.errno = usercopy_touser(remaining, &time, sizeof(timespec_t)) ? EFAULT : EINTR;
|
ret.errno = usercopy_touser(remaining, &time, sizeof(timespec_t)) ? EFAULT : EINTR;
|
||||||
|
|||||||
Reference in New Issue
Block a user