blob: c88990e246c443e2191f865aa17f367195c75b07 [file] [log] [blame]
Amit Nagal7c9f2fc2024-02-08 16:35:08 +05301/*
2 * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
3 * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8#include <arch.h>
9#include <asm_macros.S>
10#include <assert_macros.S>
11#include <drivers/console.h>
12#include <drivers/cadence/cdns_uart.h>
13#include <platform_def.h>
14
15 /*
16 * "core" functions are low-level implementations that don't require
17 * writable memory and are thus safe to call in BL1 crash context.
18 */
19 .globl console_core_init
20 .globl console_core_putc
21 .globl console_core_getc
22 .globl console_core_flush
23
24 .globl console_init
25 .globl console_putc
26 .globl console_getc
27 .globl console_flush
28
29 /*
30 * The console base is in the data section and not in .bss
31 * even though it is zero-init. In particular, this allows
32 * the console functions to start using this variable before
33 * the runtime memory is initialized for images which do not
34 * need to copy the .data section from ROM to RAM.
35 */
36 .section .data.console_base
37 .align 3
38console_base: .quad 0x0
39
40
41func console_init
42 adrp x3, console_base
43 str x0, [x3, :lo12:console_base]
44 b console_core_init
45endfunc console_init
46
47 /* -----------------------------------------------
48 * int console_core_init(uintptr_t base_addr)
49 * Function to initialize the console without a
50 * C Runtime to print debug information. This
51 * function will be accessed by console_init and
52 * crash reporting.
53 * We assume that the bootloader already set up
54 * the HW (baud, ...) and only enable the trans-
55 * mitter and receiver here.
56 * In: x0 - console base address
57 * Out: return 1 on success else 0 on error
58 * Clobber list : x1, x2, x3
59 * -----------------------------------------------
60 */
61func console_core_init
62 /* Check the input base address */
63 cbz x0, core_init_fail
64
65 /* RX/TX enabled & reset */
66 mov w3, #(R_UART_CR_TX_EN | R_UART_CR_RX_EN | R_UART_CR_TXRST | R_UART_CR_RXRST)
67 str w3, [x0, #R_UART_CR]
68
69 mov w0, #1
70 ret
71core_init_fail:
72 mov w0, wzr
73 ret
74endfunc console_core_init
75
76
77 /* --------------------------------------------------------
78 * int console_cdns_core_putc(int c, uintptr_t base_addr)
79 * Function to output a character over the console. It
80 * returns the character printed on success or -1 on error.
81 * In : w0 - character to be printed
82 * x1 - console base address
83 * Out : return -1 on error else return character.
84 * Clobber list : x2
85 * --------------------------------------------------------
86 */
87func console_core_putc
88 cbz x1, putc_error
89 /* Prepend '\r' to '\n' */
90 cmp w0, #0xA
91 b.ne 2f
921:
93 /* Check if the transmit FIFO is empty */
94 ldr w2, [x1, #R_UART_SR]
95 tbz w2, #UART_SR_INTR_TEMPTY_BIT, 1b
96 mov w2, #0xD
97 str w2, [x1, #R_UART_TX]
982:
99 /* Check if the transmit FIFO is empty */
100 ldr w2, [x1, #R_UART_SR]
101 tbz w2, #UART_SR_INTR_TEMPTY_BIT, 2b
102 str w0, [x1, #R_UART_TX]
103 ret
104putc_error:
105 mov w0, #ERROR_NO_VALID_CONSOLE
106 ret
107endfunc console_core_putc
108
109 /* --------------------------------------------------------
110 * int console_cdns_putc(int c, console_t *cdns)
111 * Function to output a character over the console. It
112 * returns the character printed on success or -1 on error.
113 * In : w0 - character to be printed
114 * x1 - pointer to console_t structure
115 * Out : return -1 on error else return character.
116 * Clobber list : x2
117 * --------------------------------------------------------
118 */
119func console_putc
120 adrp x1, console_base
121 ldr x1, [x1, :lo12:console_base]
122 b console_core_putc
123endfunc console_putc
124
125 /* ---------------------------------------------
126 * int console_cdns_core_getc(uintptr_t base_addr)
127 * Function to get a character from the console.
128 * It returns the character grabbed on success
129 * or -1 if no character is available.
130 * In : x0 - console base address
131 * Out: w0 - character if available, else -1
132 * Clobber list : x0, x1
133 * ---------------------------------------------
134 */
135func console_core_getc
136 adr x0, console_base
137 ldr x0, [x0]
138
139 /* Check if the receive FIFO is empty */
140 ldr w1, [x0, #R_UART_SR]
141 tbnz w1, #UART_SR_INTR_REMPTY_BIT, no_char
142 ldr w1, [x0, #R_UART_RX]
143 mov w0, w1
144 ret
145no_char:
146 mov w0, #ERROR_NO_PENDING_CHAR
147 ret
148endfunc console_core_getc
149
150 /* ---------------------------------------------
151 * int console_cdns_getc(console_t *console)
152 * Function to get a character from the console.
153 * It returns the character grabbed on success
154 * or -1 if no character is available.
155 * In : x0 - pointer to console_t structure
156 * Out: w0 - character if available, else -1
157 * Clobber list : x0, x1
158 * ---------------------------------------------
159 */
160func console_getc
161 adrp x0, console_base
162 ldr x0, [x0, :lo12:console_base]
163 b console_core_getc
164endfunc console_getc
165
166 /* ---------------------------------------------
167 * int console_cdns_core_flush(uintptr_t base_addr)
168 * Function to force a write of all buffered
169 * data that hasn't been output.
170 * In : x0 - console base address
171 * Out : void
172 * Clobber list : x0, x1
173 * ---------------------------------------------
174 */
175func console_core_flush
176 cbz x0, flush_error
177 /* Loop until the transmit FIFO is empty */
1781:
179 ldr w2, [x1, #R_UART_SR]
180 tbz w2, #UART_SR_INTR_TEMPTY_BIT, 1b
181 str w0, [x1, #R_UART_TX]
182 ret
183flush_error:
184 mov w0, #ERROR_NO_VALID_CONSOLE
185 ret
186endfunc console_core_flush
187
188 /* ---------------------------------------------
189 * void console_cdns_flush(console_t *console)
190 * Function to force a write of all buffered
191 * data that hasn't been output.
192 * In : x0 - pointer to console_t structure
193 * Out : void.
194 * Clobber list : x0, x1
195 * ---------------------------------------------
196 */
197func console_flush
198 adrp x0, console_base
199 ldr x0, [x0, :lo12:console_base]
200 b console_core_flush
201endfunc console_flush