diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/arm/gic/arm_gic_v2.c | 6 | ||||
-rw-r--r-- | drivers/arm/gic/arm_gic_v2v3.c | 19 | ||||
-rw-r--r-- | drivers/arm/gic/gic_v3.c | 5 | ||||
-rw-r--r-- | drivers/arm/sp805/sp805.c | 58 | ||||
-rw-r--r-- | drivers/cadence/uart/aarch64/cdns_console.S | 201 |
5 files changed, 274 insertions, 15 deletions
diff --git a/drivers/arm/gic/arm_gic_v2.c b/drivers/arm/gic/arm_gic_v2.c index 826662632..a781703a4 100644 --- a/drivers/arm/gic/arm_gic_v2.c +++ b/drivers/arm/gic/arm_gic_v2.c @@ -9,6 +9,7 @@ #include <assert.h> #include <debug.h> #include <drivers/arm/gic_v2.h> +#include <stdbool.h> void arm_gic_enable_interrupts_local(void) { @@ -119,3 +120,8 @@ void arm_gic_init(uintptr_t gicc_base, INFO("ARM GIC v2 driver initialized\n"); } +bool arm_gic_is_espi_supported(void) +{ + /* ESPI not supported by GICv2. */ + return false; +} diff --git a/drivers/arm/gic/arm_gic_v2v3.c b/drivers/arm/gic/arm_gic_v2v3.c index a3f84d078..9c7692e09 100644 --- a/drivers/arm/gic/arm_gic_v2v3.c +++ b/drivers/arm/gic/arm_gic_v2v3.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Arm Limited. All rights reserved. + * Copyright (c) 2018-2023, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,6 +11,7 @@ #include <drivers/arm/gic_common.h> #include <drivers/arm/gic_v2.h> #include <drivers/arm/gic_v3.h> +#include <stdbool.h> /* Record whether a GICv3 was detected on the system */ static unsigned int gicv3_detected; @@ -194,3 +195,19 @@ void arm_gic_init(uintptr_t gicc_base, INFO("%s mode detected\n", (gicv3_detected) ? "GICv3" : "GICv2"); } + +bool arm_gic_is_espi_supported(void) +{ + unsigned int typer_reg = gicv3_get_gicd_typer(); + + if (!gicv3_detected) { + return false; + } + + /* Check if extended SPI range is implemented. */ + if ((typer_reg & TYPER_ESPI) != 0U) { + return true; + } + + return false; +} diff --git a/drivers/arm/gic/gic_v3.c b/drivers/arm/gic/gic_v3.c index 56049e313..93c707a5d 100644 --- a/drivers/arm/gic/gic_v3.c +++ b/drivers/arm/gic/gic_v3.c @@ -505,3 +505,8 @@ void gicv3_init(uintptr_t gicr_base, uintptr_t gicd_base) gicr_base_addr = gicr_base; gicd_base_addr = gicd_base; } + +unsigned int gicv3_get_gicd_typer(void) +{ + return gicd_read_typer(gicd_base_addr); +} diff --git a/drivers/arm/sp805/sp805.c b/drivers/arm/sp805/sp805.c index 2318c40d8..85da43ae8 100644 --- a/drivers/arm/sp805/sp805.c +++ b/drivers/arm/sp805/sp805.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Arm Limited. All rights reserved. + * Copyright (c) 2018-2021, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -109,45 +109,75 @@ static inline uint32_t sp805_read_wdog_pcell_id(unsigned long base, unsigned int return mmio_read_32(base + SP805_WDOG_PCELL_ID_OFF + (id << 2)); } -void sp805_wdog_start(uint32_t wdog_cycles) +static void sp805_wdog_start_(unsigned long base, uint32_t wdog_cycles) { /* Unlock to access the watchdog registers */ - sp805_write_wdog_lock(SP805_WDOG_BASE, SP805_WDOG_UNLOCK_ACCESS); + sp805_write_wdog_lock(base, SP805_WDOG_UNLOCK_ACCESS); /* Write the number of cycles needed */ - sp805_write_wdog_load(SP805_WDOG_BASE, wdog_cycles); + sp805_write_wdog_load(base, wdog_cycles); /* Enable reset interrupt and watchdog interrupt on expiry */ - sp805_write_wdog_ctrl(SP805_WDOG_BASE, + sp805_write_wdog_ctrl(base, SP805_WDOG_CTRL_RESEN | SP805_WDOG_CTRL_INTEN); /* Lock registers so that they can't be accidently overwritten */ - sp805_write_wdog_lock(SP805_WDOG_BASE, 0x0); + sp805_write_wdog_lock(base, 0x0); } -void sp805_wdog_stop(void) +static void sp805_wdog_stop_(unsigned long base) { /* Unlock to access the watchdog registers */ - sp805_write_wdog_lock(SP805_WDOG_BASE, SP805_WDOG_UNLOCK_ACCESS); + sp805_write_wdog_lock(base, SP805_WDOG_UNLOCK_ACCESS); /* Clearing INTEN bit stops the counter */ - sp805_write_wdog_ctrl(SP805_WDOG_BASE, 0x00); + sp805_write_wdog_ctrl(base, 0x00); /* Lock registers so that they can't be accidently overwritten */ - sp805_write_wdog_lock(SP805_WDOG_BASE, 0x0); + sp805_write_wdog_lock(base, 0x0); } -void sp805_wdog_refresh(void) +static void sp805_wdog_refresh_(unsigned long base) { /* Unlock to access the watchdog registers */ - sp805_write_wdog_lock(SP805_WDOG_BASE, SP805_WDOG_UNLOCK_ACCESS); + sp805_write_wdog_lock(base, SP805_WDOG_UNLOCK_ACCESS); /* * Write of any value to WdogIntClr clears interrupt and reloads * the counter from the value in WdogLoad Register. */ - sp805_write_wdog_int_clr(SP805_WDOG_BASE, 1); + sp805_write_wdog_int_clr(base, 1); /* Lock registers so that they can't be accidently overwritten */ - sp805_write_wdog_lock(SP805_WDOG_BASE, 0x0); + sp805_write_wdog_lock(base, 0x0); +} + +void sp805_wdog_start(uint32_t wdog_cycles) +{ + sp805_wdog_start_(SP805_WDOG_BASE, wdog_cycles); +} + +void sp805_wdog_stop(void) +{ + sp805_wdog_stop_(SP805_WDOG_BASE); +} + +void sp805_wdog_refresh(void) +{ + sp805_wdog_refresh_(SP805_WDOG_BASE); +} + +void sp805_twdog_start(uint32_t wdog_cycles) +{ + sp805_wdog_start_(SP805_TWDOG_BASE, wdog_cycles); +} + +void sp805_twdog_stop(void) +{ + sp805_wdog_stop_(SP805_TWDOG_BASE); +} + +void sp805_twdog_refresh(void) +{ + sp805_wdog_refresh_(SP805_TWDOG_BASE); } diff --git a/drivers/cadence/uart/aarch64/cdns_console.S b/drivers/cadence/uart/aarch64/cdns_console.S new file mode 100644 index 000000000..c88990e24 --- /dev/null +++ b/drivers/cadence/uart/aarch64/cdns_console.S @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch.h> +#include <asm_macros.S> +#include <assert_macros.S> +#include <drivers/console.h> +#include <drivers/cadence/cdns_uart.h> +#include <platform_def.h> + + /* + * "core" functions are low-level implementations that don't require + * writable memory and are thus safe to call in BL1 crash context. + */ + .globl console_core_init + .globl console_core_putc + .globl console_core_getc + .globl console_core_flush + + .globl console_init + .globl console_putc + .globl console_getc + .globl console_flush + + /* + * The console base is in the data section and not in .bss + * even though it is zero-init. In particular, this allows + * the console functions to start using this variable before + * the runtime memory is initialized for images which do not + * need to copy the .data section from ROM to RAM. + */ + .section .data.console_base + .align 3 +console_base: .quad 0x0 + + +func console_init + adrp x3, console_base + str x0, [x3, :lo12:console_base] + b console_core_init +endfunc console_init + + /* ----------------------------------------------- + * int console_core_init(uintptr_t base_addr) + * Function to initialize the console without a + * C Runtime to print debug information. This + * function will be accessed by console_init and + * crash reporting. + * We assume that the bootloader already set up + * the HW (baud, ...) and only enable the trans- + * mitter and receiver here. + * In: x0 - console base address + * Out: return 1 on success else 0 on error + * Clobber list : x1, x2, x3 + * ----------------------------------------------- + */ +func console_core_init + /* Check the input base address */ + cbz x0, core_init_fail + + /* RX/TX enabled & reset */ + mov w3, #(R_UART_CR_TX_EN | R_UART_CR_RX_EN | R_UART_CR_TXRST | R_UART_CR_RXRST) + str w3, [x0, #R_UART_CR] + + mov w0, #1 + ret +core_init_fail: + mov w0, wzr + ret +endfunc console_core_init + + + /* -------------------------------------------------------- + * int console_cdns_core_putc(int c, uintptr_t base_addr) + * Function to output a character over the console. It + * returns the character printed on success or -1 on error. + * In : w0 - character to be printed + * x1 - console base address + * Out : return -1 on error else return character. + * Clobber list : x2 + * -------------------------------------------------------- + */ +func console_core_putc + cbz x1, putc_error + /* Prepend '\r' to '\n' */ + cmp w0, #0xA + b.ne 2f +1: + /* Check if the transmit FIFO is empty */ + ldr w2, [x1, #R_UART_SR] + tbz w2, #UART_SR_INTR_TEMPTY_BIT, 1b + mov w2, #0xD + str w2, [x1, #R_UART_TX] +2: + /* Check if the transmit FIFO is empty */ + ldr w2, [x1, #R_UART_SR] + tbz w2, #UART_SR_INTR_TEMPTY_BIT, 2b + str w0, [x1, #R_UART_TX] + ret +putc_error: + mov w0, #ERROR_NO_VALID_CONSOLE + ret +endfunc console_core_putc + + /* -------------------------------------------------------- + * int console_cdns_putc(int c, console_t *cdns) + * Function to output a character over the console. It + * returns the character printed on success or -1 on error. + * In : w0 - character to be printed + * x1 - pointer to console_t structure + * Out : return -1 on error else return character. + * Clobber list : x2 + * -------------------------------------------------------- + */ +func console_putc + adrp x1, console_base + ldr x1, [x1, :lo12:console_base] + b console_core_putc +endfunc console_putc + + /* --------------------------------------------- + * int console_cdns_core_getc(uintptr_t base_addr) + * Function to get a character from the console. + * It returns the character grabbed on success + * or -1 if no character is available. + * In : x0 - console base address + * Out: w0 - character if available, else -1 + * Clobber list : x0, x1 + * --------------------------------------------- + */ +func console_core_getc + adr x0, console_base + ldr x0, [x0] + + /* Check if the receive FIFO is empty */ + ldr w1, [x0, #R_UART_SR] + tbnz w1, #UART_SR_INTR_REMPTY_BIT, no_char + ldr w1, [x0, #R_UART_RX] + mov w0, w1 + ret +no_char: + mov w0, #ERROR_NO_PENDING_CHAR + ret +endfunc console_core_getc + + /* --------------------------------------------- + * int console_cdns_getc(console_t *console) + * Function to get a character from the console. + * It returns the character grabbed on success + * or -1 if no character is available. + * In : x0 - pointer to console_t structure + * Out: w0 - character if available, else -1 + * Clobber list : x0, x1 + * --------------------------------------------- + */ +func console_getc + adrp x0, console_base + ldr x0, [x0, :lo12:console_base] + b console_core_getc +endfunc console_getc + + /* --------------------------------------------- + * int console_cdns_core_flush(uintptr_t base_addr) + * Function to force a write of all buffered + * data that hasn't been output. + * In : x0 - console base address + * Out : void + * Clobber list : x0, x1 + * --------------------------------------------- + */ +func console_core_flush + cbz x0, flush_error + /* Loop until the transmit FIFO is empty */ +1: + ldr w2, [x1, #R_UART_SR] + tbz w2, #UART_SR_INTR_TEMPTY_BIT, 1b + str w0, [x1, #R_UART_TX] + ret +flush_error: + mov w0, #ERROR_NO_VALID_CONSOLE + ret +endfunc console_core_flush + + /* --------------------------------------------- + * void console_cdns_flush(console_t *console) + * Function to force a write of all buffered + * data that hasn't been output. + * In : x0 - pointer to console_t structure + * Out : void. + * Clobber list : x0, x1 + * --------------------------------------------- + */ +func console_flush + adrp x0, console_base + ldr x0, [x0, :lo12:console_base] + b console_core_flush +endfunc console_flush |