x86: unify x86_64/i686 platform init
This commit is contained in:
parent
0b2822cea1
commit
433094837d
@ -440,7 +440,7 @@ impl ConsoleState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Move cursor to position
|
// Move cursor to position
|
||||||
b'f' => {
|
b'f' if self.esc_args.len() >= 2 => {
|
||||||
let row = self.esc_args[0].clamp(1, self.buffer.height) - 1;
|
let row = self.esc_args[0].clamp(1, self.buffer.height) - 1;
|
||||||
let col = self.esc_args[1].clamp(1, CONSOLE_ROW_LEN as u32) - 1;
|
let col = self.esc_args[1].clamp(1, CONSOLE_ROW_LEN as u32) - 1;
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ impl<const STEPS: usize> TimerWheel<STEPS> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn register_timeout(duration: Duration, waker: &Waker) {
|
fn register_timeout(duration: Duration, waker: &Waker) {
|
||||||
let nticks = duration.as_millis().min(288).max(2) as u64;
|
let nticks = duration.as_millis().clamp(2, 288) as u64;
|
||||||
|
|
||||||
if nticks < 32 {
|
if nticks < 32 {
|
||||||
SHORT_TERM_SLEEPS.lock().wake_after(nticks, waker);
|
SHORT_TERM_SLEEPS.lock().wake_after(nticks, waker);
|
||||||
|
@ -3,6 +3,8 @@ use libk_mm::{
|
|||||||
phys::PhysicalMemoryRegion,
|
phys::PhysicalMemoryRegion,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::arch::x86::InitrdSource;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct MultibootInfo {
|
pub struct MultibootInfo {
|
||||||
@ -92,3 +94,13 @@ impl MultibootMemoryMapEntry {
|
|||||||
self.ty == 1
|
self.ty == 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl InitrdSource for MultibootModuleEntry {
|
||||||
|
fn start(&self) -> PhysicalAddress {
|
||||||
|
PhysicalAddress::from_u32(self.mod_start)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn end(&self) -> PhysicalAddress {
|
||||||
|
PhysicalAddress::from_u32(self.mod_end)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -5,18 +5,15 @@ use abi::error::Error;
|
|||||||
use alloc::sync::Arc;
|
use alloc::sync::Arc;
|
||||||
use boot::multiboot::MultibootInfo;
|
use boot::multiboot::MultibootInfo;
|
||||||
use device_api::{
|
use device_api::{
|
||||||
device::Device,
|
interrupt::{IpiDeliveryTarget, IpiMessage},
|
||||||
interrupt::{IpiDeliveryTarget, IpiMessage, Irq},
|
|
||||||
ResetDevice,
|
ResetDevice,
|
||||||
};
|
};
|
||||||
use git_version::git_version;
|
|
||||||
use kernel_arch::{Architecture, ArchitectureImpl};
|
use kernel_arch::{Architecture, ArchitectureImpl};
|
||||||
use kernel_arch_i686::{gdt, mem::table::L3, PerCpuData};
|
use kernel_arch_i686::{gdt, mem::table::L3, PerCpuData};
|
||||||
use kernel_arch_x86::cpuid::{self, CpuFeatures, EcxFeatures, EdxFeatures};
|
use kernel_arch_x86::cpuid::{self, CpuFeatures, EcxFeatures, EdxFeatures};
|
||||||
use libk::{
|
use libk::{
|
||||||
arch::Cpu,
|
arch::Cpu,
|
||||||
debug::{self, LogLevel},
|
debug::{self, LogLevel},
|
||||||
devfs,
|
|
||||||
device::{
|
device::{
|
||||||
display::{
|
display::{
|
||||||
console::{add_console_autoflush, ConsoleWrapper},
|
console::{add_console_autoflush, ConsoleWrapper},
|
||||||
@ -28,55 +25,23 @@ use libk::{
|
|||||||
vfs::{Terminal, TerminalInput},
|
vfs::{Terminal, TerminalInput},
|
||||||
};
|
};
|
||||||
use libk_mm::{
|
use libk_mm::{
|
||||||
address::{PhysicalAddress, Virtualize},
|
address::PhysicalAddress,
|
||||||
phys::{self, reserved::reserve_region, PhysicalMemoryRegion},
|
phys::{self, reserved::reserve_region, PhysicalMemoryRegion},
|
||||||
table::EntryLevelExt,
|
|
||||||
};
|
};
|
||||||
use libk_util::sync::IrqSafeSpinlock;
|
|
||||||
use peripherals::textfb::TextFramebuffer;
|
use peripherals::textfb::TextFramebuffer;
|
||||||
use ygg_driver_pci::{LegacyPciAccess, PciBusManager};
|
|
||||||
|
use crate::arch::x86;
|
||||||
|
|
||||||
|
use super::Platform;
|
||||||
|
|
||||||
mod boot;
|
mod boot;
|
||||||
pub mod exception;
|
pub mod exception;
|
||||||
mod peripherals;
|
mod peripherals;
|
||||||
|
|
||||||
use crate::{
|
|
||||||
arch::x86::{
|
|
||||||
intrinsics::IoPortAccess,
|
|
||||||
peripherals::{i8253::I8253, ps2::PS2Controller, rtc::Rtc},
|
|
||||||
ISA_IRQ_OFFSET,
|
|
||||||
},
|
|
||||||
fs::{Initrd, INITRD_DATA},
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::{
|
|
||||||
x86::{
|
|
||||||
intrinsics::IoPort,
|
|
||||||
peripherals::{i8259::I8259, serial::ComPort},
|
|
||||||
},
|
|
||||||
Platform,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LegacyPciInner {
|
|
||||||
address: IoPort<u32>,
|
|
||||||
data: IoPort<u32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct LegacyPci {
|
|
||||||
inner: IrqSafeSpinlock<LegacyPciInner>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct I686;
|
pub struct I686;
|
||||||
|
|
||||||
static SWITCH_TO_GRAPHIC: AtomicBool = AtomicBool::new(false);
|
static SWITCH_TO_GRAPHIC: AtomicBool = AtomicBool::new(false);
|
||||||
|
|
||||||
static PCI: LegacyPci = LegacyPci {
|
|
||||||
inner: IrqSafeSpinlock::new(LegacyPciInner {
|
|
||||||
address: IoPort::new(0xCF8),
|
|
||||||
data: IoPort::new(0xCFC),
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
||||||
pub static PLATFORM: I686 = I686;
|
pub static PLATFORM: I686 = I686;
|
||||||
|
|
||||||
impl Platform for I686 {
|
impl Platform for I686 {
|
||||||
@ -101,32 +66,7 @@ impl Platform for I686 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl I686 {
|
impl I686 {
|
||||||
fn init_initrd(initrd_start: PhysicalAddress, initrd_end: PhysicalAddress) {
|
unsafe fn init_memory_management(&self, multiboot_info: &MultibootInfo) -> Result<(), Error> {
|
||||||
if initrd_start.is_zero() || initrd_end <= initrd_start {
|
|
||||||
log::info!("No initrd loaded");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let start_aligned = initrd_start.page_align_down::<L3>();
|
|
||||||
let end_aligned = initrd_start.page_align_up::<L3>();
|
|
||||||
|
|
||||||
let data = unsafe {
|
|
||||||
core::slice::from_raw_parts(
|
|
||||||
start_aligned.virtualize() as *const u8,
|
|
||||||
initrd_end - initrd_start,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
let initrd = Initrd {
|
|
||||||
phys_page_start: start_aligned,
|
|
||||||
phys_page_len: end_aligned - start_aligned,
|
|
||||||
data,
|
|
||||||
};
|
|
||||||
|
|
||||||
INITRD_DATA.init(initrd);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn init_platform(&'static self, multiboot_info: &MultibootInfo) -> Result<(), Error> {
|
|
||||||
reserve_region(
|
reserve_region(
|
||||||
"lowmem",
|
"lowmem",
|
||||||
PhysicalMemoryRegion {
|
PhysicalMemoryRegion {
|
||||||
@ -138,34 +78,18 @@ impl I686 {
|
|||||||
let modules = multiboot_info.modules();
|
let modules = multiboot_info.modules();
|
||||||
if !modules.is_empty() {
|
if !modules.is_empty() {
|
||||||
let initrd = &modules[0];
|
let initrd = &modules[0];
|
||||||
let start = PhysicalAddress::from_u32(initrd.mod_start);
|
x86::set_initrd(initrd, true);
|
||||||
let end = PhysicalAddress::from_u32(initrd.mod_end);
|
|
||||||
|
|
||||||
if initrd.mod_start < initrd.mod_end {
|
|
||||||
let size = initrd.mod_end - initrd.mod_start;
|
|
||||||
|
|
||||||
reserve_region(
|
|
||||||
"initrd",
|
|
||||||
PhysicalMemoryRegion {
|
|
||||||
base: start,
|
|
||||||
size: size as _,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Self::init_initrd(start, end);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize physical memory
|
// Initialize physical memory
|
||||||
phys::init_from_iter(multiboot_info.memory_map_iter(), |_, _, _| Ok(()))?;
|
phys::init_from_iter(multiboot_info.memory_map_iter(), |_, _, _| Ok(()))?;
|
||||||
|
|
||||||
debug::init();
|
Ok(())
|
||||||
devfs::init();
|
}
|
||||||
|
|
||||||
let com1_3 = ComPort::setup(0x3F8, 0x3E8, Irq::External(ISA_IRQ_OFFSET + 4))?;
|
unsafe fn init_cpu(&self) -> Result<(), Error> {
|
||||||
|
init_gdt();
|
||||||
unsafe { init_gdt() };
|
exception::init_exceptions();
|
||||||
unsafe { exception::init_exceptions() };
|
|
||||||
|
|
||||||
let (have_features, will_features) = cpuid::setup_features(
|
let (have_features, will_features) = cpuid::setup_features(
|
||||||
CpuFeatures {
|
CpuFeatures {
|
||||||
@ -185,38 +109,10 @@ impl I686 {
|
|||||||
};
|
};
|
||||||
Cpu::init_local(Some(0), cpu_data);
|
Cpu::init_local(Some(0), cpu_data);
|
||||||
|
|
||||||
runtime::init_task_queue();
|
Ok(())
|
||||||
|
}
|
||||||
// Register the PCI drivers
|
|
||||||
// TODO make this implicit init
|
|
||||||
// TODO AHCI hangs inside interrupt handler in i686
|
|
||||||
// ygg_driver_pci::register_class_driver(
|
|
||||||
// "AHCI SATA Controller",
|
|
||||||
// 0x01,
|
|
||||||
// Some(0x06),
|
|
||||||
// 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_vendor_driver(
|
|
||||||
"Virtio PCI GPU Device",
|
|
||||||
0x1AF4,
|
|
||||||
0x1050,
|
|
||||||
ygg_driver_virtio_gpu::probe,
|
|
||||||
);
|
|
||||||
ygg_driver_pci::register_vendor_driver(
|
|
||||||
"Virtio PCI Network Device",
|
|
||||||
0x1AF4,
|
|
||||||
0x1000,
|
|
||||||
ygg_driver_virtio_net::probe,
|
|
||||||
);
|
|
||||||
|
|
||||||
|
unsafe fn init_framebuffer(&self) -> Result<(), Error> {
|
||||||
DEVICE_REGISTRY.display.set_callback(|device, _| {
|
DEVICE_REGISTRY.display.set_callback(|device, _| {
|
||||||
log::info!("Display registered: {:?}", device.display_name());
|
log::info!("Display registered: {:?}", device.display_name());
|
||||||
if device
|
if device
|
||||||
@ -227,21 +123,6 @@ impl I686 {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let i8259 = I8259::setup().expect("Could not initialize i8259 PIC");
|
|
||||||
let i8253 = I8253::setup().expect("Could not initialize i8253 Timer");
|
|
||||||
|
|
||||||
i8259.set_i8253(i8253);
|
|
||||||
|
|
||||||
if let Err(error) = PS2Controller::setup() {
|
|
||||||
log::error!("Could not initialize PS/2 Controller: {error:?}");
|
|
||||||
}
|
|
||||||
if let Err(error) = Rtc::setup() {
|
|
||||||
log::error!("RTC init error: {error:?}");
|
|
||||||
}
|
|
||||||
if let Err(error) = unsafe { com1_3.port_a().clone().init_irq() } {
|
|
||||||
log::error!("COM port IRQ init error: {error:?}");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup text framebuffer
|
// Setup text framebuffer
|
||||||
// TODO check if video mode is set from boot info
|
// TODO check if video mode is set from boot info
|
||||||
let textfb = Arc::new(TextFramebuffer::new(
|
let textfb = Arc::new(TextFramebuffer::new(
|
||||||
@ -254,7 +135,7 @@ impl I686 {
|
|||||||
|
|
||||||
let textfb_console = Arc::new(Terminal::from_parts(
|
let textfb_console = Arc::new(Terminal::from_parts(
|
||||||
Default::default(),
|
Default::default(),
|
||||||
TerminalInput::with_capacity(256).unwrap(),
|
TerminalInput::with_capacity(256)?,
|
||||||
ConsoleWrapper(textfb),
|
ConsoleWrapper(textfb),
|
||||||
));
|
));
|
||||||
let keyboard_input = ygg_driver_input::setup();
|
let keyboard_input = ygg_driver_input::setup();
|
||||||
@ -267,43 +148,27 @@ impl I686 {
|
|||||||
.ok();
|
.ok();
|
||||||
DEVICE_REGISTRY.terminal.register(textfb_console).ok();
|
DEVICE_REGISTRY.terminal.register(textfb_console).ok();
|
||||||
|
|
||||||
log::info!(
|
|
||||||
"Yggdrasil v{} ({})",
|
|
||||||
env!("CARGO_PKG_VERSION"),
|
|
||||||
git_version!()
|
|
||||||
);
|
|
||||||
|
|
||||||
PciBusManager::add_legacy_segment(&PCI)?;
|
|
||||||
PciBusManager::setup_bus_devices()?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl LegacyPciAccess for LegacyPci {
|
unsafe fn init_platform(&'static self, multiboot_info: &MultibootInfo) -> Result<(), Error> {
|
||||||
fn write_u32(&self, bus: u8, slot: u8, func: u8, offset: u8, value: u32) {
|
self.init_memory_management(multiboot_info)
|
||||||
assert_eq!(offset & 0x3, 0);
|
.expect("Could not initialize memory management");
|
||||||
let inner = self.inner.lock();
|
|
||||||
inner.address.write(Self::addr(bus, slot, func, offset));
|
|
||||||
inner.data.write(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_u32(&self, bus: u8, slot: u8, func: u8, offset: u8) -> u32 {
|
self.init_cpu().expect("Could not initialize CPU");
|
||||||
assert_eq!(offset & 0x3, 0);
|
|
||||||
let inner = self.inner.lock();
|
|
||||||
inner.address.write(Self::addr(bus, slot, func, offset));
|
|
||||||
inner.data.read()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LegacyPci {
|
x86::register_pci_drivers();
|
||||||
#[inline]
|
|
||||||
const fn addr(bus: u8, slot: u8, func: u8, offset: u8) -> u32 {
|
let early = x86::init_platform_devices_early()?;
|
||||||
((bus as u32) << 16)
|
|
||||||
| ((slot as u32) << 11)
|
if let Err(error) = self.init_framebuffer() {
|
||||||
| ((func as u32) << 8)
|
log::error!("Could not initialize boot framebuffer: {error:?}");
|
||||||
| (offset as u32 & 0xFC)
|
}
|
||||||
| (1 << 31)
|
|
||||||
|
x86::add_legacy_pci();
|
||||||
|
x86::init_platform_devices(early);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,22 @@
|
|||||||
|
|
||||||
#![allow(missing_docs)]
|
#![allow(missing_docs)]
|
||||||
|
|
||||||
|
use abi::error::Error;
|
||||||
|
use alloc::sync::Arc;
|
||||||
|
use device_api::{device::Device, interrupt::Irq};
|
||||||
|
use libk::{debug, devfs, task::runtime};
|
||||||
|
use libk_mm::{
|
||||||
|
address::{PhysicalAddress, Virtualize},
|
||||||
|
phys::{self, PhysicalMemoryRegion},
|
||||||
|
table::EntryLevelExt,
|
||||||
|
};
|
||||||
|
use peripherals::{i8253::I8253, i8259::I8259, ps2::PS2Controller, rtc::Rtc, serial::ComPort};
|
||||||
|
use ygg_driver_pci::PciBusManager;
|
||||||
|
|
||||||
|
use crate::fs::{Initrd, INITRD_DATA};
|
||||||
|
|
||||||
|
use super::L3;
|
||||||
|
|
||||||
#[cfg(any(target_arch = "x86_64", rust_analyzer))]
|
#[cfg(any(target_arch = "x86_64", rust_analyzer))]
|
||||||
pub const ISA_IRQ_OFFSET: u32 = crate::arch::x86_64::ISA_IRQ_OFFSET;
|
pub const ISA_IRQ_OFFSET: u32 = crate::arch::x86_64::ISA_IRQ_OFFSET;
|
||||||
|
|
||||||
@ -9,4 +25,156 @@ pub const ISA_IRQ_OFFSET: u32 = crate::arch::x86_64::ISA_IRQ_OFFSET;
|
|||||||
pub const ISA_IRQ_OFFSET: u32 = 0;
|
pub const ISA_IRQ_OFFSET: u32 = 0;
|
||||||
|
|
||||||
pub mod intrinsics;
|
pub mod intrinsics;
|
||||||
|
mod pci;
|
||||||
pub mod peripherals;
|
pub mod peripherals;
|
||||||
|
|
||||||
|
pub trait InitrdSource {
|
||||||
|
fn start(&self) -> PhysicalAddress;
|
||||||
|
fn end(&self) -> PhysicalAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct EarlyPlatformDevices {
|
||||||
|
pub com1_3: Arc<ComPort>,
|
||||||
|
pub i8259: Arc<I8259>,
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO move this to some sort of .init_array-style implicit thing
|
||||||
|
pub fn register_pci_drivers() {
|
||||||
|
// XXX: Only works with MSI-X, so no i686
|
||||||
|
#[cfg(any(target_arch = "x86_64", rust_analyzer))]
|
||||||
|
ygg_driver_pci::register_class_driver(
|
||||||
|
"NVMe Host Controller",
|
||||||
|
0x01,
|
||||||
|
Some(0x08),
|
||||||
|
Some(0x02),
|
||||||
|
ygg_driver_nvme::probe,
|
||||||
|
);
|
||||||
|
// XXX: i686 hangs in interrupt handler
|
||||||
|
#[cfg(any(target_arch = "x86_64", rust_analyzer))]
|
||||||
|
ygg_driver_pci::register_class_driver(
|
||||||
|
"AHCI Controller",
|
||||||
|
0x01,
|
||||||
|
Some(0x06),
|
||||||
|
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_vendor_driver(
|
||||||
|
"Virtio PCI GPU Device",
|
||||||
|
0x1AF4,
|
||||||
|
0x1050,
|
||||||
|
ygg_driver_virtio_gpu::probe,
|
||||||
|
);
|
||||||
|
ygg_driver_pci::register_vendor_driver(
|
||||||
|
"Virtio PCI Network Device",
|
||||||
|
0x1AF4,
|
||||||
|
0x1000,
|
||||||
|
ygg_driver_virtio_net::probe,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the bare minimum required to:
|
||||||
|
// * Allocate/manage interrupts
|
||||||
|
// * Print debug output
|
||||||
|
pub fn init_platform_devices_early() -> Result<EarlyPlatformDevices, Error> {
|
||||||
|
devfs::init();
|
||||||
|
debug::init();
|
||||||
|
|
||||||
|
// Initialize async executor queue
|
||||||
|
runtime::init_task_queue();
|
||||||
|
|
||||||
|
let com1_3 = ComPort::setup(0x3F8, 0x3E8, Irq::External(ISA_IRQ_OFFSET + 4))?;
|
||||||
|
let i8259 = I8259::setup().expect("Could not initialize i8259 PIC");
|
||||||
|
|
||||||
|
#[cfg(any(target_arch = "x86", rust_analyzer))]
|
||||||
|
{
|
||||||
|
use libk::device::register_external_interrupt_controller;
|
||||||
|
|
||||||
|
// No other interrupt handling options
|
||||||
|
unsafe { i8259.clone().init() }?;
|
||||||
|
register_external_interrupt_controller(i8259.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(any(target_arch = "x86_64", rust_analyzer))]
|
||||||
|
{
|
||||||
|
i8259.disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(EarlyPlatformDevices { i8259, com1_3 })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_legacy_pci() {
|
||||||
|
if let Err(error) = PciBusManager::add_legacy_segment(&pci::PCI) {
|
||||||
|
log::error!("Couldn't add legacy x86 PCI: {error:?}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init_platform_devices(early: EarlyPlatformDevices) {
|
||||||
|
// TODO clocksource can be selected here
|
||||||
|
match I8253::setup() {
|
||||||
|
Ok(i8253) => {
|
||||||
|
early.i8259.set_i8253(i8253);
|
||||||
|
}
|
||||||
|
Err(error) => {
|
||||||
|
log::error!("Couldn't setup i8253: {error:?}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Err(error) = PS2Controller::setup() {
|
||||||
|
log::error!("PS/2 controller init error: {error:?}");
|
||||||
|
}
|
||||||
|
if let Err(error) = Rtc::setup() {
|
||||||
|
log::error!("RTC init error: {error:?}");
|
||||||
|
}
|
||||||
|
if let Err(error) = unsafe { early.com1_3.port_a().clone().init_irq() } {
|
||||||
|
log::error!("COM port IRQ init error: {error:?}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Err(error) = PciBusManager::setup_bus_devices() {
|
||||||
|
log::error!("PCI bus device setup error(s): {error:?}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_initrd(initrd: &impl InitrdSource, reserve: bool) {
|
||||||
|
let initrd_start = initrd.start();
|
||||||
|
let initrd_end = initrd.end();
|
||||||
|
|
||||||
|
if initrd_start.is_zero() || initrd_end <= initrd_start {
|
||||||
|
log::info!("No initrd loaded");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let start_aligned = initrd_start.page_align_down::<L3>();
|
||||||
|
let end_aligned = initrd_end.page_align_up::<L3>();
|
||||||
|
let size = end_aligned - start_aligned;
|
||||||
|
|
||||||
|
if reserve {
|
||||||
|
phys::reserved::reserve_region(
|
||||||
|
"initrd",
|
||||||
|
PhysicalMemoryRegion {
|
||||||
|
base: start_aligned,
|
||||||
|
size,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = unsafe {
|
||||||
|
core::slice::from_raw_parts(
|
||||||
|
start_aligned.virtualize() as *const u8,
|
||||||
|
initrd_end - initrd_start,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
let initrd = Initrd {
|
||||||
|
phys_page_start: start_aligned,
|
||||||
|
phys_page_len: end_aligned - start_aligned,
|
||||||
|
data,
|
||||||
|
};
|
||||||
|
|
||||||
|
INITRD_DATA.init(initrd);
|
||||||
|
}
|
||||||
|
49
kernel/src/arch/x86/pci.rs
Normal file
49
kernel/src/arch/x86/pci.rs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
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>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) struct LegacyPci {
|
||||||
|
inner: IrqSafeSpinlock<LegacyPciInner>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) static PCI: LegacyPci = LegacyPci {
|
||||||
|
inner: IrqSafeSpinlock::new(LegacyPciInner {
|
||||||
|
address: IoPort::new(0xCF8),
|
||||||
|
data: IoPort::new(0xCFC),
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
impl LegacyPciAccess for LegacyPci {
|
||||||
|
fn write_u32(&self, bus: u8, slot: u8, func: u8, offset: u8, value: u32) {
|
||||||
|
assert_eq!(offset & 0x3, 0);
|
||||||
|
let inner = self.inner.lock();
|
||||||
|
inner.address.write(Self::addr(bus, slot, func, offset));
|
||||||
|
inner.data.write(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_u32(&self, bus: u8, slot: u8, func: u8, offset: u8) -> u32 {
|
||||||
|
assert_eq!(offset & 0x3, 0);
|
||||||
|
let inner = self.inner.lock();
|
||||||
|
inner.address.write(Self::addr(bus, slot, func, offset));
|
||||||
|
inner.data.read()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LegacyPci {
|
||||||
|
#[inline]
|
||||||
|
const fn addr(bus: u8, slot: u8, func: u8, offset: u8) -> u32 {
|
||||||
|
((bus as u32) << 16)
|
||||||
|
| ((slot as u32) << 11)
|
||||||
|
| ((func as u32) << 8)
|
||||||
|
| (offset as u32 & 0xFC)
|
||||||
|
| (1 << 31)
|
||||||
|
}
|
||||||
|
}
|
@ -9,7 +9,6 @@ use device_api::{
|
|||||||
IrqOptions,
|
IrqOptions,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use libk::device::register_external_interrupt_controller;
|
|
||||||
use libk_util::{sync::IrqSafeSpinlock, OneTimeInit};
|
use libk_util::{sync::IrqSafeSpinlock, OneTimeInit};
|
||||||
|
|
||||||
use crate::arch::x86::intrinsics::{IoPort, IoPortAccess};
|
use crate::arch::x86::intrinsics::{IoPort, IoPortAccess};
|
||||||
@ -124,8 +123,6 @@ impl I8259 {
|
|||||||
|
|
||||||
pub fn setup() -> Result<Arc<Self>, Error> {
|
pub fn setup() -> Result<Arc<Self>, Error> {
|
||||||
let this = Arc::new(Self::new());
|
let this = Arc::new(Self::new());
|
||||||
unsafe { this.clone().init() }?;
|
|
||||||
register_external_interrupt_controller(this.clone());
|
|
||||||
I8259.init(this.clone());
|
I8259.init(this.clone());
|
||||||
Ok(this)
|
Ok(this)
|
||||||
}
|
}
|
||||||
@ -134,9 +131,8 @@ impl I8259 {
|
|||||||
self.i8253.init(i8253);
|
self.i8253.init(i8253);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn disable() {
|
pub fn disable(&self) {
|
||||||
let inner = Self::new_inner();
|
let inner = self.inner.lock();
|
||||||
|
|
||||||
log::info!("Disabling i8259 PIC");
|
log::info!("Disabling i8259 PIC");
|
||||||
|
|
||||||
// Remap PIC IRQ vectors to 32..
|
// Remap PIC IRQ vectors to 32..
|
||||||
|
@ -54,7 +54,7 @@ impl Inner {
|
|||||||
self.wait_for_update();
|
self.wait_for_update();
|
||||||
let mut last = self.try_read_time();
|
let mut last = self.try_read_time();
|
||||||
|
|
||||||
let time = loop {
|
loop {
|
||||||
self.wait_for_update();
|
self.wait_for_update();
|
||||||
let now = self.try_read_time();
|
let now = self.try_read_time();
|
||||||
|
|
||||||
@ -62,9 +62,7 @@ impl Inner {
|
|||||||
break now;
|
break now;
|
||||||
}
|
}
|
||||||
last = now;
|
last = now;
|
||||||
};
|
}
|
||||||
|
|
||||||
time
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wait_for_update(&mut self) {
|
fn wait_for_update(&mut self) {
|
||||||
|
@ -3,7 +3,6 @@ use core::{arch::global_asm, sync::atomic::Ordering};
|
|||||||
|
|
||||||
use kernel_arch_x86::registers::MSR_IA32_KERNEL_GS_BASE;
|
use kernel_arch_x86::registers::MSR_IA32_KERNEL_GS_BASE;
|
||||||
use kernel_arch_x86_64::CPU_COUNT;
|
use kernel_arch_x86_64::CPU_COUNT;
|
||||||
use libk::{devfs, task::runtime};
|
|
||||||
use tock_registers::interfaces::Writeable;
|
use tock_registers::interfaces::Writeable;
|
||||||
use yboot_proto::{
|
use yboot_proto::{
|
||||||
v1::{FramebufferOption, MemoryMap},
|
v1::{FramebufferOption, MemoryMap},
|
||||||
@ -12,7 +11,7 @@ use yboot_proto::{
|
|||||||
|
|
||||||
use crate::{kernel_main, kernel_secondary_main, mem::KERNEL_VIRT_OFFSET};
|
use crate::{kernel_main, kernel_secondary_main, mem::KERNEL_VIRT_OFFSET};
|
||||||
|
|
||||||
use super::{exception, syscall, PLATFORM};
|
use super::PLATFORM;
|
||||||
|
|
||||||
pub enum BootData {
|
pub enum BootData {
|
||||||
YBoot(&'static LoadProtocolV1),
|
YBoot(&'static LoadProtocolV1),
|
||||||
@ -79,23 +78,6 @@ extern "C" fn __x86_64_upper_entry() -> ! {
|
|||||||
|
|
||||||
PLATFORM.set_boot_data(BootData::YBoot(&YBOOT_DATA));
|
PLATFORM.set_boot_data(BootData::YBoot(&YBOOT_DATA));
|
||||||
|
|
||||||
// Setup memory management: kernel virtual memory tables, physical page manager and heap
|
|
||||||
unsafe {
|
|
||||||
PLATFORM
|
|
||||||
.init_memory_management()
|
|
||||||
.expect("Could not initialize memory management");
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
exception::init_exceptions(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize async executor queue
|
|
||||||
runtime::init_task_queue();
|
|
||||||
|
|
||||||
devfs::init();
|
|
||||||
|
|
||||||
// Initializes: local CPU, platform devices (timers/serials/etc), debug output
|
|
||||||
unsafe {
|
unsafe {
|
||||||
PLATFORM
|
PLATFORM
|
||||||
.init_platform(0)
|
.init_platform(0)
|
||||||
@ -113,13 +95,7 @@ pub extern "C" fn __x86_64_ap_entry() -> ! {
|
|||||||
init_dummy_cpu();
|
init_dummy_cpu();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Still not initialized: GDT, IDT, CPU features, syscall, kernel_gs_base
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
// Cpu::init_local(LocalApic::new(), cpu_id as u32);
|
|
||||||
syscall::init_syscall();
|
|
||||||
exception::init_exceptions(cpu_id);
|
|
||||||
|
|
||||||
PLATFORM
|
PLATFORM
|
||||||
.init_platform(cpu_id)
|
.init_platform(cpu_id)
|
||||||
.expect("Could not initialize the platform (AP)");
|
.expect("Could not initialize the platform (AP)");
|
||||||
|
@ -6,8 +6,6 @@ use abi::error::Error;
|
|||||||
use acpi::{AcpiAllocator, AcpiHandlerImpl};
|
use acpi::{AcpiAllocator, AcpiHandlerImpl};
|
||||||
use alloc::{boxed::Box, sync::Arc};
|
use alloc::{boxed::Box, sync::Arc};
|
||||||
use apic::{ioapic::IoApic, local::LocalApic};
|
use apic::{ioapic::IoApic, local::LocalApic};
|
||||||
use device_api::{device::Device, interrupt::Irq};
|
|
||||||
use git_version::git_version;
|
|
||||||
use kernel_arch_x86::{
|
use kernel_arch_x86::{
|
||||||
cpuid::{self, CpuFeatures, EcxFeatures, EdxFeatures},
|
cpuid::{self, CpuFeatures, EcxFeatures, EdxFeatures},
|
||||||
gdt,
|
gdt,
|
||||||
@ -31,7 +29,7 @@ use libk::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
use libk_mm::{
|
use libk_mm::{
|
||||||
address::{PhysicalAddress, Virtualize},
|
address::PhysicalAddress,
|
||||||
phys::{self, reserved::reserve_region, PhysicalMemoryRegion},
|
phys::{self, reserved::reserve_region, PhysicalMemoryRegion},
|
||||||
table::{EntryLevel, EntryLevelExt},
|
table::{EntryLevel, EntryLevelExt},
|
||||||
};
|
};
|
||||||
@ -49,19 +47,12 @@ mod exception;
|
|||||||
mod smp;
|
mod smp;
|
||||||
mod syscall;
|
mod syscall;
|
||||||
|
|
||||||
use crate::{
|
use crate::{arch::x86, device::display::linear_fb::LinearFramebuffer};
|
||||||
arch::x86::peripherals::{i8253::I8253, ps2::PS2Controller, rtc::Rtc},
|
|
||||||
device::display::linear_fb::LinearFramebuffer,
|
|
||||||
fs::{Initrd, INITRD_DATA},
|
|
||||||
};
|
|
||||||
|
|
||||||
use self::boot::BootData;
|
use self::boot::BootData;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
x86::{
|
x86::{intrinsics, InitrdSource},
|
||||||
intrinsics,
|
|
||||||
peripherals::{i8259::I8259, serial::ComPort},
|
|
||||||
},
|
|
||||||
Platform,
|
Platform,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -251,8 +242,39 @@ impl X86_64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn init_platform(&'static self, cpu_id: usize) -> Result<(), Error> {
|
unsafe fn init_platform(&'static self, cpu_id: usize) -> Result<(), Error> {
|
||||||
|
if cpu_id == 0 {
|
||||||
|
PLATFORM
|
||||||
|
.init_memory_management()
|
||||||
|
.expect("Could not initialize memory management");
|
||||||
|
}
|
||||||
|
|
||||||
|
self.init_local_cpu(cpu_id);
|
||||||
|
|
||||||
|
if cpu_id == 0 {
|
||||||
|
x86::register_pci_drivers();
|
||||||
|
|
||||||
|
self.setup_from_boot_data()?;
|
||||||
|
|
||||||
|
let early = x86::init_platform_devices_early()?;
|
||||||
|
|
||||||
|
if let Err(error) = self.init_framebuffer() {
|
||||||
|
log::error!("Could not initialize boot framebuffer: {error:?}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(acpi) = self.acpi.try_get() {
|
||||||
|
self.init_platform_from_acpi(acpi)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
x86::init_platform_devices(early);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn init_local_cpu(&self, cpu_id: usize) {
|
||||||
let local_apic = Box::new(LocalApic::new());
|
let local_apic = Box::new(LocalApic::new());
|
||||||
let tss_address = gdt::init();
|
let tss_address = gdt::init();
|
||||||
|
exception::init_exceptions(cpu_id);
|
||||||
|
|
||||||
let (have_features, will_features) = cpuid::setup_features(
|
let (have_features, will_features) = cpuid::setup_features(
|
||||||
CpuFeatures {
|
CpuFeatures {
|
||||||
@ -285,119 +307,16 @@ impl X86_64 {
|
|||||||
Cpu::init_local(Some(cpu_id as _), cpu_data);
|
Cpu::init_local(Some(cpu_id as _), cpu_data);
|
||||||
|
|
||||||
syscall::init_syscall();
|
syscall::init_syscall();
|
||||||
|
|
||||||
if cpu_id == 0 {
|
|
||||||
// Register the PCI drivers
|
|
||||||
// TODO make this implicit init
|
|
||||||
ygg_driver_pci::register_class_driver(
|
|
||||||
"NVMe Host Controller",
|
|
||||||
0x01,
|
|
||||||
Some(0x08),
|
|
||||||
Some(0x02),
|
|
||||||
ygg_driver_nvme::probe,
|
|
||||||
);
|
|
||||||
ygg_driver_pci::register_class_driver(
|
|
||||||
"AHCI Controller",
|
|
||||||
0x01,
|
|
||||||
Some(0x06),
|
|
||||||
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_vendor_driver(
|
|
||||||
"Virtio PCI GPU Device",
|
|
||||||
0x1AF4,
|
|
||||||
0x1050,
|
|
||||||
ygg_driver_virtio_gpu::probe,
|
|
||||||
);
|
|
||||||
ygg_driver_pci::register_vendor_driver(
|
|
||||||
"Virtio PCI Network Device",
|
|
||||||
0x1AF4,
|
|
||||||
0x1000,
|
|
||||||
ygg_driver_virtio_net::probe,
|
|
||||||
);
|
|
||||||
|
|
||||||
match self.boot_data.get() {
|
|
||||||
&BootData::YBoot(data) => {
|
|
||||||
let start = PhysicalAddress::from_u64(data.initrd_address);
|
|
||||||
Self::init_initrd(start, start.add(data.initrd_size as usize));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.init_acpi_from_boot_data()?;
|
|
||||||
|
|
||||||
I8259::disable();
|
|
||||||
|
|
||||||
debug::init();
|
|
||||||
|
|
||||||
let com1_3 = ComPort::setup(0x3F8, 0x3E8, Irq::External(ISA_IRQ_OFFSET + 4))?;
|
|
||||||
// TODO register platform devices
|
|
||||||
|
|
||||||
DEVICE_REGISTRY.display.set_callback(|device, node| {
|
|
||||||
log::info!("Display registered: {:?}", device.display_name());
|
|
||||||
// let node = devfs::add_block_device(device, BlockDeviceType::Framebuffer);
|
|
||||||
|
|
||||||
if device
|
|
||||||
.driver_flags()
|
|
||||||
.contains(DriverFlags::REPLACES_BOOT_FRAMEBUFFER)
|
|
||||||
{
|
|
||||||
// Switch fbconsole to the new framebuffer
|
|
||||||
if let Some(fbconsole) = PLATFORM.fbconsole.try_get()
|
|
||||||
&& fbconsole.uses_boot_framebuffer()
|
|
||||||
{
|
|
||||||
if let Err(error) = fbconsole.set_display(device.clone()) {
|
|
||||||
log::error!("Couldn't set fb console display: {error:?}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Switch /dev/fb0 to the new node
|
|
||||||
if let Some(node) = node {
|
|
||||||
devfs::set_node("fb0", node).ok();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
self.init_framebuffer()?;
|
|
||||||
|
|
||||||
log::info!(
|
|
||||||
"Yggdrasil v{} ({})",
|
|
||||||
env!("CARGO_PKG_VERSION"),
|
|
||||||
git_version!()
|
|
||||||
);
|
|
||||||
|
|
||||||
// RTC.init()?;
|
|
||||||
|
|
||||||
if let Some(acpi) = self.acpi.try_get() {
|
|
||||||
self.init_platform_from_acpi(acpi)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Err(error) = I8253::setup() {
|
|
||||||
log::error!("Couldn't setup i8253: {error:?}");
|
|
||||||
}
|
|
||||||
if let Err(error) = PS2Controller::setup() {
|
|
||||||
log::error!("PS/2 controller init error: {error:?}");
|
|
||||||
}
|
|
||||||
if let Err(error) = Rtc::setup() {
|
|
||||||
log::error!("RTC init error: {error:?}");
|
|
||||||
}
|
|
||||||
if let Err(error) = unsafe { com1_3.port_a().clone().init_irq() } {
|
|
||||||
log::error!("COM port IRQ init error: {error:?}");
|
|
||||||
}
|
|
||||||
|
|
||||||
PciBusManager::setup_bus_devices()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn init_acpi_from_boot_data(&self) -> Result<(), Error> {
|
unsafe fn setup_from_boot_data(&self) -> Result<(), Error> {
|
||||||
match self.boot_data.get() {
|
match self.boot_data.get() {
|
||||||
&BootData::YBoot(data) => self.init_acpi_from_rsdp(data.rsdp_address as usize),
|
&BootData::YBoot(data) => {
|
||||||
|
// Already reserved in set_boot_data()
|
||||||
|
x86::set_initrd(data, false);
|
||||||
|
|
||||||
|
self.init_acpi_from_rsdp(data.rsdp_address as usize)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -420,16 +339,19 @@ impl X86_64 {
|
|||||||
})?;
|
})?;
|
||||||
|
|
||||||
let InterruptModel::Apic(apic_info) = platform_info.interrupt_model else {
|
let InterruptModel::Apic(apic_info) = platform_info.interrupt_model else {
|
||||||
panic!("The processor does not support APIC");
|
unreachable!("The processor does not support APIC");
|
||||||
};
|
};
|
||||||
|
|
||||||
let ioapic = IoApic::from_acpi(&apic_info)?;
|
let ioapic = IoApic::from_acpi(&apic_info)?;
|
||||||
register_external_interrupt_controller(ioapic);
|
register_external_interrupt_controller(ioapic);
|
||||||
|
|
||||||
// acpi::init_acpi(acpi).unwrap();
|
// acpi::init_acpi(acpi).unwrap();
|
||||||
|
|
||||||
if let Ok(mcfg) = acpi.find_table::<Mcfg>() {
|
if let Ok(mcfg) = acpi.find_table::<Mcfg>() {
|
||||||
for entry in mcfg.entries() {
|
for entry in mcfg.entries() {
|
||||||
PciBusManager::add_segment_from_mcfg(entry)?;
|
if let Err(error) = PciBusManager::add_segment_from_mcfg(entry) {
|
||||||
|
log::error!("Could not add PCI bus segment: {error:?}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -437,6 +359,29 @@ impl X86_64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn init_framebuffer(&'static self) -> Result<(), Error> {
|
unsafe fn init_framebuffer(&'static self) -> Result<(), Error> {
|
||||||
|
DEVICE_REGISTRY.display.set_callback(|device, node| {
|
||||||
|
log::info!("Display registered: {:?}", device.display_name());
|
||||||
|
|
||||||
|
if device
|
||||||
|
.driver_flags()
|
||||||
|
.contains(DriverFlags::REPLACES_BOOT_FRAMEBUFFER)
|
||||||
|
{
|
||||||
|
// Switch fbconsole to the new framebuffer
|
||||||
|
if let Some(fbconsole) = PLATFORM.fbconsole.try_get()
|
||||||
|
&& fbconsole.uses_boot_framebuffer()
|
||||||
|
{
|
||||||
|
if let Err(error) = fbconsole.set_display(device.clone()) {
|
||||||
|
log::error!("Couldn't set fb console display: {error:?}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Switch /dev/fb0 to the new node
|
||||||
|
if let Some(node) = node {
|
||||||
|
devfs::set_node("fb0", node).ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
let display = match self.boot_data.get() {
|
let display = match self.boot_data.get() {
|
||||||
&BootData::YBoot(data) => {
|
&BootData::YBoot(data) => {
|
||||||
let info = &data.opt_framebuffer;
|
let info = &data.opt_framebuffer;
|
||||||
@ -465,9 +410,7 @@ impl X86_64 {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Register boot display
|
// Register boot display
|
||||||
// let display = Box::leak(Box::new(DisplayDeviceWrapper::new(display)));
|
|
||||||
DEVICE_REGISTRY.display.register(display.clone(), true)?;
|
DEVICE_REGISTRY.display.register(display.clone(), true)?;
|
||||||
// register_display_device(display);
|
|
||||||
|
|
||||||
let fbconsole = self
|
let fbconsole = self
|
||||||
.fbconsole
|
.fbconsole
|
||||||
@ -482,28 +425,38 @@ impl X86_64 {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_initrd(initrd_start: PhysicalAddress, initrd_end: PhysicalAddress) {
|
// fn init_initrd(initrd_start: PhysicalAddress, initrd_end: PhysicalAddress) {
|
||||||
if initrd_start.is_zero() || initrd_end <= initrd_start {
|
// if initrd_start.is_zero() || initrd_end <= initrd_start {
|
||||||
log::info!("No initrd loaded");
|
// log::info!("No initrd loaded");
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
let start_aligned = initrd_start.page_align_down::<L3>();
|
// let start_aligned = initrd_start.page_align_down::<L3>();
|
||||||
let end_aligned = initrd_start.page_align_up::<L3>();
|
// let end_aligned = initrd_start.page_align_up::<L3>();
|
||||||
|
|
||||||
let data = unsafe {
|
// let data = unsafe {
|
||||||
core::slice::from_raw_parts(
|
// core::slice::from_raw_parts(
|
||||||
start_aligned.virtualize() as *const u8,
|
// start_aligned.virtualize() as *const u8,
|
||||||
initrd_end - initrd_start,
|
// initrd_end - initrd_start,
|
||||||
)
|
// )
|
||||||
};
|
// };
|
||||||
|
|
||||||
let initrd = Initrd {
|
// let initrd = Initrd {
|
||||||
phys_page_start: start_aligned,
|
// phys_page_start: start_aligned,
|
||||||
phys_page_len: end_aligned - start_aligned,
|
// phys_page_len: end_aligned - start_aligned,
|
||||||
data,
|
// data,
|
||||||
};
|
// };
|
||||||
|
|
||||||
INITRD_DATA.init(initrd);
|
// INITRD_DATA.init(initrd);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InitrdSource for LoadProtocolV1 {
|
||||||
|
fn start(&self) -> PhysicalAddress {
|
||||||
|
PhysicalAddress::from_u64(self.initrd_address)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn end(&self) -> PhysicalAddress {
|
||||||
|
PhysicalAddress::from_u64(self.initrd_address + self.initrd_size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
use alloc::borrow::ToOwned;
|
use alloc::borrow::ToOwned;
|
||||||
use arch::Platform;
|
use arch::Platform;
|
||||||
use fs::sysfs;
|
use fs::sysfs;
|
||||||
|
use git_version::git_version;
|
||||||
use kernel_arch::{Architecture, ArchitectureImpl};
|
use kernel_arch::{Architecture, ArchitectureImpl};
|
||||||
use libk::{arch::Cpu, devfs};
|
use libk::{arch::Cpu, devfs};
|
||||||
use libk_util::sync::SpinFence;
|
use libk_util::sync::SpinFence;
|
||||||
@ -87,6 +88,12 @@ pub fn kernel_secondary_main() -> ! {
|
|||||||
/// * Basic debugging facilities
|
/// * Basic debugging facilities
|
||||||
/// * Initrd
|
/// * Initrd
|
||||||
pub fn kernel_main() -> ! {
|
pub fn kernel_main() -> ! {
|
||||||
|
log::info!(
|
||||||
|
"Yggdrasil v{} ({})",
|
||||||
|
env!("CARGO_PKG_VERSION"),
|
||||||
|
git_version!()
|
||||||
|
);
|
||||||
|
|
||||||
libk::panic::set_handler(panic::panic_handler);
|
libk::panic::set_handler(panic::panic_handler);
|
||||||
|
|
||||||
// Setup the sysfs
|
// Setup the sysfs
|
||||||
|
Loading…
x
Reference in New Issue
Block a user