Compare commits
3 Commits
3b7bae534d
...
299ee1dfa8
| Author | SHA1 | Date | |
|---|---|---|---|
| 299ee1dfa8 | |||
| 253143edf5 | |||
| 7f8e600ecd |
@@ -0,0 +1,36 @@
|
||||
#include <stdckdint.h>
|
||||
#include <stdint.h>
|
||||
#include <uacpi/kernel_api.h>
|
||||
#include <uacpi/status.h>
|
||||
#include <x86_64/asm.h>
|
||||
|
||||
uacpi_status uacpi_kernel_io_map(uacpi_io_addr base, uacpi_size len, uacpi_handle* out_handle) {
|
||||
uintptr_t end;
|
||||
if (ckd_add(&end, base, len) || end > 0x10000)
|
||||
return UACPI_STATUS_INVALID_ARGUMENT;
|
||||
*out_handle = (uacpi_handle)(uintptr_t)base;
|
||||
return UACPI_STATUS_OK;
|
||||
}
|
||||
|
||||
void uacpi_kernel_io_unmap(uacpi_handle handle) {
|
||||
// Left intentionally blank.
|
||||
}
|
||||
|
||||
#define IO_READ(width, suffix) \
|
||||
uacpi_status uacpi_kernel_io_read##width(uacpi_handle handle, uacpi_size offset, uacpi_u##width* out_value) { \
|
||||
*out_value = asm_in##suffix((uintptr_t)handle + offset); \
|
||||
return UACPI_STATUS_OK; \
|
||||
}
|
||||
|
||||
#define IO_WRITE(width, suffix) \
|
||||
uacpi_status uacpi_kernel_io_write##width(uacpi_handle handle, uacpi_size offset, uacpi_u##width in_value) { \
|
||||
asm_out##suffix((uintptr_t)handle + offset, in_value); \
|
||||
return UACPI_STATUS_OK; \
|
||||
}
|
||||
|
||||
IO_READ(8, b)
|
||||
IO_READ(16, w)
|
||||
IO_READ(32, l)
|
||||
IO_WRITE(8, b)
|
||||
IO_WRITE(16, w)
|
||||
IO_WRITE(32, l)
|
||||
+11
-5
@@ -7,6 +7,7 @@
|
||||
#include <zinnia/utils.h>
|
||||
#include <zinnia/vma.h>
|
||||
#include <arch/cpu.h>
|
||||
#include <arch/timer.h>
|
||||
#include <stdint.h>
|
||||
#include <x86_64/apic.h>
|
||||
#include <x86_64/asm.h>
|
||||
@@ -95,17 +96,22 @@ void lapic_init(struct local_apic* lapic) {
|
||||
clock_spin_ns(10'000'000);
|
||||
|
||||
lapic->ticks_per_10ms = 0xFFFF'FFFF - lapic_read_reg(lapic, APIC_REG_CCR);
|
||||
lapic_write_reg(lapic, APIC_REG_LVT_TR, IDT_IPI_RESCHED | 0x20000);
|
||||
lapic_write_reg(lapic, APIC_REG_ICR_TIMER, lapic->ticks_per_10ms);
|
||||
lapic_write_reg(lapic, APIC_REG_LVT_TR, mmio_field(APIC_LVT_TR_VECTOR, IDT_TIMER));
|
||||
lapic_write_reg(lapic, APIC_REG_ICR_TIMER, 0);
|
||||
}
|
||||
|
||||
void arch_timer_program(uint64_t deadline_ns) {
|
||||
struct local_apic* lapic = &percpu_ref(arch_data)->lapic;
|
||||
const uint64_t now = clock_get_elapsed_ns();
|
||||
const uint64_t delta = MIN(deadline_ns > now ? deadline_ns - now : 0, 1'000'000'000);
|
||||
const uint64_t ticks = delta * lapic->ticks_per_10ms / 10'000'000;
|
||||
lapic_write_reg(lapic, APIC_REG_ICR_TIMER, MIN(MAX(ticks, 1), 0xFFFF'FFFF));
|
||||
}
|
||||
|
||||
void lapic_eoi(struct local_apic* lapic) {
|
||||
lapic_write_reg(lapic, APIC_REG_EOI, 0);
|
||||
}
|
||||
|
||||
constexpr uint64_t the_icr =
|
||||
mmio_field(APIC_ICR_VECTOR, 128) | mmio_field(APIC_ICR_DELIVERY_MODE, APIC_DELIVERY_STARTUP);
|
||||
|
||||
void lapic_send_ipi(
|
||||
struct local_apic* lapic,
|
||||
uint32_t target,
|
||||
|
||||
@@ -27,3 +27,7 @@ kernel_sources += files(
|
||||
if kconfig.get('CONFIG_PCI', 'n') == 'y'
|
||||
kernel_sources += files('pci.c')
|
||||
endif
|
||||
|
||||
if kconfig.get('CONFIG_ACPI', 'n') == 'y'
|
||||
kernel_sources += files('acpi.c')
|
||||
endif
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void arch_timer_program(uint64_t deadline_ns);
|
||||
@@ -1,9 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <zinnia/compiler.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct [[gnu::packed]] guid {
|
||||
struct [[__packed]] guid {
|
||||
uint32_t time_low;
|
||||
uint16_t time_mid;
|
||||
uint16_t time_hi_version;
|
||||
|
||||
+1
-1
Submodule subprojects/uacpi updated: f5f6cc29f8...686a9a52d9
Reference in New Issue
Block a user