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;
|
use limine::RsdpRequest;
|
||||||
|
|
||||||
static RSDP_REQUEST: RsdpRequest = RsdpRequest::new(0);
|
static RSDP_REQUEST: RsdpRequest = RsdpRequest::new(0);
|
||||||
@@ -10,14 +14,52 @@ struct Rsdp {
|
|||||||
oem_id: [u8; 6],
|
oem_id: [u8; 6],
|
||||||
revision: u8,
|
revision: u8,
|
||||||
rsdt_address: u32,
|
rsdt_address: u32,
|
||||||
|
}
|
||||||
|
|
||||||
// Only on Revision > 0
|
#[repr(C, packed)]
|
||||||
|
struct Xsdp {
|
||||||
length: u32,
|
length: u32,
|
||||||
xsdt_address: u64,
|
xsdt_address: u64,
|
||||||
extended_checksum: u8,
|
extended_checksum: u8,
|
||||||
reserved: [u8; 3],
|
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_V1_LENGTH: usize = 20;
|
||||||
const RSDP_V2_EXT_LENGTH: usize = core::mem::size_of::<Rsdp>() - RSDP_V1_LENGTH;
|
const RSDP_V2_EXT_LENGTH: usize = core::mem::size_of::<Rsdp>() - RSDP_V1_LENGTH;
|
||||||
const RSDP_SIG: [u8; 8] = *b"RSD PTR ";
|
const RSDP_SIG: [u8; 8] = *b"RSD PTR ";
|
||||||
@@ -28,21 +70,10 @@ impl Rsdp {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if core::str::from_utf8(&self.oem_id).is_err() {
|
let bytes = unsafe { core::slice::from_raw_parts(self as *const Rsdp as *const u8, 20) };
|
||||||
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 sum = bytes.iter().fold(0u8, |sum, &byte| sum.wrapping_add(byte));
|
let sum = bytes.iter().fold(0u8, |sum, &byte| sum.wrapping_add(byte));
|
||||||
|
|
||||||
if sum != 0 {
|
if sum & 0xFF != 0 {
|
||||||
return false;
|
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() {
|
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();
|
let rsdp_response = RSDP_REQUEST.get_response().get();
|
||||||
|
|
||||||
if rsdp_response.is_none() {
|
if rsdp_response.is_none() {
|
||||||
log_error!("Failed to initialize ACPI: RSDP not found!");
|
log_error!("Failed to initialize ACPI: RSDP not found!");
|
||||||
return;
|
return Err(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let rsdp_address = &rsdp_response.unwrap().address;
|
let rsdp_address = &rsdp_response.unwrap().address;
|
||||||
@@ -64,23 +134,77 @@ pub fn init_acpi() {
|
|||||||
|
|
||||||
if !rsdp_table.is_valid() {
|
if !rsdp_table.is_valid() {
|
||||||
log_error!("Failed to initialize ACPI: RSDP was not valid!");
|
log_error!("Failed to initialize ACPI: RSDP was not valid!");
|
||||||
return;
|
return Err(());
|
||||||
}
|
}
|
||||||
|
|
||||||
log_info!("{}", rsdp_table.revision);
|
if rsdp_table.revision == 2 {
|
||||||
let mut facp: Option<&AcpiSdtHeader> = None;
|
let xsdp_table: &Xsdp = unsafe { &*(rsdp_address.as_ptr().unwrap() as *const Xsdp) };
|
||||||
|
|
||||||
let rsdt_address = rsdp_table.rsdt_address;
|
if !xsdp_table.is_valid() {
|
||||||
facp = find_facp(rsdt_address as *const u32, rsdp_table.revision);
|
log_error!("Failed to initalize ACPI: XSDP was not valid!");
|
||||||
|
return Err(());
|
||||||
if facp.is_some() {
|
|
||||||
log_ok!("Successfully found FADT");
|
|
||||||
}
|
|
||||||
log_ok!("Successfully initialized ACPI");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)]
|
#[repr(C)]
|
||||||
struct AcpiSdtHeader {
|
struct SdtHeader {
|
||||||
signature: [u8; 4],
|
signature: [u8; 4],
|
||||||
length: u32,
|
length: u32,
|
||||||
revision: u8,
|
revision: u8,
|
||||||
@@ -92,7 +216,7 @@ struct AcpiSdtHeader {
|
|||||||
creator_revision: u32,
|
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;
|
let mut sum: u8 = 0;
|
||||||
|
|
||||||
for i in 0..unsafe { (*table_header).length } {
|
for i in 0..unsafe { (*table_header).length } {
|
||||||
@@ -102,34 +226,35 @@ fn check_rsdt_checksum(table_header: *const AcpiSdtHeader) -> bool {
|
|||||||
return sum == 0;
|
return sum == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C, packed)]
|
||||||
struct Rsdt {
|
struct RSDT {
|
||||||
h: AcpiSdtHeader,
|
h: SdtHeader,
|
||||||
pointer_to_other_sdt: *const u32,
|
pointer_to_other_sdt: *const u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_facp(root_sdt: *const u32, revision: u8) -> Option<&'static AcpiSdtHeader> {
|
fn find_fadt(root_sdt: *const RSDT) -> Option<SdtHeader> {
|
||||||
let rsdt: &mut Rsdt = unsafe { &mut *(root_sdt as *mut Rsdt) };
|
// unsafe {
|
||||||
rsdt.pointer_to_other_sdt =
|
// let rsdt = root_sdt.as_ref()?;
|
||||||
[(rsdt.h.length - core::mem::size_of::<AcpiSdtHeader>() as u32) / 4].as_ptr();
|
// 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 {
|
// let h_ptr = rsdt.pointer_to_other_sdt[i as usize] as *const AcpiSdtHeader;
|
||||||
crate::println!("{i}");
|
// let h = h_ptr.as_ref()?;
|
||||||
let h = unsafe { rsdt.pointer_to_other_sdt.add(i as usize) as *const AcpiSdtHeader };
|
// let slice = core::slice::from_raw_parts(h.signature.as_ptr(), 4);
|
||||||
let signature_bytes = unsafe { (*h).signature };
|
|
||||||
let signature_str = core::str::from_utf8(&signature_bytes).unwrap_or("");
|
|
||||||
|
|
||||||
crate::println!("{signature_str} {signature_bytes:?} {:?}", b"FACP");
|
// let signature = core::str::from_utf8(slice).ok()?;
|
||||||
|
|
||||||
// if signature_str == "FACP" {
|
// if signature == "FACP" {
|
||||||
// let facp_header = unsafe { &*(h as *const _) };
|
// return Some(*h_ptr);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // No FACP found
|
||||||
// return None;
|
// return None;
|
||||||
// }
|
// }
|
||||||
}
|
None
|
||||||
|
|
||||||
return None;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,13 @@ pub mod compressors;
|
|||||||
|
|
||||||
use core::fmt::{self, Debug};
|
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 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};
|
use super::vfs::{VfsDirectory, VfsFile, VfsFileSystem};
|
||||||
|
|
||||||
@@ -233,10 +236,9 @@ impl Squashfs<'_> {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
let mut buffer: Vec<u8> = Vec::new();
|
let mut buffer: Vec<u8> = Vec::new();
|
||||||
|
|
||||||
if table_is_compressed {
|
|
||||||
let bytes = if metadata_block.0 { &table[2..] } else { table };
|
let bytes = if metadata_block.0 { &table[2..] } else { table };
|
||||||
|
|
||||||
|
if table_is_compressed {
|
||||||
match self.superblock.compressor {
|
match self.superblock.compressor {
|
||||||
SquashfsCompressionType::Gzip => {
|
SquashfsCompressionType::Gzip => {
|
||||||
buffer.extend_from_slice(&compressors::gzip::uncompress_data(bytes).unwrap());
|
buffer.extend_from_slice(&compressors::gzip::uncompress_data(bytes).unwrap());
|
||||||
@@ -246,15 +248,7 @@ impl Squashfs<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
unsafe {
|
buffer.extend(bytes);
|
||||||
core::ptr::copy_nonoverlapping(
|
|
||||||
table.as_ptr().add(2),
|
|
||||||
buffer.as_mut_ptr(),
|
|
||||||
table_size as usize,
|
|
||||||
);
|
|
||||||
|
|
||||||
buffer.set_len(table_size as usize);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
@@ -500,16 +494,10 @@ impl<'a> VfsFile for BasicFileInode<'a> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
unsafe {
|
block_data.extend(
|
||||||
core::ptr::copy_nonoverlapping(
|
&data_table[self.block_offset as usize..(self.block_offset + self.file_size) as usize],
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ok(Arc::from(block_data));
|
return Ok(Arc::from(block_data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,10 @@ use drivers::serial;
|
|||||||
use libs::util::hcf;
|
use libs::util::hcf;
|
||||||
use limine::KernelFileRequest;
|
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);
|
pub static KERNEL_REQUEST: KernelFileRequest = KernelFileRequest::new(0);
|
||||||
|
|
||||||
@@ -37,6 +40,8 @@ pub extern "C" fn _start() -> ! {
|
|||||||
|
|
||||||
drivers::fs::vfs::init();
|
drivers::fs::vfs::init();
|
||||||
|
|
||||||
|
// crate::println!("{:?}", INITRAMFS.open("/font.psf").unwrap().read());
|
||||||
|
|
||||||
if let Some(kernel) = KERNEL_REQUEST.get_response().get() {
|
if let Some(kernel) = KERNEL_REQUEST.get_response().get() {
|
||||||
crate::println!("{:X?}", kernel.kernel_file.get().unwrap().gpt_disk_uuid);
|
crate::println!("{:X?}", kernel.kernel_file.get().unwrap().gpt_disk_uuid);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user