diff options
author | Soby Mathew <soby.mathew@arm.com> | 2014-06-24 12:28:41 +0100 |
---|---|---|
committer | Soby Mathew <soby.mathew@arm.com> | 2014-07-28 10:44:04 +0100 |
commit | fce5f7501afad3fb1aa0cbff3c3d666e2c0f36f9 (patch) | |
tree | 5791bfd0084ca699f87301d1a2ac0f475ecbc772 /drivers | |
parent | 592dd7cbe658cc33ae2818c9ed543ac57e97f784 (diff) |
Introduce asm console functions in TF
This patch replaces the pl011 console family of functions
with their equivalents defined in assembly. The baud rate is
defined by the PL011_BAUDRATE macro and IBRD and FBRD values
for pl011 are computed statically. This patch will enable
us to invoke the console functions without the C Runtime Stack.
Change-Id: Ic3f7b7370ded38bf9020bf746b362081b76642c7
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/arm/pl011/pl011.c | 41 | ||||
-rw-r--r-- | drivers/arm/pl011/pl011_console.S | 175 | ||||
-rw-r--r-- | drivers/arm/pl011/pl011_console.c | 98 |
3 files changed, 175 insertions, 139 deletions
diff --git a/drivers/arm/pl011/pl011.c b/drivers/arm/pl011/pl011.c deleted file mode 100644 index e296c23..0000000 --- a/drivers/arm/pl011/pl011.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2013-2014, 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 <assert.h> -#include <pl011.h> - -void pl011_setbaudrate(unsigned long base_addr, unsigned int baudrate) -{ - unsigned int divisor; - assert(baudrate); - divisor = (PL011_CLK_IN_HZ * 4) / baudrate; - pl011_write_ibrd(base_addr, divisor >> 6); - pl011_write_fbrd(base_addr, divisor & 0x3F); -} diff --git a/drivers/arm/pl011/pl011_console.S b/drivers/arm/pl011/pl011_console.S new file mode 100644 index 0000000..bf26b6b --- /dev/null +++ b/drivers/arm/pl011/pl011_console.S @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2013-2014, 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 <arch.h> +#include <asm_macros.S> +#include <pl011.h> + + .globl console_init + .globl console_putc + .globl console_core_init + .globl console_core_putc + .globl console_getc + + /* + * 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 + + /* --------------------------------------------- + * int console_init(unsigned long base_addr) + * Function to initialize the console without a + * C Runtime to print debug information. It saves + * the console base to the data section. + * In: x0 - console base address + * out: return 1 on success. + * Clobber list : x1, x2 + * --------------------------------------------- + */ +func console_init + adrp x1, console_base + str x0, [x1, :lo12:console_base] + b console_core_init + + /* --------------------------------------------- + * int console_core_init(unsigned long 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. + * In: x0 - console base address + * Out: return 1 on success + * Clobber list : x1, x2 + * --------------------------------------------- + */ +func console_core_init + /* Check the input base address */ + cbz x0, init_fail + /* Program the baudrate */ +#if defined(PL011_INTEGER) && defined(PL011_FRACTIONAL) + mov w1, #PL011_INTEGER + str w1, [x0, #UARTIBRD] + mov w1, #PL011_FRACTIONAL + str w1, [x0, #UARTFBRD] +#else +.set BRD, ((PL011_CLK_IN_HZ << 2) / PL011_BAUDRATE) + /* Write the IBRD */ + mov w1, #((BRD >> 6) & 0xffff) +.if BRD>=0x400000 + movk w1, #(BRD >> 22), LSL #16 +.endif + str w1, [x0, #UARTIBRD] + /* Write the FBRD */ + mov w1, #(BRD & 0x3f) + str w1, [x0, #UARTFBRD] +#endif + 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] + mov w0, #1 +init_fail: + ret + + /* --------------------------------------------- + * int console_putc(int c) + * Function to output a character over the + * console. It returns the character printed on + * success or -1 on error. + * In : x0 - character to be printed + * Out : return -1 on error else return character. + * Clobber list : x1, x2 + * --------------------------------------------- + */ +func console_putc + adrp x2, console_base + ldr x1, [x2, :lo12:console_base] + b console_core_putc + + /* -------------------------------------------------------- + * int console_core_putc(int c, unsigned long base_addr) + * Function to output a character over the console. It + * returns the character printed on success or -1 on error. + * In : x0 - 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 x0, #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 + + /* --------------------------------------------- + * int console_getc(void) + * Function to get a character from the console. + * It returns the character grabbed on success + * or -1 on error. + * Clobber list : x0, x1 + * --------------------------------------------- + */ +func console_getc + adrp x0, console_base + ldr x1, [x0, :lo12:console_base] + cbz x1, getc_error +1: + /* Check if the receive FIFO is empty */ + ldr w0, [x1, #UARTFR] + tbnz w0, #PL011_UARTFR_RXFE_BIT, 1b + ldr w0, [x1, #UARTDR] + ret +getc_error: + mov w0, #-1 + ret diff --git a/drivers/arm/pl011/pl011_console.c b/drivers/arm/pl011/pl011_console.c deleted file mode 100644 index 81897ca..0000000 --- a/drivers/arm/pl011/pl011_console.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2013-2014, 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 <assert.h> -#include <console.h> -#include <pl011.h> - -static unsigned long uart_base; - -void console_init(unsigned long base_addr) -{ - /* TODO: assert() internally calls printf() and will result in - * an infinite loop. This needs to be fixed with some kind of - * exception mechanism or early panic support. This also applies - * to the other assert() calls below. - */ - assert(base_addr); - - /* Initialise internal base address variable */ - uart_base = base_addr; - - /* Baud Rate */ -#if defined(PL011_INTEGER) && defined(PL011_FRACTIONAL) - pl011_write_ibrd(uart_base, PL011_INTEGER); - pl011_write_fbrd(uart_base, PL011_FRACTIONAL); -#else - pl011_setbaudrate(uart_base, PL011_BAUDRATE); -#endif - - pl011_write_lcr_h(uart_base, PL011_LINE_CONTROL); - - /* Clear any pending errors */ - pl011_write_ecr(uart_base, 0); - - /* Enable tx, rx, and uart overall */ - pl011_write_cr(uart_base, PL011_UARTCR_RXE | PL011_UARTCR_TXE | - PL011_UARTCR_UARTEN); - -} - -#define WAIT_UNTIL_UART_FREE(base) \ - while ((pl011_read_fr(base) & PL011_UARTFR_TXFF)) \ - continue - -int console_putc(int c) -{ - /* If the console has not been initialized then return an error - * code. Asserting here would result in recursion and stack - * exhaustion - */ - if (!uart_base) - return -1; - - if (c == '\n') { - WAIT_UNTIL_UART_FREE(uart_base); - pl011_write_dr(uart_base, '\r'); - } - - WAIT_UNTIL_UART_FREE(uart_base); - pl011_write_dr(uart_base, c); - return c; -} - -int console_getc(void) -{ - assert(uart_base); - - while ((pl011_read_fr(uart_base) & PL011_UARTFR_RXFE) != 0) - ; - return pl011_read_dr(uart_base); -} |