Skip to content

Commit

Permalink
MADT parsed
Browse files Browse the repository at this point in the history
  • Loading branch information
nothotscott committed Apr 3, 2021
1 parent 73c8b27 commit afe01f0
Show file tree
Hide file tree
Showing 11 changed files with 197 additions and 18 deletions.
2 changes: 1 addition & 1 deletion build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ function launch-qemu {
)
$program_args = "-drive file=$ABSOLUTE_WIN/$BUILD_DIR/$OSNAME.img "
$program_args += "-drive if=pflash,format=raw,unit=0,readonly=on,file=$OVMF_DIR_WIN/$OVMF_NAME "
$program_args += "-machine type=q35 -cpu qemu64 -m 512M -net none -serial stdio -no-reboot "
$program_args += "-machine type=q35 -cpu qemu64 -smp 2 -m 512M -net none -serial stdio -no-reboot "
if ($debug -eq $true) {
powershell.exe "Start-Process qemu-system-x86_64.exe -ArgumentList '$program_args -s -S'"
} else {
Expand Down
5 changes: 5 additions & 0 deletions src/kernel/kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@
position++; \
}

typedef struct LinkedNode {
void* data;
struct LinkedNode* next;
} LinkedNode;


// From kernel.ld linker script
extern void** _kernel_start;
Expand Down
12 changes: 8 additions & 4 deletions src/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "x86_64/pit.h"
#include "x86_64/acpi.h"
#include "x86_64/pci.h"
#include "x86_64/madt.h"
#include "x86_64/syscall.h"


Expand Down Expand Up @@ -63,12 +64,15 @@ void setup_interrupts() {
idt_load();
}

void setup_pci() {
void setup_acpi() {
struct RSDP2* rsdp = g_interface->rsdp;
struct SDTHeader* xsdt = (struct SDTHeader*)rsdp->xsdt_base;
struct MCFGHeader* mcfg = (struct MCFGHeader*)acpi_get_table(xsdt, "MCFG");
struct MADTHeader* madt = (struct MADTHeader*)acpi_get_table(xsdt, "APIC");
pci_init(mcfg);
pci_print();
io_enable_apic();
madt_init(madt);
//pci_print();
}

void setup_syscall(){
Expand All @@ -86,8 +90,8 @@ void setup() {
debug_output("Setup gdt\n");
setup_interrupts();
debug_output("Setup interrupts\n");
setup_pci();
debug_output("Setup PCI\n");
setup_acpi();
debug_output("Setup ACPI\n");
setup_syscall();
debug_output("Setup syscall\n");

Expand Down
18 changes: 8 additions & 10 deletions src/kernel/x86_64/acpi.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,16 @@ struct SDTHeader {

// Memory Mapped Configuration Space Access Header
struct MCFGHeader {
char signature[4];
uint32_t length;
uint8_t revision;
uint8_t checksum;
uint8_t oem_id[6];
uint8_t oem_table_id[8];
uint32_t oem_revision;
uint32_t creator_id;
uint32_t creator_revision;
uint8_t reserved[8];
struct SDTHeader header;
uint8_t reserved[8];
} __attribute__((packed));

// Multiple APIC Description Table Header
struct MADTHeader {
struct SDTHeader header;
uint32_t apic_address;
uint32_t flags;
} __attribute__((packed));

// Looks up and returns the ACPI table starting at [xsdt] with the [signature]
struct SDTHeader* acpi_get_table(struct SDTHeader* xsdt, char* signature);
2 changes: 1 addition & 1 deletion src/kernel/x86_64/idt.asm
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
;; File: idt.asm
;; Description: x86_64 Interrupt Descriptor Table functions
;;
;; Copyright 2020 Scott Maday
;; Copyright 2020-2021 Scott Maday
;; Check the LICENSE file that came with this program for licensing terms
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Expand Down
17 changes: 17 additions & 0 deletions src/kernel/x86_64/io.asm
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,23 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


GLOBAL io_enable_apic
io_enable_apic:
push rax
push rcx
push rdx

mov ecx, 0x1b ; IA32_APIC_BASE_MSR?
rdmsr
or eax, 0x800 ; IA32_APIC_BASE_MSR_ENABLE?
wrmsr

pop rdx
pop rcx
pop rax
ret


GLOBAL outb
outb: ; rdi=[port], rsi=[value]
mov rdx, rdi ; port
Expand Down
2 changes: 2 additions & 0 deletions src/kernel/x86_64/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

#define IO_PIC_EOI 0x20

// Enables APIC
void io_enable_apic();

// Sends value out onto the processor bus on port
extern void outb(uint16_t port, uint8_t value);
Expand Down
58 changes: 58 additions & 0 deletions src/kernel/x86_64/madt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* File: apic.c
* *****************************************************************************
* Copyright 2021 Scott Maday
* Check the LICENSE file that came with this program for licensing terms
*/

#include "memory/paging.h"
#include "acpi.h"
#include "madt.h"


// Array of processors
static struct MADTLocalProcessor* s_processors[MADT_MAX_PROCESSORS];
static size_t s_processors_num = 0;


#include <stdio.h>
void madt_init(struct MADTHeader* madt) {
for(size_t t = 0; t < madt->header.length - sizeof(struct MADTHeader); /* Do not increment here */ ){
struct MADTRecord* record = (struct MADTRecord*)((uint64_t)madt + sizeof(struct MADTHeader) + t);
paging_identity_map_page(record);
printf("Record type: %d size: %d\n", record->type, record->length);
t += record->length; // increment here
switch(record->type) {
case MADT_TYPE_LOCAL_PROCESSOR:
{
struct MADTLocalProcessor* processor = (struct MADTLocalProcessor*)record;
s_processors[s_processors_num] = processor;
s_processors_num++;
printf(" Processor ID: %d APIC-ID: %d Flags: %d\n", processor->processor_id, processor->apic_id, processor->flags);
}
break;
case MADT_TYPE_IOAPIC:
{
struct MADTIOAPIC* io_apic = (struct MADTIOAPIC*)record;
void* apic_ptr = (void*)(uint64_t)io_apic->apic_address;
paging_identity_map_page(apic_ptr);
printf(" IO APIC: 0x%x\n", apic_ptr);
}
break;
case MADT_TYPE_INTERRUPT_SOURCE_OVERRIDE:
{
struct MADTInterruptSourceOverride* iso = (struct MADTInterruptSourceOverride*)record;
printf(" Interrupt Source Override source: 0x%d\n", iso->source);
}
break;
case MADT_TYPE_NONMASKABLE_INTERRUPT:
{
struct MADTNonMaskableInterrupt* nmi = (struct MADTNonMaskableInterrupt*)record;
printf(" Non-Maskable Interrupt ID: %d\n", nmi->apic_id);
}
break;
case MADT_TYPE_LOCAL_APICADDRESS_OVERRIDE:
break;
}
}
}
94 changes: 94 additions & 0 deletions src/kernel/x86_64/madt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* File: madt.h
* Description: Parse's the MADT (APIC signature) table
* MADT stands for Multiple APIC Description Table
* The file is named this instead of apic so that it's not
* lexically confused with acpi.
* *****************************************************************************
* Copyright 2021 Scott Maday
* Check the LICENSE file that came with this program for licensing terms
*/

#pragma once

#include "acpi.h"

#define MADT_MAX_PROCESSORS 256
#define MADT_IO_APICS 256

struct MADTRecord {
uint8_t type;
uint8_t length;
} __attribute__((packed));

// Type 0: Single physical processor and its local interrupt controller
struct MADTLocalProcessor {
struct MADTRecord record;
uint8_t processor_id;
uint8_t apic_id;
uint32_t flags;
} __attribute__((packed));
// Type 1: IO APIC, the global system interrupt base is the first interrupt number that this IO APIC handles
struct MADTIOAPIC {
struct MADTRecord record;
uint8_t apic_id;
uint8_t reserved;
uint32_t apic_address;
uint32_t global_interrupt_base;
} __attribute__((packed));
// Type 2: Interrupt Source Override explaining how IRQ sources are mapped to global system interrupts
struct MADTInterruptSourceOverride {
struct MADTRecord record;
uint8_t bus; // Always 0 (ISA)
uint8_t source;
uint32_t global_interrupt;
uint16_t flags;
} __attribute__((packed));
// Type 4: Non-maskable interrupt(NMI), which is connected to each processor where it exists
struct MADTNonMaskableInterrupt {
struct MADTRecord record;
uint8_t apic_id;
uint16_t flags;
uint8_t lint;
} __attribute__((packed));
// Type 5: Local APIC Address Override which provides 64 bit systems with an override of the physical address of the local APIC
// There should only be 1 of these
struct MADTLocalAPICAddressOverride {
struct MADTRecord record;
uint8_t reserved[2];
uint64_t local_apic_address;
} __attribute__((packed));


enum MADTType {
MADT_TYPE_LOCAL_PROCESSOR = 0,
MADT_TYPE_IOAPIC = 1,
MADT_TYPE_INTERRUPT_SOURCE_OVERRIDE = 2,
MADT_TYPE_NONMASKABLE_INTERRUPT = 4,
MADT_TYPE_LOCAL_APICADDRESS_OVERRIDE = 5
};

enum MADTIOAPICTriggerMode {
MADT_IOAPIC_TRIGGER_MODE_EDGE,
MADT_IOAPIC_TRIGGER_MODE_LEVEL
};
enum MADTIOAPICPolarity {
MADT_IOAPIC_POLARITY_ACTIVEHIGH,
MADT_IOAPIC_POLARITY_ACTIVELOW
};
enum MADTIOAPICDestinationMode {
MADT_IOAPIC_DESTINATIONMODE_PHYSICAL,
MADT_IOAPIC_DESTINATIONMODE_LOGICAL
};
enum MADTIOAPICDeliveryMode {
MADT_IOAPIC_DELIVERY_MODE_FIXED,
MADT_IOAPIC_DELIVERY_MODE_LOWESTPRIORITY,
MADT_IOAPIC_DELIVERY_MODE_SMI,
MADT_IOAPIC_DELIVERY_MODE_NMI = 0b100,
MADT_IOAPIC_DELIVERY_MODE_INIT,
MADT_IOAPIC_DELIVERY_MODE_EXTINT = 0b111,
};


// Initializes ACPI from [madt]
void madt_init(struct MADTHeader* madt);
3 changes: 2 additions & 1 deletion src/kernel/x86_64/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@
#include "pci.h"


// Array of PCI devices
static struct PCIDeviceHeader* s_pci_devices[PCI_MAX_LANES];
static size_t s_pci_devices_num = 0;


void pci_init(struct MCFGHeader* mcfg) {
//printf("MCFG Length %d\n", mcfg->length);
for(size_t t = 0; t < mcfg->length - sizeof(struct MCFGHeader); t += sizeof(struct PCIDeviceConfigurationDescriptor)){
for(size_t t = 0; t < mcfg->header.length - sizeof(struct MCFGHeader); t += sizeof(struct PCIDeviceConfigurationDescriptor)){
struct PCIDeviceConfigurationDescriptor* descriptor = (struct PCIDeviceConfigurationDescriptor*)((uint64_t)mcfg + sizeof(struct MCFGHeader) + t);
for(uint8_t bus_i = descriptor->bus_start; bus_i < descriptor->bus_end; bus_i++) {
void* bus = (void*)descriptor->base + ((uint64_t)bus_i << 20);
Expand Down
2 changes: 1 addition & 1 deletion src/kernel/x86_64/pit.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

#define PIT_BASE_FREQUENCY 1193182
#define PIT_MAX_DIVISOR 65535
#define PIT_DEFAULT_DIVISOR PIT_MAX_DIVISOR / 10
#define PIT_DEFAULT_DIVISOR PIT_MAX_DIVISOR

#define PIT_PORT 0x40

Expand Down

0 comments on commit afe01f0

Please sign in to comment.