|
1 | 1 | #include "apic.h" |
2 | | -#include "driver/uacpi/acpi.h" |
3 | | -#include "driver/uacpi/tables.h" |
4 | | -#include "timer.h" |
5 | 2 | #include "intctl.h" |
6 | 3 | #include "io.h" |
| 4 | +#include "lib/acpica/acpi.h" |
7 | 5 | #include "mem/frame.h" |
8 | 6 | #include "mem/page.h" |
9 | | -#include "term/klog.h" |
10 | 7 | #include "task/smp.h" |
| 8 | +#include "term/klog.h" |
| 9 | +#include "timer.h" |
11 | 10 |
|
12 | 11 | bool x2apic_mode = false; |
13 | 12 | uint64_t lapic_address; |
@@ -126,29 +125,29 @@ void lapic_timer_stop() { |
126 | 125 | lapic_write(LAPIC_REG_TIMER, (1 << 16)); |
127 | 126 | } |
128 | 127 |
|
129 | | -static void apic_handle_ioapic(struct acpi_madt_ioapic *ioapic_madt) { |
| 128 | +static void apic_handle_ioapic(ACPI_MADT_IO_APIC *ioapic_madt) { |
130 | 129 | struct ioapic_info *ioapic = &found_ioapics[found_ioapic_count]; |
131 | 130 | found_ioapic_count++; |
132 | 131 |
|
133 | | - uint64_t mmio_phys = ioapic_madt->address; |
| 132 | + uint64_t mmio_phys = ioapic_madt->Address; |
134 | 133 | uint64_t mmio_virt = (uint64_t)phys_to_virt(mmio_phys); |
135 | 134 | page_map_range(get_kernel_pagedir(), mmio_virt, mmio_phys, PAGE_SIZE, KERNEL_PTE_FLAGS); |
136 | 135 | ioapic->mmio_base = mmio_virt; |
137 | 136 |
|
138 | | - ioapic->gsi_base = ioapic_madt->gsi_base; |
| 137 | + ioapic->gsi_base = ioapic_madt->GlobalIrqBase; |
139 | 138 | ioapic->irq_count = (ioapic_mmio_read(ioapic->mmio_base, 0x01) & 0x00FF0000) >> 16; |
140 | 139 |
|
141 | 140 | kinfo("IOAPIC found: MMIO %p, GSI base %d, IRQs %d", (void *)ioapic->mmio_base, |
142 | | - ioapic->gsi_base, ioapic->irq_count); |
| 141 | + ioapic->gsi_base, ioapic->irq_count); |
143 | 142 |
|
144 | | - ioapic->id = ioapic_madt->id; |
| 143 | + ioapic->id = ioapic_madt->Id; |
145 | 144 | } |
146 | 145 |
|
147 | | -static void apic_handle_override(struct acpi_madt_interrupt_source_override *override_madt) { |
| 146 | +static void apic_handle_override(ACPI_MADT_INTERRUPT_OVERRIDE *override_madt) { |
148 | 147 | struct iso_info *override = &found_isos[found_iso_count]; |
149 | 148 | found_iso_count++; |
150 | | - override->irq_source = override_madt->source; |
151 | | - override->gsi = override_madt->gsi; |
| 149 | + override->irq_source = override_madt->SourceIrq; |
| 150 | + override->gsi = override_madt->GlobalIrq; |
152 | 151 | } |
153 | 152 |
|
154 | 153 | void local_apic_init() { |
@@ -193,53 +192,51 @@ void ap_local_apic_init() { |
193 | 192 | } |
194 | 193 |
|
195 | 194 | void apic_init() { |
196 | | - struct uacpi_table madt_table; |
197 | | - uacpi_status status = uacpi_table_find_by_signature("APIC", &madt_table); |
198 | | - if (status != UACPI_STATUS_OK) return; |
199 | | - struct acpi_madt *madt = (struct acpi_madt *)madt_table.ptr; |
200 | | - lapic_address = (uint64_t)phys_to_virt((uint64_t)madt->local_interrupt_controller_address); |
201 | | - page_map_range(get_kernel_pagedir(), lapic_address, madt->local_interrupt_controller_address, |
202 | | - PAGE_SIZE, KERNEL_PTE_FLAGS); |
203 | | - x2apic_mode = x2apic_mode_supported(); |
204 | | - uint64_t current = 0; |
205 | | - for (;;) { |
206 | | - if (current + ((uint32_t)sizeof(struct acpi_madt) - 1) >= madt->hdr.length) { break; } |
207 | | - struct acpi_entry_hdr *header = |
208 | | - (struct acpi_entry_hdr *)((uint64_t)(&madt->entries) + current); |
209 | | - if (header->type == ACPI_MADT_ENTRY_TYPE_IOAPIC) { |
210 | | - struct acpi_madt_ioapic *ioapic = |
211 | | - (struct acpi_madt_ioapic *)((uint64_t)(&madt->entries) + current); |
| 195 | + ACPI_TABLE_MADT *madt = NULL; |
| 196 | + const ACPI_STATUS status = AcpiGetTable(ACPI_SIG_MADT, 1, (ACPI_TABLE_HEADER **)&madt); |
| 197 | + if (ACPI_FAILURE(status)) { |
| 198 | + kerror("Failed to get MADT table: %s", AcpiFormatException(status)); |
| 199 | + return; |
| 200 | + } |
| 201 | + |
| 202 | + lapic_address = (uint64_t)phys_to_virt(madt->Address); |
| 203 | + page_map_range(get_kernel_pagedir(), lapic_address, madt->Address, PAGE_SIZE, KERNEL_PTE_FLAGS); |
| 204 | + x2apic_mode = x2apic_mode_supported(); |
| 205 | + ACPI_SUBTABLE_HEADER *subtable = (ACPI_SUBTABLE_HEADER *)(madt + 1); |
| 206 | + uintptr_t end = (uintptr_t)madt + madt->Header.Length; |
| 207 | + while ((uintptr_t)subtable < end) { |
| 208 | + switch (subtable->Type) { |
| 209 | + case ACPI_MADT_TYPE_IO_APIC:; |
| 210 | + ACPI_MADT_IO_APIC *ioapic = (ACPI_MADT_IO_APIC *)subtable; |
212 | 211 | apic_handle_ioapic(ioapic); |
213 | | - } else if (header->type == ACPI_MADT_ENTRY_TYPE_INTERRUPT_SOURCE_OVERRIDE) { |
214 | | - struct acpi_madt_interrupt_source_override *override = |
215 | | - (struct acpi_madt_interrupt_source_override *)((uint64_t)(&madt->entries) + |
216 | | - current); |
217 | | - apic_handle_override(override); |
| 212 | + break; |
| 213 | + case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:; |
| 214 | + ACPI_MADT_INTERRUPT_OVERRIDE *iso = (ACPI_MADT_INTERRUPT_OVERRIDE *)subtable; |
| 215 | + apic_handle_override(iso); |
| 216 | + break; |
| 217 | + default: break; |
218 | 218 | } |
219 | | - current += (uint64_t)header->length; |
| 219 | + subtable = (ACPI_SUBTABLE_HEADER *)((char *)subtable + subtable->Length); |
220 | 220 | } |
221 | 221 |
|
222 | 222 | disable_pic(); |
223 | 223 | local_apic_init(); |
224 | 224 | } |
225 | 225 |
|
226 | | -int64_t apic_mask(uint64_t irq,uint64_t flags) { |
227 | | - if (flags & IRQ_FLAGS_MSIX) |
228 | | - return 0; |
| 226 | +int64_t apic_mask(uint64_t irq, uint64_t flags) { |
| 227 | + if (flags & IRQ_FLAGS_MSIX) return 0; |
229 | 228 | ioapic_disable((uint8_t)irq); |
230 | 229 | return 0; |
231 | 230 | } |
232 | 231 |
|
233 | | -int64_t apic_unmask(uint64_t irq,uint64_t flags) { |
234 | | - if (flags & IRQ_FLAGS_MSIX) |
235 | | - return 0; |
| 232 | +int64_t apic_unmask(uint64_t irq, uint64_t flags) { |
| 233 | + if (flags & IRQ_FLAGS_MSIX) return 0; |
236 | 234 | ioapic_enable((uint8_t)irq); |
237 | 235 | return 0; |
238 | 236 | } |
239 | 237 |
|
240 | | -int64_t apic_install(uint64_t vector, uint64_t irq,uint64_t flags) { |
241 | | - if (flags & IRQ_FLAGS_MSIX) |
242 | | - return 0; |
| 238 | +int64_t apic_install(uint64_t vector, uint64_t irq, uint64_t flags) { |
| 239 | + if (flags & IRQ_FLAGS_MSIX) return 0; |
243 | 240 | ioapic_add(vector, irq); |
244 | 241 | return 0; |
245 | 242 | } |
|
0 commit comments