https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=299090
Bug ID: 299090
Summary: loader.efi: hw.uart.console in loader.conf is replaced
by the SPCR value
Product: Base System
Version: 15.1-RELEASE
Hardware: Any
OS: Any
Status: New
Severity: Affects Some People
Priority: ---
Component: kern
Assignee: [email protected]
Reporter: [email protected]
Created attachment 275337
--> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=275337&action=edit
[PATCH] loader.efi: Don't replace a hw.uart.console set by the user
DESCRIPTION
When the firmware provides an ACPI SPCR table, a hw.uart.console line in
loader.conf has no effect. At the OK prompt, "show hw.uart.console" prints
the value derived from the SPCR, not the one from loader.conf.
check_acpi_spcr() sets hw.uart.console unconditionally. It is called from
parse_uefi_con_out(), which runs once in main() and again from
efi_console.c whenever the console mode is updated. loader.lua runs
efi-autoresizecons right after config.load(), so the order is:
1. main(): hw.uart.console = SPCR value
2. loader.conf: hw.uart.console = the user's value (setenv succeeds)
3. efi-autoresizecons -> parse_uefi_con_out() -> check_acpi_spcr():
hw.uart.console = SPCR value again
I confirmed step 2 by printing from config.lua's setEnv(): the user's value
is set and reads back, and it is gone by the time local.lua runs. Setting
the variable at the OK prompt works, because nothing runs the SPCR code
after that.
This leaves no persistent way to correct or override what the SPCR says,
for example when the table describes the UART wrongly or the user wants a
different port or speed.
Related: PR 292206, fixed by d82698ac68 ("loader.efi: Only use SPCR if
enabled"), was a case of the SPCR producing a bad hw.uart.console. Its
commit message notes "While one could unset this value to boot, you
couldn't do that automatically very easily." This is the same problem in
general: with this patch, loader.conf can correct whatever the SPCR says.
The attached patch skips the SPCR translation when hw.uart.console is
already set, as the x86 code in bootinfo.c already does ("if someone
specifically setup hw.uart.console, don't override that"). At the first
call nothing has set it yet, so the default behaviour doesn't change.
AFFECTED VERSIONS
main, stable/15 and releng/15.1. check_acpi_spcr() came in with
70253b538f68 ("loader.efi: Parse SPCR table entry in ACPI tables"), so 14.x
is not affected.
HOW TO REPEAT
On an EFI system whose firmware provides SPCR, put a hw.uart.console line
in /boot/loader.conf, stop at the OK prompt and run
"show hw.uart.console".
I used QEMU's riscv virt machine with its bundled EDK2 firmware, which
provides SPCR, and hw.uart.console="mm:0x10000000,rs:0,br:115200". That
table gives a 32-bit register stride for a byte-spaced UART (being reported
to QEMU), so the SPCR value can't boot the kernel and the loader.conf value
is needed.
TESTED
riscv64 15.1-RELEASE-p3 world, kernel with the uart_cpu_fdt.c NULL-tag fix
from PR 299089, hw.uart.console in loader.conf:
loader result
15.1-RELEASE-p3 loader.conf value replaced; kernel faults (rs:2)
with patch loader.conf value kept; boots to multi-user
Without a loader.conf setting the patched loader passes the SPCR value as
before. Not tested on arm64 or amd64.
ATTACHMENTS
0001-loader.efi-Don-t-replace-a-hw.uart.console-set-by-th.patch
against main ff2efe65a89a
--
You are receiving this mail because:
You are the assignee for the bug.