bug fixes and acpi stuff gn

This commit is contained in:
Zoe
2023-12-17 23:52:15 -06:00
parent a374c753a3
commit f03d29d1fa
3 changed files with 205 additions and 87 deletions

View File

@@ -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,37 +81,130 @@ impl Rsdp {
}
}
pub fn init_acpi() {
let rsdp_response = RSDP_REQUEST.get_response().get();
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 rsdp_response.is_none() {
log_error!("Failed to initialize ACPI: RSDP not found!");
return;
if sum & 0xFF != 0 {
return false;
}
return true;
}
let rsdp_address = &rsdp_response.unwrap().address;
let rsdp_table: &Rsdp = unsafe { &*(rsdp_address.as_ptr().unwrap() as *const Rsdp) };
if !rsdp_table.is_valid() {
log_error!("Failed to initialize ACPI: RSDP was not valid!");
return;
}
log_info!("{}", rsdp_table.revision);
let mut facp: Option<&AcpiSdtHeader> = None;
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");
}
log_ok!("Successfully initialized ACPI");
}
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 Err(());
}
let rsdp_address = &rsdp_response.unwrap().address;
let rsdp_table: &Rsdp = unsafe { &*(rsdp_address.as_ptr().unwrap() as *const Rsdp) };
if !rsdp_table.is_valid() {
log_error!("Failed to initialize ACPI: RSDP was not valid!");
return Err(());
}
if rsdp_table.revision == 2 {
let xsdp_table: &Xsdp = unsafe { &*(rsdp_address.as_ptr().unwrap() as *const Xsdp) };
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));
}
}
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 _) };
// return None;
// }
}
// if signature == "FACP" {
// return Some(*h_ptr);
// }
// }
return None;
// // No FACP found
// return None;
// }
None
}

View File

@@ -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();
let bytes = if metadata_block.0 { &table[2..] } else { table };
if table_is_compressed {
let bytes = if metadata_block.0 { &table[2..] } else { table };
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,15 +494,9 @@ 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.set_len(self.file_size as usize);
}
block_data.extend(
&data_table[self.block_offset as usize..(self.block_offset + self.file_size) as usize],
);
return Ok(Arc::from(block_data));
}

View File

@@ -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);
}