diff options
-rw-r--r-- | kernel/drivers/acpi.c | 24 | ||||
-rw-r--r-- | kernel/inc/acpi.h | 46 | ||||
-rw-r--r-- | kernel/main.c | 1 |
3 files changed, 66 insertions, 5 deletions
diff --git a/kernel/drivers/acpi.c b/kernel/drivers/acpi.c index f7f643c..999c0ed 100644 --- a/kernel/drivers/acpi.c +++ b/kernel/drivers/acpi.c @@ -50,8 +50,12 @@ void *find_sdt(struct rsdt *rsdt, const char *signature) for (int i = 0; i < entries; i++) { struct sdt_header *header = (struct sdt_header *)rsdt->sdt_pointer[i]; - if (memcmp(header->signature, signature, 4) == 0) - return header; + if (memcmp(header->signature, signature, 4) == 0) { + if (check_sdt(header)) + return header; + else + break; + } } return NULL; @@ -68,6 +72,18 @@ void acpi_install() madt = find_sdt(rsdt, MADT_MAGIC); fadt = find_sdt(rsdt, FADT_MAGIC); hpet = find_sdt(rsdt, HPET_MAGIC); - assert(madt && check_sdt(&madt->header) && fadt && check_sdt(&fadt->header) && hpet && - check_sdt(&hpet->header)); +} + +void hpet_install() +{ + if (hpet && hpet->legacy_replacement && hpet->comparator_count > 0) { + struct hpet_registers *r = (struct hpet_registers *)hpet->address.phys; + printf("HPET tick period: %dns\n", r->features.tick_period / 1000000); + printf("Periodic support: %d\n", r->timer.periodic_support); + r->config.enable = 1; + r->config.legacy_replacement = 1; + r->timer.enable = 1; + } else { + hpet = NULL; + } } diff --git a/kernel/inc/acpi.h b/kernel/inc/acpi.h index 2b4c76e..498384e 100644 --- a/kernel/inc/acpi.h +++ b/kernel/inc/acpi.h @@ -16,7 +16,7 @@ struct address_structure { u8 register_bit_width; u8 register_bit_offset; u8 reserved; - u64 address; + u32 phys; // Actually u64 }; struct sdt_header { @@ -68,6 +68,49 @@ struct hpet { u8 page_protection; }; +struct hpet_registers { + struct { + u8 revision; + u8 comparator_count : 5; + u8 counter_size : 1; + u8 reserved : 1; + u8 legacy_replacement : 1; + u16 pci_vendor_id; + u32 tick_period; + } features; + u64 reserved1; + struct { + u8 enable : 1; + u8 legacy_replacement : 1; + u64 reserved : 62; + } config; + u64 reserved2; + struct { + u32 status; // For timer #n + u32 reserved; + } int_status; + u8 reserved3[200]; // Why?! + u32 counter; + u32 counter_high; // 0 due to 64 bit + u64 reserved4; + struct { + u8 reserved1 : 1; + u8 type : 1; + u8 enable : 1; + u8 periodic : 1; + u8 periodic_support : 1; + u8 size : 1; // 1 if 64 bit + u8 set_accumulator : 1; + u8 reserved2 : 1; + u8 force_32 : 1; // For 64 bit + u8 apic_routing : 5; + u8 fsb : 1; + u8 fsb_support : 1; + u16 reserved3; + u32 routing_capability; + } timer; +}; + struct rsdp { struct sdp_header header; struct rsdt *rsdt; @@ -78,5 +121,6 @@ struct fadt *fadt; struct hpet *hpet; void acpi_install(); +void hpet_install(); #endif diff --git a/kernel/main.c b/kernel/main.c index 34332e2..fc304b2 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -25,6 +25,7 @@ void kernel_main(struct vid_info *vid_info) // Install drivers acpi_install(); + hpet_install(); interrupts_install(); fpu_install(); timer_install(); |