x86-64: make init return Result

This commit is contained in:
Mark Poliakov 2023-09-15 23:23:20 +03:00
parent 5351ccf038
commit 03180a1561
3 changed files with 64 additions and 40 deletions

View File

@ -89,7 +89,9 @@ extern "C" fn __x86_64_upper_entry() -> ! {
// Setup memory management: kernel virtual memory tables, physical page manager and heap
unsafe {
ARCHITECTURE.init_memory_management();
ARCHITECTURE
.init_memory_management()
.expect("Could not initialize memory management");
}
unsafe {
@ -103,7 +105,9 @@ extern "C" fn __x86_64_upper_entry() -> ! {
// Initializes: local CPU, platform devices (timers/serials/etc), debug output
unsafe {
ARCHITECTURE.init_platform(0);
ARCHITECTURE
.init_platform(0)
.expect("Could not initialize the platform");
}
kernel_main()
@ -126,7 +130,9 @@ pub extern "C" fn __x86_64_ap_entry() -> ! {
// syscall::init_syscall();
exception::init_exceptions(cpu_id);
ARCHITECTURE.init_platform(cpu_id);
ARCHITECTURE
.init_platform(cpu_id)
.expect("Could not initialize the platform (AP)");
}
CPU_COUNT.fetch_add(1, Ordering::Release);

View File

@ -276,20 +276,19 @@ impl X86_64 {
self.boot_data.init(data);
}
unsafe fn init_physical_memory_from_yboot(data: &LoadProtocolV1) {
unsafe fn init_physical_memory_from_yboot(data: &LoadProtocolV1) -> Result<(), Error> {
let mmap = EarlyMapping::<AvailableMemoryRegion>::map_slice(
PhysicalAddress::from_raw(data.memory_map.address),
data.memory_map.len as usize,
)
.unwrap();
)?;
phys::init_from_iter(mmap.as_ref().iter().map(|reg| PhysicalMemoryRegion {
base: PhysicalAddress::from_raw(reg.start_address),
size: reg.page_count as usize * 0x1000,
}));
}))
}
unsafe fn init_memory_management(&self) {
unsafe fn init_memory_management(&self) -> Result<(), Error> {
const HEAP_PAGES: usize = 16;
init_fixed_tables();
@ -304,21 +303,23 @@ impl X86_64 {
);
match self.boot_data.get() {
&BootData::YBoot(data) => Self::init_physical_memory_from_yboot(data),
&BootData::YBoot(data) => Self::init_physical_memory_from_yboot(data)?,
}
// Setup heap
for i in 0..HEAP_PAGES {
// Allocate in 2MiB chunks
let l2_page = phys::alloc_2m_page().unwrap();
let l2_page = phys::alloc_2m_page()?;
map_heap_block(i, l2_page);
}
heap::init_heap(HEAP_MAPPING_OFFSET, HEAP_PAGES * L2::SIZE);
Ok(())
}
unsafe fn init_platform(&'static self, cpu_id: usize) {
unsafe fn init_platform(&'static self, cpu_id: usize) -> Result<(), Error> {
Cpu::init_local(LocalApic::new(), cpu_id as _);
if cpu_id == 0 {
@ -329,7 +330,7 @@ impl X86_64 {
}
}
self.init_acpi_from_boot_data();
self.init_acpi_from_boot_data()?;
Self::disable_8259();
@ -338,7 +339,7 @@ impl X86_64 {
let com1_3 = Box::leak(Box::new(ComPort::new(0x3F8, 0x3E8, IrqNumber::Isa(4))));
debug::add_sink(com1_3.port_a(), LogLevel::Debug);
self.init_framebuffer();
self.init_framebuffer()?;
debug::init();
@ -348,7 +349,7 @@ impl X86_64 {
0x64,
0x60,
)));
ps2.init().unwrap();
ps2.init()?;
infoln!(
"Yggdrasil v{} ({})",
@ -357,75 +358,90 @@ impl X86_64 {
);
if let Some(acpi) = self.acpi.try_get() {
self.init_platform_from_acpi(acpi);
self.init_platform_from_acpi(acpi)?;
}
self.timer.get().init_irq().unwrap();
self.timer.get().init_irq()?;
ps2.connect(self.tty.get());
ps2.init_irq().unwrap();
ps2.init_irq()?;
device::register_device(self.ioapic.get());
device::register_device(ps2);
PciBusManager::setup_bus_devices().unwrap();
PciBusManager::setup_bus_devices()?;
}
Ok(())
}
unsafe fn init_acpi_from_boot_data(&self) {
unsafe fn init_acpi_from_boot_data(&self) -> Result<(), Error> {
match self.boot_data.get() {
&BootData::YBoot(data) => self.init_acpi_from_rsdp(data.rsdp_address as usize),
}
}
unsafe fn init_acpi_from_rsdp(&self, rsdp: usize) {
let acpi_tables = AcpiTables::from_rsdp(AcpiHandlerImpl, rsdp).unwrap();
unsafe fn init_acpi_from_rsdp(&self, rsdp: usize) -> Result<(), Error> {
let acpi_tables = AcpiTables::from_rsdp(AcpiHandlerImpl, rsdp).map_err(|err| {
errorln!("Could not initialize ACPI tables: {:?}", err);
Error::InvalidArgument
})?;
self.acpi.init(acpi_tables);
Ok(())
}
unsafe fn init_platform_from_acpi(&self, acpi: &'static AcpiTables<AcpiHandlerImpl>) {
let platform_info = acpi.platform_info_in(AcpiAllocator).unwrap();
unsafe fn init_platform_from_acpi(
&self,
acpi: &'static AcpiTables<AcpiHandlerImpl>,
) -> Result<(), Error> {
let platform_info = acpi.platform_info_in(AcpiAllocator).map_err(|err| {
errorln!("Could not get ACPI platform info: {:?}", err);
Error::InvalidArgument
})?;
let InterruptModel::Apic(apic_info) = platform_info.interrupt_model else {
panic!("The processor does not support APIC");
};
self.ioapic.init(IoApic::from_acpi(&apic_info).unwrap());
self.ioapic.init(IoApic::from_acpi(&apic_info)?);
// acpi::init_acpi(acpi).unwrap();
if let Ok(mcfg) = acpi.find_table::<Mcfg>() {
for entry in mcfg.entries() {
PciBusManager::add_segment_from_mcfg(entry).unwrap();
PciBusManager::add_segment_from_mcfg(entry)?;
}
}
Ok(())
}
unsafe fn init_framebuffer(&'static self) {
unsafe fn init_framebuffer(&'static self) -> Result<(), Error> {
match self.boot_data.get() {
&BootData::YBoot(data) => {
let info = &data.opt_framebuffer;
self.framebuffer.init(
LinearFramebuffer::from_physical_bits(
PhysicalAddress::from_raw(info.res_address),
info.res_size as usize,
info.res_stride as usize,
info.res_width,
info.res_height,
)
.unwrap(),
);
self.framebuffer.init(LinearFramebuffer::from_physical_bits(
PhysicalAddress::from_raw(info.res_address),
info.res_size as usize,
info.res_stride as usize,
info.res_width,
info.res_height,
)?);
}
}
self.fbconsole
.init(FramebufferConsole::from_framebuffer(self.framebuffer.get(), None).unwrap());
self.fbconsole.init(FramebufferConsole::from_framebuffer(
self.framebuffer.get(),
None,
)?);
debug::add_sink(self.fbconsole.get(), LogLevel::Info);
self.tty.init(CombinedTerminal::new(self.fbconsole.get()));
devfs::add_char_device(self.tty.get(), CharDeviceType::TtyRegular).unwrap();
devfs::add_char_device(self.tty.get(), CharDeviceType::TtyRegular)?;
console::add_console_autoflush(self.fbconsole.get());
Ok(())
}
fn init_initrd(initrd_start: PhysicalAddress, initrd_end: PhysicalAddress) {

View File

@ -1,5 +1,7 @@
//! Facilities for mapping devices to virtual address space
use core::{marker::PhantomData, mem::size_of, ops::Deref, sync::atomic::AtomicUsize};
// TODO
#![allow(unused)]
use core::{mem::size_of, ops::Deref};
use abi::error::Error;
use alloc::sync::Arc;