• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6#include <arch.h>
7#include <asm_macros.S>
8#include <pl011.h>
9
10/*
11 * Pull in generic functions to provide backwards compatibility for
12 * platform makefiles
13 */
14#include "../../../console/aarch64/console.S"
15
16
17	.globl	console_core_init
18	.globl	console_core_putc
19	.globl	console_core_getc
20	.globl	console_core_flush
21
22
23	/* -----------------------------------------------
24	 * int console_core_init(uintptr_t base_addr,
25	 * unsigned int uart_clk, unsigned int baud_rate)
26	 * Function to initialize the console without a
27	 * C Runtime to print debug information. This
28	 * function will be accessed by console_init and
29	 * crash reporting.
30	 * In: x0 - console base address
31	 *     w1 - Uart clock in Hz
32	 *     w2 - Baud rate
33	 * Out: return 1 on success else 0 on error
34	 * Clobber list : x1, x2, x3, x4
35	 * -----------------------------------------------
36	 */
37func console_core_init
38	/* Check the input base address */
39	cbz	x0, core_init_fail
40#if !PL011_GENERIC_UART
41	/* Check baud rate and uart clock for sanity */
42	cbz	w1, core_init_fail
43	cbz	w2, core_init_fail
44	/* Disable uart before programming */
45	ldr	w3, [x0, #UARTCR]
46	mov	w4, #PL011_UARTCR_UARTEN
47	bic	w3, w3, w4
48	str	w3, [x0, #UARTCR]
49	/* Program the baudrate */
50	/* Divisor =  (Uart clock * 4) / baudrate */
51	lsl	w1, w1, #2
52	udiv	w2, w1, w2
53	/* IBRD = Divisor >> 6 */
54	lsr	w1, w2, #6
55	/* Write the IBRD */
56	str	w1, [x0, #UARTIBRD]
57	/* FBRD = Divisor & 0x3F */
58	and	w1, w2, #0x3f
59	/* Write the FBRD */
60	str	w1, [x0, #UARTFBRD]
61	mov	w1, #PL011_LINE_CONTROL
62	str	w1, [x0, #UARTLCR_H]
63	/* Clear any pending errors */
64	str	wzr, [x0, #UARTECR]
65	/* Enable tx, rx, and uart overall */
66	mov	w1, #(PL011_UARTCR_RXE | PL011_UARTCR_TXE | PL011_UARTCR_UARTEN)
67	str	w1, [x0, #UARTCR]
68#endif
69	mov	w0, #1
70	ret
71core_init_fail:
72	mov	w0, wzr
73	ret
74endfunc console_core_init
75
76	/* --------------------------------------------------------
77	 * int console_core_putc(int c, uintptr_t base_addr)
78	 * Function to output a character over the console. It
79	 * returns the character printed on success or -1 on error.
80	 * In : w0 - character to be printed
81	 *      x1 - console base address
82	 * Out : return -1 on error else return character.
83	 * Clobber list : x2
84	 * --------------------------------------------------------
85	 */
86func console_core_putc
87	/* Check the input parameter */
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 full */
94	ldr	w2, [x1, #UARTFR]
95	tbnz	w2, #PL011_UARTFR_TXFF_BIT, 1b
96	mov	w2, #0xD
97	str	w2, [x1, #UARTDR]
982:
99	/* Check if the transmit FIFO is full */
100	ldr	w2, [x1, #UARTFR]
101	tbnz	w2, #PL011_UARTFR_TXFF_BIT, 2b
102	str	w0, [x1, #UARTDR]
103	ret
104putc_error:
105	mov	w0, #-1
106	ret
107endfunc console_core_putc
108
109	/* ---------------------------------------------
110	 * int console_core_getc(uintptr_t base_addr)
111	 * Function to get a character from the console.
112	 * It returns the character grabbed on success
113	 * or -1 on error.
114	 * In : x0 - console base address
115	 * Clobber list : x0, x1
116	 * ---------------------------------------------
117	 */
118func console_core_getc
119	cbz	x0, getc_error
1201:
121	/* Check if the receive FIFO is empty */
122	ldr	w1, [x0, #UARTFR]
123	tbnz	w1, #PL011_UARTFR_RXFE_BIT, 1b
124	ldr	w1, [x0, #UARTDR]
125	mov	w0, w1
126	ret
127getc_error:
128	mov	w0, #-1
129	ret
130endfunc console_core_getc
131
132	/* ---------------------------------------------
133	 * int console_core_flush(uintptr_t base_addr)
134	 * Function to force a write of all buffered
135	 * data that hasn't been output.
136	 * In : x0 - console base address
137	 * Out : return -1 on error else return 0.
138	 * Clobber list : x0, x1
139	 * ---------------------------------------------
140	 */
141func console_core_flush
142	cbz	x0, flush_error
143
1441:
145	/* Loop until the transmit FIFO is empty */
146	ldr	w1, [x0, #UARTFR]
147	tbnz	w1, #PL011_UARTFR_BUSY_BIT, 1b
148
149	mov	w0, #0
150	ret
151flush_error:
152	mov	w0, #-1
153	ret
154endfunc console_core_flush
155