From 9b22a6965579ea1867aea291d910c96f386b518b Mon Sep 17 00:00:00 2001 From: Brett Weiland Date: Tue, 24 Aug 2021 14:09:29 -0500 Subject: major backup 8.24.21 --- src/kernel/madt.c | 179 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100644 src/kernel/madt.c (limited to 'src/kernel/madt.c') diff --git a/src/kernel/madt.c b/src/kernel/madt.c new file mode 100644 index 0000000..62e0535 --- /dev/null +++ b/src/kernel/madt.c @@ -0,0 +1,179 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//madt entry types. there's more, we don't need em yet +#define LOCAL_APIC 0 +#define IO_APIC 1 +#define IO_INT_OVERRIDE 2 +#define IO_APIC_NMI_SOURCE 3 +#define IO_APIC_NMI 4 +#define MADT_LOCAL_APIC_ADDR_OVERRIDE 5 + +struct madt_sdt { + sdt_head header; + uint32_t apic_base; + uint32_t flags; +} __attribute__((packed)); + +struct madt_entry { + uint8_t type; + uint8_t length; +} __attribute__((packed)); + +struct madt_local_apic { + uint8_t processor_id; + uint8_t apic_id; + uint32_t flags; +} __attribute__((packed)); + +struct madt_local_apic_override { + uint16_t reserved; + void *apic_base; +} __attribute__((packed)); + +struct madt_ioapic { + uint8_t apic_id; + uint8_t reserved; + uint32_t addr; + uint32_t gsi_base; +} __attribute__((packed)); + +struct madt_io_int_override { + uint8_t bus_src; //not sure what this is used for. + uint8_t irq; + uint32_t global_vector; + uint16_t flags; +} __attribute__((packed)); + +static struct madt_sdt *madt; + + +void init_madt() { + madt = find_sdt(SDT_MADT); +} + +void debug_madt() { + struct madt_entry *entry; + for( + entry = (void *)madt + sizeof(*madt); + (void *)entry < (void *)madt + madt->header.length; + entry = (void *)entry + entry->length) { + printf("MADT debug: "); + switch(entry->type) { + case LOCAL_APIC: + printf("local APIC\n"); + break; + case IO_APIC: + printf("IOAPIC\n"); + break; + case IO_INT_OVERRIDE: + printf("IOAPIC interupt override\n"); + break; + case IO_APIC_NMI_SOURCE: + printf("IOAPIC NMI\n"); + break; + case IO_APIC_NMI: + printf("Local APIC NMI\n"); + break; + case MADT_LOCAL_APIC_ADDR_OVERRIDE: + printf("APIC addr override\n"); + break; + default: + printf("other\n"); + break; + } + } +} + +unsigned int irq_to_gsi(unsigned int irq) { + struct madt_io_int_override *irq_override; + struct madt_entry *entry; + + for( + entry = (void *)madt + sizeof(*madt); + (void *)entry < (void *)madt + madt->header.length; + entry = (void *)entry + entry->length) { + + if(entry->type == IO_INT_OVERRIDE) { + irq_override = (void *)entry + 2; + if(irq_override->irq == irq) return irq_override->global_vector; + } + } + return (uint32_t)irq; //no entry found +} + +void get_ioapic(struct ioapic_fixedlen *ret) { + struct madt_entry *entry; + struct madt_ioapic *mpio_entry; + + ret->count = 0; + + for( + entry = (void *)madt + sizeof(*madt); + (void *)entry < (void *)madt + madt->header.length; + entry = (void *)entry + entry->length) { + if(entry->type == IO_APIC) { + mpio_entry = (void *)entry + 2; + if(ret->count) { + ret->ioapic = realloc(ret->ioapic, ++ret->count * sizeof(struct ioapic_t)); + } + else { + ret->ioapic = malloc(++ret->count * sizeof(struct ioapic_t)); + } + ret->ioapic[ret->count - 1].address = PHYS_TO_VIRT((uintptr_t)mpio_entry->addr); + ret->ioapic[ret->count - 1].gsi_base = mpio_entry->gsi_base; + } + } +} + +lapic_t get_lapic() { + struct madt_local_apic_override *ap_override; + struct madt_entry *entry; + + for( + entry = (void *)madt + sizeof(*madt); + (void *)entry < (void *)madt + madt->header.length; + entry = (void *)entry + entry->length) { + + if(entry->type == MADT_LOCAL_APIC_ADDR_OVERRIDE) { + ap_override = (void *)entry + 2; + + return (lapic_t)PHYS_TO_VIRT(ap_override->apic_base); + } + } + return (lapic_t)PHYS_TO_VIRT((uint64_t)madt->apic_base); +} + +void get_coreinfo(struct cores_info *cores) { + struct madt_local_apic *ap_info; + struct madt_entry *entry; + uint32_t unused_cpuid, ebx; + + __get_cpuid(1, &unused_cpuid, &ebx, &unused_cpuid, &unused_cpuid); + cores->bsp = ebx << 24; + + bzero(cores, sizeof(*cores)); + + for( + entry = (void *)madt + sizeof(*madt); + (void *)entry < (void *)madt + madt->header.length; + entry = (void *)entry + entry->length) { + + if(entry->type == LOCAL_APIC) { + ap_info = (void *)entry + 2; + if(ap_info->flags & 1) { + cores->apic_id[cores->corecount] = ap_info->processor_id; + cores->corecount++; + } + } + } +} -- cgit v1.2.3