Skip to content

Commit

Permalink
- MADT
Browse files Browse the repository at this point in the history
fgsoftware1 committed Oct 2, 2024
1 parent 7a3279e commit 456353d
Showing 14 changed files with 562 additions and 50 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
*.o
*.a
*.bin
*.iso
*.elf
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
====
fgOS
PiriquitOS
====

.. image:: https://app.codacy.com/project/badge/Grade/ed7a424ed40f46b7951a63c882f6fbf6
6 changes: 4 additions & 2 deletions build.ninja
Original file line number Diff line number Diff line change
@@ -25,13 +25,15 @@ build ./build/i386/keyboard.o: gcc ./src/arch/i386/kernel/drivers/keyboard.c
build ./build/i386/fpu.o: gcc ./src/arch/i386/kernel/drivers/fpu.c
build ./build/i386/pit.o: gcc ./src/arch/i386/kernel/drivers/pit.c
build ./build/i386/console.o: gcc ./src/arch/i386/kernel/console.c
build ./build/i386/acpi.o: gcc ./src/arch/i386/kernel/acpi.c
build ./build/i386/madt.o: gcc ./src/arch/i386/kernel/madt.c
build ./build/i386/kernel.o: gcc ./src/arch/i386/kernel/kernel.c

build ./isodir/boot/piriquitOS-i386.bin: ld ./build/libc/string.o ./build/i386/boot.o ./build/i386/gdt.asm.o ./build/i386/gdt.c.o ./build/i386/idt.c.o ./build/i386/idt.asm.o ./build/i386/irq.o ./build/i386/exceptions.o ./build/i386/isr.o ./build/i386/io.o ./build/i386/vga.o ./build/i386/pic.o ./build/i386/cmos.o ./build/i386/keyboard.o ./build/i386/pit.o ./build/i386/console.o ./build/i386/fpu.o ./build/i386/kernel.o
build ./isodir/boot/piriquitOS-i386.bin: ld ./build/i386/acpi.o ./build/i386/madt.o ./build/libc/string.o ./build/i386/boot.o ./build/i386/gdt.asm.o ./build/i386/gdt.c.o ./build/i386/idt.c.o ./build/i386/idt.asm.o ./build/i386/irq.o ./build/i386/exceptions.o ./build/i386/isr.o ./build/i386/io.o ./build/i386/vga.o ./build/i386/pic.o ./build/i386/cmos.o ./build/i386/keyboard.o ./build/i386/pit.o ./build/i386/console.o ./build/i386/fpu.o ./build/i386/kernel.o
build ./build/piriquitOS-i386.iso: iso ./isodir

#phony
build libc: phony ./build/libc/string.o ./libs/libc.a
build i386: phony ./build/libc/string.o ./build/i386/boot.o ./build/i386/gdt.asm.o ./build/i386/idt.asm.o ./build/i386/irq.o ./build/i386/exceptions.o ./build/i386/isr.o ./build/i386/io.o ./build/i386/vga.o ./build/i386/pic.o ./build/i386/cmos.o ./build/i386/keyboard.o ./build/i386/console.o ./build/i386/fpu.o ./build/i386/pit.o ./build/i386/kernel.o ./isodir/boot/piriquitOS-i386.bin ./build/piriquitOS-i386.iso
build i386: phony ./libs/libc.a ./build/i386/acpi.o ./build/i386/madt.o ./build/i386/boot.o ./build/i386/gdt.asm.o ./build/i386/idt.asm.o ./build/i386/irq.o ./build/i386/exceptions.o ./build/i386/isr.o ./build/i386/io.o ./build/i386/vga.o ./build/i386/pic.o ./build/i386/cmos.o ./build/i386/keyboard.o ./build/i386/console.o ./build/i386/fpu.o ./build/i386/pit.o ./build/i386/kernel.o ./isodir/boot/piriquitOS-i386.bin ./build/piriquitOS-i386.iso

default help
83 changes: 83 additions & 0 deletions src/arch/i386/kernel/acpi.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#include "include/acpi.h"
#include "libc/include/string.h"
#include "libc/include/stdio.h"

static acpi_rsdp_t *rsdp = NULL;
static acpi_xsdt_t *xsdt = NULL;

static bool validate_table(acpi_sdt_header_t *table_header) {
u8 sum = 0;
for (u32 i = 0; i < table_header->length; i++) {
sum += ((u8 *) table_header)[i];
}
return sum == 0;
}

bool acpi_init(void) {
// Search for the RSDP
for (u8 *addr = (u8 *)0x000E0000; addr < (u8 *)0x00100000; addr += 16) {
if (memcmp(addr, "RSD PTR ", 8) == 0) {
rsdp = (acpi_rsdp_t *)addr;
break;
}
}

if (!rsdp) {
printf("ACPI: RSDP not found\n");
return false;
}

// Validate RSDP checksum
u8 sum = 0;
for (int i = 0; i < sizeof(acpi_rsdp_t); i++) {
sum += ((u8 *)rsdp)[i];
}
if (sum != 0) {
printf("ACPI: RSDP checksum invalid\n");
return false;
}

// Get XSDT
xsdt = (acpi_xsdt_t *)(u32)rsdp->rsdt_address;

if (!validate_table(&xsdt->header)) {
printf("ACPI: XSDT checksum invalid\n");
return false;
}

printf("ACPI: Initialization successful\n");
return true;
}

void *acpi_find_table(const char *signature) {
u32 entries = (xsdt->header.length - sizeof(acpi_sdt_header_t)) / sizeof(u64);

for (u32 i = 0; i < entries; i++) {
acpi_sdt_header_t *header = (acpi_sdt_header_t *)(u32)xsdt->entry[i];
if (memcmp(header->signature, signature, 4) == 0) {
if (validate_table(header)) {
return header;
} else {
printf("ACPI: Found table %.4s but checksum invalid\n", signature);
return NULL;
}
}
}

printf("ACPI: Table %.4s not found\n", signature);
return NULL;
}

void probe_acpi(void) {
printf("ACPI: Probing tables\n");
printf("ACPI: RSDP found at 0x%x\n", (u32)rsdp);
printf("ACPI: XSDT found at 0x%x\n", (u32)xsdt);

u32 entries = (xsdt->header.length - sizeof(acpi_sdt_header_t)) / sizeof(u64);
printf("ACPI: XSDT contains %d entries\n", entries);

for (u32 i = 0; i < entries; i++) {
acpi_sdt_header_t *header = (acpi_sdt_header_t *)(u32)xsdt->entry[i];
printf("ACPI: Found table %.4s at 0x%x\n", header->signature, (u32)header);
}
}
39 changes: 35 additions & 4 deletions src/arch/i386/kernel/drivers/cmos.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
#include "../include/drivers/cmos.h"
#include "../include/drivers/pic.h"
#include "../include/console.h"
#include "../include/isr.h"
#include "../include/io.h"

void rtc_handler(struct registers_t *r) {
void rtc_handler(struct registers_t *r)
{
u8 seconds = cmos_read(RTC_SECONDS);
u8 minutes = cmos_read(RTC_MINUTES);
u8 hours = cmos_read(RTC_HOURS);
@@ -14,18 +16,47 @@ void rtc_handler(struct registers_t *r) {
pic_eoi(IRQ_CMOS);
}

void init_cmos(){
void init_cmos()
{
printf("Initiating CMOS...\n");
isr_register_interrupt_handler(IRQ_CMOS, rtc_handler);
cmos_self_test();
unmask(IRQ_CMOS - IRQ_BASE);
cmos_write(0x0A, cmos_read(0x0A) | 0x40);
}

u8 cmos_read(u8 reg) {
void cmos_self_test()
{
printf("Performing CMOS self-test...\n");

u8 test_address = 0x10;
u8 test_value = 0xAA;
u8 original_value = cmos_read(test_address);

cmos_write(test_address, test_value);

u8 read_value = cmos_read(test_address);

if (read_value == test_value)
{
printf("CMOS self-test passed.\n");
}
else
{
printf("CMOS self-test failed.\n");
}

cmos_write(test_address, original_value);
}

u8 cmos_read(u8 reg)
{
outportb(CMOS_ADDR_REG, reg);
return inportb(CMOS_DATA_REG);
}

void cmos_write(u8 reg, u8 val) {
void cmos_write(u8 reg, u8 val)
{
outportb(CMOS_ADDR_REG, reg);
outportb(CMOS_DATA_REG, val);
}
71 changes: 69 additions & 2 deletions src/arch/i386/kernel/drivers/keyboard.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#include "../include/drivers/keyboard.h"
#include "../include/drivers/pic.h"
#include "../include/console.h"
#include "../include/console.h"
#include "../include/idt.h"
#include "../include/io.h"
@@ -16,8 +18,7 @@ char g_scan_code_chars[128] = {
0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0,
'\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0, '*', 0, ' ',
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, 0, 0, '+', 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0
};
0, 0, 0, 0, 0, 0, 0, 0, 0};

static int get_scancode()
{
@@ -153,12 +154,78 @@ void keyboard_handler(registers_t *r)
break;
}
}

pic_eoi(IRQ_KEYBOARD);
}

static void wait_for_keyboard_controller(void){
while (inportb(KEYBOARD_STATUS_PORT) & 0x02)
;
}

static void keyboard_send_command(u8 command){
wait_for_keyboard_controller();
outportb(KEYBOARD_COMMAND_PORT, command);
}

static void keyboard_send_data(u8 data){
wait_for_keyboard_controller();
outportb(KEYBOARD_DATA_PORT, data);
}

void init_keyboard()
{
printf("Initiating keyboard...\n");
flush_keyboard_buffer();
isr_register_interrupt_handler(IRQ_KEYBOARD, keyboard_handler);
keyboard_self_test();
unmask(IRQ_KEYBOARD - IRQ_BASE);
}

void flush_keyboard_buffer(void){
while (inportb(KEYBOARD_STATUS_PORT) & 0x01)
{
inportb(KEYBOARD_DATA_PORT);
}
}

void keyboard_self_test(){
printf("Performing keyboard self-test...\n");

// disable keyboard
keyboard_send_command(0xAD);

// Flush the keyboard buffer
flush_keyboard_buffer();

// Perform keyboard controller self-test
keyboard_send_command(0xAA);
if (inportb(KEYBOARD_DATA_PORT) != 0x55)
{
printf("Keyboard controller self-test failed\n");
return;
}

// Perform keyboard interface test
keyboard_send_command(0xAB);
if (inportb(KEYBOARD_DATA_PORT) != 0x00)
{
printf("Keyboard interface test failed\n");
return;
}

// Enable keyboard
keyboard_send_command(0xAE);

// Reset keyboard
keyboard_send_data(0xFF);
if (inportb(KEYBOARD_DATA_PORT) != 0xFA)
{
printf("Keyboard reset failed\n");
return;
}

printf("If no errors where printed above keyboard self-test passed.\n");
}

char kb_getchar()
7 changes: 3 additions & 4 deletions src/arch/i386/kernel/drivers/pic.c
Original file line number Diff line number Diff line change
@@ -25,8 +25,7 @@ void init_pic()
outportb(PIC_SLAVE_DATA, a2);

//! MASKING ALL INTERRUPTS
//outportb(PIC_MASTER_DATA, 0xFF);
//outportb(PIC_SLAVE_DATA, 0xFF);
pic_disable();
}

void pic_disable()
@@ -56,7 +55,7 @@ void mask(u8 irq)
port = PIC_SLAVE_DATA;
irq -= 8;
}
value = inportb(port) &~ (1 << irq);
value = inportb(port) | (1 << irq);
outportb(port, value);
}

@@ -74,7 +73,7 @@ void unmask(u8 irq)
port = PIC_SLAVE_DATA;
irq -= 8;
}
value = inportb(port) | (1 << irq);
value = inportb(port) &~ (1 << irq);
outportb(port, value);
}

38 changes: 16 additions & 22 deletions src/arch/i386/kernel/drivers/pit.c
Original file line number Diff line number Diff line change
@@ -3,28 +3,21 @@
#include "../include/io.h"
#include "../include/isr.h"

u64 ticks;
const u32 freq = 100;
volatile u32 pit_ticks = 0;

void pit_handler(struct registers_t *r) { ticks += 1; }
void pit_handler(struct registers_t *r) { pit_ticks ++; }

void init_pit() {
printf("Initiating PIT...\n");
isr_register_interrupt_handler(IRQ_TIMER, pit_handler);
start_pit_timer();
unmask(IRQ_TIMER - IRQ_BASE);
}

void start_pit_timer() {
if (freq == 0) {
printf("Can't divide by zero!");
return;
}

u16 divisor = 1193180 / freq;

outportb(PIT_COMMAND_PORT, PIT_COMMAND_REGISTER);
outportb(PIT_CH0_DATA_PORT, (u8)(divisor & 0xFF)); // Send the low byte
outportb(PIT_CH0_DATA_PORT, (u8)((divisor >> 8) & 0xFF)); // Send the high byte
void start_pit_timer(u32 frequency) {
u32 divisor = PIT_FREQUENCY / frequency;
outportb(PIT_COMMAND_REGISTER, 0x36); // Set the operating mode to square wave generator
outportb(PIT_CH0_DATA_PORT, divisor & 0xFF); // Set low byte of divisor
outportb(PIT_CH0_DATA_PORT, (divisor >> 8) & 0xFF); // Set high byte of divisor
}

void stop_pit_timer() { outportb(PIT_COMMAND_PORT, 0x30); }
@@ -73,20 +66,21 @@ void write_pit(u8 channel, u8 value) {
}

void sleep(u32 milliseconds) {
// Calculate the number of PIT ticks needed for the delay
u32 ticks = milliseconds * 1000 / ticks;
u32 ticks = (milliseconds * PIT_FREQUENCY) / 1000;

// Save the current PIT channel 0 count
u8 initialCounter = inportb(PIT_CH0_DATA_PORT);
u8 initialCounterLow = inportb(PIT_CH0_DATA_PORT);
u8 initialCounterHigh = inportb(PIT_CH0_DATA_PORT);

start_pit_timer();
pit_ticks = 0;
start_pit_timer(1000); // Set PIT to 1ms intervals

while (ticks > 0) {
while (pit_ticks < ticks) {
// Wait for PIT interrupt
ticks--;
}

// Restore the initial PIT channel 0 count
outportb(PIT_COMMAND_REGISTER, 0x36); // Set the operating mode to square wave generator
outportb(PIT_CH0_DATA_PORT, initialCounter); // Set the initial counter value
outportb(PIT_CH0_DATA_PORT, initialCounterLow); // Restore low byte of initial counter
outportb(PIT_CH0_DATA_PORT, initialCounterHigh); // Restore high byte of initial counter
}
39 changes: 39 additions & 0 deletions src/arch/i386/kernel/include/acpi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#ifndef ACPI_H
#define ACPI_H

#include "libc/include/types.h"

// ACPI table header structure
typedef struct {
char signature[4];
u32 length;
u8 revision;
u8 checksum;
char oem_id[6];
char oem_table_id[8];
u32 oem_revision;
u32 creator_id;
u32 creator_revision;
} __attribute__((packed)) acpi_sdt_header_t;

// Root System Description Pointer (RSDP) structure
typedef struct {
char signature[8];
u8 checksum;
char oem_id[6];
u8 revision;
u32 rsdt_address;
} __attribute__((packed)) acpi_rsdp_t;

// Extended System Description Table (XSDT) structure
typedef struct {
acpi_sdt_header_t header;
u64 entry[1];
} __attribute__((packed)) acpi_xsdt_t;

// Function declarations
bool acpi_init(void);
void *acpi_find_table(const char *signature);
void probe_acpi(void);

#endif // ACPI_H
1 change: 1 addition & 0 deletions src/arch/i386/kernel/include/drivers/pit.h
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@
#define PIT_CH2_DATA_PORT 0x42
#define PIT_COMMAND_PORT 0x43
#define PIT_COMMAND_REGISTER 0x36
#define PIT_FREQUENCY 1193182

#include "../libc/include/types.h"

64 changes: 64 additions & 0 deletions src/arch/i386/kernel/include/madt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#ifndef MADT_H
#define MADT_H

#include "libc/include/types.h"

#define MADT_TYPE_LOCAL_APIC 0
#define MADT_TYPE_IO_APIC 1
#define MADT_TYPE_INTERRUPT_OVERRIDE 2
#define MADT_TYPE_NMI_SOURCE 3
#define MADT_TYPE_LOCAL_APIC_NMI 4
#define MADT_TYPE_LOCAL_APIC_OVERRIDE 5
#define MADT_TYPE_IO_SAPIC 6
#define MADT_TYPE_LOCAL_SAPIC 7
#define MADT_TYPE_PLATFORM_INT_SOURCES 8
#define APIC_LOCAL_APIC_PRESENT 0x01
#define APIC_IO_APIC_PRESENT 0x02

struct acpi_header
{
char signature[4];
u32 length;
u8 revision;
u8 checksum;
char oem_id[6];
char oem_table_id[8];
u32 oem_revision;
u32 creator_id;
u32 creator_revision;
};

struct rsdp
{
char signature[8];
u8 checksum;
char oem_id[6];
u8 revision;
u32 rsdt_address;
// ACPI 2.0+ fields
u32 length;
u64 xsdt_address;
u8 extended_checksum;
u8 reserved[3];
};

struct rsdt
{
struct acpi_header header;
u32 entry[0];
};

struct madt
{
struct acpi_header header;
u32 local_apic_address;
u32 flags;
};

struct madt_entry_header
{
u8 type;
u8 length;
};

#endif // !MADT_H
2 changes: 1 addition & 1 deletion src/arch/i386/kernel/isr.c
Original file line number Diff line number Diff line change
@@ -64,7 +64,7 @@ static void print_registers(registers_t *reg) {
printf("err_code=%d\n", reg->err_code);
printf("eax=0x%x, ebx=0x%x, ecx=0x%x, edx=0x%x\n", reg->eax, reg->ebx, reg->ecx, reg->edx);
printf("edi=0x%x, esi=0x%x, ebp=0x%x, esp=0x%x\n", reg->edi, reg->esi, reg->ebp, reg->esp);
printf("eip=0x%x, cs=0x%x, ss=0x%x, eflags=0x%x, useresp=0x%x\n", reg->eip, reg->ss, reg->eflags, reg->useresp);
printf("eip=0x%x, cs=0x%x, ss=0x%x, eflags=0x%x, useresp=0x%x\n", reg->eip, reg->cs, reg->ss, reg->eflags, reg->useresp);
}

void isr_exception_handler(registers_t reg) {
43 changes: 29 additions & 14 deletions src/arch/i386/kernel/kernel.c
Original file line number Diff line number Diff line change
@@ -7,16 +7,16 @@
#include "include/drivers/cmos.h"
#include "include/drivers/fpu.h"
#include "include/drivers/pit.h"
#include "include/madt.h"

void cpuid(u32 type, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx)
{
asmv("cpuid"
: "=a"(*eax),
"=b"(*ebx),
"=c"(*ecx),
"=d"(*edx)
: "0"(type)
);
: "=a"(*eax),
"=b"(*ebx),
"=c"(*ecx),
"=d"(*edx)
: "0"(type));
}

int cpuid_info(int print)
@@ -87,37 +87,52 @@ void kmain()
{
continue;
}

if (strcmp(buffer, "clear") == 0)
{
console_clear(COLOR_WHITE, COLOR_BLACK);
}else if (strcmp(buffer, "cpuid") == 0)
}
else if (strcmp(buffer, "cpuid") == 0)
{
cpuid_info(1);
}else if (strcmp(buffer, "help") == 0)
}
else if (strcmp(buffer, "help") == 0)
{
printf("Commands:\n help\n cpuid\n echo\n time\n shutdown\n");
}else if (is_echo(buffer))
}
else if (is_echo(buffer))
{
printf("%s\n", buffer + 5);
}else if (strcmp(buffer, "shutdown") == 0)
}
else if (strcmp(buffer, "shutdown") == 0)
{
printf("Shutting down in 5s...\n");
sleep(5);
shutdown();
}else if (strcmp(buffer, "time") == 0)
}
else if (strcmp(buffer, "time") == 0)
{
u8 seconds = cmos_read(RTC_SECONDS);
u8 minutes = cmos_read(RTC_MINUTES);
u8 hours = cmos_read(RTC_HOURS);
u8 hours = cmos_read(RTC_HOURS);
u8 day = cmos_read(RTC_DAY);
u8 month = cmos_read(RTC_MONTH);
u8 year = cmos_read(RTC_YEAR);
u8 century = cmos_read(RTC_CENTURY);

printf("Time: %d:%d:%d\n", hours, minutes, seconds);
printf("Date: %d/%d/%d%d\n", day, month, year, century);
}else if (strcmp(buffer, "devinfo") == 0){
}
else if (strcmp(buffer, "devinfo") == 0)
{
printf("===PIC===\n");
probe_pic();
}else
}
else if (strcmp(buffer, "madtinfo") == 0)
{
probe_madt();
}
else
{
printf("invalid command: %s\n", buffer);
}
216 changes: 216 additions & 0 deletions src/arch/i386/kernel/madt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
#include "include/madt.h"
#include "include/console.h"
#include "include/drivers/pit.h"

struct rsdp *find_rsdp(void)
{
u32 *addr;
for (addr = (u32 *)0x000E0000; addr < (u32 *)0x00100000; addr += 4)
{
if (*addr == 0x20445352 && *(addr + 1) == 0x20525450)
{
return (struct rsdp *)addr;
}
}
return NULL;
}

bool verify_checksum(void *table, u32 length)
{
u8 sum = 0;
for (u32 i = 0; i < length; i++)
{
sum += ((u8 *)table)[i];
}
return sum == 0;
}

void *find_madt(struct rsdp *rsdp)
{
if (!rsdp)
{
printf("RSDP is NULL\n");
return NULL;
}

printf("RSDP found at: 0x%08X\n", (u32)rsdp);
printf("RSDT address: 0x%08X\n", rsdp->rsdt_address);

if (!verify_checksum(rsdp, 20))
{
printf("RSDP checksum verification failed\n");
return NULL;
}

struct rsdt *rsdt = (struct rsdt *)(uintptr_t)rsdp->rsdt_address;
if (!rsdt)
{
printf("RSDT is NULL\n");
return NULL;
}

printf("RSDT found at: 0x%08X\n", (u32)rsdt);

if (!verify_checksum(rsdt, rsdt->header.length))
{
printf("RSDT checksum verification failed\n");
return NULL;
}

u32 entries = (rsdt->header.length - sizeof(struct acpi_header)) / 4;
printf("Number of RSDT entries: %d\n", entries);

for (u32 i = 0; i < entries; i++)
{
struct acpi_header *header = (struct acpi_header *)(uintptr_t)rsdt->entry[i];
printf("Table %d address: 0x%08X\n", i, (u32)header);

if (header)
{
printf("Table %d signature: %.4s\n", i, header->signature);
if (*(u32 *)header->signature == 0x43495041)
{
printf("MADT found at: 0x%08X\n", (u32)header);
if (verify_checksum(header, header->length))
{
return header;
}
else
{
printf("MADT checksum verification failed\n");
}
}
}
else
{
printf("Table %d is NULL\n", i);
}
}

printf("MADT not found in RSDT\n");
return NULL;
}

bool check_apic_presence(struct madt *madt)
{
u8 apic_presence = 0;
u8 *entry = (u8 *)madt + sizeof(struct madt);
u8 *end = (u8 *)madt + madt->header.length;

while (entry < end)
{
struct madt_entry_header *header = (struct madt_entry_header *)entry;

switch (header->type)
{
case 0: // Processor LAPIC
apic_presence |= APIC_LOCAL_APIC_PRESENT;
break;
case 1: // I/O APIC
apic_presence |= APIC_IO_APIC_PRESENT;
break;
}

entry += header->length;
}

return apic_presence != 0;
}

void print_madt_info(struct madt *madt)
{
if (!madt)
{
printf("Error: MADT pointer is NULL\n");
return;
}

printf("MADT Information:\n");
printf(" Signature: %.4s\n", madt->header.signature);
printf(" Length: %u\n", madt->header.length);
printf(" Revision: %u\n", madt->header.revision);
printf(" Checksum: 0x%02X\n", madt->header.checksum);
printf(" OEM ID: %.6s\n", madt->header.oem_id);
printf(" OEM Table ID: %.8s\n", madt->header.oem_table_id);
printf(" OEM Revision: %u\n", madt->header.oem_revision);
printf(" Creator ID: 0x%08X\n", madt->header.creator_id);
printf(" Creator Revision: %u\n", madt->header.creator_revision);
printf(" LAPIC Address: 0x%08X\n", madt->local_apic_address);
printf(" Flags: 0x%08X\n", madt->flags);

bool apic_present = check_apic_presence(madt);

if (apic_present != 0)
{
printf("Checking for APIC...\n");
}

if (apic_present)
{
printf("APIC is present\n");

u32 offset = sizeof(struct madt);
while (offset < madt->header.length)
{
struct madt_entry_header *entry = (struct madt_entry_header *)((u8 *)madt + offset);

switch (entry->type)
{
case MADT_TYPE_LOCAL_APIC:
printf(" Local APIC:\n");
printf(" Processor ID: %u\n", *((u8 *)entry + 2));
printf(" APIC ID: %u\n", *((u8 *)entry + 3));
printf(" Flags: 0x%08X\n", *((u32 *)((u8 *)entry + 4)));
break;
case MADT_TYPE_IO_APIC:
printf(" I/O APIC:\n");
printf(" I/O APIC ID: %u\n", *((u8 *)entry + 2));
printf(" I/O APIC Address: 0x%08X\n", *((u32 *)((u8 *)entry + 4)));
printf(" Global System Interrupt Base: %u\n", *((u32 *)((u8 *)entry + 8)));
sleep(5);
console_clear(COLOR_WHITE, COLOR_BLACK);
break;
// case MADT_TYPE_INTERRUPT_OVERRIDE:
// printf(" Interrupt Source Override:\n");
// printf(" Bus: %u\n", *((u8 *)entry + 2));
// printf(" Source: %u\n", *((u8 *)entry + 3));
// printf(" Global System Interrupt: %u\n", *((u32 *)((u8 *)entry + 4)));
// printf(" Flags: 0x%04X\n", *((u16 *)((u8 *)entry + 8)));
// break;
default:
//TODO: Print unhandled MADT entry type
//printf(" Unknown MADT entry type: %u\n", entry->type);
break;
}

offset += entry->length;
}
}
else
{
printf("No APIC found!\n");
// TODO: Uncomment this when APIC is implemented
// printf("Falling back to PIC!\n");
}
}

void probe_madt(void)
{
struct rsdp *rsdp = find_rsdp();
if (!rsdp)
{
printf("RSDP not found\n");
return;
}

struct madt *madt = (struct madt *)find_madt(rsdp);
if (madt)
{
printf("MADT found!\n");
print_madt_info(madt);
}
else
{
printf("MADT not found!\n");
}
}

0 comments on commit 456353d

Please sign in to comment.