We currently have contexts in which the local variable "nic" is a
pointer to the global variable also called "nic". This complicates
the creation of macros.
Rename the global variable to "legacy_nic" to reduce pollution of the
global namespace and to allow for the creation of macros referring to
fields within this global variable.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add support for probing a device based on the path or alias found in
the "/chosen/stdout-path" node, and using a consequently instantiated
UART as the default serial console.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The 16550 design includes a programmable 16-bit clock divider for an
arbitrary input clock, requiring knowledge of the input clock
frequency in order to calculate the divider value for a given baud
rate. The 16550 UARTs in an x86 PC will always have a 1.8432 MHz
input clock. Non-x86 systems may have other input clock frequencies.
Define the input clock frequency as a property of a 16550 UART, and
read the value from the device tree "clock-frequency" property.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some implementations of 16550-compatible UARTs (e.g. the DesignWare
UART) are known to ignore writes to the line control register while
the transmitter is active.
Wait for the transmitter to become empty before attempting to write to
the line control register.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow the platform configuration to provide a mechanism for
identifying the serial console UART. Provide two globally available
mechanisms: "null" (i.e. no serial console), and "fixed" (i.e. use
whatever is specified by COMCONSOLE in config/serial.h).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When a native serial driver is enabled for the system console device
specified via "/chosen/stdout-path", it is very likely that this will
correspond to the same physical serial port used for the SBI debug
console.
Inhibit input and output via the SBI console whenever a serial console
is active, to avoid duplicated output characters and unpredictable
input behaviour.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
iPXE drivers have been written with the implicit assumption that MMIO
writes are allowed to be posted but that an MMIO register read or
write after another MMIO register write will always observe the
effects of the first write.
For example: after having written a byte to the transmit holding
register (THR) of a 16550 UART, it is expected that any subsequent
read of the line status register (LSR) will observe a value consistent
with the occurrence of the write.
RISC-V does not seem to provide any ordering guarantees between
accesses to different registers within the same MMIO device. Add
fences as part of the MMIO accessors to provide the assumed
guarantees.
Use "fence io, io" before each MMIO read or write to enforce full
serialisation of MMIO accesses with respect to each other. This is
almost certainly more conservative than is strictly necessary.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Use the generic UART driver-private data pointer, rather than
embedding the generic UART within the 16550 UART structure.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
16550 UARTs exist on non-x86 platforms but will be accessible via MMIO
rather than port I/O. It is possible to encounter MMIO-mapped 16550
UARTs on x86 platforms, but there is no real requirement to support
them in iPXE since the standard COM1, COM2, etc ports have been
present on every PC-compatible machine since 1981.
Assume for now that accessing 16550 UART registers requires
inb()/outb() on x86 and readb()/writeb() on other architectures.
Allow for the existence of a register shift on MMIO-mapped 16550
UARTs, since modern SoCs tend to treat register addresses as being
aligned to either 32-bit or 64-bit boundaries.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Remove the assumption that all platforms use a fixed number of 16550
UARTs identifiable by a simple numeric index. Create an abstraction
allowing for dynamic instantiation and registration of any number of
arbitrary UART models.
The common case of the serial console on x86 uses a single fixed UART
specified at compile time. Avoid unnecessarily dragging in the
dynamic instantiation code in this use case by allowing COMCONSOLE to
refer to a single static UART object representing the relevant port.
When selecting a UART by command-line argument (as used in the
"gdbstub serial <port>" command), allow the UART to be specified as
either a numeric index (to retain backwards compatiblity) or a
case-insensitive port name such as "COM2".
Signed-off-by: Michael Brown <mcb30@ipxe.org>
In the context of serial consoles, the use of any frame formats other
than the standard 8 data bits, no parity, and one stop bit is so rare
as to be nonexistent.
Remove the almost certainly unused support for custom frame formats.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The early UART is an optional feature used to obtain debug output from
the prefix before iPXE is able to parse the device tree.
Extend this feature to also cover any console output that iPXE
attempts to send to the SBI console, on the basis that the purpose of
the early UART is to provide an output-only device for situations in
which there is no functional SBI console.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The RISC-V "fence" instruction encoding includes bits for predecessor
and successor input and output operations, separate from read and
write operations. It is up to the CPU implementation to decide what
counts as I/O space rather than memory space for the purposes of this
instruction.
Since we do not expect fencing to be performance-critical, keep
everything as simple and reliable as possible by using the unadorned
"fence" instruction (equivalent to "fence iorw, iorw").
Add a memory clobber to ensure that the compiler does not reorder the
barrier. (The volatile qualifier seems to already prevent reordering
in practice, but this is not guaranteed according to the compiler
documentation.)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Non-permitted name characters such as a colon are sometimes used to
separate alias names or paths from additional metadata, such as the
baud rate for a UART in the "/chosen/stdout-path" property.
Support the use of such alias names and paths by allowing any
character not permitted in a property name to terminate a property or
node name match. (This is a very relaxed matching rule that will
produce false positive matches on invalid input, but this is unlikely
to cause problems in practice.)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Devices with only 32-bit DMA addressing are relatively common even on
systems with 64-bit CPUs. Limit relocation of iPXE to 32-bit address
space so that I/O buffers and other DMA allocations will be accessible
by 32-bit devices.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
We will want to be able to create the console device as early as
possible. Refactor devicetree probing to remove the assumption that a
devicetree device must have a devicetree parent, and expose functions
to allow a standalone device to be created given only the offset of a
node within the tree.
The full device path is no longer trivial to construct with this
assumption removed. The full path is currently used only for debug
messages. Remove the stored full path, use just the node name for
debug messages, and ensure that the topology information previously
visible in the full path is reconstructible from the combined debug
output if needed.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add support for RFC 3442 classless static routes provided via DHCP
option 121.
Originally-implemented-by: Hazel Smith <hazel.smith@leicester.ac.uk>
Originally-implemented-by: Raphael Pour <raphael.pour@hetzner.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Extend the definition of an IPv4 routing table entry to allow for the
expression of non-default gateways for specified off-link subnets, and
of on-link secondary subnets (where we can send directly to the
destination address even though our source address is not within the
subnet).
This more precise definition also allows us to correctly handle
routing in the (uncommon for iPXE) case when multiple network
interfaces are open concurrently and more than one interface has a
default gateway.
The common case of a single IPv4 address/netmask and a default gateway
now results in two routing table entries. To retain backwards
compatibility with existing documentation (and to avoid on-screen
clutter), the "route" command prints default gateways on the same line
as the locally assigned address. There is therefore no change in
output from the "route" command unless explicit additional (off-link
or on-link) routes are present.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Xuantie/T-Head processors such as the C910 (as used in the Sipeed
Lichee Pi 4A) use the high bits of the PTE in a very non-standard way
that is incompatible with the RISC-V specification.
As per the "Memory Attribute Extension (XTheadMae)", bits 62 and 61
represent cacheability and "bufferability" (write-back cacheability)
respectively. If we do not enable these bits, then the processor gets
incredibly confused at the point that paging is enabled. The symptom
is that cache lines will occasionally fail to fill, and so reads from
any address may return unrelated data from a previously read cache
line for a different address.
Work around these hardware flaws by detecting T-Head CPUs (via the
"get machine vendor ID" SBI call), then reading the vendor-specific
SXSTATUS register to determine whether or not the vendor-specific
Memory Attribute Extension has been enabled by the M-mode firmware.
If it has, then set bits 61 and 62 in each page table entry that is
used to access normal memory.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add a fence between the write to the UART transmit register and the
subsequent read from the transmit status register, to ensure that the
status correctly reflects the occurrence of the write.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The RISC-V specification states that "if SATP is written with an
unsupported mode, the entire write has no effect; no fields in SATP
are modified". We currently rely on this specified behaviour when
calculating the early UART base address: if SATP has a non-zero value
then we assume that paging must be enabled.
The XuanTie C910 CPU (as used in the Lichee Pi 4A) does not conform to
this specified behaviour. Writing SATP with an unsupported mode will
leave SATP.MODE as zero (i.e. bare physical addressing) but the write
to SATP.PPN will still take effect, leaving SATP with an illegal
non-zero value.
Work around this misbehaviour by explicitly writing zero to SATP if we
detect that the mode change has not taken effect (e.g. because the CPU
does not support the requested paging mode).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
We currently rely on the recursive nature of devicetree bus probing to
obtain the region cell size specification from the parent device.
This blocks the possibility of creating a standalone console device
based on /chosen/stdout-path before probing the whole bus.
Fix by using fdt_parent() to locate the parent device at the point of
use within dt_ioremap().
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some platforms (such as the Sipeed Lichee Pi 4A) choose to make early
debugging entertainingly cumbersome for the programmer. These
platforms not only fail to provide a functional SBI debug console, but
also choose to place the UART at a physical address that cannot be
identity-mapped under the only paging model supported by the CPU.
Support such platforms by creating a virtual address mapping for the
early UART (in the 2MB megapage immediately below iPXE itself), and
using this as the UART base address whenever paging is enabled.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some platforms (such as the Sipeed Lichee Pi 4A) do not provide a
functional SBI debug console. We can obtain early debug messages on
these systems by writing directly to the UART used by the vendor
firmware.
There is no viable way to parse the UART address from the device tree,
since the prefix debug messages occur extremely early, before the C
runtime environment is available and therefore before any information
has been parsed from the device tree. The early UART model and
register addresses must be configured by editing config/serial.h if
needed. (This is an acceptable limitation, since prefix debugging is
an extremely specialised use case.)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Abstract out the SBI debug console calls into macros that can be
shared between print_message and print_hex_value.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The riscv,isa devicetree property appears not to be fully populated on
some real-world systems. For example, the Sipeed Lichee Pi 4A
(running the vendor U-Boot) reports itself as "rv64imafdcvsu", which
does not include the "zicntr" extension even though the time CSR is
present and functional.
Ignore the riscv,isa property and rely solely on CSR testing to
determine whether or not extensions are present.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
With the 64-bit paging schemes (Sv39, Sv48, and Sv57), we identity-map
as much of the physical address space as is possible. Experimentation
shows that this is not sufficient to provide access to all I/O
devices. For example: the Sipeed Lichee Pi 4A includes a CPU that
supports only Sv39, but places I/O devices at the top of a 40-bit
address space.
Add support for creating I/O page table entries on demand to map I/O
devices, based on the existing design used for x86_64 BIOS.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Support debug consoles that do not automatically convert LF to CRLF by
including the CR character within the debug message strings.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Provide DBGC_MEMMAP() as a replacement for memmap_dump(), allowing the
colour used to match other messages within the same message group.
Retain a dedicated colour for output from memmap_dump_all(), on the
basis that it is generally most useful to visually compare full memory
dumps against previous full memory dumps.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Use the terminology "min" and "max" for addresses covered by a memory
region descriptor, since this is sufficiently intuitive to generally
not require further explanation.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Use the shared initrd reshuffling and CPIO header construction code
for RISC-V bare-metal kernels. This allows for files to be injected
into the constructed ("magic") initrd image in exactly the same way as
is done for bzImage and UEFI kernels.
We append a dummy image encompassing the FDT to the end of the
reshuffle list, so that it ends up directly following the constructed
initrd in memory (but excluded from the initrd length, which was
recorded before constructing the FDT).
We also temporarily prepend the kernel binary itself to the reshuffle
list. This is guaranteed to be safe (since reshuffling is designed to
be unable to fail), and avoids the requirement for the kernel segment
to be available before reshuffling. This is useful since current
RISC-V bare-metal kernels tend to be distributed as EFI zboot images,
which require large temporary allocations from the external heap for
the intermediate images created during archive extraction.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Any initrd images that are not within the external heap (e.g. embedded
images) do not need to be copied to the external heap for reshuffling,
and can just be left in their original locations.
Ignore any images that are not already within the external heap (or,
more precisely, that are wholly outside of the reshuffle region within
the external heap) when squashing and swapping images.
This reduces the maximum additional storage required by squashing and
swapping to zero, and so ensures that the reshuffling step is
guaranteed to succeed under all circumstances. (This is unrelated to
the post-reshuffle load region check, which is still required.)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Provide a reusable function initrd_load_all() to load all initrds
(including any constructed CPIO headers) into a contiguous memory
region, and support functions to find the constructed total length and
permissible post-reshuffling load address range.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
It is hypothetically possible for external heap memory allocated
during driver startup to have been freed before an image was
downloaded, which could therefore leave an image straddling the
address recorded as the top of the reshuffle region.
Allow for this possibility by skipping squashing for any images
already straddling (or touching) the top of the reshuffle region.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Alignment of initrd lengths is applicable to all Linux kernels, not
just those in the x86 bzImage format.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Eliminate the requirement for free space when reshuffling initrds by
swapping adjacent initrds using an in-place triple reversal.
Signed-off-by: Michael Brown <mcb30@ipxe.org>