blob: 5d6b95fe3ea5e4e9afd25e2a164762db8594158b [file] [log] [blame]
Soby Mathew420cc372016-03-24 16:52:40 +00001/*
Daniel Boulby05e7f562018-09-19 13:58:20 +01002 * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
Soby Mathew420cc372016-03-24 16:52:40 +00003 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Soby Mathew420cc372016-03-24 16:52:40 +00005 */
6#include <arch.h>
7#include <asm_macros.S>
Daniel Boulby05e7f562018-09-19 13:58:20 +01008#include <assert_macros.S>
Soby Mathew58873ae2018-10-10 16:03:09 +01009#define USE_FINISH_CONSOLE_REG_2
Daniel Boulby05e7f562018-09-19 13:58:20 +010010#include <console_macros.S>
Soby Mathew420cc372016-03-24 16:52:40 +000011#include <pl011.h>
12
Julius Werner6b88b652018-11-27 17:50:28 -080013#if !MULTI_CONSOLE_API
Soby Mathew420cc372016-03-24 16:52:40 +000014/*
15 * Pull in generic functions to provide backwards compatibility for
16 * platform makefiles
17 */
18#include "../../../console/aarch32/console.S"
Julius Werner6b88b652018-11-27 17:50:28 -080019#endif
Soby Mathew420cc372016-03-24 16:52:40 +000020
Daniel Boulby05e7f562018-09-19 13:58:20 +010021 /*
22 * "core" functions are low-level implementations that don't require
23 * writeable memory and are thus safe to call in BL1 crash context.
24 */
25 .globl console_pl011_core_init
26 .globl console_pl011_core_putc
27 .globl console_pl011_core_getc
28 .globl console_pl011_core_flush
29
30 .globl console_pl011_putc
31 .globl console_pl011_getc
32 .globl console_pl011_flush
Soby Mathew420cc372016-03-24 16:52:40 +000033
34
35 /* -----------------------------------------------
36 * int console_core_init(uintptr_t base_addr,
37 * unsigned int uart_clk, unsigned int baud_rate)
38 * Function to initialize the console without a
39 * C Runtime to print debug information. This
40 * function will be accessed by console_init and
41 * crash reporting.
42 * In: r0 - console base address
43 * r1 - Uart clock in Hz
44 * r2 - Baud rate
45 * Out: return 1 on success else 0 on error
46 * Clobber list : r1, r2, r3
47 * -----------------------------------------------
48 */
Daniel Boulby05e7f562018-09-19 13:58:20 +010049func console_pl011_core_init
Soby Mathew420cc372016-03-24 16:52:40 +000050 /* Check the input base address */
51 cmp r0, #0
52 beq core_init_fail
53#if !PL011_GENERIC_UART
54 /* Check baud rate and uart clock for sanity */
55 cmp r1, #0
56 beq core_init_fail
57 cmp r2, #0
58 beq core_init_fail
59 /* Disable the UART before initialization */
60 ldr r3, [r0, #UARTCR]
61 bic r3, r3, #PL011_UARTCR_UARTEN
62 str r3, [r0, #UARTCR]
63 /* Program the baudrate */
64 /* Divisor = (Uart clock * 4) / baudrate */
65 lsl r1, r1, #2
66 udiv r2, r1, r2
67 /* IBRD = Divisor >> 6 */
68 lsr r1, r2, #6
69 /* Write the IBRD */
70 str r1, [r0, #UARTIBRD]
71 /* FBRD = Divisor & 0x3F */
72 and r1, r2, #0x3f
73 /* Write the FBRD */
74 str r1, [r0, #UARTFBRD]
75 mov r1, #PL011_LINE_CONTROL
76 str r1, [r0, #UARTLCR_H]
77 /* Clear any pending errors */
78 mov r1, #0
79 str r1, [r0, #UARTECR]
80 /* Enable tx, rx, and uart overall */
81 ldr r1, =(PL011_UARTCR_RXE | PL011_UARTCR_TXE | PL011_UARTCR_UARTEN)
82 str r1, [r0, #UARTCR]
83#endif
84 mov r0, #1
85 bx lr
86core_init_fail:
87 mov r0, #0
88 bx lr
Daniel Boulby05e7f562018-09-19 13:58:20 +010089endfunc console_pl011_core_init
90
91#if MULTI_CONSOLE_API
92 .globl console_pl011_register
93
94 /* -------------------------------------------------------
Antonio Nino Diaz992c5ac2018-10-08 13:26:48 +010095 * int console_pl011_register(uintptr_t baseaddr,
96 * uint32_t clock, uint32_t baud,
97 * console_pl011_t *console);
Daniel Boulby05e7f562018-09-19 13:58:20 +010098 * Function to initialize and register a new PL011
99 * console. Storage passed in for the console struct
100 * *must* be persistent (i.e. not from the stack).
101 * In: r0 - UART register base address
102 * r1 - UART clock in Hz
103 * r2 - Baud rate
104 * r3 - pointer to empty console_pl011_t struct
105 * Out: return 1 on success, 0 on error
106 * Clobber list : r0, r1, r2
107 * -------------------------------------------------------
108 */
109func console_pl011_register
110 push {r4, lr}
111 mov r4, r3
112 cmp r4, #0
113 beq register_fail
114 str r0, [r4, #CONSOLE_T_PL011_BASE]
115
116 bl console_pl011_core_init
117 cmp r0, #0
118 beq register_fail
119
120 mov r0, r4
121 pop {r4, lr}
Soby Mathew58873ae2018-10-10 16:03:09 +0100122 finish_console_register pl011 putc=1, getc=1, flush=1
Daniel Boulby05e7f562018-09-19 13:58:20 +0100123
124register_fail:
125 pop {r4, pc}
126endfunc console_pl011_register
127#else
128 .globl console_core_init
129 .globl console_core_putc
130 .globl console_core_getc
131 .globl console_core_flush
132 .equ console_core_init, console_pl011_core_init
133 .equ console_core_putc, console_pl011_core_putc
134 .equ console_core_getc, console_pl011_core_getc
135 .equ console_core_flush, console_pl011_core_flush
136#endif
Soby Mathew420cc372016-03-24 16:52:40 +0000137
138 /* --------------------------------------------------------
139 * int console_core_putc(int c, uintptr_t base_addr)
140 * Function to output a character over the console. It
141 * returns the character printed on success or -1 on error.
142 * In : r0 - character to be printed
143 * r1 - console base address
144 * Out : return -1 on error else return character.
145 * Clobber list : r2
146 * --------------------------------------------------------
147 */
Daniel Boulby05e7f562018-09-19 13:58:20 +0100148func console_pl011_core_putc
Soby Mathew420cc372016-03-24 16:52:40 +0000149 /* Check the input parameter */
150 cmp r1, #0
151 beq putc_error
152 /* Prepend '\r' to '\n' */
153 cmp r0, #0xA
154 bne 2f
1551:
156 /* Check if the transmit FIFO is full */
157 ldr r2, [r1, #UARTFR]
Yatharth Kochard0f5f9c2016-11-09 15:39:25 +0000158 tst r2, #PL011_UARTFR_TXFF
159 bne 1b
Soby Mathew420cc372016-03-24 16:52:40 +0000160 mov r2, #0xD
161 str r2, [r1, #UARTDR]
1622:
163 /* Check if the transmit FIFO is full */
164 ldr r2, [r1, #UARTFR]
Yatharth Kochard0f5f9c2016-11-09 15:39:25 +0000165 tst r2, #PL011_UARTFR_TXFF
166 bne 2b
Soby Mathew420cc372016-03-24 16:52:40 +0000167 str r0, [r1, #UARTDR]
168 bx lr
169putc_error:
170 mov r0, #-1
171 bx lr
Daniel Boulby05e7f562018-09-19 13:58:20 +0100172endfunc console_pl011_core_putc
173
174 /* --------------------------------------------------------
175 * int console_pl011_putc(int c, console_pl011_t *console)
176 * Function to output a character over the console. It
177 * returns the character printed on success or -1 on error.
178 * In: r0 - character to be printed
179 * r1 - pointer to console_t structure
180 * Out : return -1 on error else return character.
181 * Clobber list: r2
182 * -------------------------------------------------------
183 */
184func console_pl011_putc
185#if ENABLE_ASSERTIONS
186 cmp r1, #0
187 ASM_ASSERT(ne)
188#endif /* ENABLE_ASSERTIONS */
189 ldr r1, [r1, #CONSOLE_T_PL011_BASE]
190 b console_pl011_core_putc
191endfunc console_pl011_putc
Soby Mathew420cc372016-03-24 16:52:40 +0000192
193 /* ---------------------------------------------
194 * int console_core_getc(uintptr_t base_addr)
195 * Function to get a character from the console.
196 * It returns the character grabbed on success
197 * or -1 on error.
198 * In : r0 - console base address
199 * Clobber list : r0, r1
200 * ---------------------------------------------
201 */
Daniel Boulby05e7f562018-09-19 13:58:20 +0100202func console_pl011_core_getc
Soby Mathew420cc372016-03-24 16:52:40 +0000203 cmp r0, #0
204 beq getc_error
2051:
206 /* Check if the receive FIFO is empty */
207 ldr r1, [r0, #UARTFR]
Yatharth Kochard0f5f9c2016-11-09 15:39:25 +0000208 tst r1, #PL011_UARTFR_RXFE
209 bne 1b
Soby Mathew420cc372016-03-24 16:52:40 +0000210 ldr r1, [r0, #UARTDR]
211 mov r0, r1
212 bx lr
213getc_error:
214 mov r0, #-1
215 bx lr
Daniel Boulby05e7f562018-09-19 13:58:20 +0100216endfunc console_pl011_core_getc
217
218 /* ------------------------------------------------
219 * int console_pl011_getc(console_pl011_t *console)
220 * Function to get a character from the console.
221 * It returns the character grabbed on success
222 * or -1 if no character is available.
223 * In : r0 - pointer to console_t structure
224 * Out: r0 - character if available, else -1
225 * Clobber list: r0, r1
226 * ------------------------------------------------
227 */
228func console_pl011_getc
229#if ENABLE_ASSERTIONS
230 cmp r0, #0
231 ASM_ASSERT(ne)
232#endif /* ENABLE_ASSERTIONS */
233 ldr r0, [r0, #CONSOLE_T_PL011_BASE]
234 b console_pl011_core_getc
235endfunc console_pl011_getc
Antonio Nino Diaz8377ae42017-02-06 16:03:41 +0000236
237 /* ---------------------------------------------
238 * int console_core_flush(uintptr_t base_addr)
239 * Function to force a write of all buffered
240 * data that hasn't been output.
241 * In : r0 - console base address
242 * Out : return -1 on error else return 0.
243 * Clobber list : r0, r1
244 * ---------------------------------------------
245 */
Daniel Boulby05e7f562018-09-19 13:58:20 +0100246func console_pl011_core_flush
Antonio Nino Diaz8377ae42017-02-06 16:03:41 +0000247 cmp r0, #0
248 beq flush_error
249
2501:
251 /* Loop while the transmit FIFO is busy */
252 ldr r1, [r0, #UARTFR]
253 tst r1, #PL011_UARTFR_BUSY
254 bne 1b
255
256 mov r0, #0
257 bx lr
258flush_error:
259 mov r0, #-1
260 bx lr
Daniel Boulby05e7f562018-09-19 13:58:20 +0100261endfunc console_pl011_core_flush
262
263 /* ---------------------------------------------
264 * int console_pl011_flush(console_pl011_t *console)
265 * Function to force a write of all buffered
266 * data that hasn't been output.
267 * In : r0 - pointer to console_t structure
268 * Out : return -1 on error else return 0.
269 * Clobber list: r0, r1
270 * ---------------------------------------------
271 */
272func console_pl011_flush
273#if ENABLE_ASSERTIONS
274 cmp r0, #0
275 ASM_ASSERT(ne)
276#endif /* ENABLE_ASSERTIONS */
277 ldr r0, [r0, #CONSOLE_T_PL011_BASE]
278 b console_pl011_core_flush
279endfunc console_pl011_flush