Each board has one serial line that is its console, the lowest common denominator beside the screen and keyboard. Its address was QEMU's, fixed: on a Raspberry Pi 5 the aarch64 one is ordinary RAM, written to with every character printed; on a Milk-V Mars the riscv64 one is the board's UART with registers four bytes apart, and the UEFI loader would have waited for ever on its first character; on a PC with no COM1 the prompt read 0xFF for ever. console_attach_serial(), called before anything prints: COM1 if a UART answers there; elsewhere the UART that /chosen/stdout-path names (fdt_uart.c: alias, path, the address carried up through each bus's ranges, reg-shift and reg-io-width); with no devicetree, QEMU's. A devicetree that names no usable console gives no line, not a guess. A line that does not come ready is given up, not waited on. The riscv64 loader's early serial does the same. tools/fdt_uart_test.c, run by hand, 19 checks plain and under the sanitizers: devicetrees shaped like the Mars's, the Pi 5's and QEMU's, what must find nothing, and a block cut short at every length; and the Pi 5's real devicetree gives a PL011 at 0x107d001000. Acceptance, one QEMU at a time: v3 on amd64 (logs/20261013-204436), aarch64 (-204803) and riscv64 (-205001) to the zuse prompt, no unknown word, hash 0x08873e0f44b7cb2a on all three as before. -204600 is an aarch64 run during which the disk images were restored under it by a script that had been refused a second QEMU; it passed and is kept, and was run again. v4 on the three ISAs (-211149, -211444, -211857): POST 538 of 538, dict_hash 0xe5a57f3eb72ff94a, the typed session unchanged. The Mars image through OpenSBI and U-Boot in QEMU took its line and its interrupt controller from the devicetree and passed POST. Found on the way and not mended (boards/BRINGUP.md 1.6): built with EMERGENCY_CONSOLE_ENABLED=1 the prompt floods with empty lines. -210442 shows it; the commit before this does the same. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
52 lines
1.9 KiB
C
52 lines
1.9 KiB
C
/*
|
||
StarForth — Steady-State Virtual Machine Runtime
|
||
Copyright (c) 2023–2025 Robert A. James. All rights reserved.
|
||
Licensed under the StarForth License, Version 1.0.
|
||
*/
|
||
|
||
/**
|
||
* fdt_uart.h - the console's serial line, as a board's devicetree names it.
|
||
*
|
||
* A board has one serial line that is its console, and its devicetree says
|
||
* which: /chosen/stdout-path, either the path of a node or an alias for one
|
||
* (/aliases), with line settings after a colon that are not used here. The
|
||
* firmware that handed the devicetree over has already set that line up.
|
||
* This finds what kind of UART it is, where it is as the CPU addresses it,
|
||
* and how its registers are laid out.
|
||
*
|
||
* Nothing is guessed. If the devicetree does not name a console, or names
|
||
* one this cannot place or has no driver for, there is no line.
|
||
*
|
||
* Verified off the boards by tools/fdt_uart_test.c.
|
||
*/
|
||
#ifndef STARKERNEL_FDT_UART_H
|
||
#define STARKERNEL_FDT_UART_H
|
||
|
||
#include <stdint.h>
|
||
|
||
enum
|
||
{
|
||
FDT_UART_NONE = 0, /**< no line */
|
||
FDT_UART_PL011, /**< ARM PL011: 32-bit registers, four bytes apart */
|
||
FDT_UART_16550 /**< 16550 and its kin (ns16550a, snps,dw-apb-uart), by memory */
|
||
};
|
||
|
||
typedef struct
|
||
{
|
||
int kind; /**< FDT_UART_* */
|
||
uint64_t base; /**< address of register 0, as the CPU sees it */
|
||
uint32_t reg_shift; /**< register n is at base + (n << reg_shift) */
|
||
uint32_t io_width; /**< bytes read or written at a time: 1 or 4 */
|
||
} fdt_uart_t;
|
||
|
||
/**
|
||
* @brief Find the console's serial line in a devicetree.
|
||
* @param fdt Blob; NULL and what is not a devicetree are safe.
|
||
* @param out Receives the line; its kind is FDT_UART_NONE when 0 is returned.
|
||
* @return 1 if the devicetree names a console UART that was found, placed
|
||
* and is of a kind listed above; 0 otherwise.
|
||
*/
|
||
int fdt_console_uart(const void* fdt, fdt_uart_t* out);
|
||
|
||
#endif /* STARKERNEL_FDT_UART_H */
|