acpi: move ACPI to its own driver
This commit is contained in:
parent
9e48530e62
commit
6e7a42c2cb
19
Cargo.lock
generated
19
Cargo.lock
generated
@ -2460,6 +2460,22 @@ dependencies = [
|
||||
"bytemuck",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ygg_driver_acpi"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"acpi",
|
||||
"acpi-system",
|
||||
"aml",
|
||||
"device-api",
|
||||
"kernel-arch-x86",
|
||||
"libk",
|
||||
"libk-mm",
|
||||
"libk-util",
|
||||
"log",
|
||||
"rsdp",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ygg_driver_ahci"
|
||||
version = "0.1.0"
|
||||
@ -2658,8 +2674,6 @@ dependencies = [
|
||||
"abi-lib",
|
||||
"abi-serde",
|
||||
"acpi",
|
||||
"acpi-system",
|
||||
"aml",
|
||||
"async-trait",
|
||||
"bitflags 2.6.0",
|
||||
"bytemuck",
|
||||
@ -2690,6 +2704,7 @@ dependencies = [
|
||||
"tock-registers 0.9.0",
|
||||
"vmalloc",
|
||||
"yboot-proto",
|
||||
"ygg_driver_acpi",
|
||||
"ygg_driver_ahci",
|
||||
"ygg_driver_input",
|
||||
"ygg_driver_net_core",
|
||||
|
@ -39,6 +39,7 @@ ahash = { version = "0.8.11", default-features = false, features = ["no-rng"] }
|
||||
|
||||
# acpi
|
||||
acpi = { git = "https://github.com/alnyan/acpi.git", package = "acpi", branch = "acpi-system" }
|
||||
rsdp = { git = "https://github.com/alnyan/acpi.git", package = "rsdp", branch = "acpi-system" }
|
||||
aml = { git = "https://github.com/alnyan/acpi.git", branch = "acpi-system" }
|
||||
acpi-system = { git = "https://github.com/alnyan/acpi-system.git" }
|
||||
|
||||
|
@ -61,12 +61,11 @@ kernel-arch-riscv64.workspace = true
|
||||
yboot-proto.workspace = true
|
||||
kernel-arch-x86_64.workspace = true
|
||||
kernel-arch-x86.workspace = true
|
||||
ygg_driver_acpi.path = "driver/acpi"
|
||||
|
||||
ygg_driver_nvme = { path = "driver/block/nvme" }
|
||||
|
||||
acpi.workspace = true
|
||||
aml.workspace = true
|
||||
acpi-system.workspace = true
|
||||
|
||||
[target.'cfg(target_arch = "x86")'.dependencies]
|
||||
kernel-arch-i686.workspace = true
|
||||
@ -87,6 +86,8 @@ kernel-arch-x86.workspace = true
|
||||
kernel-arch-aarch64.workspace = true
|
||||
kernel-arch-riscv64.workspace = true
|
||||
|
||||
ygg_driver_acpi.path = "driver/acpi"
|
||||
|
||||
[features]
|
||||
default = ["fb_console"]
|
||||
fb_console = []
|
||||
|
@ -6,4 +6,10 @@ extern crate alloc;
|
||||
|
||||
pub mod cpuid;
|
||||
pub mod gdt;
|
||||
pub mod intrinsics;
|
||||
pub mod registers;
|
||||
|
||||
#[cfg(any(target_arch = "x86_64", rust_analyzer))]
|
||||
pub const ISA_IRQ_OFFSET: u32 = 1024;
|
||||
#[cfg(any(target_arch = "x86", rust_analyzer))]
|
||||
pub const ISA_IRQ_OFFSET: u32 = 0;
|
||||
|
18
kernel/driver/acpi/Cargo.toml
Normal file
18
kernel/driver/acpi/Cargo.toml
Normal file
@ -0,0 +1,18 @@
|
||||
[package]
|
||||
name = "ygg_driver_acpi"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
libk-util.workspace = true
|
||||
libk-mm.workspace = true
|
||||
libk.workspace = true
|
||||
device-api.workspace = true
|
||||
kernel-arch-x86.path = "../../arch/x86"
|
||||
|
||||
acpi.workspace = true
|
||||
rsdp.workspace = true
|
||||
aml.workspace = true
|
||||
acpi-system.workspace = true
|
||||
|
||||
log.workspace = true
|
131
kernel/driver/acpi/src/aml_handler.rs
Normal file
131
kernel/driver/acpi/src/aml_handler.rs
Normal file
@ -0,0 +1,131 @@
|
||||
use core::time::Duration;
|
||||
|
||||
use crate::AcpiHandlerImpl;
|
||||
|
||||
impl aml::Handler for AcpiHandlerImpl {
|
||||
fn read_io_u8(&self, port: u16) -> u8 {
|
||||
<Self as acpi_system::Handler>::io_read_u8(port)
|
||||
}
|
||||
|
||||
fn read_io_u16(&self, port: u16) -> u16 {
|
||||
<Self as acpi_system::Handler>::io_read_u16(port)
|
||||
}
|
||||
|
||||
fn read_io_u32(&self, port: u16) -> u32 {
|
||||
<Self as acpi_system::Handler>::io_read_u32(port)
|
||||
}
|
||||
|
||||
fn write_io_u8(&self, port: u16, value: u8) {
|
||||
<Self as acpi_system::Handler>::io_write_u8(port, value)
|
||||
}
|
||||
|
||||
fn write_io_u16(&self, port: u16, value: u16) {
|
||||
<Self as acpi_system::Handler>::io_write_u16(port, value)
|
||||
}
|
||||
|
||||
fn write_io_u32(&self, port: u16, value: u32) {
|
||||
<Self as acpi_system::Handler>::io_write_u32(port, value)
|
||||
}
|
||||
|
||||
fn read_u8(&self, address: usize) -> u8 {
|
||||
<Self as acpi_system::Handler>::mem_read_u8(address as u64)
|
||||
}
|
||||
|
||||
fn read_u16(&self, address: usize) -> u16 {
|
||||
<Self as acpi_system::Handler>::mem_read_u16(address as u64)
|
||||
}
|
||||
|
||||
fn read_u32(&self, address: usize) -> u32 {
|
||||
<Self as acpi_system::Handler>::mem_read_u32(address as u64)
|
||||
}
|
||||
|
||||
fn read_u64(&self, address: usize) -> u64 {
|
||||
<Self as acpi_system::Handler>::mem_read_u64(address as u64)
|
||||
}
|
||||
|
||||
fn write_u8(&self, address: usize, value: u8) {
|
||||
<Self as acpi_system::Handler>::mem_write_u8(address as u64, value)
|
||||
}
|
||||
|
||||
fn write_u16(&self, address: usize, value: u16) {
|
||||
<Self as acpi_system::Handler>::mem_write_u16(address as u64, value)
|
||||
}
|
||||
|
||||
fn write_u32(&self, address: usize, value: u32) {
|
||||
<Self as acpi_system::Handler>::mem_write_u32(address as u64, value)
|
||||
}
|
||||
|
||||
fn write_u64(&self, address: usize, value: u64) {
|
||||
<Self as acpi_system::Handler>::mem_write_u64(address as u64, value)
|
||||
}
|
||||
|
||||
fn read_pci_u8(&self, _segment: u16, _bus: u8, _device: u8, _function: u8, _offset: u16) -> u8 {
|
||||
0xFF
|
||||
}
|
||||
|
||||
fn read_pci_u16(
|
||||
&self,
|
||||
_segment: u16,
|
||||
_bus: u8,
|
||||
_device: u8,
|
||||
_function: u8,
|
||||
_offset: u16,
|
||||
) -> u16 {
|
||||
0xFFFF
|
||||
}
|
||||
|
||||
fn read_pci_u32(
|
||||
&self,
|
||||
_segment: u16,
|
||||
_bus: u8,
|
||||
_device: u8,
|
||||
_function: u8,
|
||||
_offset: u16,
|
||||
) -> u32 {
|
||||
0xFFFFFFFF
|
||||
}
|
||||
|
||||
fn write_pci_u8(
|
||||
&self,
|
||||
_segment: u16,
|
||||
_bus: u8,
|
||||
_device: u8,
|
||||
_function: u8,
|
||||
_offset: u16,
|
||||
_value: u8,
|
||||
) {
|
||||
}
|
||||
|
||||
fn write_pci_u16(
|
||||
&self,
|
||||
_segment: u16,
|
||||
_bus: u8,
|
||||
_device: u8,
|
||||
_function: u8,
|
||||
_offset: u16,
|
||||
_value: u16,
|
||||
) {
|
||||
}
|
||||
|
||||
fn write_pci_u32(
|
||||
&self,
|
||||
_segment: u16,
|
||||
_bus: u8,
|
||||
_device: u8,
|
||||
_function: u8,
|
||||
_offset: u16,
|
||||
_value: u32,
|
||||
) {
|
||||
}
|
||||
|
||||
fn read_ec_u8(&self, _address: u64) -> u8 {
|
||||
0x00
|
||||
}
|
||||
|
||||
fn write_ec_u8(&self, _address: u64, _value: u8) {}
|
||||
|
||||
fn sleep(&self, _duration: Duration) {
|
||||
todo!()
|
||||
// util::polling_sleep(duration).unwrap();
|
||||
}
|
||||
}
|
171
kernel/driver/acpi/src/handler.rs
Normal file
171
kernel/driver/acpi/src/handler.rs
Normal file
@ -0,0 +1,171 @@
|
||||
use core::{ptr::NonNull, time::Duration};
|
||||
|
||||
use acpi::PhysicalMapping;
|
||||
use acpi_system::AcpiSystemError;
|
||||
use alloc::sync::Arc;
|
||||
use device_api::{
|
||||
device::Device,
|
||||
interrupt::{InterruptHandler, Irq},
|
||||
};
|
||||
use kernel_arch_x86::{intrinsics, ISA_IRQ_OFFSET};
|
||||
use libk::device::external_interrupt_controller;
|
||||
use libk_mm::{
|
||||
address::{PhysicalAddress, Virtualize},
|
||||
pointer::PhysicalRef,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
mem::{read_memory, write_memory},
|
||||
ACPI_SYSTEM,
|
||||
};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[doc(hidden)]
|
||||
pub struct AcpiHandlerImpl;
|
||||
|
||||
struct SciHandler;
|
||||
|
||||
impl acpi_system::Handler for AcpiHandlerImpl {
|
||||
type MappedSlice = PhysicalRef<'static, [u8]>;
|
||||
|
||||
unsafe fn map_slice(address: u64, length: u64) -> Self::MappedSlice {
|
||||
unsafe {
|
||||
PhysicalRef::map_slice(
|
||||
PhysicalAddress::from_u64(address),
|
||||
length.try_into().unwrap(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn io_read_u8(port: u16) -> u8 {
|
||||
let value = unsafe { intrinsics::inb(port) };
|
||||
log::trace!("io_read_u8 {:#x} <- {:#x}", port, value);
|
||||
value
|
||||
}
|
||||
|
||||
fn io_read_u16(port: u16) -> u16 {
|
||||
let value = unsafe { intrinsics::inw(port) };
|
||||
log::trace!("io_read_u16 {:#x} <- {:#x}", port, value);
|
||||
value
|
||||
}
|
||||
|
||||
fn io_read_u32(port: u16) -> u32 {
|
||||
let value = unsafe { intrinsics::inl(port) };
|
||||
log::trace!("io_read_u32 {:#x} <- {:#x}", port, value);
|
||||
value
|
||||
}
|
||||
|
||||
fn io_write_u8(port: u16, value: u8) {
|
||||
log::trace!("io_write_u8 {:#x}, {:#x}", port, value);
|
||||
unsafe { intrinsics::outb(port, value) }
|
||||
}
|
||||
|
||||
fn io_write_u16(port: u16, value: u16) {
|
||||
log::trace!("io_write_u16 {:#x}, {:#x}", port, value);
|
||||
unsafe { intrinsics::outw(port, value) }
|
||||
}
|
||||
|
||||
fn io_write_u32(port: u16, value: u32) {
|
||||
log::trace!("io_write_u32 {:#x}, {:#x}", port, value);
|
||||
unsafe { intrinsics::outl(port, value) }
|
||||
}
|
||||
|
||||
fn mem_read_u8(address: u64) -> u8 {
|
||||
let value = unsafe { read_memory(PhysicalAddress::from_u64(address)) };
|
||||
log::trace!("mem_read_u8 {:#x} -> {:#x}", address, value);
|
||||
value
|
||||
}
|
||||
|
||||
fn mem_read_u16(address: u64) -> u16 {
|
||||
let value = unsafe { read_memory(PhysicalAddress::from_u64(address)) };
|
||||
log::trace!("mem_read_u16 {:#x} -> {:#x}", address, value);
|
||||
value
|
||||
}
|
||||
|
||||
fn mem_read_u32(address: u64) -> u32 {
|
||||
let value = unsafe { read_memory(PhysicalAddress::from_u64(address)) };
|
||||
log::trace!("mem_read_u32 {:#x} -> {:#x}", address, value);
|
||||
value
|
||||
}
|
||||
|
||||
fn mem_read_u64(address: u64) -> u64 {
|
||||
let value = unsafe { read_memory(PhysicalAddress::from_u64(address)) };
|
||||
log::trace!("mem_read_u64 {:#x} -> {:#x}", address, value);
|
||||
value
|
||||
}
|
||||
|
||||
fn mem_write_u8(address: u64, value: u8) {
|
||||
log::trace!("mem_write_u8 {:#x}, {:#x}", address, value);
|
||||
unsafe { write_memory(PhysicalAddress::from_u64(address), value) }
|
||||
}
|
||||
|
||||
fn mem_write_u16(address: u64, value: u16) {
|
||||
log::trace!("mem_write_u16 {:#x}, {:#x}", address, value);
|
||||
unsafe { write_memory(PhysicalAddress::from_u64(address), value) }
|
||||
}
|
||||
|
||||
fn mem_write_u32(address: u64, value: u32) {
|
||||
log::trace!("mem_write_u32 {:#x}, {:#x}", address, value);
|
||||
unsafe { write_memory(PhysicalAddress::from_u64(address), value) }
|
||||
}
|
||||
|
||||
fn mem_write_u64(address: u64, value: u64) {
|
||||
log::trace!("mem_write_u64 {:#x}, {:#x}", address, value);
|
||||
unsafe { write_memory(PhysicalAddress::from_u64(address), value) }
|
||||
}
|
||||
|
||||
fn install_interrupt_handler(irq: u32) -> Result<(), AcpiSystemError> {
|
||||
log::info!("Installing ACPI SCI handler at IRQ #{}", irq);
|
||||
|
||||
let intc = external_interrupt_controller().expect("No external intc");
|
||||
let handler = Arc::new(SciHandler);
|
||||
let irq = Irq::External(irq + ISA_IRQ_OFFSET);
|
||||
|
||||
intc.register_irq(irq, Default::default(), handler).unwrap();
|
||||
intc.enable_irq(irq).unwrap();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn stall(_duration: Duration) {
|
||||
// TODO polling_sleep is not yet implemented properly
|
||||
todo!()
|
||||
// util::polling_sleep(duration).ok();
|
||||
}
|
||||
}
|
||||
|
||||
impl rsdp::handler::AcpiHandler for AcpiHandlerImpl {
|
||||
unsafe fn map_physical_region<T>(
|
||||
&self,
|
||||
physical_address: usize,
|
||||
size: usize,
|
||||
) -> PhysicalMapping<Self, T> {
|
||||
unsafe {
|
||||
PhysicalMapping::new(
|
||||
physical_address,
|
||||
NonNull::new_unchecked(
|
||||
PhysicalAddress::from_usize(physical_address).virtualize() as *mut T
|
||||
),
|
||||
size,
|
||||
size,
|
||||
*self,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn unmap_physical_region<T>(_region: &acpi::PhysicalMapping<Self, T>) {}
|
||||
}
|
||||
|
||||
impl InterruptHandler for SciHandler {
|
||||
fn handle_irq(self: Arc<Self>, _vector: Option<usize>) -> bool {
|
||||
log::trace!("ACPI SCI received");
|
||||
ACPI_SYSTEM.get().lock().handle_sci();
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl Device for SciHandler {
|
||||
fn display_name(&self) -> &str {
|
||||
"ACPI SCI handler"
|
||||
}
|
||||
}
|
74
kernel/driver/acpi/src/lib.rs
Normal file
74
kernel/driver/acpi/src/lib.rs
Normal file
@ -0,0 +1,74 @@
|
||||
#![feature(allocator_api)]
|
||||
#![no_std]
|
||||
|
||||
use acpi::AcpiTables;
|
||||
use acpi_system::{AcpiInterruptMethod, AcpiSystem};
|
||||
use alloc::boxed::Box;
|
||||
use libk::error::Error;
|
||||
use libk_util::{sync::IrqSafeSpinlock, OneTimeInit};
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
pub mod mem;
|
||||
pub use mem::AcpiAllocator;
|
||||
pub mod handler;
|
||||
pub use handler::AcpiHandlerImpl;
|
||||
pub mod aml_handler;
|
||||
|
||||
pub use acpi_system::{EventAction, FixedEvent};
|
||||
|
||||
static ACPI_SYSTEM: OneTimeInit<IrqSafeSpinlock<AcpiSystem<AcpiHandlerImpl>>> = OneTimeInit::new();
|
||||
|
||||
pub fn add_event_handler<F: Fn(&AcpiSystem<AcpiHandlerImpl>) -> EventAction + 'static>(
|
||||
event: &FixedEvent,
|
||||
handler: F,
|
||||
) -> Result<(), Error> {
|
||||
ACPI_SYSTEM
|
||||
.get()
|
||||
.lock()
|
||||
.enable_fixed_event(event, Box::new(handler))
|
||||
.map_err(|_| Error::InvalidArgument)
|
||||
}
|
||||
|
||||
/// Initializes ACPI management
|
||||
pub fn switch_to_acpi(tables: &'static AcpiTables<AcpiHandlerImpl>) -> Result<(), Error> {
|
||||
// NOTE mostly broken for real HW
|
||||
let mut system = AcpiSystem::new(tables, Box::new(AcpiHandlerImpl)).unwrap();
|
||||
|
||||
system.initialize(AcpiInterruptMethod::Apic).unwrap();
|
||||
|
||||
// system
|
||||
// .enable_fixed_event(
|
||||
// &FixedEvent::POWER_BUTTON,
|
||||
// Box::new(|_| {
|
||||
// log::info!("Power button was pressed");
|
||||
|
||||
// // TODO the correct way would be to
|
||||
// // 1. Nicely ask all the processes to quit
|
||||
// // 2. Wait for some time
|
||||
// // 3. Kill the remaining ones
|
||||
// // 4. Halt other cores
|
||||
// // 5. Sync filesystem
|
||||
// // 6. Do something with the devices
|
||||
// // 7. Actually enter the S5 state
|
||||
|
||||
// unsafe {
|
||||
// PLATFORM
|
||||
// .send_ipi(IpiDeliveryTarget::OtherCpus, IpiMessage::Shutdown)
|
||||
// .unwrap();
|
||||
// }
|
||||
|
||||
// SHUTDOWN_FENCE.signal();
|
||||
// SHUTDOWN_FENCE.wait_all(CPU_COUNT.load(Ordering::Acquire));
|
||||
|
||||
// log::info!("CPUs are parked, can shutdown now");
|
||||
|
||||
// EventAction::EnterSleepState(AcpiSleepState::S5)
|
||||
// }),
|
||||
// )
|
||||
// .unwrap();
|
||||
|
||||
ACPI_SYSTEM.init(IrqSafeSpinlock::new(system));
|
||||
|
||||
Ok(())
|
||||
}
|
64
kernel/driver/acpi/src/mem.rs
Normal file
64
kernel/driver/acpi/src/mem.rs
Normal file
@ -0,0 +1,64 @@
|
||||
//! ACPI memory IO and management functions
|
||||
|
||||
use core::{
|
||||
alloc::{AllocError, Allocator, GlobalAlloc, Layout},
|
||||
ptr::NonNull,
|
||||
};
|
||||
|
||||
use libk_mm::{address::PhysicalAddress, device::DeviceMemoryMapping, heap::GLOBAL_HEAP};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[doc(hidden)]
|
||||
pub struct AcpiAllocator;
|
||||
|
||||
unsafe impl Allocator for AcpiAllocator {
|
||||
fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
|
||||
let ptr = unsafe { GLOBAL_HEAP.alloc(layout) };
|
||||
log::trace!("ACPI alloc: {:?} -> {:p}", layout, ptr);
|
||||
|
||||
if ptr.is_null() {
|
||||
Err(AllocError)
|
||||
} else {
|
||||
unsafe {
|
||||
Ok(NonNull::slice_from_raw_parts(
|
||||
NonNull::new_unchecked(ptr),
|
||||
layout.size(),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
|
||||
log::trace!("ACPI dealloc: {:?}, {:?}", ptr, layout);
|
||||
unsafe { GLOBAL_HEAP.dealloc(ptr.as_ptr(), layout) };
|
||||
}
|
||||
}
|
||||
|
||||
// TODO don't map memory as device if not necessary
|
||||
pub unsafe fn read_memory<T>(address: PhysicalAddress) -> T {
|
||||
let io =
|
||||
unsafe { DeviceMemoryMapping::map(address, size_of::<T>(), Default::default()).unwrap() };
|
||||
let address = io.address();
|
||||
|
||||
unsafe {
|
||||
if address % align_of::<T>() == 0 {
|
||||
(address as *const T).read_volatile()
|
||||
} else {
|
||||
(address as *const T).read_unaligned()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn write_memory<T>(address: PhysicalAddress, value: T) {
|
||||
let io =
|
||||
unsafe { DeviceMemoryMapping::map(address, size_of::<T>(), Default::default()).unwrap() };
|
||||
let address = io.address();
|
||||
|
||||
unsafe {
|
||||
if address % align_of::<T>() == 0 {
|
||||
(address as *mut T).write_volatile(value)
|
||||
} else {
|
||||
(address as *mut T).write_unaligned(value)
|
||||
}
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@
|
||||
use abi::error::Error;
|
||||
use alloc::{sync::Arc, vec::Vec};
|
||||
use device_api::{device::Device, interrupt::Irq};
|
||||
use kernel_arch_x86::ISA_IRQ_OFFSET;
|
||||
use libk::{
|
||||
config, debug,
|
||||
fs::{devfs, sysfs},
|
||||
@ -22,13 +23,6 @@ use crate::fs::{Initrd, INITRD_DATA};
|
||||
|
||||
use super::L3;
|
||||
|
||||
#[cfg(any(target_arch = "x86_64", rust_analyzer))]
|
||||
pub const ISA_IRQ_OFFSET: u32 = crate::arch::x86_64::ISA_IRQ_OFFSET;
|
||||
|
||||
#[cfg(any(target_arch = "x86", rust_analyzer))]
|
||||
pub const ISA_IRQ_OFFSET: u32 = 0;
|
||||
|
||||
pub mod intrinsics;
|
||||
mod pci;
|
||||
pub mod peripherals;
|
||||
|
||||
@ -76,13 +70,13 @@ pub fn register_pci_drivers() {
|
||||
Some(0x01),
|
||||
ygg_driver_ahci::probe,
|
||||
);
|
||||
ygg_driver_pci::register_class_driver(
|
||||
"USB xHCI",
|
||||
0x0C,
|
||||
Some(0x03),
|
||||
Some(0x30),
|
||||
ygg_driver_usb_xhci::probe,
|
||||
);
|
||||
// ygg_driver_pci::register_class_driver(
|
||||
// "USB xHCI",
|
||||
// 0x0C,
|
||||
// Some(0x03),
|
||||
// Some(0x30),
|
||||
// ygg_driver_usb_xhci::probe,
|
||||
// );
|
||||
ygg_driver_pci::register_vendor_driver(
|
||||
"Virtio PCI GPU Device",
|
||||
0x1AF4,
|
||||
|
@ -1,10 +1,7 @@
|
||||
use kernel_arch_x86::intrinsics::{IoPort, IoPortAccess};
|
||||
use libk_util::sync::IrqSafeSpinlock;
|
||||
use ygg_driver_pci::LegacyPciAccess;
|
||||
|
||||
use crate::arch::x86::intrinsics::IoPortAccess;
|
||||
|
||||
use super::intrinsics::IoPort;
|
||||
|
||||
struct LegacyPciInner {
|
||||
address: IoPort<u32>,
|
||||
data: IoPort<u32>,
|
||||
|
@ -4,13 +4,12 @@ use device_api::{
|
||||
device::Device,
|
||||
interrupt::{InterruptHandler, Irq},
|
||||
};
|
||||
use libk::{device::external_interrupt_controller, task::runtime, time};
|
||||
use libk_util::{sync::IrqSafeSpinlock, OneTimeInit};
|
||||
|
||||
use crate::arch::x86::{
|
||||
use kernel_arch_x86::{
|
||||
intrinsics::{IoPort, IoPortAccess},
|
||||
ISA_IRQ_OFFSET,
|
||||
};
|
||||
use libk::{device::external_interrupt_controller, task::runtime, time};
|
||||
use libk_util::{sync::IrqSafeSpinlock, OneTimeInit};
|
||||
|
||||
const FREQUENCY: u32 = 1193180;
|
||||
|
||||
|
@ -9,10 +9,9 @@ use device_api::{
|
||||
IrqOptions,
|
||||
},
|
||||
};
|
||||
use kernel_arch_x86::intrinsics::{IoPort, IoPortAccess};
|
||||
use libk_util::{sync::IrqSafeSpinlock, OneTimeInit};
|
||||
|
||||
use crate::arch::x86::intrinsics::{IoPort, IoPortAccess};
|
||||
|
||||
#[cfg(any(target_arch = "x86", rust_analyzer))]
|
||||
use crate::arch::i686::exception;
|
||||
#[cfg(any(target_arch = "x86", rust_analyzer))]
|
||||
|
@ -8,14 +8,14 @@ use device_api::{
|
||||
device::Device,
|
||||
interrupt::{InterruptHandler, Irq},
|
||||
};
|
||||
use kernel_arch_x86::{
|
||||
intrinsics::{IoPort, IoPortAccess},
|
||||
ISA_IRQ_OFFSET,
|
||||
};
|
||||
use libk::device::external_interrupt_controller;
|
||||
use libk_util::sync::IrqSafeSpinlock;
|
||||
|
||||
use crate::arch::x86::{
|
||||
intrinsics::{IoPort, IoPortAccess},
|
||||
peripherals::ps2::codeset::{CODE_SET_1_00, CODE_SET_1_E0},
|
||||
ISA_IRQ_OFFSET,
|
||||
};
|
||||
use codeset::{CODE_SET_1_00, CODE_SET_1_E0};
|
||||
|
||||
mod codeset;
|
||||
|
||||
|
@ -5,13 +5,12 @@ use device_api::{
|
||||
interrupt::{InterruptHandler, Irq},
|
||||
};
|
||||
use kernel_arch::{Architecture, ArchitectureImpl};
|
||||
use libk::{device::external_interrupt_controller, time};
|
||||
use libk_util::sync::IrqSafeSpinlock;
|
||||
|
||||
use crate::arch::x86::{
|
||||
use kernel_arch_x86::{
|
||||
intrinsics::{io_wait, IoPort, IoPortAccess},
|
||||
ISA_IRQ_OFFSET,
|
||||
};
|
||||
use libk::{device::external_interrupt_controller, time};
|
||||
use libk_util::sync::IrqSafeSpinlock;
|
||||
|
||||
const NMI_DISABLE: u8 = 1 << 7;
|
||||
const CMOS_REG_SEC: u8 = 0x00;
|
||||
|
@ -5,6 +5,7 @@ use device_api::{
|
||||
device::Device,
|
||||
interrupt::{InterruptHandler, Irq},
|
||||
};
|
||||
use kernel_arch_x86::intrinsics::{IoPort, IoPortAccess};
|
||||
use libk::{
|
||||
debug::DebugSink,
|
||||
device::{external_interrupt_controller, manager::DEVICE_REGISTRY},
|
||||
@ -12,8 +13,6 @@ use libk::{
|
||||
};
|
||||
use libk_util::sync::IrqSafeSpinlock;
|
||||
|
||||
use crate::arch::x86::intrinsics::{IoPort, IoPortAccess};
|
||||
|
||||
// Single port
|
||||
struct Regs {
|
||||
dr: IoPort<u8>,
|
||||
|
@ -1,390 +0,0 @@
|
||||
//! x86-64 implementation of ACPI management interfaces
|
||||
use core::{
|
||||
alloc::{AllocError, Allocator, GlobalAlloc, Layout},
|
||||
ptr::NonNull,
|
||||
sync::atomic::Ordering,
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use ::acpi::{AcpiHandler, AcpiTables, PhysicalMapping};
|
||||
use acpi_system::{
|
||||
AcpiInterruptMethod, AcpiSleepState, AcpiSystem, AcpiSystemError, EventAction, FixedEvent,
|
||||
};
|
||||
use alloc::{boxed::Box, sync::Arc};
|
||||
use device_api::{
|
||||
device::Device,
|
||||
interrupt::{InterruptHandler, IpiDeliveryTarget, IpiMessage, Irq},
|
||||
};
|
||||
use kernel_arch_x86_64::CPU_COUNT;
|
||||
use libk::device::external_interrupt_controller;
|
||||
use libk_mm::{
|
||||
address::{PhysicalAddress, Virtualize},
|
||||
heap::GLOBAL_HEAP,
|
||||
pointer::PhysicalRef,
|
||||
};
|
||||
use libk_util::{sync::IrqSafeSpinlock, OneTimeInit};
|
||||
use yggdrasil_abi::error::Error;
|
||||
|
||||
use crate::{
|
||||
arch::{
|
||||
x86_64::{apic::ioapic::ISA_IRQ_OFFSET, SHUTDOWN_FENCE},
|
||||
Platform, PLATFORM,
|
||||
},
|
||||
mem::{read_memory, write_memory},
|
||||
};
|
||||
|
||||
use super::intrinsics;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[doc(hidden)]
|
||||
pub struct AcpiAllocator;
|
||||
#[derive(Clone, Copy)]
|
||||
#[doc(hidden)]
|
||||
pub struct AcpiHandlerImpl;
|
||||
struct SciHandler;
|
||||
|
||||
static ACPI_SYSTEM: OneTimeInit<IrqSafeSpinlock<AcpiSystem<AcpiHandlerImpl>>> = OneTimeInit::new();
|
||||
|
||||
// impl Device for SciHandler {
|
||||
// fn display_name(&self) -> &'static str {
|
||||
// "ACPI interrupt handler"
|
||||
// }
|
||||
// }
|
||||
|
||||
impl Device for SciHandler {
|
||||
fn display_name(&self) -> &str {
|
||||
"ACPI SCI Handler"
|
||||
}
|
||||
}
|
||||
|
||||
impl InterruptHandler for SciHandler {
|
||||
fn handle_irq(self: Arc<Self>, _vector: Option<usize>) -> bool {
|
||||
log::trace!("ACPI SCI received");
|
||||
ACPI_SYSTEM.get().lock().handle_sci();
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Allocator for AcpiAllocator {
|
||||
fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
|
||||
let ptr = unsafe { GLOBAL_HEAP.alloc(layout) };
|
||||
log::trace!("ACPI alloc: {:?} -> {:p}", layout, ptr);
|
||||
|
||||
if ptr.is_null() {
|
||||
Err(AllocError)
|
||||
} else {
|
||||
unsafe {
|
||||
Ok(NonNull::slice_from_raw_parts(
|
||||
NonNull::new_unchecked(ptr),
|
||||
layout.size(),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
|
||||
log::trace!("ACPI dealloc: {:?}, {:?}", ptr, layout);
|
||||
GLOBAL_HEAP.dealloc(ptr.as_ptr(), layout);
|
||||
}
|
||||
}
|
||||
|
||||
impl acpi_system::Handler for AcpiHandlerImpl {
|
||||
type MappedSlice = PhysicalRef<'static, [u8]>;
|
||||
|
||||
unsafe fn map_slice(address: u64, length: u64) -> Self::MappedSlice {
|
||||
PhysicalRef::map_slice(
|
||||
PhysicalAddress::from_u64(address),
|
||||
length.try_into().unwrap(),
|
||||
)
|
||||
}
|
||||
|
||||
fn io_read_u8(port: u16) -> u8 {
|
||||
let value = unsafe { intrinsics::inb(port) };
|
||||
log::trace!("io_read_u8 {:#x} <- {:#x}", port, value);
|
||||
value
|
||||
}
|
||||
|
||||
fn io_read_u16(port: u16) -> u16 {
|
||||
let value = unsafe { intrinsics::inw(port) };
|
||||
log::trace!("io_read_u16 {:#x} <- {:#x}", port, value);
|
||||
value
|
||||
}
|
||||
|
||||
fn io_read_u32(port: u16) -> u32 {
|
||||
let value = unsafe { intrinsics::inl(port) };
|
||||
log::trace!("io_read_u32 {:#x} <- {:#x}", port, value);
|
||||
value
|
||||
}
|
||||
|
||||
fn io_write_u8(port: u16, value: u8) {
|
||||
log::trace!("io_write_u8 {:#x}, {:#x}", port, value);
|
||||
unsafe { intrinsics::outb(port, value) }
|
||||
}
|
||||
|
||||
fn io_write_u16(port: u16, value: u16) {
|
||||
log::trace!("io_write_u16 {:#x}, {:#x}", port, value);
|
||||
unsafe { intrinsics::outw(port, value) }
|
||||
}
|
||||
|
||||
fn io_write_u32(port: u16, value: u32) {
|
||||
log::trace!("io_write_u32 {:#x}, {:#x}", port, value);
|
||||
unsafe { intrinsics::outl(port, value) }
|
||||
}
|
||||
|
||||
fn mem_read_u8(address: u64) -> u8 {
|
||||
let value = unsafe { read_memory(PhysicalAddress::from_u64(address)) };
|
||||
log::trace!("mem_read_u8 {:#x} -> {:#x}", address, value);
|
||||
value
|
||||
}
|
||||
|
||||
fn mem_read_u16(address: u64) -> u16 {
|
||||
let value = unsafe { read_memory(PhysicalAddress::from_u64(address)) };
|
||||
log::trace!("mem_read_u16 {:#x} -> {:#x}", address, value);
|
||||
value
|
||||
}
|
||||
|
||||
fn mem_read_u32(address: u64) -> u32 {
|
||||
let value = unsafe { read_memory(PhysicalAddress::from_u64(address)) };
|
||||
log::trace!("mem_read_u32 {:#x} -> {:#x}", address, value);
|
||||
value
|
||||
}
|
||||
|
||||
fn mem_read_u64(address: u64) -> u64 {
|
||||
let value = unsafe { read_memory(PhysicalAddress::from_u64(address)) };
|
||||
log::trace!("mem_read_u64 {:#x} -> {:#x}", address, value);
|
||||
value
|
||||
}
|
||||
|
||||
fn mem_write_u8(address: u64, value: u8) {
|
||||
log::trace!("mem_write_u8 {:#x}, {:#x}", address, value);
|
||||
unsafe { write_memory(PhysicalAddress::from_u64(address), value) }
|
||||
}
|
||||
|
||||
fn mem_write_u16(address: u64, value: u16) {
|
||||
log::trace!("mem_write_u16 {:#x}, {:#x}", address, value);
|
||||
unsafe { write_memory(PhysicalAddress::from_u64(address), value) }
|
||||
}
|
||||
|
||||
fn mem_write_u32(address: u64, value: u32) {
|
||||
log::trace!("mem_write_u32 {:#x}, {:#x}", address, value);
|
||||
unsafe { write_memory(PhysicalAddress::from_u64(address), value) }
|
||||
}
|
||||
|
||||
fn mem_write_u64(address: u64, value: u64) {
|
||||
log::trace!("mem_write_u64 {:#x}, {:#x}", address, value);
|
||||
unsafe { write_memory(PhysicalAddress::from_u64(address), value) }
|
||||
}
|
||||
|
||||
fn install_interrupt_handler(irq: u32) -> Result<(), AcpiSystemError> {
|
||||
log::info!("Installing ACPI SCI handler at IRQ #{}", irq);
|
||||
|
||||
let intc = external_interrupt_controller().expect("No external intc");
|
||||
let handler = Arc::new(SciHandler);
|
||||
let irq = Irq::External(irq + ISA_IRQ_OFFSET);
|
||||
|
||||
intc.register_irq(irq, Default::default(), handler).unwrap();
|
||||
intc.enable_irq(irq).unwrap();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn stall(_duration: Duration) {
|
||||
// TODO polling_sleep is not yet implemented properly
|
||||
todo!()
|
||||
// util::polling_sleep(duration).ok();
|
||||
}
|
||||
}
|
||||
|
||||
impl aml::Handler for AcpiHandlerImpl {
|
||||
fn read_io_u8(&self, port: u16) -> u8 {
|
||||
<Self as acpi_system::Handler>::io_read_u8(port)
|
||||
}
|
||||
|
||||
fn read_io_u16(&self, port: u16) -> u16 {
|
||||
<Self as acpi_system::Handler>::io_read_u16(port)
|
||||
}
|
||||
|
||||
fn read_io_u32(&self, port: u16) -> u32 {
|
||||
<Self as acpi_system::Handler>::io_read_u32(port)
|
||||
}
|
||||
|
||||
fn write_io_u8(&self, port: u16, value: u8) {
|
||||
<Self as acpi_system::Handler>::io_write_u8(port, value)
|
||||
}
|
||||
|
||||
fn write_io_u16(&self, port: u16, value: u16) {
|
||||
<Self as acpi_system::Handler>::io_write_u16(port, value)
|
||||
}
|
||||
|
||||
fn write_io_u32(&self, port: u16, value: u32) {
|
||||
<Self as acpi_system::Handler>::io_write_u32(port, value)
|
||||
}
|
||||
|
||||
fn read_u8(&self, address: usize) -> u8 {
|
||||
<Self as acpi_system::Handler>::mem_read_u8(address as u64)
|
||||
}
|
||||
|
||||
fn read_u16(&self, address: usize) -> u16 {
|
||||
<Self as acpi_system::Handler>::mem_read_u16(address as u64)
|
||||
}
|
||||
|
||||
fn read_u32(&self, address: usize) -> u32 {
|
||||
<Self as acpi_system::Handler>::mem_read_u32(address as u64)
|
||||
}
|
||||
|
||||
fn read_u64(&self, address: usize) -> u64 {
|
||||
<Self as acpi_system::Handler>::mem_read_u64(address as u64)
|
||||
}
|
||||
|
||||
fn write_u8(&self, address: usize, value: u8) {
|
||||
<Self as acpi_system::Handler>::mem_write_u8(address as u64, value)
|
||||
}
|
||||
|
||||
fn write_u16(&self, address: usize, value: u16) {
|
||||
<Self as acpi_system::Handler>::mem_write_u16(address as u64, value)
|
||||
}
|
||||
|
||||
fn write_u32(&self, address: usize, value: u32) {
|
||||
<Self as acpi_system::Handler>::mem_write_u32(address as u64, value)
|
||||
}
|
||||
|
||||
fn write_u64(&self, address: usize, value: u64) {
|
||||
<Self as acpi_system::Handler>::mem_write_u64(address as u64, value)
|
||||
}
|
||||
|
||||
fn read_pci_u8(&self, _segment: u16, _bus: u8, _device: u8, _function: u8, _offset: u16) -> u8 {
|
||||
0xFF
|
||||
}
|
||||
|
||||
fn read_pci_u16(
|
||||
&self,
|
||||
_segment: u16,
|
||||
_bus: u8,
|
||||
_device: u8,
|
||||
_function: u8,
|
||||
_offset: u16,
|
||||
) -> u16 {
|
||||
0xFFFF
|
||||
}
|
||||
|
||||
fn read_pci_u32(
|
||||
&self,
|
||||
_segment: u16,
|
||||
_bus: u8,
|
||||
_device: u8,
|
||||
_function: u8,
|
||||
_offset: u16,
|
||||
) -> u32 {
|
||||
0xFFFFFFFF
|
||||
}
|
||||
|
||||
fn write_pci_u8(
|
||||
&self,
|
||||
_segment: u16,
|
||||
_bus: u8,
|
||||
_device: u8,
|
||||
_function: u8,
|
||||
_offset: u16,
|
||||
_value: u8,
|
||||
) {
|
||||
}
|
||||
|
||||
fn write_pci_u16(
|
||||
&self,
|
||||
_segment: u16,
|
||||
_bus: u8,
|
||||
_device: u8,
|
||||
_function: u8,
|
||||
_offset: u16,
|
||||
_value: u16,
|
||||
) {
|
||||
}
|
||||
|
||||
fn write_pci_u32(
|
||||
&self,
|
||||
_segment: u16,
|
||||
_bus: u8,
|
||||
_device: u8,
|
||||
_function: u8,
|
||||
_offset: u16,
|
||||
_value: u32,
|
||||
) {
|
||||
}
|
||||
|
||||
fn read_ec_u8(&self, _address: u64) -> u8 {
|
||||
0x00
|
||||
}
|
||||
|
||||
fn write_ec_u8(&self, _address: u64, _value: u8) {}
|
||||
|
||||
fn sleep(&self, _duration: Duration) {
|
||||
todo!()
|
||||
// util::polling_sleep(duration).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
impl AcpiHandler for AcpiHandlerImpl {
|
||||
// No actual address space modification is performed
|
||||
unsafe fn map_physical_region<T>(
|
||||
&self,
|
||||
physical_address: usize,
|
||||
size: usize,
|
||||
) -> PhysicalMapping<Self, T> {
|
||||
PhysicalMapping::new(
|
||||
physical_address,
|
||||
NonNull::new_unchecked(
|
||||
PhysicalAddress::from_usize(physical_address).virtualize() as *mut T
|
||||
),
|
||||
size,
|
||||
size,
|
||||
*self,
|
||||
)
|
||||
}
|
||||
|
||||
// Unmap nothing, these addresses are "virtualized" to high address space
|
||||
fn unmap_physical_region<T>(_region: &PhysicalMapping<Self, T>) {}
|
||||
}
|
||||
|
||||
/// Initializes ACPI management
|
||||
#[allow(unused)]
|
||||
pub fn init_acpi(tables: &'static AcpiTables<AcpiHandlerImpl>) -> Result<(), Error> {
|
||||
// TODO currently broken for real HW
|
||||
let mut system = AcpiSystem::new(tables, Box::new(AcpiHandlerImpl)).unwrap();
|
||||
|
||||
system.initialize(AcpiInterruptMethod::Apic).unwrap();
|
||||
|
||||
system
|
||||
.enable_fixed_event(
|
||||
&FixedEvent::POWER_BUTTON,
|
||||
Box::new(|_| {
|
||||
log::info!("Power button was pressed");
|
||||
|
||||
// TODO the correct way would be to
|
||||
// 1. Nicely ask all the processes to quit
|
||||
// 2. Wait for some time
|
||||
// 3. Kill the remaining ones
|
||||
// 4. Halt other cores
|
||||
// 5. Sync filesystem
|
||||
// 6. Do something with the devices
|
||||
// 7. Actually enter the S5 state
|
||||
|
||||
unsafe {
|
||||
PLATFORM
|
||||
.send_ipi(IpiDeliveryTarget::OtherCpus, IpiMessage::Shutdown)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
SHUTDOWN_FENCE.signal();
|
||||
SHUTDOWN_FENCE.wait_all(CPU_COUNT.load(Ordering::Acquire));
|
||||
|
||||
log::info!("CPUs are parked, can shutdown now");
|
||||
|
||||
EventAction::EnterSleepState(AcpiSleepState::S5)
|
||||
}),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
ACPI_SYSTEM.init(IrqSafeSpinlock::new(system));
|
||||
|
||||
Ok(())
|
||||
}
|
@ -9,6 +9,7 @@ use device_api::{
|
||||
IrqLevel, IrqOptions, IrqTrigger,
|
||||
},
|
||||
};
|
||||
use kernel_arch_x86::ISA_IRQ_OFFSET;
|
||||
use libk_mm::{address::PhysicalAddress, device::DeviceMemoryIo};
|
||||
use libk_util::sync::{spin_rwlock::IrqSafeRwLock, IrqSafeSpinlock};
|
||||
use tock_registers::{
|
||||
@ -16,13 +17,12 @@ use tock_registers::{
|
||||
register_structs,
|
||||
registers::{ReadWrite, WriteOnly},
|
||||
};
|
||||
use ygg_driver_acpi::AcpiAllocator;
|
||||
|
||||
use crate::arch::x86_64::{acpi::AcpiAllocator, apic::local::BSP_APIC_ID};
|
||||
use crate::arch::x86_64::apic::local::BSP_APIC_ID;
|
||||
|
||||
use super::{APIC_EXTERNAL_OFFSET, POPULATED_EXTERNAL_VECTORS};
|
||||
|
||||
pub const ISA_IRQ_OFFSET: u32 = 1024;
|
||||
|
||||
// IRQ 0 is timer, IRQ 1 reserved (for now?), +32 offset for exception entries
|
||||
const IO_APIC_VECTOR_OFFSET: u32 = 32 + APIC_EXTERNAL_OFFSET;
|
||||
|
||||
|
@ -3,13 +3,12 @@ use core::{mem::size_of, ops::DerefMut, ptr::null_mut, sync::atomic::Ordering};
|
||||
|
||||
use ::acpi::{mcfg::Mcfg, AcpiTables, HpetInfo, InterruptModel};
|
||||
use abi::error::Error;
|
||||
use acpi::{AcpiAllocator, AcpiHandlerImpl};
|
||||
use alloc::{boxed::Box, sync::Arc};
|
||||
use apic::{ioapic::IoApic, local::LocalApic};
|
||||
use device_api::device::Device;
|
||||
use kernel_arch_x86::{
|
||||
cpuid::{self, CpuFeatures, EcxFeatures, EdxFeatures, ExtEdxFeatures},
|
||||
gdt,
|
||||
gdt, intrinsics,
|
||||
};
|
||||
use kernel_arch_x86_64::{
|
||||
mem::{
|
||||
@ -34,14 +33,14 @@ use libk_mm::{
|
||||
phys::{self, reserved::reserve_region, PhysicalMemoryRegion},
|
||||
table::{EntryLevel, EntryLevelExt},
|
||||
};
|
||||
use libk_util::{sync::SpinFence, OneTimeInit};
|
||||
use libk_util::OneTimeInit;
|
||||
use yboot_proto::{
|
||||
v1::{self, AvailableMemoryRegion},
|
||||
LoadProtocolV1,
|
||||
};
|
||||
use ygg_driver_acpi::{AcpiAllocator, AcpiHandlerImpl, EventAction, FixedEvent};
|
||||
use ygg_driver_pci::PciBusManager;
|
||||
|
||||
mod acpi;
|
||||
mod apic;
|
||||
mod boot;
|
||||
mod exception;
|
||||
@ -55,13 +54,7 @@ use crate::{
|
||||
|
||||
use self::boot::BootData;
|
||||
|
||||
use super::{
|
||||
x86::{intrinsics, InitrdSource},
|
||||
Platform,
|
||||
};
|
||||
|
||||
/// Offset where legacy ISA IRQs are remapped
|
||||
pub const ISA_IRQ_OFFSET: u32 = apic::ioapic::ISA_IRQ_OFFSET;
|
||||
use super::{x86::InitrdSource, Platform};
|
||||
|
||||
/// x86-64 architecture implementation
|
||||
pub struct X86_64 {
|
||||
@ -71,8 +64,6 @@ pub struct X86_64 {
|
||||
fbconsole: OneTimeInit<Arc<FramebufferConsole>>,
|
||||
}
|
||||
|
||||
static SHUTDOWN_FENCE: SpinFence = SpinFence::new();
|
||||
|
||||
/// Global x86-64 architecture value
|
||||
pub static PLATFORM: X86_64 = X86_64 {
|
||||
boot_data: OneTimeInit::new(),
|
||||
@ -385,7 +376,18 @@ impl X86_64 {
|
||||
let ioapic = IoApic::from_acpi(&apic_info)?;
|
||||
register_external_interrupt_controller(ioapic);
|
||||
|
||||
// acpi::init_acpi(acpi).unwrap();
|
||||
if let Err(error) = ygg_driver_acpi::switch_to_acpi(acpi) {
|
||||
log::error!("ACPI initialization error: {error:?}");
|
||||
} else {
|
||||
if let Err(error) =
|
||||
ygg_driver_acpi::add_event_handler(&FixedEvent::POWER_BUTTON, |_| {
|
||||
log::info!("Power button pressed!");
|
||||
EventAction::Nothing
|
||||
})
|
||||
{
|
||||
log::error!("Couldn't set ACPI power button handler: {error:?}");
|
||||
}
|
||||
}
|
||||
|
||||
if let Ok(mcfg) = acpi.find_table::<Mcfg>() {
|
||||
for entry in mcfg.entries() {
|
||||
|
@ -18,11 +18,10 @@ use libk_mm::{
|
||||
pointer::PhysicalRefMut,
|
||||
TableAllocatorImpl,
|
||||
};
|
||||
use ygg_driver_acpi::AcpiAllocator;
|
||||
|
||||
use crate::arch::x86_64::boot::__x86_64_ap_entry;
|
||||
|
||||
use super::acpi::AcpiAllocator;
|
||||
|
||||
static AP_BOOTSTRAP_BIN: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/__x86_64_ap_boot.bin"));
|
||||
|
||||
const AP_STACK_PAGES: usize = 8;
|
||||
|
Loading…
x
Reference in New Issue
Block a user