Initialize ACPI tables

This commit is contained in:
Mathieu Strypsteen 2024-07-12 13:18:03 +02:00
parent 17c4d60c82
commit 0983b36cc7
4 changed files with 52 additions and 19 deletions

View file

@ -1,4 +1,5 @@
use core::{
arch::asm,
panic,
sync::atomic::{AtomicBool, Ordering},
};
@ -40,6 +41,11 @@ fn _get_free_frame() -> u64 {
}
panic!("No free memory left");
}
fn invlpg(addr: u64) {
unsafe {
asm!("invlpg [{}]", in(reg) addr);
}
}
fn virt_to_phys(virt: u64) -> u64 {
if !PAGING_ACTIVE.load(Ordering::Relaxed) {
return virt - KERNEL_HEAP_START + HEAP_PHYS_START.get().unwrap();
@ -64,22 +70,25 @@ fn get_table_entry(table: &mut PageTable, i: usize) -> &mut PageTable {
}
return table.entries_virt[i].as_mut().unwrap();
}
fn get_page(pml4: &PageTable, virt: u64) -> Option<&PageEntry> {
fn get_page(pml4: &mut PageTable, virt: u64) -> Option<&mut PageEntry> {
let virt_page = virt as usize / 0x1000;
let table_i = virt_page % 512;
let directory_i = virt_page / 512 % 512;
let pdpt_i = virt_page / 512 / 512 % 512;
let pml4_i = virt_page / 512 / 512 / 512 % 512;
let pdpt = &pml4.entries_virt[pml4_i];
let pdpt = &mut pml4.entries_virt[pml4_i];
if pdpt.is_some() {
let pdpt = pdpt.as_ref().unwrap();
let directory = &pdpt.entries_virt[pdpt_i];
let pdpt = pdpt.as_mut().unwrap();
let directory = &mut pdpt.entries_virt[pdpt_i];
if directory.is_some() {
let directory = directory.as_ref().unwrap();
let table = &directory.entries_virt[directory_i];
let directory = directory.as_mut().unwrap();
let table = &mut directory.entries_virt[directory_i];
if table.is_some() {
let table = table.as_ref().unwrap();
return Some(&table.entries_phys[table_i]);
let table = table.as_mut().unwrap();
if table.entries_phys[table_i].present() == 0 {
return None;
}
return Some(&mut table.entries_phys[table_i]);
}
}
}
@ -125,6 +134,19 @@ fn map(pml4: &mut PageTable, virt: u64, phys: u64, user: bool, write: bool, exec
table.entries_phys[table_i].set_execute_disable(!exec as u64);
table.entries_phys[table_i].set_present(1);
}
pub unsafe fn unmap(address: u64) {
let mut current_pml4 = CURRENT_PML4.lock();
let page = get_page(current_pml4.as_mut().unwrap(), address);
assert!(page.is_some(), "Page isn't mapped");
match page {
Some(page) => {
page.set_present(0);
page.set_address(0);
invlpg(address);
}
None => {}
}
}
pub unsafe fn map_range(virt_start: u64, phys_start: u64, size: u64, user: bool, write: bool, exec: bool) {
assert_eq!(virt_start % 0x1000, 0);
assert_eq!(phys_start % 0x1000, 0);

View file

@ -3,7 +3,7 @@
extern crate alloc;
use core::{arch::global_asm, mem::MaybeUninit, panic::PanicInfo};
use core::{arch::global_asm, mem::MaybeUninit, panic::PanicInfo, ptr::null_mut};
use cpu::{gdt::setup_gdt, idt::setup_idt, paging::setup_paging};
use kernel_common::{
@ -15,7 +15,7 @@ use kernel_common::{
use linked_list_allocator::LockedHeap;
use log::{error, info};
use spin::Once;
use sys::pic::disable_pic;
use sys::{acpica::AcpiInitializeTables, pic::disable_pic};
mod cpu;
mod misc;
@ -45,6 +45,9 @@ extern "C" fn main(temp_loader_struct: *const LoaderStruct) -> ! {
setup_paging(&loader_struct, loader_struct.phys_kernel_start, loader_struct.phys_heap_start);
disable_pic();
RSDP_ADDRESS.call_once(|| loader_struct.rsdp_address);
unsafe {
AcpiInitializeTables(null_mut(), 16, 0);
}
loop {
hlt();
}

View file

@ -7,12 +7,12 @@ use core::{
use kernel_common::log::log_raw;
use crate::{
cpu::paging::{find_free_virt_range, map_range, KERNEL_MAPPINGS_END, KERNEL_MAPPINGS_START},
cpu::paging::{find_free_virt_range, map_range, unmap, KERNEL_MAPPINGS_END, KERNEL_MAPPINGS_START},
misc::wrapped_alloc::{wrapped_alloc, wrapped_dealloc},
RSDP_ADDRESS,
};
use super::acpica::{ACPI_PHYSICAL_ADDRESS, ACPI_PREDEFINED_NAMES, ACPI_SIZE, ACPI_STATUS, ACPI_STRING, ACPI_TABLE_HEADER, UINT32};
use super::acpica::{ACPI_PHYSICAL_ADDRESS, ACPI_PREDEFINED_NAMES, ACPI_SIZE, ACPI_STATUS, ACPI_STRING, ACPI_TABLE_HEADER, UINT32, UINT64};
pub const AE_OK: ACPI_STATUS = 0;
@ -58,8 +58,8 @@ extern "C" fn AcpiOsGetRootPointer() -> ACPI_PHYSICAL_ADDRESS {
*RSDP_ADDRESS.get().unwrap()
}
#[no_mangle]
extern "C" fn AcpiOsGetThreadId() {
panic!("Unimplemented");
extern "C" fn AcpiOsGetThreadId() -> UINT64 {
1
}
#[no_mangle]
extern "C" fn AcpiOsGetTimer() {
@ -148,8 +148,16 @@ extern "C" fn AcpiOsTerminate() -> ACPI_STATUS {
AE_OK
}
#[no_mangle]
extern "C" fn AcpiOsUnmapMemory() {
panic!("Unimplemented");
extern "C" fn AcpiOsUnmapMemory(address: *mut c_void, size: ACPI_SIZE) {
let address = address as u64;
let end = (address + size + 0xfff) / 0x1000 * 0x1000;
let start = address / 0x1000 * 0x1000;
let size = end - start;
for i in 0..size / 0x1000 {
unsafe {
unmap(start + i * 0x1000);
}
}
}
#[no_mangle]
extern "C" fn AcpiOsPrint(raw_str: *const c_char) {

6
loader/Cargo.lock generated
View file

@ -123,9 +123,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.69"
version = "2.0.70"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "201fcda3845c23e8212cd466bfebf0bd20694490fc0356ae8e428e0824a915a6"
checksum = "2f0209b68b3613b093e0ec905354eccaedcfe83b8cb37cbdeae64026c3064c16"
dependencies = [
"proc-macro2",
"quote",
@ -165,7 +165,7 @@ checksum = "4f345e42323c05e41e29e409505f5f8e0df7b5743340215d60344dbd79b729f4"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.69",
"syn 2.0.70",
]
[[package]]