mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-18 12:06:43 +00:00
Get ACPI RSDP from EFI tables if not provided in boot_params
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
803f059493
commit
0c9b7c03bb
@ -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");
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user