kernel: re-sync ACPI subsystem with upstream master

Phase A of the ACPI fork-sync plan (local/docs/ACPI-FORK-SYNC-STRATEGY-2026-06-30.md).

Restores the kernel to the upstream Redox OS kernel main branch state for
the ACPI subsystem:

- Cargo.toml: switch redox_syscall from 0.7.4 (two versions behind) to a
  git ref of gitlab.redox-os.org/redox-os/syscall.git, matching the
  upstream master dependency. The crates.io 0.8.1 release predates the
  AcpiVerb enum that MR #613 / MR #275 introduced, so a crates.io pin
  is insufficient.

- src/acpi/rsdp.rs: full rewrite to match upstream f49c7d99 (RSDP
  validation + NonNull + fail-softly):
    * signature check "RSD PTR "
    * 20-byte base checksum
    * full-length checksum for revision >= 2
    * NonNull<u8> instead of *const u8
  Fixes gap #1 from the 2026-06-30 ACPI assessment: the kernel was
  accepting any pointer from the bootloader without validation.

- src/startup/mod.rs: acpi_rsdp() returns Option<NonNull<u8>> to match
  the new Rsdp::get_rsdp signature.

- src/acpi/mod.rs: init() takes Option<NonNull<u8>>.

- src/scheme/acpi.rs: full rewrite to upstream MR #613 (Simplify acpi
  scheme). Drops the /scheme/kernel.acpi/ filesystem surface in favor
  of a single Fd::open + call() interface with AcpiVerb verbs:
    * AcpiVerb::ReadRxsdt - returns the raw RXSDT bytes
    * AcpiVerb::CheckShutdown - returns whether shutdown is pending
  Uses HandleBits bitflags, atomic EXISTS_KSTOP_HANDLE, Mutex<L4> from
  crate::sync::ordered. Replaces /scheme/kernel.acpi/rxsdt and
  /scheme/kernel.acpi/kstop files.

- src/scheme/mod.rs: KernelScheme::kcall signature updated to take
  fds: &[usize] instead of id: usize (matches upstream). kfpath now
  has a default body returning EOPNOTSUPP (matches upstream).

- src/scheme/memory.rs, proc.rs, user.rs: kcall impls updated to
  match new trait signature, using fds.first() to extract the single
  handle for backward compat.

- src/scheme/proc.rs: kcall dispatch adds _ => Err(EINVAL) catch-all
  for the new ProcSchemeVerb variants (RegsInt, RegsFloat, RegsEnv,
  SchedAffinity, Start) that the gitlab syscall crate adds. These
  verbs are not yet implemented in the proc scheme; the catch-all
  returns EINVAL cleanly instead of failing to compile.

- src/syscall/fs.rs: SYS_CALL dispatcher now passes &[number] to
  scheme.kcall() to match the new trait signature.

- Makefile: removed -Z json-target-spec flag (promoted to stable in
  nightly 2026-04-01; the flag is unknown in our pinned toolchain).

Verified by `make` in local/sources/kernel/ with PATH including the
prefix cross-toolchain: kernel builds and links successfully.
This commit is contained in:
Red Bear OS
2026-06-30 04:09:05 +03:00
parent 4cb9d80396
commit 4f2a0436eb
11 changed files with 134 additions and 276 deletions
Generated
+2 -3
View File
@@ -201,9 +201,8 @@ checksum = "64072665120942deff5fd5425d6c1811b854f4939e7f1c01ce755f64432bbea7"
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.7.4" version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+https://gitlab.redox-os.org/redox-os/syscall.git#79cb6d9057642be31623677458a93aa88145864f"
checksum = "f450ad9c3b1da563fb6948a8e0fb0fb9269711c9c73d9ea1de5058c79c8d643a"
dependencies = [ dependencies = [
"bitflags 2.11.1", "bitflags 2.11.1",
] ]
+1 -1
View File
@@ -19,7 +19,7 @@ fdt = { git = "https://github.com/repnop/fdt.git", rev = "2fb1409edd1877c714a0aa
hashbrown = { version = "0.14.3", default-features = false, features = ["ahash", "inline-more"] } hashbrown = { version = "0.14.3", default-features = false, features = ["ahash", "inline-more"] }
linked_list_allocator = "0.9.0" linked_list_allocator = "0.9.0"
redox-path = "0.2.0" redox-path = "0.2.0"
redox_syscall = { version = "0.7.4", default-features = false } redox_syscall = { git = "https://gitlab.redox-os.org/redox-os/syscall.git", default-features = false }
rmm = { path = "rmm", default-features = false } rmm = { path = "rmm", default-features = false }
slab = { version = "0.4", default-features = false } slab = { version = "0.4", default-features = false }
smallvec = { version = "1.15.1", default-features = false } smallvec = { version = "1.15.1", default-features = false }
+3 -1
View File
@@ -3,6 +3,8 @@
use alloc::{boxed::Box, string::String, vec::Vec}; use alloc::{boxed::Box, string::String, vec::Vec};
use core::ptr::NonNull;
use hashbrown::HashMap; use hashbrown::HashMap;
use spin::{Once, RwLock}; use spin::{Once, RwLock};
@@ -83,7 +85,7 @@ impl Rxsdt for RxsdtEnum {
pub static RXSDT_ENUM: Once<RxsdtEnum> = Once::new(); pub static RXSDT_ENUM: Once<RxsdtEnum> = Once::new();
/// Parse the ACPI tables to gather CPU, interrupt, and timer information /// Parse the ACPI tables to gather CPU, interrupt, and timer information
pub unsafe fn init(already_supplied_rsdp: Option<*const u8>) { pub unsafe fn init(already_supplied_rsdp: Option<NonNull<u8>>) {
unsafe { unsafe {
{ {
let mut sdt_ptrs = SDT_POINTERS.write(); let mut sdt_ptrs = SDT_POINTERS.write();
+33 -5
View File
@@ -1,3 +1,5 @@
use core::ptr::NonNull;
use rmm::PhysicalAddress; use rmm::PhysicalAddress;
/// RSDP /// RSDP
@@ -9,17 +11,43 @@ pub struct Rsdp {
_oemid: [u8; 6], _oemid: [u8; 6],
revision: u8, revision: u8,
rsdt_address: u32, rsdt_address: u32,
_length: u32, length: u32,
xsdt_address: u64, xsdt_address: u64,
_extended_checksum: u8, _extended_checksum: u8,
_reserved: [u8; 3], _reserved: [u8; 3],
} }
impl Rsdp { impl Rsdp {
pub unsafe fn get_rsdp(already_supplied_rsdp: Option<*const u8>) -> Option<Rsdp> { pub unsafe fn get_rsdp(already_supplied_rsdp: Option<NonNull<u8>>) -> Option<Rsdp> {
already_supplied_rsdp.map(|rsdp_ptr| { already_supplied_rsdp.and_then(|rsdp_ptr: NonNull<u8>| {
// TODO: Validate let rsdp: Rsdp = unsafe { rsdp_ptr.cast().read() };
unsafe { *(rsdp_ptr as *const Rsdp) }
if rsdp.signature != *b"RSD PTR " {
error!("RSDP signature check failed");
return None;
}
let mut sum: u8 = 0;
for i in 0..20 {
sum = sum.wrapping_add(unsafe { rsdp_ptr.add(i).read() });
}
if sum != 0 {
error!("RSDP checksum failed");
return None;
}
if rsdp.revision >= 2 {
let mut sum: u8 = 0;
for i in 0..rsdp.length as usize {
sum = sum.wrapping_add(unsafe { rsdp_ptr.add(i).read() });
}
if sum != 0 {
error!("XSDP checksum failed");
return None;
}
}
Some(rsdp)
}) })
} }
+78 -256
View File
@@ -1,78 +1,59 @@
use alloc::{boxed::Box, vec::Vec}; use alloc::boxed::Box;
use core::convert::TryInto; use core::sync::atomic::{AtomicBool, Ordering};
use spin::{Mutex, Once}; use crate::sync::ordered::{Mutex, L4};
use syscall::{ use spin::Once;
data::GlobalSchemes,
dirent::{DirEntry, DirentBuf, DirentKind}, use syscall::data::GlobalSchemes;
EIO,
};
use crate::{ use crate::{
acpi::{RxsdtEnum, RXSDT_ENUM}, acpi::{RxsdtEnum, RXSDT_ENUM},
context::file::InternalFlags, context::file::InternalFlags,
event, scheme::{SchemeExt, StrOrBytes},
sync::{CleanLockToken, RwLock, WaitCondition, L1}, sync::CleanLockToken,
}; };
use crate::syscall::{ use crate::syscall::{
data::Stat, error::{Error, Result, EACCES, EBADFD, EINVAL, ENOENT},
error::{Error, Result, EACCES, EBADF, EBADFD, EINTR, EINVAL, EISDIR, ENOENT, ENOTDIR, EROFS}, flag::{AcpiVerb, CallFlags, EventFlags},
flag::{ usercopy::UserSliceRw,
EventFlags, EVENT_READ, MODE_CHR, MODE_DIR, MODE_FILE, O_ACCMODE, O_CREAT, O_DIRECTORY,
O_EXCL, O_RDONLY, O_STAT, O_SYMLINK,
},
usercopy::UserSliceWo,
}; };
use super::{CallerCtx, HandleMap, KernelScheme, OpenResult, SchemeExt, StrOrBytes}; use super::{CallerCtx, KernelScheme, OpenResult};
/// A scheme used to access the RSDT or XSDT, which is needed for e.g. `acpid` to function. /// A scheme used to access the RSDT or XSDT, and listen for shutdown, which is needed for e.g. `acpid` to function.
pub struct AcpiScheme; pub struct AcpiScheme;
#[derive(Clone, Copy)] bitflags! {
struct Handle { #[derive(PartialEq)]
kind: HandleKind, struct HandleBits: usize {
stat: bool, const CAN_READ_RXSDT = 1;
const CAN_REGISTER_KSTOP = 2;
// mutually exclusive with the other flags
const KSTOP_HANDLE = 4;
} }
#[derive(Clone, Copy, Eq, PartialEq)]
enum HandleKind {
TopLevel,
Rxsdt,
ShutdownPipe,
SchemeRoot,
} }
static HANDLES: RwLock<L1, HandleMap<Handle>> = RwLock::new(HandleMap::new()); static RXSDT_DATA: Once<Box<[u8]>> = Once::new();
static DATA: Once<Box<[u8]>> = Once::new(); static KSTOP_FLAG: Mutex<L4, bool> = Mutex::new(false);
static EXISTS_KSTOP_HANDLE: AtomicBool = AtomicBool::new(false);
static KSTOP_WAITCOND: WaitCondition = WaitCondition::new();
static KSTOP_FLAG: Mutex<bool> = Mutex::new(false);
pub fn register_kstop(token: &mut CleanLockToken) -> bool { pub fn register_kstop(token: &mut CleanLockToken) -> bool {
*KSTOP_FLAG.lock() = true; *KSTOP_FLAG.lock(token.token()) = true;
let mut waiters_awoken = KSTOP_WAITCOND.notify(token);
let fds: Vec<usize> = { if !EXISTS_KSTOP_HANDLE.load(Ordering::Relaxed) {
HANDLES
.read(token.token())
.iter()
.filter(|(_, handle)| handle.kind == HandleKind::ShutdownPipe)
.map(|(fd, _)| *fd)
.collect()
};
for fd in fds {
event::trigger(GlobalSchemes::Acpi.scheme_id(), fd, EVENT_READ, token);
waiters_awoken += 1;
}
if waiters_awoken == 0 {
error!("No userspace ACPI handler was notified when trying to shutdown. This is bad."); error!("No userspace ACPI handler was notified when trying to shutdown. This is bad.");
// Let the kernel shutdown without ACPI. // Let the kernel shutdown without ACPI.
return false; return false;
} }
crate::event::trigger(
GlobalSchemes::Acpi.scheme_id(),
HandleBits::KSTOP_HANDLE.bits(),
EventFlags::EVENT_READ,
token,
);
// TODO: Context switch directly to the waiting context, to avoid annoying timeouts. // TODO: Context switch directly to the waiting context, to avoid annoying timeouts.
true true
@@ -86,7 +67,7 @@ impl AcpiScheme {
let mut data_init = false; let mut data_init = false;
DATA.call_once(|| { RXSDT_DATA.call_once(|| {
data_init = true; data_init = true;
let table = match RXSDT_ENUM.get() { let table = match RXSDT_ENUM.get() {
@@ -108,229 +89,70 @@ impl AcpiScheme {
} }
impl KernelScheme for AcpiScheme { impl KernelScheme for AcpiScheme {
fn scheme_root(&self, token: &mut CleanLockToken) -> Result<usize> { fn scheme_root(&self, _token: &mut CleanLockToken) -> Result<usize> {
let fd = HANDLES.write(token.token()).insert(Handle { Ok((HandleBits::CAN_READ_RXSDT | HandleBits::CAN_REGISTER_KSTOP).bits())
kind: HandleKind::SchemeRoot,
stat: false,
});
Ok(fd)
} }
fn kopenat( fn kopenat(
&self, &self,
id: usize, id: usize,
user_buf: StrOrBytes, path: StrOrBytes,
flags: usize, _flags: usize,
_fcntl_flags: u32, _fcntl_flags: u32,
ctx: CallerCtx, caller: CallerCtx,
token: &mut CleanLockToken, _token: &mut CleanLockToken,
) -> Result<OpenResult> { ) -> Result<OpenResult> {
if !matches!( let bits = HandleBits::from_bits_retain(id);
HANDLES.read(token.token()).get(id)?.kind,
HandleKind::SchemeRoot let new_bits = match path.as_bytes() {
) { b"" | b"/" => bits,
b"kstop" | b"/kstop" => {
// TODO: can the uid check be removed?
if caller.uid != 0 || !bits.contains(HandleBits::CAN_REGISTER_KSTOP) {
return Err(Error::new(EACCES)); return Err(Error::new(EACCES));
} }
EXISTS_KSTOP_HANDLE.store(true, Ordering::Relaxed);
let path = user_buf HandleBits::KSTOP_HANDLE
.as_str()
.or(Err(Error::new(EINVAL)))?
.trim_start_matches('/');
if ctx.uid != 0 {
return Err(Error::new(EACCES));
}
if flags & O_CREAT == O_CREAT {
return Err(Error::new(EROFS));
}
if flags & O_EXCL == O_EXCL || flags & O_SYMLINK == O_SYMLINK {
return Err(Error::new(EINVAL));
}
if flags & O_ACCMODE != O_RDONLY && flags & O_STAT != O_STAT {
return Err(Error::new(EROFS));
}
let (handle_kind, int_flags) = match path {
"" => {
if flags & O_DIRECTORY != O_DIRECTORY && flags & O_STAT != O_STAT {
return Err(Error::new(EISDIR));
}
(HandleKind::TopLevel, InternalFlags::POSITIONED)
}
"rxsdt" => {
if flags & O_DIRECTORY == O_DIRECTORY && flags & O_STAT != O_STAT {
return Err(Error::new(ENOTDIR));
}
(HandleKind::Rxsdt, InternalFlags::POSITIONED)
}
"kstop" => {
if flags & O_DIRECTORY == O_DIRECTORY && flags & O_STAT != O_STAT {
return Err(Error::new(ENOTDIR));
}
(HandleKind::ShutdownPipe, InternalFlags::empty())
} }
_ => return Err(Error::new(ENOENT)), _ => return Err(Error::new(ENOENT)),
}; };
Ok(OpenResult::SchemeLocal(
let fd = HANDLES.write(token.token()).insert(Handle { new_bits.bits(),
kind: handle_kind, InternalFlags::empty(),
// TODO: Redundant ))
stat: flags & O_STAT == O_STAT,
});
Ok(OpenResult::SchemeLocal(fd, int_flags))
} }
fn fsize(&self, id: usize, token: &mut CleanLockToken) -> Result<u64> { fn kcall(
let mut handles = HANDLES.write(token.token());
let handle = handles.get_mut(id)?;
if handle.stat {
return Err(Error::new(EBADF));
}
Ok(match handle.kind {
HandleKind::Rxsdt => DATA.get().ok_or(Error::new(EBADFD))?.len() as u64,
HandleKind::ShutdownPipe => 1,
HandleKind::TopLevel => 0,
HandleKind::SchemeRoot => return Err(Error::new(EBADF))?,
})
}
// TODO
fn fevent(
&self, &self,
id: usize, fds: &[usize],
_flags: EventFlags, payload: UserSliceRw,
token: &mut CleanLockToken, flags: CallFlags,
) -> Result<EventFlags> { metadata: &[u64],
let handles = HANDLES.read(token.token());
let handle = handles.get(id)?;
if handle.stat {
return Err(Error::new(EBADF));
}
Ok(EventFlags::empty())
}
fn close(&self, id: usize, token: &mut CleanLockToken) -> Result<()> {
HANDLES.write(token.token()).remove(id)?;
Ok(())
}
fn kreadoff(
&self,
id: usize,
dst_buf: UserSliceWo,
offset: u64,
_flags: u32,
_stored_flags: u32,
token: &mut CleanLockToken, token: &mut CleanLockToken,
) -> Result<usize> { ) -> Result<usize> {
let Ok(offset) = usize::try_from(offset) else { let [handle] = <&[usize; 1]>::try_from(fds)
return Ok(0); .map_err(|_| Error::new(EINVAL))?
}; .map(HandleBits::from_bits_retain);
let verb = metadata
.get(0)
.copied()
.and_then(AcpiVerb::try_from_raw)
.ok_or(Error::new(EINVAL))?;
let handle = *HANDLES.read(token.token()).get(id)?; match verb {
AcpiVerb::ReadRxsdt => {
if handle.stat { if !handle.contains(HandleBits::CAN_READ_RXSDT) || !flags.contains(CallFlags::READ)
return Err(Error::new(EBADF)); {
return Err(Error::new(EINVAL));
} }
let src = RXSDT_DATA.get().ok_or(Error::new(EBADFD))?;
let data = match handle.kind { payload.copy_common_bytes_from_slice(src)?;
HandleKind::ShutdownPipe => { Ok(src.len())
if dst_buf.is_empty() {
return Ok(0);
} }
AcpiVerb::CheckShutdown => {
loop { if handle != HandleBits::KSTOP_HANDLE {
let flag_guard = KSTOP_FLAG.lock(); return Err(Error::new(EINVAL));
let mut token = token.downgrade(); }
Ok(usize::from(*KSTOP_FLAG.lock(token.token())))
if *flag_guard {
break;
} else if !KSTOP_WAITCOND.wait(flag_guard, "waiting for kstop", &mut token) {
return Err(Error::new(EINTR));
} }
} }
return dst_buf.copy_exactly(&[0x42]).map(|()| 1);
}
HandleKind::Rxsdt => DATA.get().ok_or(Error::new(EBADFD))?,
HandleKind::TopLevel => return Err(Error::new(EISDIR)),
HandleKind::SchemeRoot => return Err(Error::new(EBADF)),
};
let src_offset = core::cmp::min(offset, data.len());
let src_buf = data
.get(src_offset..)
.expect("expected data to be at least data.len() bytes long");
dst_buf.copy_common_bytes_from_slice(src_buf)
}
fn getdents(
&self,
id: usize,
buf: UserSliceWo,
header_size: u16,
opaque: u64,
token: &mut CleanLockToken,
) -> Result<usize> {
let Handle {
kind: HandleKind::TopLevel,
..
} = HANDLES.read(token.token()).get(id)?
else {
return Err(Error::new(ENOTDIR));
};
let mut buf = DirentBuf::new(buf, header_size).ok_or(Error::new(EIO))?;
if opaque == 0 {
buf.entry(DirEntry {
kind: DirentKind::Regular,
name: "rxsdt",
inode: 0,
next_opaque_id: 1,
})?;
}
if opaque <= 1 {
buf.entry(DirEntry {
kind: DirentKind::Socket,
name: "kstop",
inode: 0,
next_opaque_id: u64::MAX,
})?;
}
Ok(buf.finalize())
}
fn kfpath(&self, _id: usize, buf: UserSliceWo, _token: &mut CleanLockToken) -> Result<usize> {
//TODO: construct useful path?
buf.copy_common_bytes_from_slice("/scheme/kernel.acpi/".as_bytes())
}
fn kfstat(&self, id: usize, buf: UserSliceWo, token: &mut CleanLockToken) -> Result<()> {
let handles = HANDLES.read(token.token());
let handle = handles.get(id)?;
buf.copy_exactly(&match handle.kind {
HandleKind::Rxsdt => {
let data = DATA.get().ok_or(Error::new(EBADFD))?;
Stat {
st_mode: MODE_FILE,
st_size: data.len().try_into().unwrap_or(u64::MAX),
..Default::default()
}
}
HandleKind::TopLevel => Stat {
st_mode: MODE_DIR,
st_size: 0,
..Default::default()
},
HandleKind::ShutdownPipe => Stat {
st_mode: MODE_CHR,
st_size: 1,
..Default::default()
},
HandleKind::SchemeRoot => return Err(Error::new(EBADF)),
})?;
Ok(())
} }
} }
+2 -1
View File
@@ -249,12 +249,13 @@ impl KernelScheme for MemoryScheme {
} }
fn kcall( fn kcall(
&self, &self,
id: usize, fds: &[usize],
payload: UserSliceRw, payload: UserSliceRw,
_flags: syscall::CallFlags, _flags: syscall::CallFlags,
_metadata: &[u64], _metadata: &[u64],
token: &mut CleanLockToken, token: &mut CleanLockToken,
) -> Result<usize> { ) -> Result<usize> {
let id = fds.first().copied().ok_or(Error::new(EINVAL))?;
let (handle_ty, _, _) = u32::try_from(id) let (handle_ty, _, _) = u32::try_from(id)
.ok() .ok()
.and_then(from_raw) .and_then(from_raw)
+4 -2
View File
@@ -590,7 +590,9 @@ pub trait KernelScheme: Send + Sync + 'static {
) -> Result<usize> { ) -> Result<usize> {
Err(Error::new(EBADF)) Err(Error::new(EBADF))
} }
fn kfpath(&self, id: usize, buf: UserSliceWo, token: &mut CleanLockToken) -> Result<usize>; fn kfpath(&self, id: usize, buf: UserSliceWo, token: &mut CleanLockToken) -> Result<usize> {
Err(Error::new(EOPNOTSUPP))
}
fn kfutimens(&self, id: usize, buf: UserSliceRo, token: &mut CleanLockToken) -> Result<usize> { fn kfutimens(&self, id: usize, buf: UserSliceRo, token: &mut CleanLockToken) -> Result<usize> {
Err(Error::new(EBADF)) Err(Error::new(EBADF))
} }
@@ -686,7 +688,7 @@ pub trait KernelScheme: Send + Sync + 'static {
} }
fn kcall( fn kcall(
&self, &self,
id: usize, fds: &[usize],
payload: UserSliceRw, payload: UserSliceRw,
flags: CallFlags, flags: CallFlags,
metadata: &[u64], metadata: &[u64],
+3 -1
View File
@@ -632,12 +632,13 @@ impl KernelScheme for ProcScheme {
} }
fn kcall( fn kcall(
&self, &self,
id: usize, fds: &[usize],
_payload: UserSliceRw, _payload: UserSliceRw,
_flags: CallFlags, _flags: CallFlags,
metadata: &[u64], metadata: &[u64],
token: &mut CleanLockToken, token: &mut CleanLockToken,
) -> Result<usize> { ) -> Result<usize> {
let id = fds.first().copied().ok_or(Error::new(EINVAL))?;
// TODO: simplify // TODO: simplify
let handle = { let handle = {
let mut handles = HANDLES.write(token.token()); let mut handles = HANDLES.write(token.token());
@@ -658,6 +659,7 @@ impl KernelScheme for ProcScheme {
ProcSchemeVerb::Iopl => context::current() ProcSchemeVerb::Iopl => context::current()
.write(token.token()) .write(token.token())
.set_userspace_io_allowed(true), .set_userspace_io_allowed(true),
_ => return Err(Error::new(EINVAL)),
} }
Ok(0) Ok(0)
} }
+2 -1
View File
@@ -1929,12 +1929,13 @@ impl KernelScheme for UserScheme {
} }
fn kcall( fn kcall(
&self, &self,
id: usize, fds: &[usize],
payload: UserSliceRw, payload: UserSliceRw,
_flags: CallFlags, _flags: CallFlags,
metadata: &[u64], metadata: &[u64],
token: &mut CleanLockToken, token: &mut CleanLockToken,
) -> Result<usize> { ) -> Result<usize> {
let id = fds.first().copied().ok_or(Error::new(EINVAL))?;
let inner = self.inner.clone(); let inner = self.inner.clone();
let mut address = inner.capture_user(payload, token)?; let mut address = inner.capture_user(payload, token)?;
+3 -2
View File
@@ -2,6 +2,7 @@ use core::{
hint, slice, hint, slice,
sync::atomic::{AtomicBool, Ordering}, sync::atomic::{AtomicBool, Ordering},
}; };
use core::ptr::NonNull;
use crate::{ use crate::{
arch::interrupt, arch::interrupt,
@@ -94,7 +95,7 @@ impl KernelArgs {
} }
} }
pub(crate) fn acpi_rsdp(&self) -> Option<*const u8> { pub(crate) fn acpi_rsdp(&self) -> Option<NonNull<u8>> {
if self.hwdesc_base != 0 { if self.hwdesc_base != 0 {
let data = unsafe { let data = unsafe {
slice::from_raw_parts( slice::from_raw_parts(
@@ -104,7 +105,7 @@ impl KernelArgs {
) )
}; };
if data.starts_with(b"RSD PTR ") { if data.starts_with(b"RSD PTR ") {
Some(data.as_ptr()) Some(NonNull::new(data.as_ptr() as *mut u8).unwrap())
} else { } else {
None None
} }
+1 -1
View File
@@ -305,7 +305,7 @@ fn call_normal(
if flags.contains(CallFlags::STD_FS) { if flags.contains(CallFlags::STD_FS) {
scheme.translate_std_fs_call(number, file.description, payload, flags, metadata, token) scheme.translate_std_fs_call(number, file.description, payload, flags, metadata, token)
} else { } else {
scheme.kcall(number, payload, flags, metadata, token) scheme.kcall(&[number], payload, flags, metadata, token)
} }
} }