From 9c94d3b326ad14f9a64ccdf2ec1edf0af2595d0b Mon Sep 17 00:00:00 2001 From: Soby Mathew Date: Mon, 8 Aug 2016 12:38:52 +0100 Subject: Move console drivers to AArch64 folder This patch moves the various assembly console drivers into `aarch64` architecture specific folder. Stub files, which include files from new location, are retained at the original location for platform compatibility reasons. Change-Id: I0069b6c1c0489ca47f5204d4e26e3bc3def533a8 --- drivers/arm/pl011/aarch64/pl011_console.S | 153 ++++++++++++++++++++++++++++++ drivers/arm/pl011/pl011_console.S | 126 +----------------------- 2 files changed, 156 insertions(+), 123 deletions(-) create mode 100644 drivers/arm/pl011/aarch64/pl011_console.S (limited to 'drivers/arm') diff --git a/drivers/arm/pl011/aarch64/pl011_console.S b/drivers/arm/pl011/aarch64/pl011_console.S new file mode 100644 index 00000000..11e3df77 --- /dev/null +++ b/drivers/arm/pl011/aarch64/pl011_console.S @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. + * + * 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 + +/* + * Pull in generic functions to provide backwards compatibility for + * platform makefiles + */ +#include "../../../console/aarch64/console.S" + + + .globl console_core_init + .globl console_core_putc + .globl console_core_getc + + + /* ----------------------------------------------- + * int console_core_init(uintptr_t base_addr, + * unsigned int uart_clk, unsigned int baud_rate) + * Function to initialize the console without a + * C Runtime to print debug information. This + * function will be accessed by console_init and + * crash reporting. + * In: x0 - console base address + * w1 - Uart clock in Hz + * w2 - Baud rate + * Out: return 1 on success else 0 on error + * Clobber list : x1, x2, x3, x4 + * ----------------------------------------------- + */ +func console_core_init + /* Check the input base address */ + cbz x0, core_init_fail +#if !PL011_GENERIC_UART + /* Check baud rate and uart clock for sanity */ + cbz w1, core_init_fail + cbz w2, core_init_fail + /* Disable uart before programming */ + ldr w3, [x0, #UARTCR] + mov w4, #PL011_UARTCR_UARTEN + bic w3, w3, w4 + str w3, [x0, #UARTCR] + /* Program the baudrate */ + /* Divisor = (Uart clock * 4) / baudrate */ + lsl w1, w1, #2 + udiv w2, w1, w2 + /* IBRD = Divisor >> 6 */ + lsr w1, w2, #6 + /* Write the IBRD */ + str w1, [x0, #UARTIBRD] + /* FBRD = Divisor & 0x3F */ + and w1, w2, #0x3f + /* Write the FBRD */ + str w1, [x0, #UARTFBRD] + mov w1, #PL011_LINE_CONTROL + str w1, [x0, #UARTLCR_H] + /* Clear any pending errors */ + str wzr, [x0, #UARTECR] + /* Enable tx, rx, and uart overall */ + mov w1, #(PL011_UARTCR_RXE | PL011_UARTCR_TXE | PL011_UARTCR_UARTEN) + str w1, [x0, #UARTCR] +#endif + mov w0, #1 + ret +core_init_fail: + mov w0, wzr + ret +endfunc console_core_init + + /* -------------------------------------------------------- + * int console_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 + /* Check the input parameter */ + cbz x1, putc_error + /* Prepend '\r' to '\n' */ + cmp w0, #0xA + b.ne 2f +1: + /* Check if the transmit FIFO is full */ + ldr w2, [x1, #UARTFR] + tbnz w2, #PL011_UARTFR_TXFF_BIT, 1b + mov w2, #0xD + str w2, [x1, #UARTDR] +2: + /* Check if the transmit FIFO is full */ + ldr w2, [x1, #UARTFR] + tbnz w2, #PL011_UARTFR_TXFF_BIT, 2b + str w0, [x1, #UARTDR] + ret +putc_error: + mov w0, #-1 + ret +endfunc console_core_putc + + /* --------------------------------------------- + * int console_core_getc(uintptr_t base_addr) + * Function to get a character from the console. + * It returns the character grabbed on success + * or -1 on error. + * In : x0 - console base address + * Clobber list : x0, x1 + * --------------------------------------------- + */ +func console_core_getc + cbz x0, getc_error +1: + /* Check if the receive FIFO is empty */ + ldr w1, [x0, #UARTFR] + tbnz w1, #PL011_UARTFR_RXFE_BIT, 1b + ldr w1, [x0, #UARTDR] + mov w0, w1 + ret +getc_error: + mov w0, #-1 + ret +endfunc console_core_getc diff --git a/drivers/arm/pl011/pl011_console.S b/drivers/arm/pl011/pl011_console.S index 5e97e911..44aafc2d 100644 --- a/drivers/arm/pl011/pl011_console.S +++ b/drivers/arm/pl011/pl011_console.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -27,127 +27,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ -#include -#include -#include -/* - * Pull in generic functions to provide backwards compatibility for - * platform makefiles - */ -#include "../../console/console.S" - - - .globl console_core_init - .globl console_core_putc - .globl console_core_getc - - - /* ----------------------------------------------- - * int console_core_init(uintptr_t base_addr, - * unsigned int uart_clk, unsigned int baud_rate) - * Function to initialize the console without a - * C Runtime to print debug information. This - * function will be accessed by console_init and - * crash reporting. - * In: x0 - console base address - * w1 - Uart clock in Hz - * w2 - Baud rate - * Out: return 1 on success else 0 on error - * Clobber list : x1, x2, x3, x4 - * ----------------------------------------------- - */ -func console_core_init - /* Check the input base address */ - cbz x0, core_init_fail -#if !PL011_GENERIC_UART - /* Check baud rate and uart clock for sanity */ - cbz w1, core_init_fail - cbz w2, core_init_fail - /* Disable uart before programming */ - ldr w3, [x0, #UARTCR] - mov w4, #PL011_UARTCR_UARTEN - bic w3, w3, w4 - str w3, [x0, #UARTCR] - /* Program the baudrate */ - /* Divisor = (Uart clock * 4) / baudrate */ - lsl w1, w1, #2 - udiv w2, w1, w2 - /* IBRD = Divisor >> 6 */ - lsr w1, w2, #6 - /* Write the IBRD */ - str w1, [x0, #UARTIBRD] - /* FBRD = Divisor & 0x3F */ - and w1, w2, #0x3f - /* Write the FBRD */ - str w1, [x0, #UARTFBRD] - mov w1, #PL011_LINE_CONTROL - str w1, [x0, #UARTLCR_H] - /* Clear any pending errors */ - str wzr, [x0, #UARTECR] - /* Enable tx, rx, and uart overall */ - mov w1, #(PL011_UARTCR_RXE | PL011_UARTCR_TXE | PL011_UARTCR_UARTEN) - str w1, [x0, #UARTCR] +#if !ERROR_DEPRECATED +#include "./aarch64/pl011_console.S" #endif - mov w0, #1 - ret -core_init_fail: - mov w0, wzr - ret -endfunc console_core_init - - /* -------------------------------------------------------- - * int console_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 - /* Check the input parameter */ - cbz x1, putc_error - /* Prepend '\r' to '\n' */ - cmp w0, #0xA - b.ne 2f -1: - /* Check if the transmit FIFO is full */ - ldr w2, [x1, #UARTFR] - tbnz w2, #PL011_UARTFR_TXFF_BIT, 1b - mov w2, #0xD - str w2, [x1, #UARTDR] -2: - /* Check if the transmit FIFO is full */ - ldr w2, [x1, #UARTFR] - tbnz w2, #PL011_UARTFR_TXFF_BIT, 2b - str w0, [x1, #UARTDR] - ret -putc_error: - mov w0, #-1 - ret -endfunc console_core_putc - - /* --------------------------------------------- - * int console_core_getc(uintptr_t base_addr) - * Function to get a character from the console. - * It returns the character grabbed on success - * or -1 on error. - * In : x0 - console base address - * Clobber list : x0, x1 - * --------------------------------------------- - */ -func console_core_getc - cbz x0, getc_error -1: - /* Check if the receive FIFO is empty */ - ldr w1, [x0, #UARTFR] - tbnz w1, #PL011_UARTFR_RXFE_BIT, 1b - ldr w1, [x0, #UARTDR] - mov w0, w1 - ret -getc_error: - mov w0, #-1 - ret -endfunc console_core_getc -- cgit From 367d0ffb14a4ed75cf34ec8f6699fbec853d36d8 Mon Sep 17 00:00:00 2001 From: Soby Mathew Date: Thu, 5 May 2016 13:59:07 +0100 Subject: AArch32: Enable GIC and TZC support This patch modifies GICv3 and TZC drivers to add AArch32 support. No modifications are required for the GICv2 driver for AArch32 support. The TZC driver assumes that the secure world is running in Little-Endian mode to do 64 bit manipulations. Assertions are present to validate the assumption. Note: The legacy GICv3 driver is not supported for AArch32. Change-Id: Id1bc75a9f5dafb9715c9500ca77b4606eb1e2458 --- drivers/arm/gic/v3/gicv3_main.c | 4 ++++ drivers/arm/gic/v3/gicv3_private.h | 8 ++++++-- drivers/arm/tzc/tzc400.c | 2 +- drivers/arm/tzc/tzc_common_private.c | 33 +++++++++++++++++++++++++++++++++ drivers/arm/tzc/tzc_dmc500.c | 2 +- 5 files changed, 45 insertions(+), 4 deletions(-) (limited to 'drivers/arm') diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c index 6c6c7af9..8cb80203 100644 --- a/drivers/arm/gic/v3/gicv3_main.c +++ b/drivers/arm/gic/v3/gicv3_main.c @@ -75,8 +75,12 @@ void gicv3_driver_init(const gicv3_driver_data_t *plat_driver_data) plat_driver_data->g1s_interrupt_num == 0); /* Check for system register support */ +#ifdef AARCH32 + assert(read_id_pfr1() & (ID_PFR1_GIC_MASK << ID_PFR1_GIC_SHIFT)); +#else assert(read_id_aa64pfr0_el1() & (ID_AA64PFR0_GIC_MASK << ID_AA64PFR0_GIC_SHIFT)); +#endif /* AARCH32 */ /* The GIC version should be 3.0 */ gic_version = gicd_read_pidr2(plat_driver_data->gicd_base); diff --git a/drivers/arm/gic/v3/gicv3_private.h b/drivers/arm/gic/v3/gicv3_private.h index 9aa83382..1344a885 100644 --- a/drivers/arm/gic/v3/gicv3_private.h +++ b/drivers/arm/gic/v3/gicv3_private.h @@ -79,9 +79,13 @@ * Macro to convert a GICR_TYPER affinity value into a MPIDR value. Bits[31:24] * are zeroes. */ +#ifdef AARCH32 +#define mpidr_from_gicr_typer(typer_val) (((typer_val) >> 32) & 0xffffff) +#else #define mpidr_from_gicr_typer(typer_val) \ - ((((typer_val >> 56) & MPIDR_AFFLVL_MASK) << MPIDR_AFF3_SHIFT) | \ - ((typer_val >> 32) & 0xffffff)) + (((((typer_val) >> 56) & MPIDR_AFFLVL_MASK) << MPIDR_AFF3_SHIFT) | \ + (((typer_val) >> 32) & 0xffffff)) +#endif /******************************************************************************* * Private GICv3 function prototypes for accessing entire registers. diff --git a/drivers/arm/tzc/tzc400.c b/drivers/arm/tzc/tzc400.c index e5335872..ca088c32 100644 --- a/drivers/arm/tzc/tzc400.c +++ b/drivers/arm/tzc/tzc400.c @@ -206,7 +206,7 @@ void tzc400_configure_region(unsigned int filters, * Do address range check based on TZC configuration. A 64bit address is * the max and expected case. */ - assert(((region_top <= (UINT64_MAX >> (64 - tzc400.addr_width))) && + assert(((region_top <= _tzc_get_max_top_addr(tzc400.addr_width)) && (region_base < region_top))); /* region_base and (region_top + 1) must be 4KB aligned */ diff --git a/drivers/arm/tzc/tzc_common_private.c b/drivers/arm/tzc/tzc_common_private.c index dae6c3ac..8b1ddf49 100644 --- a/drivers/arm/tzc/tzc_common_private.c +++ b/drivers/arm/tzc/tzc_common_private.c @@ -28,6 +28,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include +#include #include #include @@ -199,4 +201,35 @@ static unsigned int _tzc_read_peripheral_id(uintptr_t base) return id; } + +#ifdef AARCH32 +static unsigned long long _tzc_get_max_top_addr(int addr_width) +{ + /* + * Assume at least 32 bit wide address and initialize the max. + * This function doesn't use 64-bit integer arithmetic to avoid + * having to implement additional compiler library functions. + */ + unsigned long long addr_mask = 0xFFFFFFFF; + uint32_t *addr_ptr = (uint32_t *)&addr_mask; + + assert(addr_width >= 32); + + /* This logic works only on little - endian platforms */ + assert((read_sctlr() & SCTLR_EE_BIT) == 0); + + /* + * If required address width is greater than 32, populate the higher + * 32 bits of the 64 bit field with the max address. + */ + if (addr_width > 32) + *(addr_ptr + 1) = ((1 << (addr_width - 32)) - 1); + + return addr_mask; +} +#else +#define _tzc_get_max_top_addr(addr_width)\ + (UINT64_MAX >> (64 - (addr_width))) +#endif /* AARCH32 */ + #endif diff --git a/drivers/arm/tzc/tzc_dmc500.c b/drivers/arm/tzc/tzc_dmc500.c index b2f0bf67..24e587c1 100644 --- a/drivers/arm/tzc/tzc_dmc500.c +++ b/drivers/arm/tzc/tzc_dmc500.c @@ -211,7 +211,7 @@ void tzc_dmc500_configure_region(int region_no, * Do address range check based on DMC-TZ configuration. A 43bit address * is the max and expected case. */ - assert(((region_top <= (UINT64_MAX >> (64 - 43))) && + assert(((region_top <= _tzc_get_max_top_addr(43)) && (region_base < region_top))); /* region_base and (region_top + 1) must be 4KB aligned */ -- cgit From 66be868e9acc7b34852f755934664b191e9fae13 Mon Sep 17 00:00:00 2001 From: Soby Mathew Date: Thu, 24 Mar 2016 16:52:40 +0000 Subject: AArch32: Add console driver This patch adds console drivers including the pl011 driver for the AArch32 mode. Change-Id: Ifd22520d370fca3e73dbbf6f2d97d6aee65b67dd --- drivers/arm/pl011/aarch32/pl011_console.S | 160 ++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 drivers/arm/pl011/aarch32/pl011_console.S (limited to 'drivers/arm') diff --git a/drivers/arm/pl011/aarch32/pl011_console.S b/drivers/arm/pl011/aarch32/pl011_console.S new file mode 100644 index 00000000..21ed7ab8 --- /dev/null +++ b/drivers/arm/pl011/aarch32/pl011_console.S @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * + * 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 + +/* + * Pull in generic functions to provide backwards compatibility for + * platform makefiles + */ +#include "../../../console/aarch32/console.S" + + .globl console_core_init + .globl console_core_putc + .globl console_core_getc + + + /* ----------------------------------------------- + * int console_core_init(uintptr_t base_addr, + * unsigned int uart_clk, unsigned int baud_rate) + * Function to initialize the console without a + * C Runtime to print debug information. This + * function will be accessed by console_init and + * crash reporting. + * In: r0 - console base address + * r1 - Uart clock in Hz + * r2 - Baud rate + * Out: return 1 on success else 0 on error + * Clobber list : r1, r2, r3 + * ----------------------------------------------- + */ +func console_core_init + /* Check the input base address */ + cmp r0, #0 + beq core_init_fail +#if !PL011_GENERIC_UART + /* Check baud rate and uart clock for sanity */ + cmp r1, #0 + beq core_init_fail + cmp r2, #0 + beq core_init_fail + /* Disable the UART before initialization */ + ldr r3, [r0, #UARTCR] + bic r3, r3, #PL011_UARTCR_UARTEN + str r3, [r0, #UARTCR] + /* Program the baudrate */ + /* Divisor = (Uart clock * 4) / baudrate */ + lsl r1, r1, #2 + udiv r2, r1, r2 + /* IBRD = Divisor >> 6 */ + lsr r1, r2, #6 + /* Write the IBRD */ + str r1, [r0, #UARTIBRD] + /* FBRD = Divisor & 0x3F */ + and r1, r2, #0x3f + /* Write the FBRD */ + str r1, [r0, #UARTFBRD] + mov r1, #PL011_LINE_CONTROL + str r1, [r0, #UARTLCR_H] + /* Clear any pending errors */ + mov r1, #0 + str r1, [r0, #UARTECR] + /* Enable tx, rx, and uart overall */ + ldr r1, =(PL011_UARTCR_RXE | PL011_UARTCR_TXE | PL011_UARTCR_UARTEN) + str r1, [r0, #UARTCR] +#endif + mov r0, #1 + bx lr +core_init_fail: + mov r0, #0 + bx lr +endfunc console_core_init + + /* -------------------------------------------------------- + * int console_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 : r0 - character to be printed + * r1 - console base address + * Out : return -1 on error else return character. + * Clobber list : r2 + * -------------------------------------------------------- + */ +func console_core_putc + /* Check the input parameter */ + cmp r1, #0 + beq putc_error + /* Prepend '\r' to '\n' */ + cmp r0, #0xA + bne 2f +1: + /* Check if the transmit FIFO is full */ + ldr r2, [r1, #UARTFR] + tst r2, #PL011_UARTFR_TXFF_BIT + beq 1b + mov r2, #0xD + str r2, [r1, #UARTDR] +2: + /* Check if the transmit FIFO is full */ + ldr r2, [r1, #UARTFR] + tst r2, #PL011_UARTFR_TXFF_BIT + beq 2b + str r0, [r1, #UARTDR] + bx lr +putc_error: + mov r0, #-1 + bx lr +endfunc console_core_putc + + /* --------------------------------------------- + * int console_core_getc(uintptr_t base_addr) + * Function to get a character from the console. + * It returns the character grabbed on success + * or -1 on error. + * In : r0 - console base address + * Clobber list : r0, r1 + * --------------------------------------------- + */ +func console_core_getc + cmp r0, #0 + beq getc_error +1: + /* Check if the receive FIFO is empty */ + ldr r1, [r0, #UARTFR] + tst r1, #PL011_UARTFR_RXFE_BIT + beq 1b + ldr r1, [r0, #UARTDR] + mov r0, r1 + bx lr +getc_error: + mov r0, #-1 + bx lr +endfunc console_core_getc -- cgit