https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=299089
Bug ID: 299089
Summary: uart: hw.uart.console with an mm: address faults on
riscv and arm (NULL bus space tag)
Product: Base System
Version: 15.1-RELEASE
Hardware: riscv
OS: Any
Status: New
Severity: Affects Some People
Priority: ---
Component: kern
Assignee: [email protected]
Reporter: [email protected]
Created attachment 275336
--> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=275336&action=edit
[PATCH] uart: Set the bus space tag before parsing hw.uart.console
DESCRIPTION
On riscv and arm the console is found by uart_cpu_getdev() in
uart_cpu_fdt.c. It calls uart_getenv() first, so that hw.uart.console can
override the FDT. For an "mm:" address uart_getenv() maps the UART with
uart_bus_space_mem, but uart_cpu_fdt.c only assigns that variable at the
end of uart_cpu_getdev(), after the FDT probe. On the override path it is
still NULL and bus_space_map() dereferences it (uart_subr.c:324). This
happens while the console is being set up, so the kernel hangs with no
output.
arm64 doesn't have this problem because uart_cpu_arm64.c initialises
uart_bus_space_mem to &memmap_bus.
On 15.x riscv this is hit without any user setting when booting through
loader.efi on firmware that provides an ACPI SPCR table:
check_acpi_spcr() in the loader turns the SPCR into hw.uart.console.
The attached patch sets uart_bus_space_mem to fdtbus_bs_tag before calling
uart_getenv(). fdtbus_bs_tag is defined on both riscv and arm, but no
riscv header declares it, so the patch adds a file-scope extern, the way
riscv's ofw_machdep.c and nexus.c declare memmap_bus. (b1c2e02c10 removed
an earlier extern of fdtbus_bs_tag from this file when it stopped being
used.)
AFFECTED VERSIONS
main, stable/15, releng/15.1, stable/14 and releng/14.4. On 14.x the
loader doesn't set hw.uart.console from SPCR, so it only happens when the
variable is set by hand.
HOW TO REPEAT
On a riscv system, set hw.uart.console to the console UART's address at
the loader prompt and boot. For example, on a QEMU virt machine:
OK set hw.uart.console=mm:0x10000000,rs:0,rw:1,br:115200
OK boot
or boot QEMU's riscv virt machine through its bundled EDK2 firmware
(edk2-riscv64-code.fd) with ACPI enabled, which provides an SPCR table.
TESTED
15.1-RELEASE-p3, riscv64 GENERIC, booted through loader.efi:
kernel result
15.1-RELEASE-p3 hangs at the console probe (NULL tag)
with patch maps the UART from hw.uart.console
With hw.uart.console="mm:0x10000000,rs:0,rw:1,br:115200,xo:0" set at the
loader prompt, the patched kernel boots to multi-user with uart0 as
console. Not tested on arm or on riscv hardware.
Booting all the way from SPCR alone also needs the SPCR to describe the
UART correctly. QEMU's riscv virt table currently gives a 32-bit register
stride for a byte-spaced UART; that is being reported to QEMU. A related
loader bug, where hw.uart.console from loader.conf is overwritten by the
SPCR value, is filed separately.
ATTACHMENTS
0001-uart-Set-the-bus-space-tag-before-parsing-hw.uart.co.patch
against main ff2efe65a89a
--
You are receiving this mail because:
You are the assignee for the bug.