xref: /rk3399_ARM-atf/drivers/console/aarch64/skeleton_console.S (revision 9536bae6df5638772a1e8b1c8cf8e321f4ab5452)
19c94d3b3SSoby Mathew/*
273e05284SAntonio Nino Diaz * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
39c94d3b3SSoby Mathew *
482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause
59c94d3b3SSoby Mathew */
69c94d3b3SSoby Mathew#include <asm_macros.S>
7*9536bae6SJulius Werner#include <console_macros.S>
89c94d3b3SSoby Mathew
99c94d3b3SSoby Mathew	/*
10*9536bae6SJulius Werner	 * This file contains a skeleton console driver that can be used as
11*9536bae6SJulius Werner	 * basis for a real console driver. Console drivers in Trusted Firmware
12*9536bae6SJulius Werner	 * can be instantiated multiple times. Each instance is described by a
13*9536bae6SJulius Werner	 * separate console_t structure which must be registered with the common
14*9536bae6SJulius Werner	 * console framework via console_register(). Console drivers should
15*9536bae6SJulius Werner	 * define a console_xxx_register() function that initializes a new
16*9536bae6SJulius Werner	 * console_t structure passed in from the caller and registers it after
17*9536bae6SJulius Werner	 * initializing the console hardware. Drivers may define their own
18*9536bae6SJulius Werner	 * structures extending console_t to store private driver information.
19*9536bae6SJulius Werner	 * Console drivers *MUST* take care that the console callbacks they
20*9536bae6SJulius Werner	 * implement only change registers allowed in the clobber lists defined
21*9536bae6SJulius Werner	 * in this file. (Note that in addition to the explicit clobber lists,
22*9536bae6SJulius Werner	 * any function may always clobber the intra-procedure-call registers
23*9536bae6SJulius Werner	 * X16 and X17, but may never depend on them retaining their values
24*9536bae6SJulius Werner	 * across any function call.)
25*9536bae6SJulius Werner	 * Platforms using drivers based on this template need to enable
26*9536bae6SJulius Werner	 * MULTI_CONSOLE_API := 1 in their platform.mk.
279c94d3b3SSoby Mathew	 */
289c94d3b3SSoby Mathew
29*9536bae6SJulius Werner	.globl	console_xxx_register
30*9536bae6SJulius Werner	.globl	console_xxx_putc
31*9536bae6SJulius Werner	.globl	console_xxx_getc
32*9536bae6SJulius Werner	.globl	console_xxx_flush
339c94d3b3SSoby Mathew
349c94d3b3SSoby Mathew	/* -----------------------------------------------
35*9536bae6SJulius Werner	 * int console_xxx_register(console_xxx_t *console,
36*9536bae6SJulius Werner	 * 	...additional parameters as desired...)
37*9536bae6SJulius Werner	 * Function to initialize and register the console.
38*9536bae6SJulius Werner	 * The caller needs to pass an empty console_xxx_t
39*9536bae6SJulius Werner	 * structure in which *MUST* be allocated in
40*9536bae6SJulius Werner	 * persistent memory (e.g. a global or static local
41*9536bae6SJulius Werner	 * variable, *NOT* on the stack).
42*9536bae6SJulius Werner	 * In : x0 - pointer to empty console_t structure
43*9536bae6SJulius Werner	 *      x1 through x7: additional parameters as desired
44*9536bae6SJulius Werner	 * Out: x0 - 1 on success, 0 on error
45*9536bae6SJulius Werner	 * Clobber list : x0 - x7
469c94d3b3SSoby Mathew	 * -----------------------------------------------
479c94d3b3SSoby Mathew	 */
48*9536bae6SJulius Wernerfunc console_xxx_register
49*9536bae6SJulius Werner	/*
50*9536bae6SJulius Werner	 * Store parameters (e.g. hardware base address) in driver-specific
51*9536bae6SJulius Werner	 * console_xxx_t structure field if they will need to be retrieved
52*9536bae6SJulius Werner	 * by later console callback (e.g. putc).
53*9536bae6SJulius Werner	 * Example:
54*9536bae6SJulius Werner	 */
55*9536bae6SJulius Werner	str	x1, [x0, #CONSOLE_T_XXX_BASE]
56*9536bae6SJulius Werner	str	x2, [x0, #CONSOLE_T_XXX_SOME_OTHER_VALUE]
57*9536bae6SJulius Werner
58*9536bae6SJulius Werner	/*
59*9536bae6SJulius Werner	 * Initialize console hardware, using x1 - x7 parameters as needed.
60*9536bae6SJulius Werner	 * Keep console_t pointer in x0 for later.
61*9536bae6SJulius Werner	 */
62*9536bae6SJulius Werner
63*9536bae6SJulius Werner	/* Macro to finish up registration and return (needs valid x0 + x30). */
64*9536bae6SJulius Werner	finish_console_register xxx
65*9536bae6SJulius Werner
66*9536bae6SJulius Werner	/* Jump here if hardware init fails or parameters are invalid. */
67*9536bae6SJulius Wernerregister_fail:
68*9536bae6SJulius Werner	mov	w0, #0
699c94d3b3SSoby Mathew	ret
70*9536bae6SJulius Wernerendfunc console_xxx_register
719c94d3b3SSoby Mathew
729c94d3b3SSoby Mathew	/* --------------------------------------------------------
73*9536bae6SJulius Werner	 * int console_xxx_putc(int c, console_xxx_t *console)
749c94d3b3SSoby Mathew	 * Function to output a character over the console. It
759c94d3b3SSoby Mathew	 * returns the character printed on success or -1 on error.
769c94d3b3SSoby Mathew	 * In : w0 - character to be printed
77*9536bae6SJulius Werner	 *      x1 - pointer to console_t struct
78*9536bae6SJulius Werner	 * Out: w0 - printed character on success, < 0 on error.
79*9536bae6SJulius Werner	 * Clobber list : x0, x1, x2
809c94d3b3SSoby Mathew	 * --------------------------------------------------------
819c94d3b3SSoby Mathew	 */
82*9536bae6SJulius Wernerfunc console_xxx_putc
83*9536bae6SJulius Werner	/*
84*9536bae6SJulius Werner	 * Retrieve values we need (e.g. hardware base address) from
85*9536bae6SJulius Werner	 * console_xxx_t structure pointed to by x1.
86*9536bae6SJulius Werner	 * Example:
87*9536bae6SJulius Werner	 */
88*9536bae6SJulius Werner	ldr	x1, [x1, #CONSOLE_T_XXX_BASE]
89*9536bae6SJulius Werner
90*9536bae6SJulius Werner	/*
91*9536bae6SJulius Werner	 * Write w0 to hardware.
92*9536bae6SJulius Werner	 */
93*9536bae6SJulius Werner
949c94d3b3SSoby Mathew	ret
95*9536bae6SJulius Werner
96*9536bae6SJulius Werner	/* Jump here if output fails for any reason. */
979c94d3b3SSoby Mathewputc_error:
989c94d3b3SSoby Mathew	mov	w0, #-1
999c94d3b3SSoby Mathew	ret
100*9536bae6SJulius Wernerendfunc console_xxx_putc
1019c94d3b3SSoby Mathew
1029c94d3b3SSoby Mathew	/* ---------------------------------------------
103*9536bae6SJulius Werner	 * int console_xxx_getc(console_xxx_t *console)
1049c94d3b3SSoby Mathew	 * Function to get a character from the console.
105*9536bae6SJulius Werner	 * Even though console_getc() is blocking, this
106*9536bae6SJulius Werner	 * callback has to be non-blocking and always
107*9536bae6SJulius Werner	 * return immediately to allow polling multiple
108*9536bae6SJulius Werner	 * drivers concurrently.
109*9536bae6SJulius Werner	 * Returns the character grabbed on success,
110*9536bae6SJulius Werner	 * ERROR_NO_PENDING_CHAR if no character was
111*9536bae6SJulius Werner	 * available at this time, or any value
112*9536bae6SJulius Werner	 * between -2 and -127 if there was an error.
113*9536bae6SJulius Werner	 * In : x0 - pointer to console_t struct
114*9536bae6SJulius Werner	 * Out: w0 - character on success,
115*9536bae6SJulius Werner	 *           ERROR_NO_PENDING_CHAR if no char,
116*9536bae6SJulius Werner	 *           < -1 on error
1179c94d3b3SSoby Mathew	 * Clobber list : x0, x1
1189c94d3b3SSoby Mathew	 * ---------------------------------------------
1199c94d3b3SSoby Mathew	 */
120*9536bae6SJulius Wernerfunc console_xxx_getc
121*9536bae6SJulius Werner	/*
122*9536bae6SJulius Werner	 * Retrieve values we need (e.g. hardware base address) from
123*9536bae6SJulius Werner	 * console_xxx_t structure pointed to by x0.
124*9536bae6SJulius Werner	 * Example:
125*9536bae6SJulius Werner	 */
126*9536bae6SJulius Werner	ldr	x1, [x0, #CONSOLE_T_XXX_BASE]
127*9536bae6SJulius Werner
128*9536bae6SJulius Werner	/*
129*9536bae6SJulius Werner	 * Try to read character into w0 from hardware.
130*9536bae6SJulius Werner	 */
131*9536bae6SJulius Werner
1329c94d3b3SSoby Mathew	ret
133*9536bae6SJulius Werner
134*9536bae6SJulius Werner	/* Jump here if there is no character available at this time. */
135*9536bae6SJulius Wernergetc_no_char:
136*9536bae6SJulius Werner	mov	w0, #ERROR_NO_PENDING_CHAR
137*9536bae6SJulius Werner	ret
138*9536bae6SJulius Werner
139*9536bae6SJulius Werner	/* Jump here if there was any hardware error. */
1409c94d3b3SSoby Mathewgetc_error:
141*9536bae6SJulius Werner	mov	w0, #-2		/* may pick error codes between -2 and -127 */
1429c94d3b3SSoby Mathew	ret
143*9536bae6SJulius Wernerendfunc console_xxx_getc
14473e05284SAntonio Nino Diaz
14573e05284SAntonio Nino Diaz	/* ---------------------------------------------
146*9536bae6SJulius Werner	 * int console_xxx_flush(console_xxx_t *console)
14773e05284SAntonio Nino Diaz	 * Function to force a write of all buffered
14873e05284SAntonio Nino Diaz	 * data that hasn't been output.
149*9536bae6SJulius Werner	 * In : x0 - pointer to console_xxx_t struct
150*9536bae6SJulius Werner	 * Out: w0 - 0 on success, < 0 on error
151*9536bae6SJulius Werner	 * Clobber list : x0, x1, x2, x3, x4, x5
15273e05284SAntonio Nino Diaz	 * ---------------------------------------------
15373e05284SAntonio Nino Diaz	 */
154*9536bae6SJulius Wernerfunc console_xxx_flush
155*9536bae6SJulius Werner	/*
156*9536bae6SJulius Werner	 * Retrieve values we need (e.g. hardware base address) from
157*9536bae6SJulius Werner	 * console_xxx_t structure pointed to by x0.
158*9536bae6SJulius Werner	 * Example:
159*9536bae6SJulius Werner	 */
160*9536bae6SJulius Werner	ldr	x1, [x0, #CONSOLE_T_XXX_BASE]
161*9536bae6SJulius Werner
162*9536bae6SJulius Werner	/*
163*9536bae6SJulius Werner	 * Flush all remaining output from hardware FIFOs. Do not return until
164*9536bae6SJulius Werner	 * all data has been flushed or there was an unrecoverable error.
165*9536bae6SJulius Werner	 */
166*9536bae6SJulius Werner
16773e05284SAntonio Nino Diaz	mov	w0, #0
16873e05284SAntonio Nino Diaz	ret
169*9536bae6SJulius Werner
170*9536bae6SJulius Werner	/* Jump here if an unrecoverable error has been encountered. */
17173e05284SAntonio Nino Diazflush_error:
17273e05284SAntonio Nino Diaz	mov	w0, #-1
17373e05284SAntonio Nino Diaz	ret
174*9536bae6SJulius Wernerendfunc console_xxx_flush
175