Parse acpi data table
This commit is contained in:
parent
6a033344b5
commit
95108d1c0a
@ -20,7 +20,7 @@ void kmain(uint64_t multiboot_magic, void *multiboot_data)
|
|||||||
kernel_boot_data.commandline,
|
kernel_boot_data.commandline,
|
||||||
kernel_boot_data.bootloader);
|
kernel_boot_data.bootloader);
|
||||||
|
|
||||||
cpu_init();
|
early_cpu_init();
|
||||||
debug_info("Set up boot CPU\n");
|
debug_info("Set up boot CPU\n");
|
||||||
memory_init();
|
memory_init();
|
||||||
debug_info("Set up memory management\n");
|
debug_info("Set up memory management\n");
|
||||||
@ -28,15 +28,13 @@ void kmain(uint64_t multiboot_magic, void *multiboot_data)
|
|||||||
terminal_init();
|
terminal_init();
|
||||||
debug_info("Set up debug terminal\n");
|
debug_info("Set up debug terminal\n");
|
||||||
|
|
||||||
|
cpu_init();
|
||||||
|
|
||||||
debug_info("Boot complete\n");
|
debug_info("Boot complete\n");
|
||||||
|
|
||||||
|
|
||||||
TEMP_test_scheduler();
|
TEMP_test_scheduler();
|
||||||
|
|
||||||
debug("Read MSR APIC_BASE: %lx\n", read_msr(0x0000001B));
|
|
||||||
debug("Read MSR SYSCALL_TARGET: %lx\n", read_msr(0xC0000082));
|
|
||||||
write_msr(0xC0000082, 0x1234567890abcdef);
|
|
||||||
debug("Read MSR SYSCALL_TARGET: %lx\n", read_msr(0xC0000082));
|
|
||||||
|
|
||||||
start_scheduler();
|
start_scheduler();
|
||||||
|
|
||||||
|
133
src/kernel/cpu/acpi.c
Normal file
133
src/kernel/cpu/acpi.c
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
#include <cpu.h>
|
||||||
|
#include <multiboot.h>
|
||||||
|
#include <memory.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
// ACPI Specification https://uefi.org/sites/default/files/resources/ACPI_6_3_final_Jan30.pdf
|
||||||
|
|
||||||
|
struct rsdp // 5.2.5.3
|
||||||
|
{
|
||||||
|
char signature[8];
|
||||||
|
uint8_t checksum;
|
||||||
|
char OEMID[6];
|
||||||
|
uint8_t revision;
|
||||||
|
uint32_t rsdt_p;
|
||||||
|
uint32_t length; // only if revision >= 2
|
||||||
|
uint64_t xsdt_p; // only if revision >= 2
|
||||||
|
uint8_t checksum2; // only if revision >= 2
|
||||||
|
uint8_t reserved[3]; // only if revision >= 2
|
||||||
|
}__attribute__((packed));
|
||||||
|
|
||||||
|
struct sdt_header // 5.2.6
|
||||||
|
{
|
||||||
|
char signature[4];
|
||||||
|
uint32_t length;
|
||||||
|
uint8_t revision;
|
||||||
|
uint8_t checksum;
|
||||||
|
char OEMID[6];
|
||||||
|
char OEMtable[8];
|
||||||
|
uint32_t OEMrevision;
|
||||||
|
uint32_t creatorID;
|
||||||
|
uint32_t creatorRevision;
|
||||||
|
uint8_t data[];
|
||||||
|
}__attribute__((packed));
|
||||||
|
|
||||||
|
struct madt_header // 5.2.12
|
||||||
|
{
|
||||||
|
uint32_t controllerAddress;
|
||||||
|
uint32_t flags;
|
||||||
|
uint8_t fields[];
|
||||||
|
}__attribute__((packed));
|
||||||
|
|
||||||
|
struct madt_field
|
||||||
|
{
|
||||||
|
uint8_t type;
|
||||||
|
uint8_t length;
|
||||||
|
uint8_t data[];
|
||||||
|
}__attribute__((packed));
|
||||||
|
|
||||||
|
// MADT field type: 0
|
||||||
|
#define MADT_TYPE_LAPIC 0
|
||||||
|
struct madt_data_lapic
|
||||||
|
{ // 5.2.12.2
|
||||||
|
uint8_t id;
|
||||||
|
uint8_t apic;
|
||||||
|
uint32_t flags;
|
||||||
|
}__attribute__((packed));
|
||||||
|
|
||||||
|
// MADT field type: 1
|
||||||
|
#define MADT_TYPE_IOAPIC 1
|
||||||
|
struct madt_data_ioapic
|
||||||
|
{ // 5.2.12.3
|
||||||
|
uint8_t id;
|
||||||
|
uint8_t reserved;
|
||||||
|
uint32_t address;
|
||||||
|
uint32_t base;
|
||||||
|
}__attribute__((packed));
|
||||||
|
|
||||||
|
// MADT field type: 2
|
||||||
|
#define MADT_TYPE_ISO 2
|
||||||
|
struct madt_data_iso
|
||||||
|
{ // 5.2.12.5
|
||||||
|
uint8_t bus;
|
||||||
|
uint8_t source;
|
||||||
|
uint32_t interrupt;
|
||||||
|
uint16_t flags;
|
||||||
|
}__attribute__((packed));
|
||||||
|
|
||||||
|
|
||||||
|
void acpi_parse()
|
||||||
|
{
|
||||||
|
int cpu_i=0;
|
||||||
|
|
||||||
|
struct rsdp *rsdp = kernel_boot_data.rsdp;
|
||||||
|
struct sdt_header *rsdt = P2V(rsdp->rsdt_p);
|
||||||
|
|
||||||
|
uint32_t *table = (void *)rsdt->data;
|
||||||
|
int entries = (rsdt->length - sizeof(struct sdt_header))/sizeof(uint32_t);
|
||||||
|
for(int i = 0; i < entries; i++)
|
||||||
|
{
|
||||||
|
struct sdt_header *h = P2V(table[i]);
|
||||||
|
if(h->length == 0) continue;
|
||||||
|
|
||||||
|
if(!strncmp(h->signature, "APIC", 4)) // 5.2.12
|
||||||
|
{
|
||||||
|
struct madt_header *madt = P2V(h->data);
|
||||||
|
for(
|
||||||
|
struct madt_field *f = (void *)madt->fields;
|
||||||
|
(size_t)f <= (size_t)h + h->length;
|
||||||
|
f = incptr(f, f->length)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
switch(f->type) {
|
||||||
|
case MADT_TYPE_LAPIC:
|
||||||
|
{
|
||||||
|
struct madt_data_lapic *lapic = (void *)f->data;
|
||||||
|
struct cpu *cpu = P2V(pmm_alloc());
|
||||||
|
cpus[cpu_i++] = cpu;
|
||||||
|
cpu->id = lapic->id;
|
||||||
|
cpu->apic_id = lapic->apic;
|
||||||
|
cpu->flags = lapic->flags;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MADT_TYPE_IOAPIC:
|
||||||
|
{
|
||||||
|
struct madt_data_ioapic *_ioapic = (void *)f->data;
|
||||||
|
ioapic.id = _ioapic->id;
|
||||||
|
ioapic.addr = _ioapic->address;
|
||||||
|
ioapic.base = _ioapic->base;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MADT_TYPE_ISO:
|
||||||
|
{
|
||||||
|
struct madt_data_iso *iso = (void *)f->data;
|
||||||
|
irq_redirects[iso->source] = iso->interrupt;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,18 @@
|
|||||||
|
#include <cpu.h>
|
||||||
#include <cpu/interrupts.h>
|
#include <cpu/interrupts.h>
|
||||||
|
#include <ports.h>
|
||||||
|
|
||||||
void cpu_init()
|
struct cpu *cpus[16];
|
||||||
|
struct ioapic ioapic = {0,0,0};
|
||||||
|
uint8_t irq_redirects[MAX_IRQS] = \
|
||||||
|
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23};
|
||||||
|
|
||||||
|
void early_cpu_init()
|
||||||
{
|
{
|
||||||
interrupt_init();
|
interrupt_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cpu_init()
|
||||||
|
{
|
||||||
|
acpi_parse();
|
||||||
|
}
|
@ -1,6 +1,26 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define MAX_CPUS 16
|
||||||
|
#define MAX_IRQS 24
|
||||||
|
|
||||||
|
struct cpu {
|
||||||
|
uint8_t id;
|
||||||
|
uint8_t apic_id;
|
||||||
|
uint32_t flags;
|
||||||
|
};
|
||||||
|
struct ioapic {
|
||||||
|
uint8_t id;
|
||||||
|
uint32_t addr;
|
||||||
|
uint32_t base;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct cpu *cpus[MAX_CPUS];
|
||||||
|
extern struct ioapic ioapic;
|
||||||
|
extern uint8_t irq_redirects[MAX_IRQS];
|
||||||
|
|
||||||
// cpu/cpu.c
|
// cpu/cpu.c
|
||||||
|
void early_cpu_init();
|
||||||
void cpu_init();
|
void cpu_init();
|
||||||
|
|
||||||
// cpu/registers.S
|
// cpu/registers.S
|
||||||
@ -8,3 +28,6 @@ void load_idt(void *);
|
|||||||
void write_cr3(uint64_t);
|
void write_cr3(uint64_t);
|
||||||
uint64_t read_msr(uint32_t);
|
uint64_t read_msr(uint32_t);
|
||||||
uint64_t write_msr(uint32_t msr, uint64_t value);
|
uint64_t write_msr(uint32_t msr, uint64_t value);
|
||||||
|
|
||||||
|
// cpu/acpi.c
|
||||||
|
void acpi_parse();
|
Loading…
x
Reference in New Issue
Block a user