diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst index 0b3f782c5..30b2ab26b 100644 --- a/docs/about/maintainers.rst +++ b/docs/about/maintainers.rst @@ -142,6 +142,15 @@ eMMC/UFS drivers :|F|: include/drivers/ufs.h :|F|: include/drivers/synopsys/dw_mmc.h +JTAG DCC console driver +^^^^^^^^^^^^^^^^^^^^^^^ +:M: Michal Simek +:G: `michalsimek`_ +:M: Venkatesh Yadav Abbarapu +:G: `venkatesh`_ +:F: drivers/arm/dcc/ +:F: include/drivers/arm/dcc.h + Power State Coordination Interface (PSCI) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :|M|: Javier Almansa Sobrino diff --git a/docs/plat/xilinx-versal.rst b/docs/plat/xilinx-versal.rst index 57a363bc9..3d4c4a4e1 100644 --- a/docs/plat/xilinx-versal.rst +++ b/docs/plat/xilinx-versal.rst @@ -19,6 +19,11 @@ To build ATF for different platform (supported are "silicon"(default) and "versa make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal VERSAL_PLATFORM=versal_virt bl31 ``` +To build TF-A for JTAG DCC console +```bash +make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal bl31 VERSAL_CONSOLE=dcc +``` + Xilinx Versal platform specific build options --------------------------------------------- diff --git a/docs/plat/xilinx-zynqmp.rst b/docs/plat/xilinx-zynqmp.rst index 5db4488a0..79c253509 100644 --- a/docs/plat/xilinx-zynqmp.rst +++ b/docs/plat/xilinx-zynqmp.rst @@ -22,6 +22,12 @@ To build bl32 TSP you have to rebuild bl31 too: make CROSS_COMPILE=aarch64-none-elf- PLAT=zynqmp SPD=tspd bl31 bl32 +To build TF-A for JTAG DCC console: + +.. code:: bash + + make CROSS_COMPILE=aarch64-none-elf- PLAT=zynqmp RESET_TO_BL31=1 bl31 ZYNQMP_CONSOLE=dcc + ZynqMP platform specific build options -------------------------------------- diff --git a/drivers/arm/dcc/dcc_console.c b/drivers/arm/dcc/dcc_console.c new file mode 100644 index 000000000..0b7e541f0 --- /dev/null +++ b/drivers/arm/dcc/dcc_console.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2015-2021, Xilinx Inc. + * Written by Michal Simek. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +/* DCC Status Bits */ +#define DCC_STATUS_RX BIT(30) +#define DCC_STATUS_TX BIT(29) +#define TIMEOUT_COUNT_US U(0x10624) + +struct dcc_console { + struct console console; +}; + +static inline uint32_t __dcc_getstatus(void) +{ + return read_mdccsr_el0(); +} + +static inline char __dcc_getchar(void) +{ + char c; + + c = read_dbgdtrrx_el0(); + + return c; +} + +static inline void __dcc_putchar(char c) +{ + /* + * The typecast is to make absolutely certain that 'c' is + * zero-extended. + */ + write_dbgdtrtx_el0((unsigned char)c); +} + +static int32_t dcc_status_timeout(uint32_t mask) +{ + const unsigned int timeout_count = TIMEOUT_COUNT_US; + uint64_t timeout; + unsigned int status; + + timeout = timeout_init_us(timeout_count); + + do { + status = (__dcc_getstatus() & mask); + if (timeout_elapsed(timeout)) { + return -ETIMEDOUT; + } + } while ((status != 0U)); + + return 0; +} + +static int32_t dcc_console_putc(int32_t ch, struct console *console) +{ + unsigned int status; + + status = dcc_status_timeout(DCC_STATUS_TX); + if (status != 0U) { + return status; + } + __dcc_putchar(ch); + + return ch; +} + +static int32_t dcc_console_getc(struct console *console) +{ + unsigned int status; + + status = dcc_status_timeout(DCC_STATUS_RX); + if (status != 0U) { + return status; + } + + return __dcc_getchar(); +} + +int32_t dcc_console_init(unsigned long base_addr, uint32_t uart_clk, + uint32_t baud_rate) +{ + return 0; /* No init needed */ +} + +/** + * dcc_console_flush() - Function to force a write of all buffered data + * that hasn't been output. + * @console Console struct + * + */ +static void dcc_console_flush(struct console *console) +{ + unsigned int status; + + status = dcc_status_timeout(DCC_STATUS_TX); + if (status != 0U) { + return; + } +} + +static struct dcc_console dcc_console = { + .console = { + .flags = CONSOLE_FLAG_BOOT | + CONSOLE_FLAG_RUNTIME, + .putc = dcc_console_putc, + .getc = dcc_console_getc, + .flush = dcc_console_flush, + }, +}; + +int console_dcc_register(void) +{ + return console_register(&dcc_console.console); +} diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h index 8c3400a1d..a41b3258e 100644 --- a/include/arch/aarch64/arch_helpers.h +++ b/include/arch/aarch64/arch_helpers.h @@ -260,6 +260,9 @@ DEFINE_SYSREG_RW_FUNCS(spsr_el3) DEFINE_SYSREG_RW_FUNCS(elr_el1) DEFINE_SYSREG_RW_FUNCS(elr_el2) DEFINE_SYSREG_RW_FUNCS(elr_el3) +DEFINE_SYSREG_RW_FUNCS(mdccsr_el0) +DEFINE_SYSREG_RW_FUNCS(dbgdtrrx_el0) +DEFINE_SYSREG_RW_FUNCS(dbgdtrtx_el0) DEFINE_SYSOP_FUNC(wfi) DEFINE_SYSOP_FUNC(wfe) diff --git a/include/drivers/arm/dcc.h b/include/drivers/arm/dcc.h new file mode 100644 index 000000000..1f1fd03e0 --- /dev/null +++ b/include/drivers/arm/dcc.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2021, Xilinx Inc. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef DCC_H +#define DCC_H + +#include +#include + +/* + * Initialize a new dcc console instance and register it with the console + * framework. + */ +int console_dcc_register(void); + +#endif /* DCC */ diff --git a/plat/xilinx/versal/bl31_versal_setup.c b/plat/xilinx/versal/bl31_versal_setup.c index 5e870ff5f..de36efc0a 100644 --- a/plat/xilinx/versal/bl31_versal_setup.c +++ b/plat/xilinx/versal/bl31_versal_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -22,7 +23,6 @@ static entry_point_info_t bl32_image_ep_info; static entry_point_info_t bl33_image_ep_info; -static console_t versal_runtime_console; /* * Return a pointer to the 'entry_point_info' structure of the next image for @@ -64,18 +64,26 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, { uint64_t atf_handoff_addr; - /* Initialize the console to provide early debug support */ - int rc = console_pl011_register(VERSAL_UART_BASE, - VERSAL_UART_CLOCK, - VERSAL_UART_BAUDRATE, - &versal_runtime_console); - if (rc == 0) { - panic(); + if (VERSAL_CONSOLE_IS(pl011)) { + static console_t versal_runtime_console; + /* Initialize the console to provide early debug support */ + int rc = console_pl011_register(VERSAL_UART_BASE, + VERSAL_UART_CLOCK, + VERSAL_UART_BAUDRATE, + &versal_runtime_console); + if (rc == 0) { + panic(); + } + + console_set_scope(&versal_runtime_console, CONSOLE_FLAG_BOOT | + CONSOLE_FLAG_RUNTIME); + } else if (VERSAL_CONSOLE_IS(dcc)) { + /* Initialize the dcc console for debug */ + int rc = console_dcc_register(); + if (rc == 0) { + panic(); + } } - - console_set_scope(&versal_runtime_console, CONSOLE_FLAG_BOOT | - CONSOLE_FLAG_RUNTIME); - /* Initialize the platform config for future decision making */ versal_config_setup(); /* There are no parameters from BL2 if BL31 is a reset vector */ diff --git a/plat/xilinx/versal/include/versal_def.h b/plat/xilinx/versal/include/versal_def.h index 810e5d877..001fb04ac 100644 --- a/plat/xilinx/versal/include/versal_def.h +++ b/plat/xilinx/versal/include/versal_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -67,7 +67,7 @@ #define VERSAL_UART0_BASE 0xFF000000 #define VERSAL_UART1_BASE 0xFF010000 -#if VERSAL_CONSOLE_IS(pl011) +#if VERSAL_CONSOLE_IS(pl011) || VERSAL_CONSOLE_IS(dcc) # define VERSAL_UART_BASE VERSAL_UART0_BASE #elif VERSAL_CONSOLE_IS(pl011_1) # define VERSAL_UART_BASE VERSAL_UART1_BASE diff --git a/plat/xilinx/versal/platform.mk b/plat/xilinx/versal/platform.mk index 1007e5553..ccbc08441 100644 --- a/plat/xilinx/versal/platform.mk +++ b/plat/xilinx/versal/platform.mk @@ -1,4 +1,4 @@ -# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause @@ -34,9 +34,6 @@ endif VERSAL_PLATFORM ?= silicon $(eval $(call add_define_val,VERSAL_PLATFORM,VERSAL_PLATFORM_ID_${VERSAL_PLATFORM})) -VERSAL_CONSOLE ?= pl011 -$(eval $(call add_define_val,VERSAL_CONSOLE,VERSAL_CONSOLE_ID_${VERSAL_CONSOLE})) - PLAT_INCLUDES := -Iinclude/plat/arm/common/ \ -Iplat/xilinx/common/include/ \ -Iplat/xilinx/common/ipi_mailbox_service/ \ @@ -48,6 +45,7 @@ include drivers/arm/gic/v3/gicv3.mk PLAT_BL_COMMON_SOURCES := lib/xlat_tables/xlat_tables_common.c \ lib/xlat_tables/aarch64/xlat_tables.c \ + drivers/arm/dcc/dcc_console.c \ drivers/delay_timer/delay_timer.c \ drivers/delay_timer/generic_delay_timer.c \ ${GICV3_SOURCES} \ @@ -59,6 +57,14 @@ PLAT_BL_COMMON_SOURCES := lib/xlat_tables/xlat_tables_common.c \ plat/xilinx/versal/aarch64/versal_helpers.S \ plat/xilinx/versal/aarch64/versal_common.c +VERSAL_CONSOLE ?= pl011 +ifeq (${VERSAL_CONSOLE}, $(filter ${VERSAL_CONSOLE},pl011 pl011_0 pl011_1 dcc)) +else + $(error "Please define VERSAL_CONSOLE") +endif + +$(eval $(call add_define_val,VERSAL_CONSOLE,VERSAL_CONSOLE_ID_${VERSAL_CONSOLE})) + BL31_SOURCES += drivers/arm/cci/cci.c \ lib/cpus/aarch64/cortex_a72.S \ plat/common/plat_psci_common.c \ diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c index d4cd7f65b..4a09b4b03 100644 --- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c +++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -62,15 +63,23 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { uint64_t atf_handoff_addr; - /* Register the console to provide early debug support */ - static console_t bl31_boot_console; - (void)console_cdns_register(ZYNQMP_UART_BASE, - zynqmp_get_uart_clk(), - ZYNQMP_UART_BAUDRATE, - &bl31_boot_console); - console_set_scope(&bl31_boot_console, - CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_BOOT); + if (ZYNQMP_CONSOLE_IS(cadence)) { + /* Register the console to provide early debug support */ + static console_t bl31_boot_console; + (void)console_cdns_register(ZYNQMP_UART_BASE, + zynqmp_get_uart_clk(), + ZYNQMP_UART_BAUDRATE, + &bl31_boot_console); + console_set_scope(&bl31_boot_console, + CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_BOOT); + } else if (ZYNQMP_CONSOLE_IS(dcc)) { + /* Initialize the dcc console for debug */ + int rc = console_dcc_register(); + if (rc == 0) { + panic(); + } + } /* Initialize the platform config for future decision making */ zynqmp_config_setup(); diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk index 6e700b9b1..921a6e180 100644 --- a/plat/xilinx/zynqmp/platform.mk +++ b/plat/xilinx/zynqmp/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause @@ -41,8 +41,6 @@ ifdef ZYNQMP_BL32_MEM_BASE $(eval $(call add_define,ZYNQMP_BL32_MEM_SIZE)) endif -ZYNQMP_CONSOLE ?= cadence -$(eval $(call add_define_val,ZYNQMP_CONSOLE,ZYNQMP_CONSOLE_ID_${ZYNQMP_CONSOLE})) ifdef ZYNQMP_WDT_RESTART $(eval $(call add_define,ZYNQMP_WDT_RESTART)) @@ -64,6 +62,7 @@ include drivers/arm/gic/v2/gicv2.mk PLAT_BL_COMMON_SOURCES := lib/xlat_tables/xlat_tables_common.c \ lib/xlat_tables/aarch64/xlat_tables.c \ + drivers/arm/dcc/dcc_console.c \ drivers/delay_timer/delay_timer.c \ drivers/delay_timer/generic_delay_timer.c \ ${GICV2_SOURCES} \ @@ -78,6 +77,13 @@ PLAT_BL_COMMON_SOURCES := lib/xlat_tables/xlat_tables_common.c \ plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S \ plat/xilinx/zynqmp/aarch64/zynqmp_common.c +ZYNQMP_CONSOLE ?= cadence +ifeq (${ZYNQMP_CONSOLE}, $(filter ${ZYNQMP_CONSOLE},cadence cadence0 cadence1 dcc)) +else + $(error "Please define ZYNQMP_CONSOLE") +endif +$(eval $(call add_define_val,ZYNQMP_CONSOLE,ZYNQMP_CONSOLE_ID_${ZYNQMP_CONSOLE})) + BL31_SOURCES += drivers/arm/cci/cci.c \ lib/cpus/aarch64/aem_generic.S \ lib/cpus/aarch64/cortex_a53.S \