From 2eac660ff68a805cfcb02ca108b1e6cdac0f7d4e Mon Sep 17 00:00:00 2001 From: qinwei1 Date: Wed, 26 Apr 2023 09:36:15 +0800 Subject: [PATCH] arm64: Updating ARCH_EARLY_PRINT support Summary: Keeping this option out of depend on any common serial. Using the option, need to implement xxx_lowputc.S/c. You can also logging the booting message through rewriting fake arm64_lowputc with other debug method (eg semihosting, ARM debug channel etc). Signed-off-by: qinwei1 --- arch/arm64/Kconfig | 11 +++-- arch/arm64/src/a64/Make.defs | 2 + arch/arm64/src/a64/a64_lowputc.S | 9 ++++ arch/arm64/src/a64/a64_serial.c | 46 ++++--------------- arch/arm64/src/common/arm64_head.S | 2 +- arch/arm64/src/common/arm64_internal.h | 2 - arch/arm64/src/fvp-v8r/Kconfig | 1 - arch/arm64/src/fvp-v8r/Make.defs | 5 +- arch/arm64/src/fvp-v8r/fvp_boot.c | 5 -- arch/arm64/src/fvp-v8r/fvp_lowputc.S | 22 +++++++++ arch/arm64/src/fvp-v8r/serial_pl011.c | 32 ++++--------- arch/arm64/src/qemu/Make.defs | 2 + arch/arm64/src/qemu/qemu_lowputc.S | 10 ++++ arch/arm64/src/qemu/qemu_serial.c | 31 ++++--------- .../fvp-v8r/fvp-armv8r/configs/nsh/defconfig | 1 + .../fvp-armv8r/configs/nsh_smp/defconfig | 1 + .../fvp-v8r/fvp-armv8r/scripts/fvp_cfg.txt | 2 +- 17 files changed, 85 insertions(+), 99 deletions(-) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 05d41177199..d4c20389ebc 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -119,11 +119,14 @@ config ARCH_EARLY_PRINT the NuttX should be execute at EL1 in NS(ARmv8-A) or S(ARmv8-R) state. but booting NuttX have different ELs and state while with different platform, if NuttX runing at wrong ELs or state it will - be not normal anymore. So we need to print something in arm64_head.S + not normal anymore. So we need to print something in arm64_head.S to debug this situation. - Enabling this option will need to implement arm64_earlyserialinit and - arm64_lowputc functions just you see in qemu, if you not sure, - keeping the option disable. + Enabling this option will need to implement arm64_earlyprintinit and + arm64_lowputc functions just you see in qemu_lowputc.S. + by default, UART dev will be used. You can also logging the booting + message through rewriting fake arm64_lowputc with other debug + method (eg semihosting , ARM debug channel etc) + if you not sure, keeping the option disable. config ARCH_CORTEX_A53 bool diff --git a/arch/arm64/src/a64/Make.defs b/arch/arm64/src/a64/Make.defs index 091ed06801a..e0fdcc69b55 100644 --- a/arch/arm64/src/a64/Make.defs +++ b/arch/arm64/src/a64/Make.defs @@ -39,4 +39,6 @@ ifeq ($(CONFIG_A64_TCON0),y) CHIP_CSRCS += a64_tcon0.c endif +ifeq ($(CONFIG_ARCH_EARLY_PRINT),y) CHIP_ASRCS = a64_lowputc.S +endif diff --git a/arch/arm64/src/a64/a64_lowputc.S b/arch/arm64/src/a64/a64_lowputc.S index ce7005d0b51..564770b25dd 100644 --- a/arch/arm64/src/a64/a64_lowputc.S +++ b/arch/arm64/src/a64/a64_lowputc.S @@ -49,6 +49,15 @@ * Public Functions ****************************************************************************/ +/* Initialize A64 UART + * xb: Register that contains the UART Base Address + * c: Scratch register number + */ + +GTEXT(arm64_earlyprintinit) +SECTION_FUNC(text, arm64_earlyprintinit) + ret /* Do nothing because U-Boot has already initialized UART */ + /* Wait for A64 UART to be ready to transmit * xb: Register that contains the UART Base Address * wt: Scratch register number diff --git a/arch/arm64/src/a64/a64_serial.c b/arch/arm64/src/a64/a64_serial.c index ab61e11ebb4..c48fa5aac66 100644 --- a/arch/arm64/src/a64/a64_serial.c +++ b/arch/arm64/src/a64/a64_serial.c @@ -634,16 +634,20 @@ void arm64_earlyserialinit(void) int up_putc(int ch) { +#ifdef CONSOLE_DEV + struct uart_dev_s *dev = &CONSOLE_DEV; + /* Check for LF */ if (ch == '\n') { /* Add CR */ - arm64_lowputc('\r'); + a64_uart_send(dev, '\r'); } - arm64_lowputc((uint8_t)ch); + a64_uart_send(dev, ch); +#endif return ch; } @@ -661,6 +665,7 @@ int up_putc(int ch) void arm64_serialinit(void) { +#ifdef CONSOLE_DEV int ret; ret = uart_register("/dev/console", &CONSOLE_DEV); @@ -675,42 +680,7 @@ void arm64_serialinit(void) { sinfo("error at register dev/ttyS0, ret =%d\n", ret); } -} - -#else /* USE_SERIALDRIVER */ - -/*************************************************************************** - * Public Functions - ***************************************************************************/ - -/*************************************************************************** - * Name: up_putc - * - * Description: - * Provide priority, low-level access to support OS debug - * writes - * - * Input Parameters: - * ch - Character to be transmitted over UART - * - * Returned Value: - * Character that was transmitted - * - ***************************************************************************/ - -int up_putc(int ch) -{ - /* Check for LF */ - - if (ch == '\n') - { - /* Add CR */ - - arm64_lowputc('\r'); - } - - arm64_lowputc((uint8_t)ch); - return ch; +#endif } #endif /* USE_SERIALDRIVER */ diff --git a/arch/arm64/src/common/arm64_head.S b/arch/arm64/src/common/arm64_head.S index 46da686c954..60ca2a65c63 100644 --- a/arch/arm64/src/common/arm64_head.S +++ b/arch/arm64/src/common/arm64_head.S @@ -193,7 +193,7 @@ primary_core: * Should only be called on the boot CPU */ - bl arm64_earlyserialinit + bl arm64_earlyprintinit #endif PRINT(primary_boot, "- Ready to Boot Primary CPU\r\n") diff --git a/arch/arm64/src/common/arm64_internal.h b/arch/arm64/src/common/arm64_internal.h index 98c4e79c00d..5895ee41192 100644 --- a/arch/arm64/src/common/arm64_internal.h +++ b/arch/arm64/src/common/arm64_internal.h @@ -321,8 +321,6 @@ void arm64_serialinit(void); void arm64_earlyserialinit(void); #endif -void arm64_lowputc(char c); - /* DMA */ #ifdef CONFIG_ARCH_DMA diff --git a/arch/arm64/src/fvp-v8r/Kconfig b/arch/arm64/src/fvp-v8r/Kconfig index 5abaa4a9e42..c79840f7ae0 100644 --- a/arch/arm64/src/fvp-v8r/Kconfig +++ b/arch/arm64/src/fvp-v8r/Kconfig @@ -15,7 +15,6 @@ config ARCH_CHIP_FVP_R82 bool "FVP virtual Processor (Cortex-r82)" select ARCH_HAVE_MULTICPU select ARMV8R_HAVE_GICv3 - select ARCH_EARLY_PRINT select ARCH_SET_VMPIDR_EL2 endchoice # FVP Chip Selection diff --git a/arch/arm64/src/fvp-v8r/Make.defs b/arch/arm64/src/fvp-v8r/Make.defs index 9cf766dd1de..0f5d396c1b9 100644 --- a/arch/arm64/src/fvp-v8r/Make.defs +++ b/arch/arm64/src/fvp-v8r/Make.defs @@ -22,4 +22,7 @@ include common/Make.defs # fvp-specific C source files CHIP_CSRCS = fvp_boot.c serial_pl011.c -CHIP_ASRCS = fvp_lowputc.S + +ifeq ($(CONFIG_ARCH_EARLY_PRINT),y) +CHIP_ASRCS += fvp_lowputc.S +endif diff --git a/arch/arm64/src/fvp-v8r/fvp_boot.c b/arch/arm64/src/fvp-v8r/fvp_boot.c index 6650457ad9e..c340f2ae49f 100644 --- a/arch/arm64/src/fvp-v8r/fvp_boot.c +++ b/arch/arm64/src/fvp-v8r/fvp_boot.c @@ -178,11 +178,6 @@ void arm64_chip_boot(void) { /* MAP IO and DRAM, enable MMU. */ - uint64_t cpumpid; - cpumpid = read_sysreg(mpidr_el1); - - sinfo("Main CPU 0x%-16"PRIx64"", cpumpid); - arm64_mpu_init(true); #if defined(CONFIG_SMP) && defined(CONFIG_ARCH_HAVE_PCSI) diff --git a/arch/arm64/src/fvp-v8r/fvp_lowputc.S b/arch/arm64/src/fvp-v8r/fvp_lowputc.S index e7a60e882cb..1aa6e204b10 100644 --- a/arch/arm64/src/fvp-v8r/fvp_lowputc.S +++ b/arch/arm64/src/fvp-v8r/fvp_lowputc.S @@ -50,6 +50,28 @@ * Public Functions ****************************************************************************/ +/*************************************************************************** + * Name: arm64_earlyprintinit + * + * PL011 UART initialization + * xb: register which contains the UART base address + * c: scratch register number + * + ***************************************************************************/ + +GTEXT(arm64_earlyprintinit) +SECTION_FUNC(text, arm64_earlyprintinit) + ldr x15, =CONFIG_UART0_BASE + mov x0, #(7372800 / EARLY_UART_PL011_BAUD_RATE % 16) + strh w0, [x15, #0x28] /* -> UARTFBRD (Baud divisor fraction) */ + mov x0, #(7372800 / EARLY_UART_PL011_BAUD_RATE / 16) + strh w0, [x15, #0x24] /* -> UARTIBRD (Baud divisor integer) */ + mov x0, #0x60 /* 8n1 */ + str w0, [x15, #0x2C] /* -> UARTLCR_H (Line control) */ + ldr x0, =0x00000301 /* RXE | TXE | UARTEN */ + str w0, [x15, #0x30] /* -> UARTCR (Control Register) */ + ret + /* PL011 UART wait UART to be ready to transmit * xb: register which contains the UART base address * c: scratch register number diff --git a/arch/arm64/src/fvp-v8r/serial_pl011.c b/arch/arm64/src/fvp-v8r/serial_pl011.c index e855ca8ded9..f3eae01bcdf 100644 --- a/arch/arm64/src/fvp-v8r/serial_pl011.c +++ b/arch/arm64/src/fvp-v8r/serial_pl011.c @@ -810,16 +810,21 @@ void arm64_earlyserialinit(void) int up_putc(int ch) { +#ifdef CONSOLE_DEV + struct uart_dev_s *dev = &CONSOLE_DEV; + /* Check for LF */ if (ch == '\n') { /* Add CR */ - arm64_lowputc('\r'); + pl011_send(dev, '\r'); } - arm64_lowputc((uint8_t)ch); + pl011_send(dev, ch); +#endif + return ch; } @@ -833,6 +838,7 @@ int up_putc(int ch) void arm64_serialinit(void) { +#ifdef CONSOLE_DEV int ret; ret = uart_register("/dev/console", &CONSOLE_DEV); @@ -847,27 +853,7 @@ void arm64_serialinit(void) { sinfo("error at register dev/ttyS0, ret =%d\n", ret); } -} - -#else /* USE_SERIALDRIVER */ - -/*************************************************************************** - * Public Functions - ***************************************************************************/ - -int up_putc(int ch) -{ - /* Check for LF */ - - if (ch == '\n') - { - /* Add CR */ - - arm64_lowputc('\r'); - } - - arm64_lowputc((uint8_t)ch); - return ch; +#endif } #endif /* USE_SERIALDRIVER */ diff --git a/arch/arm64/src/qemu/Make.defs b/arch/arm64/src/qemu/Make.defs index 423e6e63c98..79ea095e197 100644 --- a/arch/arm64/src/qemu/Make.defs +++ b/arch/arm64/src/qemu/Make.defs @@ -23,7 +23,9 @@ include common/Make.defs # qemu-specific C source files CHIP_CSRCS = qemu_boot.c qemu_serial.c +ifeq ($(CONFIG_ARCH_EARLY_PRINT),y) CHIP_ASRCS = qemu_lowputc.S +endif ifeq ($(CONFIG_DRIVERS_VIRTIO_NET),y) CHIP_CSRCS += qemu_virtio.c diff --git a/arch/arm64/src/qemu/qemu_lowputc.S b/arch/arm64/src/qemu/qemu_lowputc.S index ddee684f07b..7efda17bfb4 100644 --- a/arch/arm64/src/qemu/qemu_lowputc.S +++ b/arch/arm64/src/qemu/qemu_lowputc.S @@ -50,6 +50,16 @@ * Public Functions ****************************************************************************/ +/* PL011 UART initialization + */ + +GTEXT(arm64_earlyprintinit) +SECTION_FUNC(text, arm64_earlyprintinit) + /* it's seem we can do nothing at the qemu platform + * for qemu pl011, the QEMU has already initialized UART + */ + ret + /* PL011 UART wait UART to be ready to transmit * xb: register which contains the UART base address * c: scratch register number diff --git a/arch/arm64/src/qemu/qemu_serial.c b/arch/arm64/src/qemu/qemu_serial.c index a825e5c56f4..563c51dc727 100644 --- a/arch/arm64/src/qemu/qemu_serial.c +++ b/arch/arm64/src/qemu/qemu_serial.c @@ -815,16 +815,20 @@ void arm64_earlyserialinit(void) int up_putc(int ch) { +#ifdef CONSOLE_DEV + struct uart_dev_s *dev = &CONSOLE_DEV; + /* Check for LF */ if (ch == '\n') { /* Add CR */ - arm64_lowputc('\r'); + qemu_pl011_send(dev, '\r'); } - arm64_lowputc((uint8_t)ch); + qemu_pl011_send(dev, ch); +#endif return ch; } @@ -838,6 +842,7 @@ int up_putc(int ch) void arm64_serialinit(void) { +#ifdef CONSOLE_DEV int ret; ret = uart_register("/dev/console", &CONSOLE_DEV); @@ -852,27 +857,7 @@ void arm64_serialinit(void) { sinfo("error at register dev/ttyS0, ret =%d\n", ret); } -} - -#else /* USE_SERIALDRIVER */ - -/*************************************************************************** - * Public Functions - ***************************************************************************/ - -int up_putc(int ch) -{ - /* Check for LF */ - - if (ch == '\n') - { - /* Add CR */ - - arm64_lowputc('\r'); - } - - arm64_lowputc((uint8_t)ch); - return ch; +#endif } #endif /* USE_SERIALDRIVER */ diff --git a/boards/arm64/fvp-v8r/fvp-armv8r/configs/nsh/defconfig b/boards/arm64/fvp-v8r/fvp-armv8r/configs/nsh/defconfig index aa34ab9e380..11222b74447 100644 --- a/boards/arm64/fvp-v8r/fvp-armv8r/configs/nsh/defconfig +++ b/boards/arm64/fvp-v8r/fvp-armv8r/configs/nsh/defconfig @@ -12,6 +12,7 @@ CONFIG_ARCH_BOARD_FVP_ARMV8R=y CONFIG_ARCH_CHIP="fvp-v8r" CONFIG_ARCH_CHIP_FVP_ARMV8R=y CONFIG_ARCH_CHIP_FVP_R82=y +CONFIG_ARCH_EARLY_PRINT=y CONFIG_ARCH_INTERRUPTSTACK=4096 CONFIG_BUILTIN=y CONFIG_DEBUG_ASSERTIONS=y diff --git a/boards/arm64/fvp-v8r/fvp-armv8r/configs/nsh_smp/defconfig b/boards/arm64/fvp-v8r/fvp-armv8r/configs/nsh_smp/defconfig index 204c7b0899a..ffd4b8c486f 100644 --- a/boards/arm64/fvp-v8r/fvp-armv8r/configs/nsh_smp/defconfig +++ b/boards/arm64/fvp-v8r/fvp-armv8r/configs/nsh_smp/defconfig @@ -12,6 +12,7 @@ CONFIG_ARCH_BOARD_FVP_ARMV8R=y CONFIG_ARCH_CHIP="fvp-v8r" CONFIG_ARCH_CHIP_FVP_ARMV8R=y CONFIG_ARCH_CHIP_FVP_R82=y +CONFIG_ARCH_EARLY_PRINT=y CONFIG_ARCH_INTERRUPTSTACK=4096 CONFIG_BUILTIN=y CONFIG_DEBUG_ASSERTIONS=y diff --git a/boards/arm64/fvp-v8r/fvp-armv8r/scripts/fvp_cfg.txt b/boards/arm64/fvp-v8r/fvp-armv8r/scripts/fvp_cfg.txt index 5c60eaa3cba..2de1e4c9064 100644 --- a/boards/arm64/fvp-v8r/fvp-armv8r/scripts/fvp_cfg.txt +++ b/boards/arm64/fvp-v8r/fvp-armv8r/scripts/fvp_cfg.txt @@ -22,4 +22,4 @@ bp.pl011_uart3.unbuffered_output=1 bp.terminal_3.start_telnet=0 bp.vis.disable_visualisation=1 bp.vis.rate_limit-enable=0 -cache_state_modelled=0 +cache_state_modelled=1