bug fixes and acpi stuff gn
This commit is contained in:
@@ -1,4 +1,8 @@
|
||||
use crate::{log_error, log_info, log_ok};
|
||||
use crate::{
|
||||
libs::{lazy::Lazy, mutex::Mutex},
|
||||
log_error, log_info, log_ok,
|
||||
};
|
||||
use alloc::{sync::Arc, vec::Vec};
|
||||
use limine::RsdpRequest;
|
||||
|
||||
static RSDP_REQUEST: RsdpRequest = RsdpRequest::new(0);
|
||||
@@ -10,14 +14,52 @@ struct Rsdp {
|
||||
oem_id: [u8; 6],
|
||||
revision: u8,
|
||||
rsdt_address: u32,
|
||||
}
|
||||
|
||||
// Only on Revision > 0
|
||||
#[repr(C, packed)]
|
||||
struct Xsdp {
|
||||
length: u32,
|
||||
xsdt_address: u64,
|
||||
extended_checksum: u8,
|
||||
reserved: [u8; 3],
|
||||
}
|
||||
|
||||
pub struct Acpi {
|
||||
tables: Arc<[*const u8]>,
|
||||
entries: usize,
|
||||
v2: bool,
|
||||
}
|
||||
|
||||
impl Acpi {
|
||||
fn has_signature(&self, table_index: usize, signature: &str) -> bool {
|
||||
unsafe {
|
||||
let sdt_header: &SdtHeader = &*(self.tables[table_index] as *const SdtHeader);
|
||||
let st = core::str::from_utf8_unchecked(&sdt_header.signature);
|
||||
st == signature
|
||||
}
|
||||
}
|
||||
|
||||
pub fn list_tables(&self) {
|
||||
unsafe {
|
||||
for i in 0..self.entries {
|
||||
let sdt_header: &SdtHeader = &*(self.tables[i] as *const SdtHeader);
|
||||
let st = sdt_header.signature;
|
||||
log_info!("entry {:02}: {:?}", i + 1, sdt_header);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_table(&self, signature: &str) -> Option<*const u8> {
|
||||
for i in 0..self.entries {
|
||||
if self.has_signature(i, signature) {
|
||||
return Some(self.tables[i]);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
const RSDP_V1_LENGTH: usize = 20;
|
||||
const RSDP_V2_EXT_LENGTH: usize = core::mem::size_of::<Rsdp>() - RSDP_V1_LENGTH;
|
||||
const RSDP_SIG: [u8; 8] = *b"RSD PTR ";
|
||||
@@ -28,21 +70,10 @@ impl Rsdp {
|
||||
return false;
|
||||
}
|
||||
|
||||
if core::str::from_utf8(&self.oem_id).is_err() {
|
||||
return false;
|
||||
}
|
||||
|
||||
let length = if self.revision > 0 {
|
||||
self.length as usize
|
||||
} else {
|
||||
RSDP_V1_LENGTH
|
||||
};
|
||||
|
||||
let bytes =
|
||||
unsafe { core::slice::from_raw_parts(self as *const Rsdp as *const u8, length) };
|
||||
let bytes = unsafe { core::slice::from_raw_parts(self as *const Rsdp as *const u8, 20) };
|
||||
let sum = bytes.iter().fold(0u8, |sum, &byte| sum.wrapping_add(byte));
|
||||
|
||||
if sum != 0 {
|
||||
if sum & 0xFF != 0 {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -50,12 +81,51 @@ impl Rsdp {
|
||||
}
|
||||
}
|
||||
|
||||
impl Xsdp {
|
||||
pub fn is_valid(&self) -> bool {
|
||||
let bytes = unsafe { core::slice::from_raw_parts(self as *const Xsdp as *const u8, 20) };
|
||||
let sum = bytes.iter().fold(0u8, |sum, &byte| sum.wrapping_add(byte));
|
||||
|
||||
if sum & 0xFF != 0 {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static ACPI: Lazy<Mutex<Acpi>> = Lazy::new(|| {
|
||||
let acpi = resolve_acpi();
|
||||
|
||||
if acpi.is_err() {
|
||||
panic!("Failed to resolve ACPI!");
|
||||
}
|
||||
|
||||
Mutex::new(acpi.unwrap())
|
||||
});
|
||||
|
||||
pub fn init_acpi() {
|
||||
let acpi_lock = ACPI.lock();
|
||||
let acpi = acpi_lock.read();
|
||||
|
||||
log_ok!("Successfully initialized ACPI with {} tables", acpi.entries);
|
||||
|
||||
acpi.list_tables()
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum AcpiRootTable {
|
||||
Rsdp(u32),
|
||||
Xsdp(u64),
|
||||
}
|
||||
|
||||
impl AcpiRootTable {
|
||||
pub fn get_from_bootloader() -> Result<Self, ()> {
|
||||
let rsdp_response = RSDP_REQUEST.get_response().get();
|
||||
|
||||
if rsdp_response.is_none() {
|
||||
log_error!("Failed to initialize ACPI: RSDP not found!");
|
||||
return;
|
||||
return Err(());
|
||||
}
|
||||
|
||||
let rsdp_address = &rsdp_response.unwrap().address;
|
||||
@@ -64,23 +134,77 @@ pub fn init_acpi() {
|
||||
|
||||
if !rsdp_table.is_valid() {
|
||||
log_error!("Failed to initialize ACPI: RSDP was not valid!");
|
||||
return;
|
||||
return Err(());
|
||||
}
|
||||
|
||||
log_info!("{}", rsdp_table.revision);
|
||||
let mut facp: Option<&AcpiSdtHeader> = None;
|
||||
if rsdp_table.revision == 2 {
|
||||
let xsdp_table: &Xsdp = unsafe { &*(rsdp_address.as_ptr().unwrap() as *const Xsdp) };
|
||||
|
||||
let rsdt_address = rsdp_table.rsdt_address;
|
||||
facp = find_facp(rsdt_address as *const u32, rsdp_table.revision);
|
||||
|
||||
if facp.is_some() {
|
||||
log_ok!("Successfully found FADT");
|
||||
if !xsdp_table.is_valid() {
|
||||
log_error!("Failed to initalize ACPI: XSDP was not valid!");
|
||||
return Err(());
|
||||
}
|
||||
|
||||
return Ok(AcpiRootTable::Xsdp(xsdp_table.xsdt_address));
|
||||
}
|
||||
|
||||
return Ok(AcpiRootTable::Rsdp(rsdp_table.rsdt_address));
|
||||
}
|
||||
log_ok!("Successfully initialized ACPI");
|
||||
}
|
||||
|
||||
fn resolve_acpi() -> Result<Acpi, ()> {
|
||||
let root_table = AcpiRootTable::get_from_bootloader()?;
|
||||
|
||||
crate::println!("{:?}", root_table);
|
||||
|
||||
let (header_addr, ptr_size, ext_table) = match root_table {
|
||||
AcpiRootTable::Rsdp(addr) => (addr as u64, core::mem::size_of::<u32>(), false),
|
||||
AcpiRootTable::Xsdp(addr) => (addr, core::mem::size_of::<u64>(), true),
|
||||
};
|
||||
|
||||
let root_header: &SdtHeader = unsafe { &*(header_addr as *const SdtHeader) };
|
||||
|
||||
unsafe {
|
||||
if !ext_table {
|
||||
if core::str::from_utf8_unchecked(&root_header.signature) != "RSDT" {
|
||||
log_error!("Invalid root table header, expected RSDT.");
|
||||
return Err(());
|
||||
}
|
||||
} else {
|
||||
if core::str::from_utf8_unchecked(&root_header.signature) != "XSDT" {
|
||||
log_error!("Invalid root table header, expected XSDT.");
|
||||
return Err(());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut entries = (root_header.length as usize - core::mem::size_of::<SdtHeader>()) / ptr_size;
|
||||
if entries > 48 {
|
||||
log_error!("Expected at most 48 ACPI tables, got {entries}!");
|
||||
entries = 48;
|
||||
}
|
||||
|
||||
let mut acpi_tables: Vec<*const u8> = Vec::with_capacity(entries);
|
||||
|
||||
for i in 0..entries {
|
||||
let address =
|
||||
(header_addr + (core::mem::size_of::<SdtHeader>() + i * ptr_size) as u64) as *const u8;
|
||||
|
||||
acpi_tables.push(address);
|
||||
}
|
||||
|
||||
crate::println!("{:?} {}", acpi_tables, entries);
|
||||
|
||||
return Ok(Acpi {
|
||||
tables: Arc::from(acpi_tables),
|
||||
entries,
|
||||
v2: ext_table,
|
||||
});
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[repr(C)]
|
||||
struct AcpiSdtHeader {
|
||||
struct SdtHeader {
|
||||
signature: [u8; 4],
|
||||
length: u32,
|
||||
revision: u8,
|
||||
@@ -92,7 +216,7 @@ struct AcpiSdtHeader {
|
||||
creator_revision: u32,
|
||||
}
|
||||
|
||||
fn check_rsdt_checksum(table_header: *const AcpiSdtHeader) -> bool {
|
||||
fn check_rsdt_checksum(table_header: *const SdtHeader) -> bool {
|
||||
let mut sum: u8 = 0;
|
||||
|
||||
for i in 0..unsafe { (*table_header).length } {
|
||||
@@ -102,34 +226,35 @@ fn check_rsdt_checksum(table_header: *const AcpiSdtHeader) -> bool {
|
||||
return sum == 0;
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
struct Rsdt {
|
||||
h: AcpiSdtHeader,
|
||||
pointer_to_other_sdt: *const u32,
|
||||
#[repr(C, packed)]
|
||||
struct RSDT {
|
||||
h: SdtHeader,
|
||||
pointer_to_other_sdt: *const u8,
|
||||
}
|
||||
|
||||
fn find_facp(root_sdt: *const u32, revision: u8) -> Option<&'static AcpiSdtHeader> {
|
||||
let rsdt: &mut Rsdt = unsafe { &mut *(root_sdt as *mut Rsdt) };
|
||||
rsdt.pointer_to_other_sdt =
|
||||
[(rsdt.h.length - core::mem::size_of::<AcpiSdtHeader>() as u32) / 4].as_ptr();
|
||||
fn find_fadt(root_sdt: *const RSDT) -> Option<SdtHeader> {
|
||||
// unsafe {
|
||||
// let rsdt = root_sdt.as_ref()?;
|
||||
// let entries = (rsdt.h.length - core::mem::size_of::<AcpiSdtHeader>() as u32) / 4;
|
||||
|
||||
let entry_bytes = if revision > 0 { 8 } else { 4 };
|
||||
// let pointer_to_other_sdt =
|
||||
|
||||
let entries = (rsdt.h.length - core::mem::size_of::<AcpiSdtHeader>() as u32) / entry_bytes;
|
||||
// for i in 0..entries {
|
||||
// crate::println!("{i}");
|
||||
|
||||
for i in 0..entries {
|
||||
crate::println!("{i}");
|
||||
let h = unsafe { rsdt.pointer_to_other_sdt.add(i as usize) as *const AcpiSdtHeader };
|
||||
let signature_bytes = unsafe { (*h).signature };
|
||||
let signature_str = core::str::from_utf8(&signature_bytes).unwrap_or("");
|
||||
// let h_ptr = rsdt.pointer_to_other_sdt[i as usize] as *const AcpiSdtHeader;
|
||||
// let h = h_ptr.as_ref()?;
|
||||
// let slice = core::slice::from_raw_parts(h.signature.as_ptr(), 4);
|
||||
|
||||
crate::println!("{signature_str} {signature_bytes:?} {:?}", b"FACP");
|
||||
// let signature = core::str::from_utf8(slice).ok()?;
|
||||
|
||||
// if signature_str == "FACP" {
|
||||
// let facp_header = unsafe { &*(h as *const _) };
|
||||
// if signature == "FACP" {
|
||||
// return Some(*h_ptr);
|
||||
// }
|
||||
// }
|
||||
|
||||
// // No FACP found
|
||||
// return None;
|
||||
// }
|
||||
}
|
||||
|
||||
return None;
|
||||
None
|
||||
}
|
||||
|
||||
@@ -2,10 +2,13 @@ pub mod compressors;
|
||||
|
||||
use core::fmt::{self, Debug};
|
||||
|
||||
use alloc::{boxed::Box, sync::Arc, vec::Vec};
|
||||
use alloc::{boxed::Box, fmt::format, format, sync::Arc, vec::Vec};
|
||||
use limine::ModuleRequest;
|
||||
|
||||
use crate::libs::{lazy::Lazy, math::ceil};
|
||||
use crate::{
|
||||
drivers::serial::write_serial,
|
||||
libs::{lazy::Lazy, math::ceil},
|
||||
};
|
||||
|
||||
use super::vfs::{VfsDirectory, VfsFile, VfsFileSystem};
|
||||
|
||||
@@ -233,10 +236,9 @@ impl Squashfs<'_> {
|
||||
// }
|
||||
|
||||
let mut buffer: Vec<u8> = Vec::new();
|
||||
|
||||
if table_is_compressed {
|
||||
let bytes = if metadata_block.0 { &table[2..] } else { table };
|
||||
|
||||
if table_is_compressed {
|
||||
match self.superblock.compressor {
|
||||
SquashfsCompressionType::Gzip => {
|
||||
buffer.extend_from_slice(&compressors::gzip::uncompress_data(bytes).unwrap());
|
||||
@@ -246,15 +248,7 @@ impl Squashfs<'_> {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unsafe {
|
||||
core::ptr::copy_nonoverlapping(
|
||||
table.as_ptr().add(2),
|
||||
buffer.as_mut_ptr(),
|
||||
table_size as usize,
|
||||
);
|
||||
|
||||
buffer.set_len(table_size as usize);
|
||||
}
|
||||
buffer.extend(bytes);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
@@ -500,16 +494,10 @@ impl<'a> VfsFile for BasicFileInode<'a> {
|
||||
),
|
||||
);
|
||||
|
||||
unsafe {
|
||||
core::ptr::copy_nonoverlapping(
|
||||
data_table.as_ptr().add(self.block_offset as usize),
|
||||
block_data.as_mut_ptr(),
|
||||
self.file_size as usize,
|
||||
block_data.extend(
|
||||
&data_table[self.block_offset as usize..(self.block_offset + self.file_size) as usize],
|
||||
);
|
||||
|
||||
block_data.set_len(self.file_size as usize);
|
||||
}
|
||||
|
||||
return Ok(Arc::from(block_data));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,10 @@ use drivers::serial;
|
||||
use libs::util::hcf;
|
||||
use limine::KernelFileRequest;
|
||||
|
||||
use crate::mem::LabelBytes;
|
||||
use crate::{
|
||||
drivers::fs::{initramfs::INITRAMFS, vfs::VfsFileSystem},
|
||||
mem::LabelBytes,
|
||||
};
|
||||
|
||||
pub static KERNEL_REQUEST: KernelFileRequest = KernelFileRequest::new(0);
|
||||
|
||||
@@ -37,6 +40,8 @@ pub extern "C" fn _start() -> ! {
|
||||
|
||||
drivers::fs::vfs::init();
|
||||
|
||||
// crate::println!("{:?}", INITRAMFS.open("/font.psf").unwrap().read());
|
||||
|
||||
if let Some(kernel) = KERNEL_REQUEST.get_response().get() {
|
||||
crate::println!("{:X?}", kernel.kernel_file.get().unwrap().gpt_disk_uuid);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user