blob: 792703a9312d20673fcc5d537f501ee5f0f64fe9 [file] [log] [blame]
Yann Gautier4b0c72a2018-07-16 10:54:09 +02001/*
2 * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6#include <asm_macros.S>
7
Yann Gautier69035a82018-07-05 16:48:16 +02008#define USART_TIMEOUT 0x1000
9
10#define USART_CR1 0x00
11#define USART_CR1_UE 0x00000001
12#define USART_CR1_TE 0x00000008
13#define USART_CR1_FIFOEN 0x20000000
14
15#define USART_CR2 0x04
16#define USART_CR2_STOP 0x00003000
17
18#define USART_BRR 0x0C
19
20#define USART_ISR 0x1C
21#define USART_ISR_TC 0x00000040
22#define USART_ISR_TXE 0x00000080
23#define USART_ISR_TEACK 0x00200000
24
25#define USART_TDR 0x28
26
Yann Gautier4b0c72a2018-07-16 10:54:09 +020027 .globl console_core_init
28 .globl console_core_putc
29 .globl console_core_getc
30 .globl console_core_flush
31
32 /* -----------------------------------------------------------------
33 * int console_core_init(uintptr_t base_addr,
34 * unsigned int uart_clk,
35 * unsigned int baud_rate)
36 *
37 * Function to initialize the console without a C Runtime to print
38 * debug information. This function will be accessed by console_init
39 * and crash reporting.
40 *
41 * In: r0 - console base address
42 * r1 - Uart clock in Hz
43 * r2 - Baud rate
44 * Out: return 1 on success else 0 on error
45 * Clobber list : r1, r2, r3
46 * -----------------------------------------------------------------
47 */
48func console_core_init
Yann Gautier69035a82018-07-05 16:48:16 +020049 /* Check the input base address */
50 cmp r0, #0
51 beq core_init_fail
52#if defined(IMAGE_BL2)
53 /* Check baud rate and uart clock for sanity */
54 cmp r1, #0
55 beq core_init_fail
56 cmp r2, #0
57 beq core_init_fail
58 /* Disable UART */
59 ldr r3, [r0, #USART_CR1]
60 bic r3, r3, #USART_CR1_UE
61 str r3, [r0, #USART_CR1]
62 /* Configure UART */
63 orr r3, r3, #(USART_CR1_TE | USART_CR1_FIFOEN)
64 str r3, [r0, #USART_CR1]
65 ldr r3, [r0, #USART_CR2]
66 bic r3, r3, #USART_CR2_STOP
67 str r3, [r0, #USART_CR2]
68 /* Divisor = (Uart clock + (baudrate / 2)) / baudrate */
69 lsl r3, r2, #1
70 add r3, r1, r3
71 udiv r3, r3, r2
72 str r3, [r0, #USART_BRR]
73 /* Enable UART */
74 ldr r3, [r0, #USART_CR1]
75 orr r3, r3, #USART_CR1_UE
76 str r3, [r0, #USART_CR1]
77 /* Check TEACK bit */
78 mov r2, #USART_TIMEOUT
79teack_loop:
80 subs r2, r2, #1
81 beq core_init_fail
82 ldr r3, [r0, #USART_ISR]
83 tst r3, #USART_ISR_TEACK
84 beq teack_loop
85#endif /* IMAGE_BL2 */
86 mov r0, #1
87 bx lr
88core_init_fail:
89 mov r0, #0
Yann Gautier4b0c72a2018-07-16 10:54:09 +020090 bx lr
91endfunc console_core_init
92
93 /* ---------------------------------------------------------------
94 * int console_core_putc(int c, uintptr_t base_addr)
95 *
96 * Function to output a character over the console. It returns the
97 * character printed on success or -1 on error.
98 *
99 * In : r0 - character to be printed
100 * r1 - console base address
101 * Out : return -1 on error else return character.
102 * Clobber list : r2
103 * ---------------------------------------------------------------
104 */
105func console_core_putc
Yann Gautier69035a82018-07-05 16:48:16 +0200106 /* Check the input parameter */
107 cmp r1, #0
108 beq putc_error
109 /* Prepend '\r' to '\n' */
110 cmp r0, #0xA
111 bne 2f
1121:
113 /* Check Transmit Data Register Empty */
114txe_loop_1:
115 ldr r2, [r1, #USART_ISR]
116 tst r2, #USART_ISR_TXE
117 beq txe_loop_1
118 mov r2, #0xD
119 str r2, [r1, #USART_TDR]
120 /* Check transmit complete flag */
121tc_loop_1:
122 ldr r2, [r1, #USART_ISR]
123 tst r2, #USART_ISR_TC
124 beq tc_loop_1
1252:
126 /* Check Transmit Data Register Empty */
127txe_loop_2:
128 ldr r2, [r1, #USART_ISR]
129 tst r2, #USART_ISR_TXE
130 beq txe_loop_2
131 str r0, [r1, #USART_TDR]
132 /* Check transmit complete flag */
133tc_loop_2:
134 ldr r2, [r1, #USART_ISR]
135 tst r2, #USART_ISR_TC
136 beq tc_loop_2
137 bx lr
138putc_error:
139 mov r0, #-1
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200140 bx lr
141endfunc console_core_putc
142
143 /* -----------------------------------------------------------
144 * int console_core_getc(uintptr_t base_addr)
145 *
146 * Function to get a character from the console.
147 * It returns the character grabbed on success or -1 on error.
148 *
149 * In : r0 - console base address
150 * Out : return -1.
151 * Clobber list : r0, r1
152 * -----------------------------------------------------------
153 */
154func console_core_getc
155 /* Not supported */
156 mov r0, #-1
157 bx lr
158endfunc console_core_getc
159
160 /* ---------------------------------------------------------------
161 * int console_core_flush(uintptr_t base_addr)
162 *
163 * Function to force a write of all buffered data that hasn't been
164 * output.
165 *
166 * In : r0 - console base address
167 * Out : return -1 on error else return 0.
168 * Clobber list : r0, r1
169 * ---------------------------------------------------------------
170 */
171func console_core_flush
Yann Gautier69035a82018-07-05 16:48:16 +0200172 cmp r0, #0
173 beq flush_error
174 /* Check Transmit Data Register Empty */
175txe_loop_3:
176 ldr r1, [r0, #USART_ISR]
177 tst r1, #USART_ISR_TXE
178 beq txe_loop_3
179 mov r0, #0
180 bx lr
181flush_error:
182 mov r0, #-1
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200183 bx lr
184endfunc console_core_flush