port apic and hpet to mmio API, apic_msis
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
#include <zinnia/assert.h>
|
||||
#include <zinnia/compiler.h>
|
||||
#include <zinnia/errno.h>
|
||||
#include <zinnia/irq.h>
|
||||
#include <zinnia/percpu.h>
|
||||
#include <zinnia/pmap.h>
|
||||
#include <zinnia/sched.h>
|
||||
@@ -10,6 +11,7 @@
|
||||
#include <bits/sched.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <x86_64/apic.h>
|
||||
#include <x86_64/asm.h>
|
||||
#include <x86_64/defs.h>
|
||||
#include <x86_64/gdt.h>
|
||||
@@ -166,6 +168,21 @@ void arch_task_fini(struct arch_task_context* context) {
|
||||
context->fpu_region = nullptr;
|
||||
}
|
||||
|
||||
void arch_task_fork(struct arch_task_context* dst) {
|
||||
if (dst->fpu_region)
|
||||
percpu_ref(arch_data)->fpu_save(dst->fpu_region);
|
||||
}
|
||||
|
||||
void arch_context_init_user(struct arch_context* ctx, uintptr_t ip, uintptr_t sp) {
|
||||
*ctx = (struct arch_context){
|
||||
.rip = ip,
|
||||
.rsp = sp,
|
||||
.rflags = 0x202,
|
||||
.cs = offsetof(struct gdt, user_code64) | CPL_USER,
|
||||
.ss = offsetof(struct gdt, user_data) | CPL_USER,
|
||||
};
|
||||
}
|
||||
|
||||
[[__naked]]
|
||||
void arch_sched_preempt_disable() {
|
||||
asm volatile(
|
||||
@@ -189,6 +206,23 @@ bool arch_sched_preempt_enable() {
|
||||
);
|
||||
}
|
||||
|
||||
void arch_sched_kick(struct percpu* cpu) {
|
||||
if (!cpu->online)
|
||||
return;
|
||||
// The xAPIC ICR takes two writes, which must not be interleaved with an IPI sent by an interrupt handler.
|
||||
irq_lock();
|
||||
lapic_send_ipi(
|
||||
&percpu_ref(arch_data)->lapic,
|
||||
percpu_ref_on(cpu, arch_data)->lapic.id,
|
||||
IDT_IPI_RESCHED,
|
||||
APIC_DELIVERY_FIXED,
|
||||
APIC_DEST_PHYSICAL,
|
||||
APIC_LEVEL_ASSERT,
|
||||
APIC_TRIGGER_EDGE
|
||||
);
|
||||
irq_unlock();
|
||||
}
|
||||
|
||||
[[__naked]]
|
||||
void arch_sched_jump_to_context(struct arch_context* context) {
|
||||
asm volatile(
|
||||
|
||||
Reference in New Issue
Block a user