• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2016-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/aarch32/console.S"
15
16	.globl	console_core_init
17	.globl	console_core_putc
18	.globl	console_core_getc
19	.globl	console_core_flush
20
21
22	/* -----------------------------------------------
23	 * int console_core_init(uintptr_t base_addr,
24	 * unsigned int uart_clk, unsigned int baud_rate)
25	 * Function to initialize the console without a
26	 * C Runtime to print debug information. This
27	 * function will be accessed by console_init and
28	 * crash reporting.
29	 * In: r0 - console base address
30	 *     r1 - Uart clock in Hz
31	 *     r2 - Baud rate
32	 * Out: return 1 on success else 0 on error
33	 * Clobber list : r1, r2, r3
34	 * -----------------------------------------------
35	 */
36func console_core_init
37	/* Check the input base address */
38	cmp	r0, #0
39	beq	core_init_fail
40#if !PL011_GENERIC_UART
41	/* Check baud rate and uart clock for sanity */
42	cmp	r1, #0
43	beq	core_init_fail
44	cmp	r2, #0
45	beq	core_init_fail
46	/* Disable the UART before initialization */
47	ldr	r3, [r0, #UARTCR]
48	bic	r3, r3, #PL011_UARTCR_UARTEN
49	str	r3, [r0, #UARTCR]
50	/* Program the baudrate */
51	/* Divisor =  (Uart clock * 4) / baudrate */
52	lsl	r1, r1, #2
53	udiv	r2, r1, r2
54	/* IBRD = Divisor >> 6 */
55	lsr	r1, r2, #6
56	/* Write the IBRD */
57	str	r1, [r0, #UARTIBRD]
58	/* FBRD = Divisor & 0x3F */
59	and	r1, r2, #0x3f
60	/* Write the FBRD */
61	str	r1, [r0, #UARTFBRD]
62	mov	r1, #PL011_LINE_CONTROL
63	str	r1, [r0, #UARTLCR_H]
64	/* Clear any pending errors */
65	mov	r1, #0
66	str	r1, [r0, #UARTECR]
67	/* Enable tx, rx, and uart overall */
68	ldr	r1, =(PL011_UARTCR_RXE | PL011_UARTCR_TXE | PL011_UARTCR_UARTEN)
69	str	r1, [r0, #UARTCR]
70#endif
71	mov	r0, #1
72	bx	lr
73core_init_fail:
74	mov	r0, #0
75	bx	lr
76endfunc console_core_init
77
78	/* --------------------------------------------------------
79	 * int console_core_putc(int c, uintptr_t base_addr)
80	 * Function to output a character over the console. It
81	 * returns the character printed on success or -1 on error.
82	 * In : r0 - character to be printed
83	 *      r1 - console base address
84	 * Out : return -1 on error else return character.
85	 * Clobber list : r2
86	 * --------------------------------------------------------
87	 */
88func console_core_putc
89	/* Check the input parameter */
90	cmp	r1, #0
91	beq	putc_error
92	/* Prepend '\r' to '\n' */
93	cmp	r0, #0xA
94	bne	2f
951:
96	/* Check if the transmit FIFO is full */
97	ldr	r2, [r1, #UARTFR]
98	tst	r2, #PL011_UARTFR_TXFF
99	bne	1b
100	mov	r2, #0xD
101	str	r2, [r1, #UARTDR]
1022:
103	/* Check if the transmit FIFO is full */
104	ldr	r2, [r1, #UARTFR]
105	tst	r2, #PL011_UARTFR_TXFF
106	bne	2b
107	str	r0, [r1, #UARTDR]
108	bx	lr
109putc_error:
110	mov	r0, #-1
111	bx	lr
112endfunc console_core_putc
113
114	/* ---------------------------------------------
115	 * int console_core_getc(uintptr_t base_addr)
116	 * Function to get a character from the console.
117	 * It returns the character grabbed on success
118	 * or -1 on error.
119	 * In : r0 - console base address
120	 * Clobber list : r0, r1
121	 * ---------------------------------------------
122	 */
123func console_core_getc
124	cmp	r0, #0
125	beq	getc_error
1261:
127	/* Check if the receive FIFO is empty */
128	ldr	r1, [r0, #UARTFR]
129	tst	r1, #PL011_UARTFR_RXFE
130	bne	1b
131	ldr	r1, [r0, #UARTDR]
132	mov	r0, r1
133	bx	lr
134getc_error:
135	mov	r0, #-1
136	bx	lr
137endfunc console_core_getc
138
139	/* ---------------------------------------------
140	 * int console_core_flush(uintptr_t base_addr)
141	 * Function to force a write of all buffered
142	 * data that hasn't been output.
143	 * In : r0 - console base address
144	 * Out : return -1 on error else return 0.
145	 * Clobber list : r0, r1
146	 * ---------------------------------------------
147	 */
148func console_core_flush
149	cmp	r0, #0
150	beq	flush_error
151
1521:
153	/* Loop while the transmit FIFO is busy */
154	ldr	r1, [r0, #UARTFR]
155	tst	r1, #PL011_UARTFR_BUSY
156	bne	1b
157
158	mov	r0, #0
159	bx	lr
160flush_error:
161	mov	r0, #-1
162	bx	lr
163endfunc console_core_flush
164