Get ACPI RSDP from EFI tables if not provided in boot_params

This commit is contained in:
Zhang Junyang
2024-08-16 12:35:16 +08:00
committed by Tate, Hongliang Tian
parent 803f059493
commit 0c9b7c03bb

View File

@ -4,7 +4,11 @@ use linux_boot_params::BootParams;
use uefi::{ use uefi::{
data_types::Handle, data_types::Handle,
proto::loaded_image::LoadedImage, proto::loaded_image::LoadedImage,
table::{boot::MemoryMap, Boot, Runtime, SystemTable}, table::{
boot::MemoryMap,
cfg::{ACPI2_GUID, ACPI_GUID},
Boot, Runtime, SystemTable,
},
}; };
use super::{ use super::{
@ -24,29 +28,32 @@ extern "sysv64" fn efi_stub_entry(handle: Handle, mut system_table: SystemTable<
} }
uefi_services::init(&mut system_table).unwrap(); uefi_services::init(&mut system_table).unwrap();
let boot_params_ptr = todo!("Use EFI boot services to fill boot params"); let boot_params = todo!("Use EFI boot services to fill boot params");
efi_phase_boot(handle, system_table, boot_params_ptr); efi_phase_boot(handle, system_table, boot_params);
} }
#[export_name = "efi_handover_entry"] #[export_name = "efi_handover_entry"]
extern "sysv64" fn efi_handover_entry( extern "sysv64" fn efi_handover_entry(
handle: Handle, handle: Handle,
mut system_table: SystemTable<Boot>, mut system_table: SystemTable<Boot>,
boot_params: *mut BootParams, boot_params_ptr: *mut BootParams,
) -> ! { ) -> ! {
unsafe { unsafe {
system_table.boot_services().set_image_handle(handle); system_table.boot_services().set_image_handle(handle);
} }
uefi_services::init(&mut system_table).unwrap(); uefi_services::init(&mut system_table).unwrap();
// SAFETY: boot_params is a valid pointer.
let boot_params = unsafe { &mut *boot_params_ptr };
efi_phase_boot(handle, system_table, boot_params) efi_phase_boot(handle, system_table, boot_params)
} }
fn efi_phase_boot( fn efi_phase_boot(
handle: Handle, handle: Handle,
system_table: SystemTable<Boot>, system_table: SystemTable<Boot>,
boot_params_ptr: *mut BootParams, boot_params: &mut BootParams,
) -> ! { ) -> ! {
// SAFETY: this init function is only called once. // SAFETY: this init function is only called once.
unsafe { crate::console::init() }; unsafe { crate::console::init() };
@ -56,7 +63,13 @@ fn efi_phase_boot(
uefi_services::println!("[EFI stub] Relocations applied."); uefi_services::println!("[EFI stub] Relocations applied.");
let payload = unsafe { crate::get_payload(&*boot_params_ptr) }; // Fill the boot params with the RSDP address if it is not provided.
if boot_params.acpi_rsdp_addr == 0 {
boot_params.acpi_rsdp_addr = get_rsdp_addr(&system_table);
}
// Load the kernel payload to memory.
let payload = crate::get_payload(boot_params);
let kernel = decode_payload(payload); let kernel = decode_payload(payload);
uefi_services::println!("[EFI stub] Loading payload."); uefi_services::println!("[EFI stub] Loading payload.");
@ -72,13 +85,13 @@ fn efi_phase_boot(
}; };
let (system_table, memory_map) = system_table.exit_boot_services(memory_type); let (system_table, memory_map) = system_table.exit_boot_services(memory_type);
efi_phase_runtime(system_table, memory_map, boot_params_ptr); efi_phase_runtime(system_table, memory_map, boot_params);
} }
fn efi_phase_runtime( fn efi_phase_runtime(
_system_table: SystemTable<Runtime>, _system_table: SystemTable<Runtime>,
memory_map: MemoryMap<'static>, memory_map: MemoryMap<'static>,
boot_params_ptr: *mut BootParams, boot_params: &mut BootParams,
) -> ! { ) -> ! {
unsafe { unsafe {
crate::console::print_str("[EFI stub] Entered runtime services.\n"); crate::console::print_str("[EFI stub] Entered runtime services.\n");
@ -103,8 +116,6 @@ fn efi_phase_runtime(
} }
} }
let boot_params = unsafe { &mut *boot_params_ptr };
// Write memory map to e820 table in boot_params. // Write memory map to e820 table in boot_params.
let e820_table = &mut boot_params.e820_table; let e820_table = &mut boot_params.e820_table;
let mut e820_entries = 0usize; let mut e820_entries = 0usize;
@ -199,5 +210,24 @@ fn efi_phase_runtime(
print_str("\n"); print_str("\n");
} }
unsafe { super::call_aster_entrypoint(super::ASTER_ENTRY_POINT as u64, boot_params_ptr as u64) } unsafe {
super::call_aster_entrypoint(
super::ASTER_ENTRY_POINT as u64,
boot_params as *const _ as u64,
)
}
}
fn get_rsdp_addr(boot_table: &SystemTable<Boot>) -> u64 {
let config_table = boot_table.config_table();
for entry in config_table {
// Prefer ACPI2 over ACPI.
if entry.guid == ACPI2_GUID {
return entry.address as usize as u64;
}
if entry.guid == ACPI_GUID {
return entry.address as usize as u64;
}
}
panic!("ACPI RSDP not found");
} }