Skip to content
Snippets Groups Projects
Commit 25e98470 authored by Eemeli Lehtonen's avatar Eemeli Lehtonen
Browse files

rename back to (r/x)sd(t/p)

parent 9a6beba6
No related branches found
No related tags found
No related merge requests found
pub mod sdp;
pub mod sdt;
use crate::util::stack_str::StackStr;
use core::{mem, slice};
//
pub mod rsdp;
pub mod rsdt;
//
pub fn init() {
_ = sdp::SdpDescriptor::get();
_ = rsdp::RsdpDescriptor::get();
_ = rsdt::Rsdt::get();
}
/// checksum_validation
///
/// sums up every byte in the structure
///
/// # Safety
///
/// * `size` has to be `None` or the memory range must be readable
unsafe fn bytes_sum_to_zero<T: Sized>(value: &T, size: Option<usize>) -> bool {
let size = size.unwrap_or(mem::size_of::<T>());
let bytes: &[u8] = unsafe { slice::from_raw_parts(value as *const T as *const u8, size) };
bytes.iter().fold(0u8, |acc, v| acc.overflowing_add(*v).0) == 0
}
//
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AcpiOem {
Bochs,
Other(StackStr<6>),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum AcpiVersion {
V1 = 1,
V2 = 2,
}
//
impl From<StackStr<6>> for AcpiOem {
fn from(v: StackStr<6>) -> Self {
match v.as_str() {
"BOCHS " => Self::Bochs,
_ => Self::Other(v),
}
}
}
//! (Root) System Description Pointer
//! Root System Description Pointer
//!
//! https://wiki.osdev.org/RSDP
//!
//! https://fi.wikipedia.org/wiki/Suomen_Sosialidemokraattinen_Puolue
//!
//! This module finds the pointer to the (Root/eXtended) System Descriptor Table [`super::sdt`]
//! This module finds the pointer to the Root/eXtended System Descriptor Table [`super::rsdt`]
use crate::{boot, debug, util::stack_str::StackStr};
use core::{mem, ops::Deref, ptr::read_volatile, slice, str::Utf8Error};
use super::{bytes_sum_to_zero, AcpiVersion};
use crate::{acpi::AcpiOem, boot, debug, util::stack_str::StackStr};
use core::{mem, ops::Deref, ptr::read_volatile, str::Utf8Error};
use spin::Lazy;
//
pub static SDP: Lazy<SdpDescriptor> = Lazy::new(SdpDescriptor::init);
pub static RSDP: Lazy<RsdpDescriptor> = Lazy::new(RsdpDescriptor::init);
//
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct SdpDescriptor {
pub struct RsdpDescriptor {
oem: AcpiOem,
version: AcpiVersion,
pointer: Sdp,
pointer: Rsdp,
}
/// System Description Pointer
/// Root/eXtended System Description Pointer
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Sdp {
pub enum Rsdp {
/// ptr to Root System Descriptor Table
RSDT(usize),
......@@ -33,21 +32,8 @@ pub enum Sdp {
XSDT(usize),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AcpiOem {
Bochs,
Other(StackStr<6>),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum AcpiVersion {
V1 = 1,
V2 = 2,
}
#[derive(Debug, Clone, Copy)]
pub enum SdpDescriptorError {
pub enum RsdpDescriptorError {
Utf8Error(Utf8Error),
InvalidSignature,
InvalidRevision,
......@@ -56,82 +42,50 @@ pub enum SdpDescriptorError {
//
impl SdpDescriptor {
impl RsdpDescriptor {
pub fn get() -> &'static Self {
&SDP
&RSDP
}
pub fn init() -> Self {
boot::sdp()
boot::rsdp()
}
/// # Safety
///
/// * `ptr` must be [valid] for reads.
pub unsafe fn try_read_from(ptr: *const ()) -> Result<Self, SdpDescriptorError> {
pub unsafe fn try_read_from(ptr: *const ()) -> Result<Self, RsdpDescriptorError> {
let rsdp: RawRsdpDescriptor2 = read_volatile(ptr as _);
let sdp = SdpDescriptor::try_from(rsdp)?;
let sdp = RsdpDescriptor::try_from(rsdp)?;
Ok(sdp)
}
pub fn pointer(&self) -> Sdp {
pub fn pointer(&self) -> Rsdp {
self.pointer
}
}
impl From<StackStr<6>> for AcpiOem {
fn from(v: StackStr<6>) -> Self {
match v.as_str() {
"BOCHS " => Self::Bochs,
_ => Self::Other(v),
}
}
}
impl AcpiVersion {
fn checksum_valid(self, value: RawRsdpDescriptor2) -> bool {
let length = match self {
AcpiVersion::V1 => mem::size_of::<RawRsdpDescriptor>(),
AcpiVersion::V2 => mem::size_of::<RawRsdpDescriptor2>().min(value.length as _),
};
}
}
impl TryFrom<u8> for AcpiVersion {
type Error = SdpDescriptorError;
fn try_from(v: u8) -> Result<Self, Self::Error> {
match v {
0 => Ok(AcpiVersion::V1),
2 => Ok(AcpiVersion::V2),
_ => Err(SdpDescriptorError::InvalidRevision),
}
}
}
impl TryFrom<RawRsdpDescriptor2> for SdpDescriptor {
type Error = SdpDescriptorError;
impl TryFrom<RawRsdpDescriptor2> for RsdpDescriptor {
type Error = RsdpDescriptorError;
fn try_from(value: RawRsdpDescriptor2) -> Result<Self, Self::Error> {
let signature = StackStr::from_utf8(value.signature)?;
if signature.as_str() != "RSD PTR " {
return Err(SdpDescriptorError::InvalidSignature);
if value.signature != *b"RSD PTR " {
return Err(RsdpDescriptorError::InvalidSignature);
}
let oem: AcpiOem = StackStr::from_utf8(value.oem_id)?.into();
debug!("RSDP Oem: {oem:?}");
let version: AcpiVersion = value.revision.try_into()?;
if !version.checksum_valid(value) {
return Err(SdpDescriptorError::InvalidChecksum);
if !version.checksum_valid(&value) {
return Err(RsdpDescriptorError::InvalidChecksum);
}
let pointer = if version == AcpiVersion::V2 {
// just reading uninitialized mem is UB af
Sdp::XSDT(value.xsdt_address as _)
Rsdp::XSDT(value.xsdt_address as _)
} else {
Sdp::RSDT(value.rsdt_address as _)
Rsdp::RSDT(value.rsdt_address as _)
};
Ok(Self {
......@@ -142,7 +96,7 @@ impl TryFrom<RawRsdpDescriptor2> for SdpDescriptor {
}
}
impl From<Utf8Error> for SdpDescriptorError {
impl From<Utf8Error> for RsdpDescriptorError {
fn from(value: Utf8Error) -> Self {
Self::Utf8Error(value)
}
......@@ -152,7 +106,7 @@ impl From<Utf8Error> for SdpDescriptorError {
// https://wiki.osdev.org/RSDP
#[derive(Debug, Clone, Copy)]
#[repr(packed)]
#[repr(packed, C)]
struct RawRsdpDescriptor {
signature: [u8; 8],
_checksum: u8,
......@@ -163,7 +117,7 @@ struct RawRsdpDescriptor {
// https://wiki.osdev.org/RSDP
#[derive(Debug, Clone, Copy)]
#[repr(packed)]
#[repr(packed, C)]
struct RawRsdpDescriptor2 {
first: RawRsdpDescriptor,
......@@ -175,29 +129,26 @@ struct RawRsdpDescriptor2 {
//
impl RawRsdpDescriptor {
pub fn checksum_valid_1(&self) -> bool {
let bytes: &[u8] = unsafe {
slice::from_raw_parts(
self as *const Self as *const u8,
mem::size_of::<RawRsdpDescriptor>(),
)
impl AcpiVersion {
fn checksum_valid(self, value: &RawRsdpDescriptor2) -> bool {
let length = match self {
AcpiVersion::V1 => mem::size_of::<RawRsdpDescriptor>(),
AcpiVersion::V2 => mem::size_of::<RawRsdpDescriptor2>().min(value.length as _),
};
bytes.iter().fold(0u8, |acc, v| acc.overflowing_add(*v).0) == 0
unsafe { bytes_sum_to_zero(value, Some(length)) }
}
}
impl RawRsdpDescriptor2 {
pub fn checksum_valid_2(&self) -> bool {
let bytes: &[u8] = unsafe {
slice::from_raw_parts(
self as *const Self as *const u8,
mem::size_of::<RawRsdpDescriptor>() - 3, // reserved fields d
)
};
impl TryFrom<u8> for AcpiVersion {
type Error = RsdpDescriptorError;
bytes.iter().fold(0u8, |acc, v| acc.overflowing_add(*v).0) == 0
fn try_from(v: u8) -> Result<Self, Self::Error> {
match v {
0 => Ok(AcpiVersion::V1),
2 => Ok(AcpiVersion::V2),
_ => Err(RsdpDescriptorError::InvalidRevision),
}
}
}
......
//! Root/eXtended System Descriptor Table
//!
//! https://wiki.osdev.org/RSDT
use crate::{
acpi::rsdp::{Rsdp, RSDP},
debug,
util::stack_str::StackStr,
};
use core::{mem, ops::Add, ptr::read_unaligned, slice, str::Utf8Error};
use spin::Lazy;
//
/// RSDT/XSDT
pub static RSDT: Lazy<Rsdt> = Lazy::new(Rsdt::init);
//
pub struct Rsdt {}
#[derive(Debug, Clone, Copy)]
pub enum RsdtError {
Utf8Error(Utf8Error),
InvalidSignature,
InvalidRevision,
InvalidChecksum,
}
//
impl Rsdt {
pub fn get() -> &'static Self {
&RSDT
}
pub fn init() -> Self {
match RSDP.pointer() {
Rsdp::RSDT(ptr) => {
let header: RawSdtHeader = unsafe { read_unaligned(ptr as *const RawSdtHeader) };
debug!("RSDT Header {header:#?}");
debug!(
"RSDT Header signature {:?}",
StackStr::from_utf8(header.signature)
);
debug!(
"RSDT Header oem_id {:?}",
StackStr::from_utf8(header.oem_id)
);
debug!(
"RSDT Header oem_table_id {:?}",
StackStr::from_utf8(header.oem_table_id)
);
let sdt_pointers = (header.length as usize - mem::size_of::<RawSdtHeader>()) / 4;
let sdt_pointers = unsafe {
slice::from_raw_parts(
(ptr + mem::size_of::<RawSdtHeader>()) as *const u32,
sdt_pointers,
)
};
debug!("RSDT pointers: {sdt_pointers:?}",);
}
Rsdp::XSDT(_) => todo!(),
}
todo!()
}
}
impl TryFrom<RawSdtHeader> for Rsdt {
type Error = RsdtError;
fn try_from(value: RawSdtHeader) -> Result<Self, Self::Error> {
if value.signature != *b"RSDT" {
return Err(RsdtError::InvalidSignature);
}
todo!()
}
}
//
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(packed, C)]
struct RawSdtHeader {
signature: [u8; 4],
length: u32,
revision: u8,
checksum: u8,
oem_id: [u8; 6],
oem_table_id: [u8; 8],
oem_revision: u32,
creator_id: u32,
creator_revision: u32,
}
//
impl RawSdtHeader {}
//
//! (Root/eXtended) System Descriptor Table
//!
//! https://wiki.osdev.org/RSDT
use crate::acpi::sdp::{Sdp, SDP};
use spin::Lazy;
//
pub static SDT: Lazy<Sdt> = Lazy::new(Sdt::init);
//
pub struct Sdt {}
//
impl Sdt {
pub fn get() -> &'static Self {
&SDT
}
pub fn init() -> Self {
match SDP.pointer() {
Sdp::RSDT(_) => todo!(),
Sdp::XSDT(_) => todo!(),
}
todo!()
}
}
//
struct SdtHeader {
signature: [u8; 4],
length: u32,
revision: u8,
checksum: u8,
oem_id: [u8; 6],
oem_table_id: [u8; 8],
oem_revision: u32,
creator_id: u32,
creator_revision: u32,
}
//
impl SdtHeader {}
......@@ -9,7 +9,7 @@ pub use addr::virt_addr;
pub use cmdline::cmdline;
pub use framebuffer::framebuffer;
pub use mem::memmap;
pub use sdp::sdp;
pub use rsdp::rsdp;
pub use smp::{boot_cpu, init as smp_init};
pub use term::_print;
......@@ -19,7 +19,7 @@ mod addr;
mod cmdline;
mod framebuffer;
mod mem;
mod sdp;
mod rsdp;
mod smp;
mod term;
......
use crate::acpi::sdp::SdpDescriptor;
use crate::acpi::rsdp::RsdpDescriptor;
use limine::LimineRsdpRequest;
use spin::Lazy;
//
pub fn sdp() -> SdpDescriptor {
pub fn rsdp() -> RsdpDescriptor {
static RSDP_REQ: LimineRsdpRequest = LimineRsdpRequest::new(0);
static SDP_DESC: Lazy<SdpDescriptor> = Lazy::new(|| {
static RSDP_DESC: Lazy<RsdpDescriptor> = Lazy::new(|| {
let rsdp = RSDP_REQ
.get_response()
.get()
.and_then(|rsdp| rsdp.address.as_ptr())
.expect("RSDP data should be readable");
unsafe { SdpDescriptor::try_read_from(rsdp as _) }.expect("RSDP should be valid")
unsafe { RsdpDescriptor::try_read_from(rsdp as _) }.expect("RSDP should be valid")
});
*SDP_DESC
*RSDP_DESC
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment