From: Michael Brown Date: Thu, 19 Jun 2025 11:57:28 +0000 (+0100) Subject: [uart] Add support for MMIO-accessible 16550 UARTs X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=71b4bfb6b2c68a9c07e7f3171721313203f2a432;p=thirdparty%2Fipxe.git [uart] Add support for MMIO-accessible 16550 UARTs 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 --- diff --git a/src/include/bits/ns16550.h b/src/include/bits/ns16550.h index 4b3e30c76..e40b2a21b 100644 --- a/src/include/bits/ns16550.h +++ b/src/include/bits/ns16550.h @@ -3,13 +3,40 @@ /** @file * - * Dummy architecture-specific 16550-compatible UART - * - * This file is included only if the architecture does not provide its - * own version of this file. + * 16550-compatible UART * */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +#include +#include + +/** + * Write to UART register + * + * @v ns16550 16550 UART + * @v address Register address + * @v data Data + */ +static inline __attribute__ (( always_inline )) void +ns16550_write ( struct ns16550_uart *ns16550, unsigned int address, + uint8_t data ) { + + writeb ( data, ( ns16550->base + ( address << ns16550->shift ) ) ); +} + +/** + * Read from UART register + * + * @v ns16550 16550 UART + * @v address Register address + * @ret data Data + */ +static inline __attribute__ (( always_inline )) uint8_t +ns16550_read ( struct ns16550_uart *ns16550, unsigned int address ) { + + return readb ( ns16550->base + ( address << ns16550->shift ) ); +} + #endif /* _BITS_NS16550_H */ diff --git a/src/include/ipxe/ns16550.h b/src/include/ipxe/ns16550.h index f7bb55a84..3aaab6891 100644 --- a/src/include/ipxe/ns16550.h +++ b/src/include/ipxe/ns16550.h @@ -82,6 +82,8 @@ struct ns16550_uart { struct uart uart; /** Register base address */ void *base; + /** Register shift */ + unsigned int shift; /** Baud rate divisor */ uint16_t divisor; };