feat: implement PCI subsystem and integrate uACPI support
See previous commit Signed-off-by: kaguya <vpshinomiya@protonmail.com>
This commit is contained in:
+119
-9
@@ -19,6 +19,13 @@
|
||||
#include "arch/x86_64/usermode.h"
|
||||
#include "syscall/syscall.h"
|
||||
#include "fs/vfs.h"
|
||||
#include "time/time.h"
|
||||
#include "arch/x86_64/pit.h"
|
||||
#include <uacpi/uacpi.h>
|
||||
#include <uacpi/event.h>
|
||||
#include <uacpi/sleep.h>
|
||||
#include "arch/x86_64/pci.h"
|
||||
|
||||
|
||||
uintptr_t g_hhdm_offset;
|
||||
#define CPU_STACK_SIZE (64 * 1024)
|
||||
@@ -47,6 +54,13 @@ static volatile struct limine_memmap_request memmap_request = {
|
||||
.revision = 6
|
||||
};
|
||||
|
||||
__attribute__((used, section(".limine_requests")))
|
||||
static volatile struct limine_rsdp_request rsdp_request = {
|
||||
.id = LIMINE_RSDP_REQUEST_ID,
|
||||
.revision = 6
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
__attribute__((used, section(".limine_requests")))
|
||||
@@ -82,7 +96,34 @@ static void hcf(void) {
|
||||
}
|
||||
}
|
||||
|
||||
extern struct kernel_pagemap;
|
||||
uint64_t g_rsdp_phys;
|
||||
|
||||
void shutdown(void) {
|
||||
uacpi_status ret2 = uacpi_prepare_for_sleep_state(UACPI_SLEEP_STATE_S5);
|
||||
if (uacpi_unlikely_error(ret2)) {
|
||||
printf("failed to prepare for sleep: %s", uacpi_status_to_string(ret2));
|
||||
}
|
||||
|
||||
ret2 = uacpi_enter_sleep_state(UACPI_SLEEP_STATE_S5);
|
||||
if (uacpi_unlikely_error(ret2)) {
|
||||
printf("failed to enter sleep: %s", uacpi_status_to_string(ret2));
|
||||
}
|
||||
}
|
||||
|
||||
static uacpi_interrupt_ret handle_power_button(uacpi_handle ctx) {
|
||||
/*
|
||||
* Shut down right here using the helper we have defined above.
|
||||
*
|
||||
* Note that it's generally terrible practice to run any AML from
|
||||
* an interrupt handler, as it's allowed to allocate, map, sleep,
|
||||
* stall, acquire mutexes, etc. So, if possible in your kernel,
|
||||
* instead schedule the shutdown callback to be run in a normal
|
||||
* preemptible context later.
|
||||
*/
|
||||
shutdown();
|
||||
return UACPI_INTERRUPT_HANDLED;
|
||||
}
|
||||
|
||||
// The following will be our kernel's entry point.
|
||||
// If renaming kmain() to something else, make sure to change the
|
||||
@@ -104,9 +145,13 @@ void kmain(void) {
|
||||
|
||||
struct limine_memmap_response *memmap_response = memmap_request.response;
|
||||
|
||||
struct limine_rsdp_response *rsdp_response = rsdp_request.response;
|
||||
|
||||
g_rsdp_phys = (uint64_t)rsdp_response->address - MEM_PHYS_OFFSET;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (!memmap_response) {
|
||||
hcf();
|
||||
@@ -117,6 +162,7 @@ void kmain(void) {
|
||||
fb_width = framebuffer->width;
|
||||
fb_height = framebuffer->height;
|
||||
fb_pitch = framebuffer->pitch / 4;
|
||||
|
||||
|
||||
|
||||
printf("Hello, Kernel!\n");
|
||||
@@ -135,23 +181,29 @@ void kmain(void) {
|
||||
|
||||
|
||||
|
||||
/*uint32_t msr_lo, msr_hi;
|
||||
uint32_t msr_lo, msr_hi;
|
||||
asm volatile("rdmsr" : "=a"(msr_lo), "=d"(msr_hi) : "c"(0x1B));
|
||||
msr_lo &= ~(1 << 11);
|
||||
asm volatile("wrmsr" : : "a"(msr_lo), "d"(msr_hi), "c"(0x1B));*/
|
||||
printf("init pmm");
|
||||
asm volatile("wrmsr" : : "a"(msr_lo), "d"(msr_hi), "c"(0x1B));
|
||||
printf("rsdp: 0x%x\n", g_rsdp_phys);
|
||||
printf("init pmm\n");
|
||||
pmm_init(memmap_response->entries, memmap_response->entry_count);
|
||||
printf("init slab");
|
||||
printf("init slab\n");
|
||||
slab_init();
|
||||
printf("init vmm");
|
||||
printf("init vmm\n");
|
||||
vmm_init(memmap_response->entries, memmap_response->entry_count);
|
||||
|
||||
printf("init gdt");
|
||||
x86_64_GDT_Initialize();
|
||||
x86_64_IDT_Initialize();
|
||||
x86_64_ISR_Initialize();
|
||||
x86_64_IRQ_Initialize();
|
||||
x86_64_EnableInterrupts();
|
||||
//lapic_timer_start(100);
|
||||
x86_64_PIT_Initialize(1000);
|
||||
asm volatile("sti");
|
||||
calibrate_tsc();
|
||||
|
||||
|
||||
//while (1) asm volatile("hlt");
|
||||
|
||||
ata_init();
|
||||
ata_identify();
|
||||
@@ -327,10 +379,68 @@ void kmain(void) {
|
||||
printf("\nKirkOS %s\n", KIRKOS_VERSION);
|
||||
|
||||
x86_64_EnableInterrupts();
|
||||
syscall_init();
|
||||
start_userspace();
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Start with this as the first step of the initialization. This loads all
|
||||
* tables, brings the event subsystem online, and enters ACPI mode. We pass
|
||||
* in 0 as the flags as we don't want to override any default behavior for now.
|
||||
*/
|
||||
uacpi_status ret = uacpi_initialize(0);
|
||||
if (uacpi_unlikely_error(ret)) {
|
||||
printf("uacpi_initialize error: %s", uacpi_status_to_string(ret));
|
||||
}
|
||||
|
||||
/*
|
||||
* Load the AML namespace. This feeds DSDT and all SSDTs to the interpreter
|
||||
* for execution.
|
||||
*/
|
||||
ret = uacpi_namespace_load();
|
||||
if (uacpi_unlikely_error(ret)) {
|
||||
printf("uacpi_namespace_load error: %s", uacpi_status_to_string(ret));
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the namespace. This calls all necessary _STA/_INI AML methods,
|
||||
* as well as _REG for registered operation region handlers.
|
||||
*/
|
||||
ret = uacpi_namespace_initialize();
|
||||
if (uacpi_unlikely_error(ret)) {
|
||||
printf("uacpi_namespace_initialize error: %s", uacpi_status_to_string(ret));
|
||||
}
|
||||
|
||||
/*
|
||||
* Tell uACPI that we have marked all GPEs we wanted for wake (even though we haven't
|
||||
* actually marked any, as we have no power management support right now). This is
|
||||
* needed to let uACPI enable all unmarked GPEs that have a corresponding AML handler.
|
||||
* These handlers are used by the firmware to dynamically execute AML code at runtime
|
||||
* to e.g. react to thermal events or device hotplug.
|
||||
*/
|
||||
ret = uacpi_finalize_gpe_initialization();
|
||||
if (uacpi_unlikely_error(ret)) {
|
||||
printf("uACPI GPE initialization error: %s", uacpi_status_to_string(ret));
|
||||
}
|
||||
|
||||
|
||||
pci_init();
|
||||
|
||||
pci_device_t hda;
|
||||
if (pci_find_hda(&hda)) {
|
||||
printf("[PCI] Found HDA controller at %02x:%02x.%x %04x:%04x\n",
|
||||
hda.addr.bus, hda.addr.device, hda.addr.function,
|
||||
hda.vendor_id, hda.device_id);
|
||||
// BAR0 is usually at hda.bar[0] & ~0xF (MMIO)
|
||||
} else {
|
||||
printf("[PCI] No HDA controller found!\n");
|
||||
}
|
||||
|
||||
|
||||
//syscall_init();
|
||||
//start_userspace();
|
||||
printf("tst");
|
||||
|
||||
|
||||
// We're done, just hang...
|
||||
hcf();
|
||||
}
|
||||
Reference in New Issue
Block a user