Files
LithosAnanake/kernel/include/starkernel/fdt_uart.h
T
rajamesandClaude Opus 5.5 c95191736e fix(console): the serial line is found, not assumed -- from the devicetree on a board, COM1 by probe on a PC
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>
2026-10-13 21:21:32 -04:00

52 lines
1.9 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
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 */