mirror of
https://github.com/systemd/systemd.git
synced 2024-11-27 04:03:36 +08:00
acpi-fpdt: Use kernel fpdt parsing
On some kernels/distros (RHEL/aarch64) /dev/mem is turned off. This means that the ACPI FPDT data is missing from systemd-analyze output when /dev/mem fails to provide the boot times. Instead recent kernels can export that data from /sys/firmware/acpi/fpdt/boot/ entries. Use that information if available first. Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
This commit is contained in:
parent
09cd639a59
commit
bc09c2d865
4
TODO
4
TODO
@ -115,6 +115,10 @@ Deprecations and removals:
|
||||
|
||||
* H2 2023: remove support for unmerged-usr
|
||||
|
||||
* Remove /dev/mem ACPI FPDT parsing when /sys/firmware/acpi/fpdt is ubiquitous.
|
||||
That requires distros to enable CONFIG_ACPI_FPDT, and have kernels v5.12 for
|
||||
x86 and v6.2 for arm.
|
||||
|
||||
Features:
|
||||
|
||||
* sd-boot: add a new PE section .bls or so that carries a cpio with additional
|
||||
|
@ -61,6 +61,37 @@ struct acpi_fpdt_boot {
|
||||
uint64_t exit_services_exit;
|
||||
} _packed;
|
||||
|
||||
/* /dev/mem is deprecated on many systems, try using /sys/firmware/acpi/fpdt parsing instead.
|
||||
* This code requires kernel version 5.12 on x86 based machines or 6.2 for arm64 */
|
||||
static int acpi_get_boot_usec_kernel_parsed(usec_t *ret_loader_start, usec_t *ret_loader_exit) {
|
||||
usec_t start, end;
|
||||
int r;
|
||||
|
||||
r = read_timestamp_file("/sys/firmware/acpi/fpdt/boot/exitbootservice_end_ns", &end);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (end == 0)
|
||||
/* Non-UEFI compatible boot. */
|
||||
return -ENODATA;
|
||||
|
||||
r = read_timestamp_file("/sys/firmware/acpi/fpdt/boot/bootloader_launch_ns", &start);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (start == 0 || end < start)
|
||||
return -EINVAL;
|
||||
if (end > NSEC_PER_HOUR)
|
||||
return -EINVAL;
|
||||
|
||||
if (ret_loader_start)
|
||||
*ret_loader_start = start / 1000;
|
||||
if (ret_loader_exit)
|
||||
*ret_loader_exit = end / 1000;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int acpi_get_boot_usec(usec_t *ret_loader_start, usec_t *ret_loader_exit) {
|
||||
_cleanup_free_ char *buf = NULL;
|
||||
struct acpi_table_header *tbl;
|
||||
@ -73,6 +104,10 @@ int acpi_get_boot_usec(usec_t *ret_loader_start, usec_t *ret_loader_exit) {
|
||||
struct acpi_fpdt_boot_header hbrec;
|
||||
struct acpi_fpdt_boot brec;
|
||||
|
||||
r = acpi_get_boot_usec_kernel_parsed(ret_loader_start, ret_loader_exit);
|
||||
if (r != -ENOENT) /* fallback to /dev/mem hack only if kernel doesn't support the new sysfs files */
|
||||
return r;
|
||||
|
||||
r = read_full_virtual_file("/sys/firmware/acpi/tables/FPDT", &buf, &l);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
Loading…
Reference in New Issue
Block a user