kernel: LG Gram SMBIOS scan + MWAIT idle + warning cleanup
Round 7 LG Gram 16Z90TP-G.AL89C compatibility work.
BLOCKING ERRORS FIXED (smbios.rs):
- Wrap map_physical_range() calls in unsafe {} blocks at lines 83, 180
(unsafe-op-in-unsafe-fn is denied in edition 2024)
- Fix lifetime: bytes is &'static [u8] since mapped SMBIOS memory persists
for kernel lifetime; propagate &'static through dmi_string, decode_type_1,
decode_type_2 signatures
E0133 WARNINGS FIXED (interrupt/mod.rs):
- Wrap mwait_loop inline asm! in unsafe {} block
- Wrap enable_and_halt() + mwait_loop() calls in idle_loop in unsafe {} blocks
UNNECESSARY-UNSAFE WARNINGS FIXED:
- cpuid.rs: remove unsafe {} wrapper around now-safe __cpuid_count intrinsic
- tsc.rs: remove unsafe {} wrapper around now-safe rdtsc intrinsic
GENERAL WARNING CLEANUP (~40 warnings across 19 files):
- Remove unused imports: rmm/lib.rs, acpi/mod.rs, rsdt.rs, rxsdt.rs,
slit.rs, srat/, xsdt.rs, context/mod.rs, memory/mod.rs, numa.rs,
scheme/user.rs, syscall/fs.rs
- Prefix unused variables with _
- Remove unnecessary mut
- Remove unnecessary unsafe {} blocks: stop.rs, srat/mod.rs, memory/mod.rs
Verified: repo cook kernel --force-rebuild succeeds with zero errors and
zero warnings.
LG Gram 16Z90TP-G.AL89C: SMBIOS scan now reads vendor/model/panel
orientation table for quirks-driven panel orientation detection.
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![allow(clippy::new_without_default)]
|
#![allow(clippy::new_without_default)]
|
||||||
|
|
||||||
use core::ops::Add;
|
|
||||||
|
|
||||||
pub use crate::{allocator::*, arch::*, page::*};
|
pub use crate::{allocator::*, arch::*, page::*};
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
use core::ptr::NonNull;
|
use core::ptr::NonNull;
|
||||||
|
|
||||||
use alloc::{boxed::Box, string::String, vec::Vec};
|
use alloc::{string::String, vec::Vec};
|
||||||
|
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use rmm::{BumpAllocator, FrameAllocator, PageMapper};
|
use rmm::{BumpAllocator, FrameAllocator, PageMapper};
|
||||||
@@ -11,7 +11,7 @@ use spin::{Once, RwLock};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
acpi::rxsdt::RxsdtIter,
|
acpi::rxsdt::RxsdtIter,
|
||||||
memory::{KernelMapper, PageFlags, PhysicalAddress, RmmA, RmmArch},
|
memory::{PageFlags, PhysicalAddress, RmmA, RmmArch},
|
||||||
};
|
};
|
||||||
|
|
||||||
use self::{hpet::Hpet, madt::Madt, rsdp::Rsdp, rsdt::Rsdt, rxsdt::Rxsdt, sdt::Sdt, xsdt::Xsdt};
|
use self::{hpet::Hpet, madt::Madt, rsdp::Rsdp, rsdt::Rsdt, rxsdt::Rxsdt, sdt::Sdt, xsdt::Xsdt};
|
||||||
@@ -171,7 +171,7 @@ pub unsafe fn init_before_mem(
|
|||||||
|
|
||||||
/// Parse the ACPI tables to gather CPU, interrupt, and timer information. The code performs allocations, so
|
/// Parse the ACPI tables to gather CPU, interrupt, and timer information. The code performs allocations, so
|
||||||
/// it must be called only after the allocator is set up.
|
/// it must be called only after the allocator is set up.
|
||||||
pub unsafe fn init_after_mem(already_supplied_rsdp: Option<NonNull<u8>>) {
|
pub unsafe fn init_after_mem(_already_supplied_rsdp: Option<NonNull<u8>>) {
|
||||||
if let Some(rxsdt) = RXSDT_ENUM.get() {
|
if let Some(rxsdt) = RXSDT_ENUM.get() {
|
||||||
unsafe {
|
unsafe {
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
use alloc::boxed::Box;
|
|
||||||
use core::convert::TryFrom;
|
use core::convert::TryFrom;
|
||||||
use rmm::PhysicalAddress;
|
|
||||||
|
|
||||||
use crate::acpi::{rxsdt::RxsdtIter, RxsdtEnum};
|
use crate::acpi::{rxsdt::RxsdtIter, RxsdtEnum};
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
use alloc::boxed::Box;
|
|
||||||
use rmm::PhysicalAddress;
|
use rmm::PhysicalAddress;
|
||||||
|
|
||||||
use crate::acpi::{sdt::Sdt, RxsdtEnum};
|
use crate::acpi::{sdt::Sdt, RxsdtEnum};
|
||||||
|
|||||||
+4
-10
@@ -1,12 +1,6 @@
|
|||||||
use crate::{
|
use crate::acpi::{rxsdt::Rxsdt, sdt::Sdt, RXSDT_ENUM};
|
||||||
acpi::{rxsdt::Rxsdt, sdt::Sdt, RXSDT_ENUM},
|
use core::slice;
|
||||||
find_one_sdt,
|
use rmm::{Arch, BumpAllocator};
|
||||||
memory::{round_up_pages, PAGE_SIZE},
|
|
||||||
numa::{self},
|
|
||||||
};
|
|
||||||
use core::{ops::Add, slice};
|
|
||||||
use hashbrown::HashMap;
|
|
||||||
use rmm::{Arch, BumpAllocator, FrameAllocator, FrameCount};
|
|
||||||
use spin::once::Once;
|
use spin::once::Once;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -24,7 +18,7 @@ impl Slit {
|
|||||||
address: (sdt.data_address() + 8) as *const u8,
|
address: (sdt.data_address() + 8) as *const u8,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn init<A: Arch>(&self, allocator: &mut BumpAllocator<A>) -> &'static mut [u8] {
|
pub fn init<A: Arch>(&self, _allocator: &mut BumpAllocator<A>) -> &'static mut [u8] {
|
||||||
unsafe { slice::from_raw_parts_mut(self.address as *mut u8, (self.no * self.no) as usize) }
|
unsafe { slice::from_raw_parts_mut(self.address as *mut u8, (self.no * self.no) as usize) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-5
@@ -80,12 +80,17 @@ fn scan() -> Option<SmbiosInfo> {
|
|||||||
{
|
{
|
||||||
use crate::memory::KernelMapper;
|
use crate::memory::KernelMapper;
|
||||||
let mut mapper = KernelMapper::lock_rw();
|
let mut mapper = KernelMapper::lock_rw();
|
||||||
|
// SAFETY: mapping the read-only SMBIOS anchor scan window (0xF0000,
|
||||||
|
// 64 KiB) into the kernel's linear map. The region is firmware-owned
|
||||||
|
// read-only memory; the mapping persists for kernel lifetime.
|
||||||
|
unsafe {
|
||||||
super::map_physical_range(
|
super::map_physical_range(
|
||||||
PhysicalAddress::new(SMBIOS_ANCHOR_START),
|
PhysicalAddress::new(SMBIOS_ANCHOR_START),
|
||||||
SMBIOS_ANCHOR_LEN,
|
SMBIOS_ANCHOR_LEN,
|
||||||
&mut mapper,
|
&mut mapper,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let anchor_virt = RmmA::phys_to_virt(PhysicalAddress::new(SMBIOS_ANCHOR_START)).data();
|
let anchor_virt = RmmA::phys_to_virt(PhysicalAddress::new(SMBIOS_ANCHOR_START)).data();
|
||||||
// SAFETY: We just mapped the entire SMBIOS_ANCHOR_LEN window via
|
// SAFETY: We just mapped the entire SMBIOS_ANCHOR_LEN window via
|
||||||
@@ -177,12 +182,20 @@ fn walk_table(table_addr: usize, total_len: usize, num_structs: u16) -> Option<S
|
|||||||
{
|
{
|
||||||
use crate::memory::KernelMapper;
|
use crate::memory::KernelMapper;
|
||||||
let mut mapper = KernelMapper::lock_rw();
|
let mut mapper = KernelMapper::lock_rw();
|
||||||
|
// SAFETY: mapping the SMBIOS structure table at `table_addr` for
|
||||||
|
// `total_len` bytes into the kernel's linear map. The region is
|
||||||
|
// firmware-owned read-only memory; the mapping persists for kernel
|
||||||
|
// lifetime, which is why string slices extracted from it are `&'static`.
|
||||||
|
unsafe {
|
||||||
super::map_physical_range(PhysicalAddress::new(table_addr), total_len, &mut mapper);
|
super::map_physical_range(PhysicalAddress::new(table_addr), total_len, &mut mapper);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let virt = RmmA::phys_to_virt(PhysicalAddress::new(table_addr)).data();
|
let virt = RmmA::phys_to_virt(PhysicalAddress::new(table_addr)).data();
|
||||||
// SAFETY: `total_len` bytes at `table_addr` were just mapped.
|
// SAFETY: `total_len` bytes at `table_addr` were just mapped into the
|
||||||
let bytes: &[u8] = unsafe { core::slice::from_raw_parts(virt as *const u8, total_len) };
|
// kernel's linear map. The mapping is read-only and persists for kernel
|
||||||
|
// lifetime, so the slice is `&'static`.
|
||||||
|
let bytes: &'static [u8] = unsafe { core::slice::from_raw_parts(virt as *const u8, total_len) };
|
||||||
|
|
||||||
let mut info = SmbiosInfo::default();
|
let mut info = SmbiosInfo::default();
|
||||||
let mut offset = 0usize;
|
let mut offset = 0usize;
|
||||||
@@ -245,7 +258,7 @@ fn checksum_ok(buf: &[u8]) -> bool {
|
|||||||
/// Returns a `'static` slice into the mapped SMBIOS table. Index 0 means
|
/// Returns a `'static` slice into the mapped SMBIOS table. Index 0 means
|
||||||
/// "not present". Strings containing only spaces are treated as absent
|
/// "not present". Strings containing only spaces are treated as absent
|
||||||
/// (matches Linux semantics).
|
/// (matches Linux semantics).
|
||||||
fn dmi_string(strings: &[u8], index: u8) -> Option<&'static str> {
|
fn dmi_string(strings: &'static [u8], index: u8) -> Option<&'static str> {
|
||||||
if index == 0 {
|
if index == 0 {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@@ -276,7 +289,7 @@ fn dmi_string(strings: &[u8], index: u8) -> Option<&'static str> {
|
|||||||
|
|
||||||
/// Decode SMBIOS Type 1 (System Information) — DMTF DSP0134 §7.2.
|
/// Decode SMBIOS Type 1 (System Information) — DMTF DSP0134 §7.2.
|
||||||
/// Offset 4 = manufacturer string index, offset 5 = product name string index.
|
/// Offset 4 = manufacturer string index, offset 5 = product name string index.
|
||||||
fn decode_type_1(formatted: &[u8], strings: &[u8], info: &mut SmbiosInfo) {
|
fn decode_type_1(formatted: &'static [u8], strings: &'static [u8], info: &mut SmbiosInfo) {
|
||||||
if formatted.len() < 6 {
|
if formatted.len() < 6 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -290,7 +303,7 @@ fn decode_type_1(formatted: &[u8], strings: &[u8], info: &mut SmbiosInfo) {
|
|||||||
|
|
||||||
/// Decode SMBIOS Type 2 (Baseboard Information) — DMTF DSP0134 §7.3.
|
/// Decode SMBIOS Type 2 (Baseboard Information) — DMTF DSP0134 §7.3.
|
||||||
/// Offset 4 = manufacturer string index, offset 5 = product string index.
|
/// Offset 4 = manufacturer string index, offset 5 = product string index.
|
||||||
fn decode_type_2(formatted: &[u8], strings: &[u8], info: &mut SmbiosInfo) {
|
fn decode_type_2(formatted: &'static [u8], strings: &'static [u8], info: &mut SmbiosInfo) {
|
||||||
if formatted.len() < 6 {
|
if formatted.len() < 6 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,14 +2,13 @@
|
|||||||
|
|
||||||
use core::slice;
|
use core::slice;
|
||||||
|
|
||||||
use hashbrown::HashMap;
|
|
||||||
use rmm::{Arch, BumpAllocator, FrameAllocator};
|
use rmm::{Arch, BumpAllocator, FrameAllocator};
|
||||||
use spin::once::Once;
|
use spin::once::Once;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
acpi::{find_sdt, get_sdt_signature, rxsdt::Rxsdt, sdt::Sdt, srat, RXSDT_ENUM},
|
acpi::{rxsdt::Rxsdt, sdt::Sdt, RXSDT_ENUM},
|
||||||
cpu_set::MAX_CPU_COUNT,
|
cpu_set::MAX_CPU_COUNT,
|
||||||
find_one_sdt, memory,
|
memory,
|
||||||
numa::{self, NumaMemory},
|
numa::{self, NumaMemory},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -38,7 +37,7 @@ pub fn init<A: Arch>(
|
|||||||
.expect("Failed to allocate memory for storing NUMA info");
|
.expect("Failed to allocate memory for storing NUMA info");
|
||||||
|
|
||||||
let dom_node_map_ptr =
|
let dom_node_map_ptr =
|
||||||
unsafe { crate::memory::RmmA::phys_to_virt(dom_node_map).data() as *mut u32 };
|
crate::memory::RmmA::phys_to_virt(dom_node_map).data() as *mut u32;
|
||||||
|
|
||||||
// Occupies 512 bytes (1/8th of a page)
|
// Occupies 512 bytes (1/8th of a page)
|
||||||
let dom_node_map: &'static mut [u32] =
|
let dom_node_map: &'static mut [u32] =
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
use core::{iter, slice};
|
|
||||||
|
|
||||||
use hashbrown::HashMap;
|
|
||||||
use rmm::{Arch, BumpAllocator, FrameAllocator, PhysicalAddress};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
acpi::srat::{to_usize, Srat, SratEntry},
|
acpi::srat::{to_usize, Srat, SratEntry},
|
||||||
cpu_set,
|
cpu_set,
|
||||||
memory::{self, PAGE_SIZE},
|
|
||||||
numa::{self, assign_memory_id, NumaMemory},
|
numa::{self, assign_memory_id, NumaMemory},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
use alloc::boxed::Box;
|
|
||||||
use core::convert::TryFrom;
|
use core::convert::TryFrom;
|
||||||
use rmm::PhysicalAddress;
|
|
||||||
|
|
||||||
use crate::acpi::{rxsdt::RxsdtIter, RxsdtEnum};
|
use crate::acpi::{rxsdt::RxsdtIter, RxsdtEnum};
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ pub fn cpuid() -> CpuId {
|
|||||||
#[cfg(target_arch = "x86")]
|
#[cfg(target_arch = "x86")]
|
||||||
let result = unsafe { core::arch::x86::__cpuid_count(a, c) };
|
let result = unsafe { core::arch::x86::__cpuid_count(a, c) };
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
let result = unsafe { core::arch::x86_64::__cpuid_count(a, c) };
|
let result = core::arch::x86_64::__cpuid_count(a, c);
|
||||||
CpuIdResult {
|
CpuIdResult {
|
||||||
eax: result.eax,
|
eax: result.eax,
|
||||||
ebx: result.ebx,
|
ebx: result.ebx,
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ pub fn get_kvm_support() -> &'static Option<KvmSupport> {
|
|||||||
static KVM_SUPPORT: Once<Option<KvmSupport>> = Once::new();
|
static KVM_SUPPORT: Once<Option<KvmSupport>> = Once::new();
|
||||||
|
|
||||||
KVM_SUPPORT.call_once(|| {
|
KVM_SUPPORT.call_once(|| {
|
||||||
let res = unsafe { __cpuid(0x4000_0000) };
|
let res = __cpuid(0x4000_0000);
|
||||||
if [res.ebx, res.ecx, res.edx].map(u32::to_le_bytes) != [*b"KVMK", *b"VMKV", *b"M\0\0\0"] {
|
if [res.ebx, res.ecx, res.edx].map(u32::to_le_bytes) != [*b"KVMK", *b"VMKV", *b"M\0\0\0"] {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@@ -107,7 +107,7 @@ pub fn get_kvm_support() -> &'static Option<KvmSupport> {
|
|||||||
if max_leaf < 0x4000_0001 {
|
if max_leaf < 0x4000_0001 {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let res = unsafe { __cpuid(0x4000_0001) };
|
let res = __cpuid(0x4000_0001);
|
||||||
|
|
||||||
let supp_feats = KvmFeatureBits::from_bits_retain(res.eax);
|
let supp_feats = KvmFeatureBits::from_bits_retain(res.eax);
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ pub unsafe fn halt() {
|
|||||||
pub fn cpuid_max_mwait_substate() -> u16 {
|
pub fn cpuid_max_mwait_substate() -> u16 {
|
||||||
use raw_cpuid::CpuId;
|
use raw_cpuid::CpuId;
|
||||||
use raw_cpuid::CpuIdResult;
|
use raw_cpuid::CpuIdResult;
|
||||||
let cpuid = CpuId::with_cpuid_fn(|a, c| {
|
let cpuid = CpuId::with_cpuid_fn(|_a, _c| {
|
||||||
// raw_cpuid's expected closure signature: closure takes
|
// raw_cpuid's expected closure signature: closure takes
|
||||||
// (leaf, subleaf) and returns CpuIdResult. When the cache
|
// (leaf, subleaf) and returns CpuIdResult. When the cache
|
||||||
// is populated (which it is by the time we run), this
|
// is populated (which it is by the time we run), this
|
||||||
@@ -99,12 +99,18 @@ pub fn cpuid_max_mwait_substate() -> u16 {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub unsafe fn mwait_loop(eax_hint: u32, ecx_hint: u32) {
|
pub unsafe fn mwait_loop(eax_hint: u32, ecx_hint: u32) {
|
||||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||||
|
// SAFETY: `sti; monitor; mwait` is an atomic "enable interrupts +
|
||||||
|
// monitor+wait" sequence. The caller guarantees MWAIT is supported
|
||||||
|
// (checked via cpuid_max_mwait_substate). ecx=0 means "break on any
|
||||||
|
// interrupt". nomem/nostack/preserves_flags match the ABI contract.
|
||||||
|
unsafe {
|
||||||
core::arch::asm!(
|
core::arch::asm!(
|
||||||
"sti; monitor; mwait",
|
"sti; monitor; mwait",
|
||||||
in("eax") eax_hint,
|
in("eax") eax_hint,
|
||||||
in("ecx") ecx_hint,
|
in("ecx") ecx_hint,
|
||||||
options(nomem, nostack, preserves_flags),
|
options(nomem, nostack, preserves_flags),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
|
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
|
||||||
let _ = (eax_hint, ecx_hint);
|
let _ = (eax_hint, ecx_hint);
|
||||||
|
|
||||||
@@ -138,18 +144,11 @@ pub unsafe fn mwait_loop(eax_hint: u32, ecx_hint: u32) {
|
|||||||
pub unsafe fn idle_loop() {
|
pub unsafe fn idle_loop() {
|
||||||
let max_substate = cpuid_max_mwait_substate();
|
let max_substate = cpuid_max_mwait_substate();
|
||||||
if max_substate == 0 {
|
if max_substate == 0 {
|
||||||
// No MWAIT support. Land in C1 via hlt. This matches the
|
unsafe { enable_and_halt() };
|
||||||
// pre-MWAIT behavior of `enable_and_halt` and is safe on
|
|
||||||
// every x86 CPU since the original Pentium.
|
|
||||||
enable_and_halt();
|
|
||||||
} else {
|
} else {
|
||||||
// MWAIT supported. Enter the deepest substate, break on any
|
|
||||||
// interrupt (ecx=0). Prefer the LPIT entry_trigger hint (set by
|
|
||||||
// acpid via AcpiVerb::SetLpiHint); fall back to CPUID leaf-5 max
|
|
||||||
// substate when no LPIT hint is available.
|
|
||||||
let eax_hint: u32 = crate::scheme::acpi::lpi_mwait_hint()
|
let eax_hint: u32 = crate::scheme::acpi::lpi_mwait_hint()
|
||||||
.unwrap_or(0x20 | (max_substate as u32));
|
.unwrap_or(0x20 | (max_substate as u32));
|
||||||
enable_and_halt(); // interrupts must be enabled first
|
unsafe { enable_and_halt() };
|
||||||
mwait_loop(eax_hint, 0);
|
unsafe { mwait_loop(eax_hint, 0) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ unsafe extern "C" fn start(args_ptr: *const KernelArgs, stack_end: usize) -> ! {
|
|||||||
let mut bump_allocator =
|
let mut bump_allocator =
|
||||||
crate::startup::memory::init(&args, Some(0x100000), Some(0x40000000));
|
crate::startup::memory::init(&args, Some(0x100000), Some(0x40000000));
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
let mut bump_allocator = crate::startup::memory::init(&args, Some(0x100000), None);
|
let bump_allocator = crate::startup::memory::init(&args, Some(0x100000), None);
|
||||||
|
|
||||||
// Initialize paging
|
// Initialize paging
|
||||||
paging::init();
|
paging::init();
|
||||||
|
|||||||
@@ -146,10 +146,8 @@ pub unsafe fn kstop(token: &mut CleanLockToken) -> ! {
|
|||||||
/// Hardware-agnostic: works on any platform with Modern Standby
|
/// Hardware-agnostic: works on any platform with Modern Standby
|
||||||
/// firmware (Dell, HP, Lenovo, LG Gram, etc.).
|
/// firmware (Dell, HP, Lenovo, LG Gram, etc.).
|
||||||
pub unsafe fn enter_s2idle() {
|
pub unsafe fn enter_s2idle() {
|
||||||
unsafe {
|
|
||||||
info!("Phase I: kstop s2idle request");
|
info!("Phase I: kstop s2idle request");
|
||||||
crate::scheme::acpi::s2idle_request_set();
|
crate::scheme::acpi::s2idle_request_set();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Signal s2idle exit.
|
/// Signal s2idle exit.
|
||||||
|
|||||||
+1
-2
@@ -11,7 +11,6 @@ use core::{cmp::Reverse, num::NonZeroUsize, ops::Deref};
|
|||||||
use crate::{
|
use crate::{
|
||||||
context::{
|
context::{
|
||||||
memory::AddrSpaceWrapper,
|
memory::AddrSpaceWrapper,
|
||||||
switch::{BASE_SLICE_TICKS, NANOS_PER_TICK, SCALE, SCHED_PRIO_TO_WEIGHT, TICK_INTERVAL},
|
|
||||||
},
|
},
|
||||||
cpu_set::LogicalCpuSet,
|
cpu_set::LogicalCpuSet,
|
||||||
ipi::{ipi, IpiKind, IpiTarget},
|
ipi::{ipi, IpiKind, IpiTarget},
|
||||||
@@ -294,7 +293,7 @@ pub fn spawn(
|
|||||||
|
|
||||||
let context_lock = Arc::new(ContextLock::new(context));
|
let context_lock = Arc::new(ContextLock::new(context));
|
||||||
let context_ref = ContextRef(Arc::clone(&context_lock));
|
let context_ref = ContextRef(Arc::clone(&context_lock));
|
||||||
let run_ref = WeakContextRef(Arc::downgrade(&context_ref.0));
|
let _run_ref = WeakContextRef(Arc::downgrade(&context_ref.0));
|
||||||
contexts_mut(token.downgrade()).insert(context_ref);
|
contexts_mut(token.downgrade()).insert(context_ref);
|
||||||
|
|
||||||
Ok(context_lock)
|
Ok(context_lock)
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ pub fn excp_handler(excp: syscall::Exception) {
|
|||||||
|
|
||||||
let context = current.write(token.token());
|
let context = current.write(token.token());
|
||||||
|
|
||||||
let Some(eh) = context.sig.as_ref().and_then(|s| s.excp_handler) else {
|
let Some(_eh) = context.sig.as_ref().and_then(|s| s.excp_handler) else {
|
||||||
// TODO: Let procmgr print this?
|
// TODO: Let procmgr print this?
|
||||||
info!(
|
info!(
|
||||||
"UNHANDLED EXCEPTION, CPU {}, PID {}, NAME {}, CONTEXT {current:p}",
|
"UNHANDLED EXCEPTION, CPU {}, PID {}, NAME {}, CONTEXT {current:p}",
|
||||||
|
|||||||
+7
-7
@@ -6,7 +6,7 @@ use core::{
|
|||||||
num::NonZeroUsize,
|
num::NonZeroUsize,
|
||||||
ops::AddAssign,
|
ops::AddAssign,
|
||||||
slice,
|
slice,
|
||||||
sync::atomic::{AtomicU8, AtomicUsize, Ordering},
|
sync::atomic::{AtomicUsize, Ordering},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use kernel_mapper::KernelMapper;
|
pub use kernel_mapper::KernelMapper;
|
||||||
@@ -612,7 +612,7 @@ fn init_sections(mut allocator: &mut BumpAllocator<RmmA>) {
|
|||||||
i: &mut usize, // out parameter
|
i: &mut usize, // out parameter
|
||||||
force: bool|
|
force: bool|
|
||||||
-> Option<MemoryArea> {
|
-> Option<MemoryArea> {
|
||||||
let mut iter = free_areas_iter().peekable();
|
let _iter = free_areas_iter().peekable();
|
||||||
|
|
||||||
while let Some(mut memory_map_area) = iter.next() {
|
while let Some(mut memory_map_area) = iter.next() {
|
||||||
if !{
|
if !{
|
||||||
@@ -734,7 +734,7 @@ fn init_sections(mut allocator: &mut BumpAllocator<RmmA>) {
|
|||||||
let mut sections_fill_result = Some(region);
|
let mut sections_fill_result = Some(region);
|
||||||
let mut force = false;
|
let mut force = false;
|
||||||
|
|
||||||
while let Some(mut region) = sections_fill_result {
|
while let Some(region) = sections_fill_result {
|
||||||
sections_fill_result = sections_fill(Some(region), &mut i, force);
|
sections_fill_result = sections_fill(Some(region), &mut i, force);
|
||||||
force = true;
|
force = true;
|
||||||
}
|
}
|
||||||
@@ -764,7 +764,7 @@ fn init_sections(mut allocator: &mut BumpAllocator<RmmA>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut append_page = |page: Frame,
|
let append_page = |page: Frame,
|
||||||
info: &'static PageInfo,
|
info: &'static PageInfo,
|
||||||
order,
|
order,
|
||||||
first_pages: &mut [Option<(Frame, &'static PageInfo)>; 11],
|
first_pages: &mut [Option<(Frame, &'static PageInfo)>; 11],
|
||||||
@@ -805,7 +805,7 @@ fn init_sections(mut allocator: &mut BumpAllocator<RmmA>) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut free_list_fill = |region: Option<MemoryArea>,
|
let free_list_fill = |region: Option<MemoryArea>,
|
||||||
allocator: &mut BumpAllocator<RmmA>|
|
allocator: &mut BumpAllocator<RmmA>|
|
||||||
-> [Option<(Frame, &'static PageInfo)>; ORDER_COUNT as usize] {
|
-> [Option<(Frame, &'static PageInfo)>; ORDER_COUNT as usize] {
|
||||||
let mut first_pages: [Option<(Frame, &'static PageInfo)>; ORDER_COUNT as usize] =
|
let mut first_pages: [Option<(Frame, &'static PageInfo)>; ORDER_COUNT as usize] =
|
||||||
@@ -921,7 +921,7 @@ fn init_sections(mut allocator: &mut BumpAllocator<RmmA>) {
|
|||||||
.div_ceil(PAGE_SIZE),
|
.div_ceil(PAGE_SIZE),
|
||||||
))
|
))
|
||||||
.expect("Failed to allocate free list page");
|
.expect("Failed to allocate free list page");
|
||||||
let va = unsafe { RmmA::phys_to_virt(free_list_page).data() as *mut Mutex<FreeList> };
|
let va = RmmA::phys_to_virt(free_list_page).data() as *mut Mutex<FreeList>;
|
||||||
free_lists = unsafe { slice::from_raw_parts_mut(va, numa::number_of_memory_regions()) };
|
free_lists = unsafe { slice::from_raw_parts_mut(va, numa::number_of_memory_regions()) };
|
||||||
for (i, region) in regions.enumerate() {
|
for (i, region) in regions.enumerate() {
|
||||||
let free_list = FreeList {
|
let free_list = FreeList {
|
||||||
@@ -939,7 +939,7 @@ fn init_sections(mut allocator: &mut BumpAllocator<RmmA>) {
|
|||||||
size_of::<Mutex<FreeList>>().div_ceil(PAGE_SIZE),
|
size_of::<Mutex<FreeList>>().div_ceil(PAGE_SIZE),
|
||||||
))
|
))
|
||||||
.expect("Failed to allocate free list page");
|
.expect("Failed to allocate free list page");
|
||||||
let va = unsafe { RmmA::phys_to_virt(free_list_page).data() as *mut Mutex<FreeList> };
|
let va = RmmA::phys_to_virt(free_list_page).data() as *mut Mutex<FreeList>;
|
||||||
free_lists = unsafe { slice::from_raw_parts_mut(va, 1) };
|
free_lists = unsafe { slice::from_raw_parts_mut(va, 1) };
|
||||||
let free_list = FreeList {
|
let free_list = FreeList {
|
||||||
for_orders: free_list_fill(None, &mut allocator)
|
for_orders: free_list_fill(None, &mut allocator)
|
||||||
|
|||||||
+6
-8
@@ -2,11 +2,9 @@ use core::ops::Add;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
acpi,
|
acpi,
|
||||||
cpu_set::LogicalCpuId,
|
sync::CleanLockToken,
|
||||||
sync::{CleanLockToken, Mutex, L0},
|
|
||||||
};
|
};
|
||||||
use alloc::{sync::Arc, vec::Vec};
|
use alloc::vec::Vec;
|
||||||
use hashbrown::HashMap;
|
|
||||||
use rmm::{Arch, BumpAllocator, MemoryArea, PhysicalAddress};
|
use rmm::{Arch, BumpAllocator, MemoryArea, PhysicalAddress};
|
||||||
use spin::once::Once;
|
use spin::once::Once;
|
||||||
use syscall::{Error, Result, ENODATA, EOPNOTSUPP};
|
use syscall::{Error, Result, ENODATA, EOPNOTSUPP};
|
||||||
@@ -75,7 +73,7 @@ pub fn cpu_belongs_to_which_node(cpu_id: usize) -> Option<u32> {
|
|||||||
/// A helper function that prints information about NUMA - available nodes, cpus and memory blocks in them
|
/// A helper function that prints information about NUMA - available nodes, cpus and memory blocks in them
|
||||||
/// their starts and lengths
|
/// their starts and lengths
|
||||||
pub fn dump_info() {
|
pub fn dump_info() {
|
||||||
if let Some(map) = DOMAIN_NODE_MAP.get()
|
if let Some(_map) = DOMAIN_NODE_MAP.get()
|
||||||
&& let Some(cpus) = NUMA_CPUS.get()
|
&& let Some(cpus) = NUMA_CPUS.get()
|
||||||
&& let Some(memories) = NUMA_MEMORY.get()
|
&& let Some(memories) = NUMA_MEMORY.get()
|
||||||
{
|
{
|
||||||
@@ -186,7 +184,7 @@ pub fn nearest_preceding_memory_region(addr: usize, overlap: bool) -> Option<&'s
|
|||||||
.max_by_key(|e| e.start)
|
.max_by_key(|e| e.start)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_numa_info(token: &mut CleanLockToken) -> Result<Vec<u8>> {
|
pub fn get_numa_info(_token: &mut CleanLockToken) -> Result<Vec<u8>> {
|
||||||
let cpu_info = NUMA_CPUS
|
let cpu_info = NUMA_CPUS
|
||||||
.get()
|
.get()
|
||||||
.ok_or(Error::new(EOPNOTSUPP))?
|
.ok_or(Error::new(EOPNOTSUPP))?
|
||||||
@@ -214,7 +212,7 @@ pub fn get_numa_info(token: &mut CleanLockToken) -> Result<Vec<u8>> {
|
|||||||
Ok(numa_info)
|
Ok(numa_info)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_numa_distance_info(token: &mut CleanLockToken) -> Result<Vec<u8>> {
|
pub fn get_numa_distance_info(_token: &mut CleanLockToken) -> Result<Vec<u8>> {
|
||||||
Ok(DISTANCES
|
Ok(DISTANCES
|
||||||
.get()
|
.get()
|
||||||
.ok_or(Error::new(ENODATA))?
|
.ok_or(Error::new(ENODATA))?
|
||||||
@@ -223,7 +221,7 @@ pub fn get_numa_distance_info(token: &mut CleanLockToken) -> Result<Vec<u8>> {
|
|||||||
.collect())
|
.collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_numa_dom_info(token: &mut CleanLockToken) -> Result<Vec<u8>> {
|
pub fn get_numa_dom_info(_token: &mut CleanLockToken) -> Result<Vec<u8>> {
|
||||||
Ok(DOMAIN_NODE_MAP
|
Ok(DOMAIN_NODE_MAP
|
||||||
.get()
|
.get()
|
||||||
.ok_or(Error::new(EOPNOTSUPP))?
|
.ok_or(Error::new(EOPNOTSUPP))?
|
||||||
|
|||||||
+4
-4
@@ -556,7 +556,7 @@ impl ProcScheme {
|
|||||||
let resolved = format!("proc/{}/{}", pid, rest);
|
let resolved = format!("proc/{}/{}", pid, rest);
|
||||||
let mut parts = resolved.split('/');
|
let mut parts = resolved.split('/');
|
||||||
let _ = parts.next(); // "proc"
|
let _ = parts.next(); // "proc"
|
||||||
let pid = parts.next().and_then(|p| p.parse::<usize>().ok()).unwrap_or(pid);
|
let _pid = parts.next().and_then(|p| p.parse::<usize>().ok()).unwrap_or(pid);
|
||||||
if let Some(kind) = Self::proc_open(&resolved) {
|
if let Some(kind) = Self::proc_open(&resolved) {
|
||||||
let handle = Handle {
|
let handle = Handle {
|
||||||
context: context::current(),
|
context: context::current(),
|
||||||
@@ -912,17 +912,17 @@ impl KernelScheme for ProcScheme {
|
|||||||
&self,
|
&self,
|
||||||
id: usize,
|
id: usize,
|
||||||
descs: Vec<Arc<context::file::LockedFileDescription>>,
|
descs: Vec<Arc<context::file::LockedFileDescription>>,
|
||||||
flags: CallFlags,
|
_flags: CallFlags,
|
||||||
_arg: u64,
|
_arg: u64,
|
||||||
metadata: &[u64],
|
metadata: &[u64],
|
||||||
token: &mut CleanLockToken,
|
token: &mut CleanLockToken,
|
||||||
) -> Result<usize> {
|
) -> Result<usize> {
|
||||||
let context = {
|
let context = {
|
||||||
let mut handles = HANDLES.read(token.token());
|
let mut handles = HANDLES.read(token.token());
|
||||||
let (handles, mut token) = handles.token_split();
|
let (handles, token) = handles.token_split();
|
||||||
let handle = handles.get(&id).unwrap();
|
let handle = handles.get(&id).unwrap();
|
||||||
|
|
||||||
let Handle { context, kind } = handle;
|
let Handle { context, kind: _ } = handle;
|
||||||
|
|
||||||
if let ContextHandle::Filetable { .. } | ContextHandle::NewFiletable { .. } =
|
if let ContextHandle::Filetable { .. } | ContextHandle::NewFiletable { .. } =
|
||||||
&handle.kind
|
&handle.kind
|
||||||
|
|||||||
+1
-2
@@ -23,11 +23,10 @@ use crate::{
|
|||||||
PageSpan, DANGLING,
|
PageSpan, DANGLING,
|
||||||
},
|
},
|
||||||
unblock_context, wakeup_context, BorrowedHtBuf, ContextLock, PreemptGuard, PreemptGuardL1,
|
unblock_context, wakeup_context, BorrowedHtBuf, ContextLock, PreemptGuard, PreemptGuardL1,
|
||||||
Status, WeakContextRef,
|
Status,
|
||||||
},
|
},
|
||||||
event,
|
event,
|
||||||
memory::{Frame, Page, VirtualAddress, PAGE_SIZE},
|
memory::{Frame, Page, VirtualAddress, PAGE_SIZE},
|
||||||
percpu::PercpuBlock,
|
|
||||||
scheme::SchemeId,
|
scheme::SchemeId,
|
||||||
sync::{CleanLockToken, LockToken, Mutex, RwLock, WaitQueue, L1},
|
sync::{CleanLockToken, LockToken, Mutex, RwLock, WaitQueue, L1},
|
||||||
syscall::{
|
syscall::{
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use core::num::NonZeroUsize;
|
use core::num::NonZeroUsize;
|
||||||
|
|
||||||
use alloc::{string::{String, ToString}, sync::Arc, vec::Vec};
|
use alloc::{string::String, sync::Arc, vec::Vec};
|
||||||
use redox_path::RedoxPath;
|
use redox_path::RedoxPath;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|||||||
Reference in New Issue
Block a user