Added apic init

This commit is contained in:
Hopeless Tyromancy 2026-02-15 02:23:08 -05:00
parent 531ce911ea
commit 4ca9447efa
10 changed files with 126 additions and 43 deletions

BIN
bin/os

Binary file not shown.

BIN
image.hdd

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -4,38 +4,14 @@
#include "../include/limine.h" #include "../include/limine.h"
// credit to dreamportdev's OSDev-Notes and the OSDev Wiki for table layouts // credit to dreamportdev's OSDev-Notes and the OSDev Wiki for table layouts
//
#include "acpi.h" #include "acpi.h"
#define RSDT_SIGNATURE "RSDT" #define RSDT_SIGNATURE "RSDT"
#define XSDT_SIGNATURE "XSDT" #define XSDT_SIGNATURE "XSDT"
bool rsdp_validate(const u8* data) {
if(memcmp(data, (const u8*)RSDP_SIGNATURE, 8) != 0) {
/* to debug in memcmp is broken somehow */
if(data[0] == 'R' && data[1] == 'S' && data[2] == 'D' && data[3] == 'T' && data[4] == ' ') {
printn((const char*)data, 8);
}
return false;
}
struct acpi_rsdp_header* head = (struct acpi_rsdp_header*)data;
size_t len = sizeof(struct acpi_rsdp_header);
len -= (head->revision == 2) * sizeof(u32) + sizeof(u64) + sizeof(u8) + sizeof(u8[3]);
u32 sum_to_zero = 0;
for(size_t i = 0; i < len; i++) {
sum_to_zero += data[i];
}
return (sum_to_zero & 0xFF) == 0;
}
static bool use_xsdt = false;
static struct acpi_rsdt* rsdt; static struct acpi_rsdt* rsdt;
static struct acpi_xsdt* xsdt;
struct acpi_sdt_header* acpi_get_header(size_t n) {
return (struct acpi_sdt_header*) (use_xsdt? xsdt->addrs[n] : (u64)rsdt->addrs[n]);
}
struct acpi_rsdp_header* rsdp; struct acpi_rsdp_header* rsdp;

View File

@ -11,15 +11,21 @@ pstruct acpi_rsdp_header {
u8 checksum; u8 checksum;
u8 OEMID[6]; u8 OEMID[6];
u8 revision; u8 revision;
u32 addr32_depr; /*
union {
struct acpi_rsdt* rsdt :32;
struct acpi_xsdt* xsdt :32;
} ptr;
*/
u32 ptr32;
// v2 // v2
u32 len; u32 len;
u64 addr; u64 ptr64;
u8 extended_checksum; u8 extended_checksum;
u8 resv[3]; u8 resv[3];
}; };
struct acpi_sdt_header { struct acpi_rsdt {
u8 signature[4]; u8 signature[4];
u32 len; u32 len;
u8 revision; u8 revision;
@ -29,18 +35,10 @@ struct acpi_sdt_header {
u32 OEM_revision; u32 OEM_revision;
u32 creator_id; u32 creator_id;
u32 creator_revision; u32 creator_revision;
union {
u32 addrs32[];
u64 addrs64[];
}; };
struct acpi_rsdt {
// signature == "RSDT"
struct acpi_sdt_header header;
u32 addrs[];
};
struct acpi_xsdt {
// signature == "XSDT"
struct acpi_rsdp_header header;
u64 addrs[];
}; };
extern struct acpi_rsdp_header* rsdp; extern struct acpi_rsdp_header* rsdp;

73
src/apic.c Normal file
View File

@ -0,0 +1,73 @@
#include "common.h"
#include "print.h"
// stub of a PIC layout, we don't need the whole thing
// as we only care about initializing it to disable it
enum {
PIC_COMM_MASTER = 0x20,
PIC_COMM_SLAVE = 0x21,
PIC_DATA_MASTER = 0xA0,
PIC_DATA_SLAVE = 0xA1,
};
static void pic_disable() {
outb(PIC_DATA_MASTER, ~0);
outb(PIC_DATA_SLAVE, ~0);
}
static inline u64 rdmsr(u32 msr) {
u32 hi, lo;
asm volatile (
"rdmsr"
: "=a"(lo), "=d"(hi)
: "c"(msr)
);
return (((u64)hi) << 32) | (u64)lo;
}
static inline void wrmsr(u32 msr, u64 val) {
u32 eax = (u32) val;
u32 edx = (u32) (val >> 32);
asm volatile (
"wrmsr"
:
: "c"(msr), "a" (eax), "d" (edx)
);
}
static u64 apic_base;
u64 apic_get_local_base() {
const u8 APIC_BASE_MSR = 0x1B;
u64 msr = rdmsr(APIC_BASE_MSR);
return (apic_base = (msr & 0xfffff000));
}
static u64 apic_set_local_base(u64 base) {
const u8 APIC_BASE_MSR = 0x1B;
wrmsr(APIC_BASE_MSR, base & 0xfffff000);
return base & 0xfffff000;
}
static u32* apic_reg(u32 reg) {
return (u32*) (apic_base + reg);
}
void apic_enable() {
pic_disable();
print("\nPIC Disabled\n");
apic_set_local_base(apic_get_local_base());
volatile u32* reg = apic_reg(0xF0);
print("Local Base Set\nReg 0xF0 at 0x");
print64((u64) reg);
// set enable flag
*reg = (*reg | 0x100);
print("\nReg written\n");
}

View File

@ -23,6 +23,16 @@ static inline void INT(int n) {
); );
} }
static inline void outb(u16 port, u8 value) {
asm volatile ("outb %0, %1" : : "a"(value), "Nd"(port));
}
static inline void outw(u16 port, u16 value) {
asm volatile ("outw %0, %1" : : "a"(value), "Nd"(port));
}
static inline void outd(u16 port, u32 value) {
asm volatile ("outl %0, %1" : : "a"(value), "Nd"(port));
}
void* memcpy(void* restrict dst, const void* src, size_t n); void* memcpy(void* restrict dst, const void* src, size_t n);
void* memset(void* s, int c, size_t n); void* memset(void* s, int c, size_t n);

View File

@ -29,8 +29,6 @@ enum INT_DESC_FLAGS {
#define CODE64_SELECTOR 0x28 #define CODE64_SELECTOR 0x28
static int cnt = 0;
struct int_desc idt[256]; struct int_desc idt[256];
void set_idt(u8 vect, void* handler, u8 dpl) { void set_idt(u8 vect, void* handler, u8 dpl) {

View File

@ -168,6 +168,9 @@ void print_memmap_entry(struct limine_memmap_entry* entry) {
u32 apic_get_local_base();
void apic_enable();
void kmain() { void kmain() {
if(LIMINE_BASE_REVISION_SUPPORTED(limine_base_revision) == false) { if(LIMINE_BASE_REVISION_SUPPORTED(limine_base_revision) == false) {
hang(); hang();
@ -212,6 +215,31 @@ void kmain() {
print("With signature: "); print("With signature: ");
printn((char*)rsdp->signature, sizeof(rsdp->signature)); printn((char*)rsdp->signature, sizeof(rsdp->signature));
print(" v");
print8(rsdp->revision);
print("\nRSDT at 0x");
struct acpi_rsdt* rsdt =
(struct acpi_rsdt*)(
(rsdp->revision? rsdp->ptr64:rsdp->ptr32) + hhdm_offset
);
print64((u64)rsdt);
print("\nSDT Signature: ");
printn((const char*) rsdt->signature, sizeof(rsdt->signature));
print("\nAPIC Local Base: ");
/* I should check cpuid to ensure its supported but it will
* be for my machines ;^) */
/* APIC stuff */
u32 r = 0xDEADBEEF;
r = apic_get_local_base();
print32(r);
apic_enable();
print("\nAPIC Enabled");
hang(); hang();
} }