mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-13 16:14:20 +00:00
uniphier: support console based on multi-console
The legacy console is gone. Re-add the console support based on the multi-console framework. I am still keeping the putc, getc, and flush callbacks in uniphier_console.S to use plat/common/aarch64/crash_console_helpers.S The console registration code already relies on that C environment has been set up. So, I just filled the struct console fields with the callback pointers, then called console_register() directly. I also re-implemented the init function in C to improve the readability. Removing the custom crash console implementation has one disadvantage; we cannot use the crash console on very early crashes because crash_console_helpers.S works only after the console is registered. I can live with this limitation. Tested on my boards, and confirmed this worked like before. Change-Id: Ieab9c849853ff6c525c15ea894a85944f257db59 Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
This commit is contained in:
parent
bb2d778c74
commit
ac9f1b5555
5 changed files with 144 additions and 179 deletions
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
|
||||
# Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
|
@ -27,8 +27,9 @@ PLAT_PATH := plat/socionext/uniphier
|
|||
PLAT_INCLUDES := -I$(PLAT_PATH)/include
|
||||
|
||||
# common sources for BL2, BL31 (and BL32 if SPD=tspd)
|
||||
PLAT_BL_COMMON_SOURCES += drivers/console/aarch64/console.S \
|
||||
PLAT_BL_COMMON_SOURCES += plat/common/aarch64/crash_console_helpers.S \
|
||||
$(PLAT_PATH)/uniphier_console.S \
|
||||
$(PLAT_PATH)/uniphier_console_setup.c \
|
||||
$(PLAT_PATH)/uniphier_helpers.S \
|
||||
$(PLAT_PATH)/uniphier_soc_info.c \
|
||||
$(PLAT_PATH)/uniphier_xlat_setup.c \
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -84,11 +84,3 @@ void bl31_plat_arch_setup(void)
|
|||
uniphier_mmap_setup(BL31_BASE, BL31_SIZE, NULL);
|
||||
enable_mmu_el3(0);
|
||||
}
|
||||
|
||||
void bl31_plat_runtime_setup(void)
|
||||
{
|
||||
/* Suppress any runtime logs unless DEBUG is defined */
|
||||
#if !DEBUG
|
||||
console_uninit();
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1,81 +1,23 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <asm_macros.S>
|
||||
#include <drivers/console.h>
|
||||
|
||||
#define UNIPHIER_UART_BASE 0x54006800
|
||||
#define UNIPHIER_UART_END 0x54006c00
|
||||
#define UNIPHIER_UART_OFFSET 0x100
|
||||
|
||||
#define UNIPHIER_UART_RX 0x00 /* In: Receive buffer */
|
||||
#define UNIPHIER_UART_TX 0x00 /* Out: Transmit buffer */
|
||||
|
||||
#define UNIPHIER_UART_FCR 0x0c /* Char/FIFO Control Register */
|
||||
#define UNIPHIER_UART_FCR_ENABLE_FIFO 0x01 /* Enable the FIFO */
|
||||
|
||||
#define UNIPHIER_UART_LCR_MCR 0x10 /* Line/Modem Control Register */
|
||||
#define UNIPHIER_UART_LCR_WLEN8 0x03 /* Wordlength: 8 bits */
|
||||
#define UNIPHIER_UART_LSR 0x14 /* Line Status Register */
|
||||
#define UNIPHIER_UART_LSR_TEMT_BIT 6 /* Transmitter empty */
|
||||
#define UNIPHIER_UART_LSR_THRE_BIT 5 /* Transmit-hold-register empty */
|
||||
#define UNIPHIER_UART_LSR_DR_BIT 0 /* Receiver data ready */
|
||||
#define UNIPHIER_UART_DLR 0x24 /* Divisor Latch Register */
|
||||
|
||||
/*
|
||||
* Uncomment for debug
|
||||
*/
|
||||
/* #define UNIPHIER_UART_INIT_DIVISOR */
|
||||
#define UNIPHIER_UART_DEFAULT_BASE (UNIPHIER_UART_BASE)
|
||||
#define UNIPHIER_UART_CLK_RATE 58820000
|
||||
#define UNIPHIER_UART_DEFAULT_BAUDRATE 115200
|
||||
|
||||
/*
|
||||
* In: x0 - console base address
|
||||
* w1 - uart clock in Hz
|
||||
* w2 - baud rate
|
||||
* Out: return 1 on success, or 0 on error
|
||||
*/
|
||||
.globl console_core_init
|
||||
func console_core_init
|
||||
cbz x0, 1f
|
||||
#ifdef UNIPHIER_UART_INIT_DIVISOR
|
||||
cbz w1, 1f
|
||||
cbz w2, 1f
|
||||
/* divisor = uart_clock / (16 * baud_rate) */
|
||||
udiv w2, w1, w2
|
||||
lsr w2, w2, #4
|
||||
#endif
|
||||
/* Make sure the transmitter is empty before the divisor set/change */
|
||||
0: ldr w1, [x0, #UNIPHIER_UART_LSR]
|
||||
tbz w1, #UNIPHIER_UART_LSR_TEMT_BIT, 0b
|
||||
#ifdef UNIPHIER_UART_INIT_DIVISOR
|
||||
str w2, [x0, #UNIPHIER_UART_DLR]
|
||||
#endif
|
||||
mov w2, #UNIPHIER_UART_FCR_ENABLE_FIFO
|
||||
str w2, [x0, #UNIPHIER_UART_FCR]
|
||||
|
||||
mov w2, #(UNIPHIER_UART_LCR_WLEN8 << 8)
|
||||
str w2, [x0, #UNIPHIER_UART_LCR_MCR]
|
||||
|
||||
mov w0, #1
|
||||
ret
|
||||
1: mov w0, #0
|
||||
ret
|
||||
endfunc console_core_init
|
||||
#include "uniphier_console.h"
|
||||
|
||||
/*
|
||||
* In: w0 - character to be printed
|
||||
* x1 - console base address
|
||||
* Out: return the character written, or -1 on error
|
||||
* x1 - pointer to console structure
|
||||
* Out: return the character written (always succeeds)
|
||||
* Clobber: x2
|
||||
*/
|
||||
.globl console_core_putc
|
||||
func console_core_putc
|
||||
/* Error out if the console is not initialized */
|
||||
cbz x1, 2f
|
||||
.globl uniphier_console_putc
|
||||
func uniphier_console_putc
|
||||
ldr x1, [x1, #CONSOLE_T_DRVDATA]
|
||||
|
||||
/* Wait until the transmitter FIFO gets empty */
|
||||
0: ldr w2, [x1, #UNIPHIER_UART_LSR]
|
||||
|
@ -86,43 +28,40 @@ func console_core_putc
|
|||
1: str w2, [x1, #UNIPHIER_UART_TX]
|
||||
|
||||
cmp w2, #'\n'
|
||||
b.ne 3f
|
||||
b.ne 2f
|
||||
mov w2, #'\r' /* Append '\r' to '\n' */
|
||||
b 1b
|
||||
2: mov w0, #-1
|
||||
3: ret
|
||||
endfunc console_core_putc
|
||||
2: ret
|
||||
endfunc uniphier_console_putc
|
||||
|
||||
/*
|
||||
* In: x0 - console base address
|
||||
* Out: return the character read
|
||||
* In: x0 - pointer to console structure
|
||||
* Out: return the character read, or ERROR_NO_PENDING_CHAR if no character
|
||||
is available
|
||||
* Clobber: x1
|
||||
*/
|
||||
.globl console_core_getc
|
||||
func console_core_getc
|
||||
/* Error out if the console is not initialized */
|
||||
cbz x0, 1f
|
||||
.globl uniphier_console_getc
|
||||
func uniphier_console_getc
|
||||
ldr x0, [x0, #CONSOLE_T_DRVDATA]
|
||||
|
||||
/* Wait while the receiver FIFO is empty */
|
||||
0: ldr w1, [x0, #UNIPHIER_UART_LSR]
|
||||
tbz w1, #UNIPHIER_UART_LSR_DR_BIT, 0b
|
||||
ldr w1, [x0, #UNIPHIER_UART_LSR]
|
||||
tbz w1, #UNIPHIER_UART_LSR_DR_BIT, 0f
|
||||
|
||||
ldr w0, [x0, #UNIPHIER_UART_RX]
|
||||
ret
|
||||
|
||||
0: mov w0, #ERROR_NO_PENDING_CHAR
|
||||
ret
|
||||
1: mov w0, #-1
|
||||
ret
|
||||
endfunc console_core_getc
|
||||
endfunc uniphier_console_getc
|
||||
|
||||
/*
|
||||
* In: x0 - console base address
|
||||
* Out: return 0, or -1 on error
|
||||
* In: x0 - pointer to console structure
|
||||
* Out: return 0 (always succeeds)
|
||||
* Clobber: x1
|
||||
*/
|
||||
.global console_core_flush
|
||||
func console_core_flush
|
||||
/* Error out if the console is not initialized */
|
||||
cbz x0, 1f
|
||||
.global uniphier_console_flush
|
||||
func uniphier_console_flush
|
||||
ldr x0, [x0, #CONSOLE_T_DRVDATA]
|
||||
|
||||
/* wait until the transmitter gets empty */
|
||||
0: ldr w1, [x0, #UNIPHIER_UART_LSR]
|
||||
|
@ -130,83 +69,4 @@ func console_core_flush
|
|||
|
||||
mov w0, #0
|
||||
ret
|
||||
1: mov w0, #-1
|
||||
ret
|
||||
endfunc console_core_flush
|
||||
|
||||
/* find initialized UART port */
|
||||
.macro uniphier_console_get_base base, tmpx, tmpw
|
||||
ldr \base, =UNIPHIER_UART_BASE
|
||||
0000: ldr \tmpw, [\base, #UNIPHIER_UART_DLR]
|
||||
mvn \tmpw, \tmpw
|
||||
uxth \tmpw, \tmpw
|
||||
cbnz \tmpw, 0001f
|
||||
add \base, \base, #UNIPHIER_UART_OFFSET
|
||||
ldr \tmpx, =UNIPHIER_UART_END
|
||||
cmp \base, \tmpx
|
||||
b.lo 0000b
|
||||
mov \base, #0
|
||||
0001:
|
||||
.endm
|
||||
|
||||
/*
|
||||
* int plat_crash_console_init(void)
|
||||
* Clobber: x0-x2
|
||||
*/
|
||||
.globl plat_crash_console_init
|
||||
func plat_crash_console_init
|
||||
#ifdef UNIPHIER_UART_INIT_DIVISOR
|
||||
ldr x0, =UNIPHIER_UART_DEFAULT_BASE
|
||||
ldr x1, =UNIPHIER_UART_CLK_RATE
|
||||
ldr x2, =UNIPHIER_UART_DEFAULT_BAUDRATE
|
||||
b console_core_init
|
||||
#else
|
||||
ret
|
||||
#endif
|
||||
endfunc plat_crash_console_init
|
||||
|
||||
/*
|
||||
* int plat_crash_console_putc(int c)
|
||||
* Clobber: x1, x2
|
||||
*/
|
||||
.globl plat_crash_console_putc
|
||||
func plat_crash_console_putc
|
||||
#ifdef UNIPHIER_UART_INIT_DIVISOR
|
||||
ldr x1, =UNIPHIER_UART_DEFAULT_BASE
|
||||
#else
|
||||
uniphier_console_get_base x1, x2, w2
|
||||
#endif
|
||||
b console_core_putc
|
||||
endfunc plat_crash_console_putc
|
||||
|
||||
/*
|
||||
* int plat_crash_console_flush(void)
|
||||
* Clobber: x0, x1
|
||||
*/
|
||||
.global plat_crash_console_flush
|
||||
func plat_crash_console_flush
|
||||
#ifdef UNIPHIER_UART_INIT_DIVISOR
|
||||
ldr x0, =UNIPHIER_UART_DEFAULT_BASE
|
||||
#else
|
||||
uniphier_console_get_base x0, x1, w1
|
||||
#endif
|
||||
b console_core_flush
|
||||
endfunc plat_crash_console_flush
|
||||
|
||||
/*
|
||||
* void uniphier_console_setup(void)
|
||||
* Clobber: x0-x2
|
||||
*/
|
||||
.globl uniphier_console_setup
|
||||
func uniphier_console_setup
|
||||
#ifdef UNIPHIER_UART_INIT_DIVISOR
|
||||
ldr x0, =UNIPHIER_UART_DEFAULT_BASE
|
||||
ldr w1, =UNIPHIER_UART_CLK_RATE
|
||||
ldr w2, =UNIPHIER_UART_DEFAULT_BAUDRATE
|
||||
#else
|
||||
uniphier_console_get_base x0, x1, w1
|
||||
mov w1, #0
|
||||
mov w2, #0
|
||||
#endif
|
||||
b console_init
|
||||
endfunc uniphier_console_setup
|
||||
endfunc uniphier_console_flush
|
||||
|
|
25
plat/socionext/uniphier/uniphier_console.h
Normal file
25
plat/socionext/uniphier/uniphier_console.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef UNIPHIER_CONSOLE_H
|
||||
#define UNIPHIER_CONSOLE_H
|
||||
|
||||
#define UNIPHIER_UART_RX 0x00 /* In: Receive buffer */
|
||||
#define UNIPHIER_UART_TX 0x00 /* Out: Transmit buffer */
|
||||
|
||||
#define UNIPHIER_UART_FCR 0x0c /* Char/FIFO Control Register */
|
||||
#define UNIPHIER_UART_FCR_ENABLE_FIFO 0x01 /* Enable the FIFO */
|
||||
|
||||
#define UNIPHIER_UART_LCR_MCR 0x10 /* Line/Modem Control Register */
|
||||
#define UNIPHIER_UART_LCR_WLEN8 0x03 /* Wordlength: 8 bits */
|
||||
#define UNIPHIER_UART_LSR 0x14 /* Line Status Register */
|
||||
#define UNIPHIER_UART_LSR_TEMT 0x40 /* Transmitter empty */
|
||||
#define UNIPHIER_UART_LSR_TEMT_BIT 6 /* Transmitter empty */
|
||||
#define UNIPHIER_UART_LSR_THRE_BIT 5 /* Transmit-hold-register empty */
|
||||
#define UNIPHIER_UART_LSR_DR_BIT 0 /* Receiver data ready */
|
||||
#define UNIPHIER_UART_DLR 0x24 /* Divisor Latch Register */
|
||||
|
||||
#endif /* UNIPHIER_CONSOLE_H */
|
87
plat/socionext/uniphier/uniphier_console_setup.c
Normal file
87
plat/socionext/uniphier/uniphier_console_setup.c
Normal file
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright (c) 2019, Socionext Inc. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <drivers/console.h>
|
||||
#include <errno.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <plat/common/platform.h>
|
||||
|
||||
#include "uniphier.h"
|
||||
#include "uniphier_console.h"
|
||||
|
||||
#define UNIPHIER_UART_BASE 0x54006800
|
||||
#define UNIPHIER_UART_END 0x54006c00
|
||||
#define UNIPHIER_UART_OFFSET 0x100
|
||||
|
||||
struct uniphier_console {
|
||||
struct console console;
|
||||
uintptr_t base;
|
||||
};
|
||||
|
||||
/* These callbacks are implemented in assembly to use crash_console_helpers.S */
|
||||
int uniphier_console_putc(int character, struct console *console);
|
||||
int uniphier_console_getc(struct console *console);
|
||||
int uniphier_console_flush(struct console *console);
|
||||
|
||||
static struct uniphier_console uniphier_console = {
|
||||
.console = {
|
||||
.flags = CONSOLE_FLAG_BOOT |
|
||||
#if DEBUG
|
||||
CONSOLE_FLAG_RUNTIME |
|
||||
#endif
|
||||
CONSOLE_FLAG_CRASH,
|
||||
.putc = uniphier_console_putc,
|
||||
.getc = uniphier_console_getc,
|
||||
.flush = uniphier_console_flush,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* There are 4 UART ports available on this platform. By default, we want to
|
||||
* use the same one as used in the previous firmware stage.
|
||||
*/
|
||||
static uintptr_t uniphier_console_get_base(void)
|
||||
{
|
||||
uintptr_t base = UNIPHIER_UART_BASE;
|
||||
uint32_t div;
|
||||
|
||||
while (base < UNIPHIER_UART_END) {
|
||||
div = mmio_read_32(base + UNIPHIER_UART_DLR);
|
||||
if (div)
|
||||
return base;
|
||||
base += UNIPHIER_UART_OFFSET;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void uniphier_console_init(uintptr_t base)
|
||||
{
|
||||
mmio_write_32(base + UNIPHIER_UART_FCR, UNIPHIER_UART_FCR_ENABLE_FIFO);
|
||||
mmio_write_32(base + UNIPHIER_UART_LCR_MCR,
|
||||
UNIPHIER_UART_LCR_WLEN8 << 8);
|
||||
}
|
||||
|
||||
void uniphier_console_setup(void)
|
||||
{
|
||||
uintptr_t base;
|
||||
|
||||
base = uniphier_console_get_base();
|
||||
if (!base)
|
||||
plat_error_handler(-EINVAL);
|
||||
|
||||
uniphier_console.base = base;
|
||||
console_register(&uniphier_console.console);
|
||||
|
||||
/*
|
||||
* The hardware might be still printing characters queued up in the
|
||||
* previous firmware stage. Make sure the transmitter is empty before
|
||||
* any initialization. Otherwise, the console might get corrupted.
|
||||
*/
|
||||
console_flush();
|
||||
|
||||
uniphier_console_init(base);
|
||||
}
|
Loading…
Add table
Reference in a new issue