Introduce asm console functions in TF
authorSoby Mathew <soby.mathew@arm.com>
Tue, 24 Jun 2014 11:28:41 +0000 (12:28 +0100)
committerSoby Mathew <soby.mathew@arm.com>
Mon, 28 Jul 2014 09:44:04 +0000 (10:44 +0100)
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

drivers/arm/pl011/pl011.c [deleted file]
drivers/arm/pl011/pl011_console.S [new file with mode: 0644]
drivers/arm/pl011/pl011_console.c [deleted file]
include/drivers/arm/pl011.h
plat/fvp/platform.mk

diff --git a/drivers/arm/pl011/pl011.c b/drivers/arm/pl011/pl011.c
deleted file mode 100644 (file)
index e296c23..0000000
+++ /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 (file)
index 0000000..bf26b6b
--- /dev/null
@@ -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 (file)
index 81897ca..0000000
+++ /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);
-}
index 281330e44311d881fd1b9e5c9aa8f897fd220969..e01d8b287694e933dc8feaa982ebf4413359f578 100644 (file)
@@ -31,9 +31,6 @@
 #ifndef __PL011_H__
 #define __PL011_H__
 
-#include <mmio.h>
-
-
 /* PL011 Registers */
 #define UARTDR                    0x000
 #define UARTRSR                   0x004
@@ -68,6 +65,9 @@
 #define PL011_UARTFR_DSR          (1 << 1)     /* Data set ready */
 #define PL011_UARTFR_CTS          (1 << 0)     /* Clear to send */
 
+#define PL011_UARTFR_TXFF_BIT  5       /* Transmit FIFO full bit in UARTFR register */
+#define PL011_UARTFR_RXFE_BIT  4       /* Receive FIFO empty bit in UARTFR register */
+
 /* Control reg bits */
 #define PL011_UARTCR_CTSEN        (1 << 15)    /* CTS hardware flow control enable */
 #define PL011_UARTCR_RTSEN        (1 << 14)    /* RTS hardware flow control enable */
 #define PL011_UARTLCR_H_PEN       (1 << 1)     /* Parity Enable */
 #define PL011_UARTLCR_H_BRK       (1 << 0)     /* Send break */
 
-/*******************************************************************************
- * Pl011 CPU interface accessors for writing registers
- ******************************************************************************/
-
-static inline void pl011_write_ibrd(unsigned long base, unsigned int val)
-{
-       mmio_write_32(base + UARTIBRD, val);
-}
-
-static inline void pl011_write_fbrd(unsigned long base, unsigned int val)
-{
-       mmio_write_32(base + UARTFBRD, val);
-}
-
-static inline void pl011_write_lcr_h(unsigned long base, unsigned int val)
-{
-       mmio_write_32(base + UARTLCR_H, val);
-}
-
-static inline void pl011_write_ecr(unsigned long base, unsigned int val)
-{
-       mmio_write_32(base + UARTECR, val);
-}
-
-static inline void pl011_write_cr(unsigned long base, unsigned int val)
-{
-       mmio_write_32(base + UARTCR, val);
-}
-
-static inline void pl011_write_dr(unsigned long base, unsigned int val)
-{
-       mmio_write_32(base + UARTDR, val);
-}
-
-/*******************************************************************************
- * Pl011 CPU interface accessors for reading registers
- ******************************************************************************/
-
-static inline unsigned int pl011_read_fr(unsigned long base)
-{
-       return mmio_read_32(base + UARTFR);
-}
-
-static inline unsigned int pl011_read_dr(unsigned long base)
-{
-       return mmio_read_32(base + UARTDR);
-}
-
-/*******************************************************************************
- * Function prototypes
- ******************************************************************************/
-
-void pl011_setbaudrate(unsigned long base_addr, unsigned int baudrate);
-
 #endif /* __PL011_H__ */
index b22a339304f8dbe6284933a7e9237570d636f418..f6275b78ee55a24d6664e87975f170daa985101b 100644 (file)
@@ -45,8 +45,7 @@ $(eval $(call add_define,TSP_RAM_LOCATION_ID))
 
 PLAT_INCLUDES          :=      -Iplat/fvp/include/
 
-PLAT_BL_COMMON_SOURCES :=      drivers/arm/pl011/pl011.c                       \
-                               drivers/arm/pl011/pl011_console.c               \
+PLAT_BL_COMMON_SOURCES :=      drivers/arm/pl011/pl011_console.S               \
                                drivers/io/io_fip.c                             \
                                drivers/io/io_memmap.c                          \
                                drivers/io/io_semihosting.c                     \