+ acpi: add acpi support + lapic: add lapic support + ioapic: add ioapic support + arch/x86_64: add support for "syscall"/"sysret"
64 lines
No EOL
1.5 KiB
C
64 lines
No EOL
1.5 KiB
C
#include "mm/pmm.h"
|
|
#include <dev/lapic.h>
|
|
#include <sys/log.h>
|
|
|
|
uint64_t apic_ticks = 0;
|
|
|
|
void lapic_init() {
|
|
lapic_write(0xf0, 0x1ff);
|
|
log("lapic - initialized\n");
|
|
}
|
|
|
|
void lapic_stop_timer() {
|
|
// We do this to avoid overlapping oneshots
|
|
lapic_write(LAPIC_TIMER_INITCNT, 0);
|
|
lapic_write(LAPIC_TIMER_LVT, LAPIC_TIMER_DISABLE);
|
|
}
|
|
|
|
void lapic_oneshot(uint8_t vec, uint64_t ms) {
|
|
lapic_stop_timer();
|
|
lapic_write(LAPIC_TIMER_DIV, 0);
|
|
lapic_write(LAPIC_TIMER_LVT, vec);
|
|
lapic_write(LAPIC_TIMER_INITCNT, apic_ticks * ms);
|
|
}
|
|
|
|
void lapic_calibrate_timer() {
|
|
lapic_stop_timer();
|
|
lapic_write(LAPIC_TIMER_DIV, 0);
|
|
lapic_write(LAPIC_TIMER_LVT, (1 << 16) | 0xff);
|
|
lapic_write(LAPIC_TIMER_INITCNT, 0xFFFFFFFF);
|
|
//pit_sleep(1); // 1 ms
|
|
lapic_write(LAPIC_TIMER_LVT, LAPIC_TIMER_DISABLE);
|
|
uint32_t ticks = 0xFFFFFFFF - lapic_read(LAPIC_TIMER_CURCNT);
|
|
apic_ticks = ticks;
|
|
lapic_stop_timer();
|
|
}
|
|
|
|
void lapic_write(uint32_t reg, uint32_t val) {
|
|
*((volatile uint32_t*)(HIGHER_HALF(0xfee00000) + reg)) = val;
|
|
}
|
|
|
|
uint32_t lapic_read(uint32_t reg) {
|
|
return *((volatile uint32_t*)(HIGHER_HALF(0xfee00000) + reg));
|
|
}
|
|
|
|
void lapic_eoi() {
|
|
lapic_write((uint8_t)0xb0, 0x0);
|
|
}
|
|
|
|
void lapic_ipi(uint32_t id, uint8_t dat) {
|
|
lapic_write(LAPIC_ICRHI, id << LAPIC_ICDESTSHIFT);
|
|
lapic_write(LAPIC_ICRLO, dat);
|
|
}
|
|
|
|
void lapic_send_all_int(uint32_t id, uint32_t vec) {
|
|
lapic_ipi(id, vec | LAPIC_ICRAIS);
|
|
}
|
|
|
|
void lapic_send_others_int(uint32_t id, uint32_t vec) {
|
|
lapic_ipi(id, vec | LAPIC_ICRAES);
|
|
}
|
|
|
|
uint32_t lapic_get_id() {
|
|
return lapic_read(0x0020) >> LAPIC_ICDESTSHIFT;
|
|
} |