Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ tools/unit-tests/unit-libwolfboot-extra
tools/unit-tests/unit-mock-state
tools/unit-tests/unit-nvm
tools/unit-tests/unit-nvm-flagshome
tools/unit-tests/unit-ns16550
tools/unit-tests/unit-parser
tools/unit-tests/unit-parser-large-header
tools/unit-tests/unit-pci
Expand Down
15 changes: 15 additions & 0 deletions arch.mk
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,10 @@ ifeq ($(ARCH),AARCH64)
endif

ifeq ($(TARGET),nxp_ls1028a)
# DUART console on the generic driver (plain MMIO on AArch64).
ifeq ($(DEBUG_UART),1)
OBJS+=hal/uart/ns16550.o
endif
ARCH_FLAGS=-mcpu=cortex-a72+crypto -march=armv8-a+crypto -mtune=cortex-a72
CFLAGS+=$(ARCH_FLAGS) -DCORTEX_A72
# ZynqMP RVBAR (0xFD5C0040) does not exist on LS1028A -- the store faults
Expand Down Expand Up @@ -1206,6 +1210,17 @@ ifeq ($(ARCH),PPC)
CFLAGS+=-fno-builtin-printf
endif

# QorIQ DUART console on the generic NS16550 driver. PowerPC MMIO needs
# get8()/set8() (sync/twi/isync, sync/eieio), not a plain volatile access.
# stage1 is size-constrained (P1021 gets 4KB total) and keeps its own
# copy, so the generic driver is only linked into the full loader.
ifeq ($(DEBUG_UART),1)
CFLAGS+=-DNS16550_IO_H='"nxp_ppc_io.h"'
ifneq ($(STAGE1),1)
OBJS+=hal/uart/ns16550.o
endif
endif

# Target-specific CPU flags
ifeq ($(TARGET),nxp_t2080)
CFLAGS+=-mcpu=e6500 -mno-altivec -mbss-plt
Expand Down
43 changes: 13 additions & 30 deletions hal/nxp_ls1028a.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,42 +43,25 @@
void hal_flash_init(void);

#ifdef DEBUG_UART
void uart_init(void)
{
/* calc divisor for UART
* example config values:
* clock_div, baud, base_clk 163 115200 400000000
* +0.5 to round up
*/
uint32_t div = (((SYS_CLK / 2.0) / (16 * BAUD_RATE)) + 0.5);
#include "ns16550.h"

while (!(UART_LSR(UART_SEL) & UART_LSR_TEMT));
static struct ns16550_dev uart_console;

/* set ier, fcr, mcr */
UART_IER(UART_SEL) = 0;
UART_FCR(UART_SEL) = (UART_FCR_TFR | UART_FCR_RFR | UART_FCR_FEN);

/* enable baud rate access (DLAB=1) - divisor latch access bit*/
UART_LCR(UART_SEL) = (UART_LCR_DLAB | UART_LCR_WLS);
/* set divisor */
UART_DLB(UART_SEL) = (div & 0xff);
UART_DMB(UART_SEL) = ((div>>8) & 0xff);
/* disable rate access (DLAB=0) */
UART_LCR(UART_SEL) = (UART_LCR_WLS);
void uart_init(void)
{
memset(&uart_console, 0, sizeof(uart_console));
uart_console.base = (uintptr_t)UART_BASE(UART_SEL);
uart_console.io_width = 1; /* byte-spaced registers */
/* Integer, not floating point: this is a bootloader. DUART is
* SYS_CLK/2. */
uart_console.clk_hz = (uint32_t)(SYS_CLK / 2);
uart_console.crlf = 1;
(void)ns16550_init(&uart_console, BAUD_RATE);
}

void uart_write(const char* buf, uint32_t sz)
{
uint32_t pos = 0;
while (sz-- > 0) {
char c = buf[pos++];
if (c == '\n') { /* handle CRLF */
while (!(UART_LSR(UART_SEL) & UART_LSR_THRE));
UART_THR(UART_SEL) = '\r';
}
while (!(UART_LSR(UART_SEL) & UART_LSR_THRE));
UART_THR(UART_SEL) = c;
}
(void)ns16550_write(&uart_console, buf, sz);
}
#endif /* DEBUG_UART */

Expand Down
27 changes: 5 additions & 22 deletions hal/nxp_ls1028a.h
Original file line number Diff line number Diff line change
Expand Up @@ -299,28 +299,11 @@
/* LS1028A PC16552D Dual UART */


#define UART_BASE(n) (0x21C0500 + (n * 100))

#define UART_RBR(n) *((volatile uint8_t*)(UART_BASE(n) + 0)) /* receiver buffer register */
#define UART_THR(n) *((volatile uint8_t*)(UART_BASE(n) + 0)) /* transmitter holding register */
#define UART_IER(n) *((volatile uint8_t*)(UART_BASE(n) + 1)) /* interrupt enable register */
#define UART_FCR(n) *((volatile uint8_t*)(UART_BASE(n) + 2)) /* FIFO control register */
#define UART_IIR(n) *((volatile uint8_t*)(UART_BASE(n) + 2)) /* interrupt ID register */
#define UART_LCR(n) *((volatile uint8_t*)(UART_BASE(n) + 3)) /* line control register */
#define UART_LSR(n) *((volatile uint8_t*)(UART_BASE(n) + 5)) /* line status register */
#define UART_SCR(n) *((volatile uint8_t*)(UART_BASE(n) + 7)) /* scratch register */

/* enabled when UART_LCR_DLAB set */
#define UART_DLB(n) *((volatile uint8_t*)(UART_BASE(n) + 0)) /* divisor least significant byte register */
#define UART_DMB(n) *((volatile uint8_t*)(UART_BASE(n) + 1)) /* divisor most significant byte register */

#define UART_FCR_TFR (0x04) /* Transmitter FIFO reset */
#define UART_FCR_RFR (0x02) /* Receiver FIFO reset */
#define UART_FCR_FEN (0x01) /* FIFO enable */
#define UART_LCR_DLAB (0x80) /* Divisor latch access bit */
#define UART_LCR_WLS (0x03) /* Word length select: 8-bits */
#define UART_LSR_TEMT (0x40) /* Transmitter empty */
#define UART_LSR_THRE (0x20) /* Transmitter holding register empty */
/* DUART_STRIDE, not decimal 100: the DUARTs are 0x100 apart. Latent only
* because UART_SEL is 0. */
#define UART_BASE(n) (0x21C0500 + ((n) * DUART_STRIDE))

/* Register layout and bit names live in include/ns16550.h. */

/* LS1028 XSPI Flex SPI Memory map - RM 18.7.2.1 */
#define XSPI_BASE (0x20C0000UL)
Expand Down
24 changes: 1 addition & 23 deletions hal/nxp_p1021.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,32 +154,10 @@
/* P1021 PC16552D Dual UART */
#define BAUD_RATE 115200
#define UART_SEL 0 /* select UART 0 or 1 */
#define UART_LCR_VAL (UART_LCR_WLS) /* data=8 bits, stop-1 bit, no parity */

#define UART_BASE(n) (CCSRBAR + 0x4500 + (n * 0x100))

#define UART_RBR(n) ((volatile uint8_t*)(UART_BASE(n) + 0)) /* receiver buffer register */
#define UART_THR(n) ((volatile uint8_t*)(UART_BASE(n) + 0)) /* transmitter holding register */
#define UART_IER(n) ((volatile uint8_t*)(UART_BASE(n) + 1)) /* interrupt enable register */
#define UART_IIR(n) ((volatile uint8_t*)(UART_BASE(n) + 2)) /* interrupt ID register */
#define UART_FCR(n) ((volatile uint8_t*)(UART_BASE(n) + 2)) /* FIFO control register */
#define UART_LCR(n) ((volatile uint8_t*)(UART_BASE(n) + 3)) /* line control register */
#define UART_MCR(n) ((volatile uint8_t*)(UART_BASE(n) + 4)) /* modem control register */
#define UART_LSR(n) ((volatile uint8_t*)(UART_BASE(n) + 5)) /* line status register */

/* enabled when UART_LCR_DLAB set */
#define UART_DLB(n) ((volatile uint8_t*)(UART_BASE(n) + 0)) /* divisor least significant byte register */
#define UART_DMB(n) ((volatile uint8_t*)(UART_BASE(n) + 1)) /* divisor most significant byte register */

#define UART_FCR_TFR (0x04) /* Transmitter FIFO reset */
#define UART_FCR_RFR (0x02) /* Receiver FIFO reset */
#define UART_FCR_FEN (0x01) /* FIFO enable */
#define UART_LCR_DLAB (0x80) /* Divisor latch access bit */
#define UART_LCR_WLS (0x03) /* Word length select: 8-bits */
#define UART_LSR_TEMT (0x40) /* Transmitter empty */
#define UART_LSR_THRE (0x20) /* Transmitter holding register empty */

/* P1021 eLBC (Enhanced Local Bus Controller) - RM 12.3 */
/* Register layout and bit names live in include/ns16550.h. */
#define ELBC_BASE (CCSRBAR + 0x5000UL)
#define ELBC_MAX_BANKS 8
#define ELBC_BANK_SZ 8192
Expand Down
85 changes: 62 additions & 23 deletions hal/nxp_ppc.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,43 +67,82 @@ static void RAMFUNCTION udelay(uint32_t delay_us)
}
#endif /* CORE_E5500 || CORE_E6500 */

/* ---- Shared PC16552D-compatible DUART driver ----
* Each target must define before including this file:
* UART_SEL, BAUD_RATE, UART_THR(n), UART_IER(n), UART_FCR(n),
* UART_LCR(n), UART_DLB(n), UART_DMB(n), UART_LSR(n),
* UART_FCR_TFR, UART_FCR_RFR, UART_FCR_FEN,
* UART_LCR_DLAB, UART_LCR_WLS, UART_LSR_TEMT, UART_LSR_THRE */
/* ---- PC16552D DUART console ----
* Each target defines UART_BASE(n), UART_SEL and BAUD_RATE. The full loader
* uses hal/uart/ns16550.c with get8()/set8() kept as the accessors via
* NS16550_IO_H, so MMIO ordering is unchanged. stage1 keeps a specialised
* copy: P1021 gives it 4KB of flash in total and the generic driver does
* not fit. */
#ifdef DEBUG_UART
#ifndef BUILD_LOADER_STAGE1

#include "ns16550.h"

static struct ns16550_dev uart_console;

/* The bus clock is only known once the PLLs have been read. */
uint32_t ns16550_hal_clk_hz(void)
{
return (uint32_t)hal_get_bus_clk();
}

void uart_init(void)
{
/* baud rate = bus_clk / (16 * div); round up */
uint32_t div = (hal_get_bus_clk() + (8 * BAUD_RATE)) / (16 * BAUD_RATE);
/* Every field is set explicitly rather than memset first: this file is
* included as source by four HALs and not all of them pull in string.h. */
uart_console.base = (uintptr_t)UART_BASE(UART_SEL);
uart_console.reg_shift = 0; /* byte-spaced registers */
uart_console.reg_off = 0;
uart_console.clk_hz = 0; /* ask ns16550_hal_clk_hz() */
uart_console.io_width = 1;
uart_console.crlf = 1; /* console duty */
(void)ns16550_init(&uart_console, BAUD_RATE);
}

while (!(get8(UART_LSR(UART_SEL)) & UART_LSR_TEMT))
;
void uart_write(const char* buf, uint32_t sz)
{
(void)ns16550_write(&uart_console, buf, sz);
}

#else /* BUILD_LOADER_STAGE1 */

set8(UART_IER(UART_SEL), 0);
set8(UART_FCR(UART_SEL), (UART_FCR_TFR | UART_FCR_RFR | UART_FCR_FEN));
/* Minimal driver for the size-constrained first stage. */
#define S1_UART(off) ((volatile unsigned char*)(UART_BASE(UART_SEL) + (off)))
#define S1_THR S1_UART(0)
#define S1_IER S1_UART(1)
#define S1_FCR S1_UART(2)
#define S1_LCR S1_UART(3)
#define S1_LSR S1_UART(5)
#define S1_DLL S1_UART(0)
#define S1_DLM S1_UART(1)

/* enable baud rate access (DLAB=1) */
set8(UART_LCR(UART_SEL), (UART_LCR_DLAB | UART_LCR_WLS));
set8(UART_DLB(UART_SEL), (div & 0xff));
set8(UART_DMB(UART_SEL), ((div >> 8) & 0xff));
/* disable baud rate access (DLAB=0) */
set8(UART_LCR(UART_SEL), (UART_LCR_WLS));
void uart_init(void)
{
uint32_t div = (hal_get_bus_clk() + (8 * BAUD_RATE)) / (16 * BAUD_RATE);

while (!(get8(S1_LSR) & 0x40))
;
set8(S1_IER, 0);
set8(S1_FCR, 0x07); /* FIFO enable + RX/TX reset */
set8(S1_LCR, 0x83); /* DLAB | 8 data bits */
set8(S1_DLL, (div & 0xff));
set8(S1_DLM, ((div >> 8) & 0xff));
set8(S1_LCR, 0x03); /* 8 data bits, DLAB clear */
}

void uart_write(const char* buf, uint32_t sz)
{
uint32_t pos = 0;
while (sz-- > 0) {
char c = buf[pos++];
if (c == '\n') { /* handle CRLF */
while ((get8(UART_LSR(UART_SEL)) & UART_LSR_THRE) == 0);
set8(UART_THR(UART_SEL), '\r');
if (c == '\n') {
while ((get8(S1_LSR) & 0x20) == 0);
set8(S1_THR, '\r');
}
while ((get8(UART_LSR(UART_SEL)) & UART_LSR_THRE) == 0);
set8(UART_THR(UART_SEL), c);
while ((get8(S1_LSR) & 0x20) == 0);
set8(S1_THR, c);
}
}

#endif /* !BUILD_LOADER_STAGE1 */
#endif /* DEBUG_UART */
24 changes: 1 addition & 23 deletions hal/nxp_t10xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -457,29 +457,7 @@ static void hal_flash_unlock_sector(uint32_t sector);

#define UART_BASE(n) (CCSRBAR + 0x11C500 + (n * 0x1000))

#define UART_RBR(n) ((volatile uint8_t*)(UART_BASE(n) + 0)) /* receiver buffer register */
#define UART_THR(n) ((volatile uint8_t*)(UART_BASE(n) + 0)) /* transmitter holding register */
#define UART_IER(n) ((volatile uint8_t*)(UART_BASE(n) + 1)) /* interrupt enable register */
#define UART_IIR(n) ((volatile uint8_t*)(UART_BASE(n) + 2)) /* interrupt ID register */
#define UART_FCR(n) ((volatile uint8_t*)(UART_BASE(n) + 2)) /* FIFO control register */
#define UART_LCR(n) ((volatile uint8_t*)(UART_BASE(n) + 3)) /* line control register */
#define UART_MCR(n) ((volatile uint8_t*)(UART_BASE(n) + 4)) /* modem control register */
#define UART_LSR(n) ((volatile uint8_t*)(UART_BASE(n) + 5)) /* line status register */

/* enabled when UART_LCR_DLAB set */
#define UART_DLB(n) ((volatile uint8_t*)(UART_BASE(n) + 0)) /* divisor least significant byte register */
#define UART_DMB(n) ((volatile uint8_t*)(UART_BASE(n) + 1)) /* divisor most significant byte register */

#define UART_FCR_TFR (0x04) /* Transmitter FIFO reset */
#define UART_FCR_RFR (0x02) /* Receiver FIFO reset */
#define UART_FCR_FEN (0x01) /* FIFO enable */
#define UART_LCR_DLAB (0x80) /* Divisor latch access bit */
#define UART_LCR_WLS (0x03) /* Word length select: 8-bits */
#define UART_LSR_TEMT (0x40) /* Transmitter empty */
#define UART_LSR_THRE (0x20) /* Transmitter holding register empty */


/* T1024 IFC (Integrated Flash Controller) - RM 23.1 */
/* Register layout and bit names live in include/ns16550.h. */
#define IFC_BASE (CCSRBAR + 0x00124000)
#define IFC_MAX_BANKS 8

Expand Down
14 changes: 10 additions & 4 deletions hal/nxp_t2080.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
#include "image.h" /* for RAMFUNCTION */
#include "nxp_ppc.h"
#include "nxp_t2080.h"
/* Register names for the DUART MCR poke in hal_flash_cache_disable_pre_os();
* nxp_ppc.c pulls this in too, but only when DEBUG_UART is set. */
#include "ns16550.h"

#define ENABLE_IFC
#define ENABLE_BUS_CLK_CALC
Expand Down Expand Up @@ -1701,17 +1704,20 @@ void hal_prepare_boot(void)
*
* Also aligns small but observable pre-jump state items to CW U-Boot's
* profile when chasing VxWorks 7 64-bit silent boot:
* - DUART1 MCR = 3 (DTR+RTS asserted; U-Boot sets this, our driver
* leaves it at the post-reset 0)
* - DUART1 MCR = 3 (DTR+RTS asserted, as U-Boot leaves it). The shared
* NS16550 driver already does this in ns16550_init(),
* but only when DEBUG_UART builds the console in, so
* the poke below still covers a console-less build.
* - TCR = 0 (matches CW U-Boot's pre-bootm value; a nonzero WRC would let
* the watchdog fire silently after VxWorks starts) */
void RAMFUNCTION hal_flash_cache_disable_pre_os(void)
{
hal_flash_cache_disable();
#ifdef ENABLE_OS64BIT
/* DUART1 modem control: DTR+RTS asserted, matching CW U-Boot's
* pre-bootm value. */
set8(UART_MCR(0), 0x03);
* pre-bootm value, which VxWorks 7 inherits. */
set8((volatile unsigned char*)(UART_BASE(0) + NS16550_MCR),
NS16550_MCR_DTR | NS16550_MCR_RTS);
/* TCR=0 matches CW U-Boot's pre-bootm value. WRC != 0 would let
* the watchdog fire silently after VxWorks starts. */
mtspr(SPRN_TCR, 0);
Expand Down
24 changes: 1 addition & 23 deletions hal/nxp_t2080.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,29 +52,7 @@

#define UART_BASE(n) (CCSRBAR + 0x11C500 + (n * 0x1000))

#define UART_RBR(n) ((volatile uint8_t*)(UART_BASE(n) + 0)) /* receiver buffer register */
#define UART_THR(n) ((volatile uint8_t*)(UART_BASE(n) + 0)) /* transmitter holding register */
#define UART_IER(n) ((volatile uint8_t*)(UART_BASE(n) + 1)) /* interrupt enable register */
#define UART_IIR(n) ((volatile uint8_t*)(UART_BASE(n) + 2)) /* interrupt ID register */
#define UART_FCR(n) ((volatile uint8_t*)(UART_BASE(n) + 2)) /* FIFO control register */
#define UART_LCR(n) ((volatile uint8_t*)(UART_BASE(n) + 3)) /* line control register */
#define UART_MCR(n) ((volatile uint8_t*)(UART_BASE(n) + 4)) /* modem control register */
#define UART_LSR(n) ((volatile uint8_t*)(UART_BASE(n) + 5)) /* line status register */

/* enabled when UART_LCR_DLAB set */
#define UART_DLB(n) ((volatile uint8_t*)(UART_BASE(n) + 0)) /* divisor least significant byte register */
#define UART_DMB(n) ((volatile uint8_t*)(UART_BASE(n) + 1)) /* divisor most significant byte register */

#define UART_FCR_TFR (0x04) /* Transmitter FIFO reset */
#define UART_FCR_RFR (0x02) /* Receiver FIFO reset */
#define UART_FCR_FEN (0x01) /* FIFO enable */
#define UART_LCR_DLAB (0x80) /* Divisor latch access bit */
#define UART_LCR_WLS (0x03) /* Word length select: 8-bits */
#define UART_LSR_TEMT (0x40) /* Transmitter empty */
#define UART_LSR_THRE (0x20) /* Transmitter holding register empty */


/* ---- IFC (Integrated Flash Controller) - T2080RM 13.3 ---- */
/* Register layout and bit names live in include/ns16550.h. */
#define IFC_BASE (CCSRBAR + 0x00124000)
#define IFC_MAX_BANKS 8

Expand Down
Loading
Loading