xref: /rk3399_ARM-atf/drivers/console/aarch64/skeleton_console.S (revision e8ada80a8496806c1f17ccbc6e2beec99d37f6c4)
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>
79536bae6SJulius Werner#include <console_macros.S>
89c94d3b3SSoby Mathew
99c94d3b3SSoby Mathew	/*
1052e91081SAmbroise Vincent	 * This file contains a skeleton console driver that can be used as a
119536bae6SJulius Werner	 * basis for a real console driver. Console drivers in Trusted Firmware
129536bae6SJulius Werner	 * can be instantiated multiple times. Each instance is described by a
139536bae6SJulius Werner	 * separate console_t structure which must be registered with the common
149536bae6SJulius Werner	 * console framework via console_register(). Console drivers should
159536bae6SJulius Werner	 * define a console_xxx_register() function that initializes a new
169536bae6SJulius Werner	 * console_t structure passed in from the caller and registers it after
179536bae6SJulius Werner	 * initializing the console hardware. Drivers may define their own
189536bae6SJulius Werner	 * structures extending console_t to store private driver information.
1952e91081SAmbroise Vincent	 * Console drivers *MUST* ensure that the console callbacks they
209536bae6SJulius Werner	 * implement only change registers allowed in the clobber lists defined
219536bae6SJulius Werner	 * in this file. (Note that in addition to the explicit clobber lists,
229536bae6SJulius Werner	 * any function may always clobber the intra-procedure-call registers
239536bae6SJulius Werner	 * X16 and X17, but may never depend on them retaining their values
249536bae6SJulius Werner	 * across any function call.)
259c94d3b3SSoby Mathew	 */
269c94d3b3SSoby Mathew
279536bae6SJulius Werner	.globl	console_xxx_register
289536bae6SJulius Werner	.globl	console_xxx_putc
299536bae6SJulius Werner	.globl	console_xxx_getc
309536bae6SJulius Werner	.globl	console_xxx_flush
319c94d3b3SSoby Mathew
329c94d3b3SSoby Mathew	/* -----------------------------------------------
339536bae6SJulius Werner	 * int console_xxx_register(console_xxx_t *console,
349536bae6SJulius Werner	 * 	...additional parameters as desired...)
359536bae6SJulius Werner	 * Function to initialize and register the console.
369536bae6SJulius Werner	 * The caller needs to pass an empty console_xxx_t
379536bae6SJulius Werner	 * structure in which *MUST* be allocated in
389536bae6SJulius Werner	 * persistent memory (e.g. a global or static local
399536bae6SJulius Werner	 * variable, *NOT* on the stack).
409536bae6SJulius Werner	 * In : x0 - pointer to empty console_t structure
419536bae6SJulius Werner	 *      x1 through x7: additional parameters as desired
429536bae6SJulius Werner	 * Out: x0 - 1 on success, 0 on error
439536bae6SJulius Werner	 * Clobber list : x0 - x7
449c94d3b3SSoby Mathew	 * -----------------------------------------------
459c94d3b3SSoby Mathew	 */
469536bae6SJulius Wernerfunc console_xxx_register
479536bae6SJulius Werner	/*
489536bae6SJulius Werner	 * Store parameters (e.g. hardware base address) in driver-specific
499536bae6SJulius Werner	 * console_xxx_t structure field if they will need to be retrieved
509536bae6SJulius Werner	 * by later console callback (e.g. putc).
519536bae6SJulius Werner	 * Example:
529536bae6SJulius Werner	 */
53*e8ada80aSAndre Przywara	str	x1, [x0, #CONSOLE_T_BASE]
549536bae6SJulius Werner	str	x2, [x0, #CONSOLE_T_XXX_SOME_OTHER_VALUE]
559536bae6SJulius Werner
569536bae6SJulius Werner	/*
579536bae6SJulius Werner	 * Initialize console hardware, using x1 - x7 parameters as needed.
589536bae6SJulius Werner	 * Keep console_t pointer in x0 for later.
599536bae6SJulius Werner	 */
609536bae6SJulius Werner
61cc5859caSSoby Mathew	/*
62cc5859caSSoby Mathew	 * Macro to finish up registration and return (needs valid x0 + x30).
63cc5859caSSoby Mathew	 * If any of the argument is unspecified, then the corresponding
64cc5859caSSoby Mathew	 * entry in console_t is set to 0.
65cc5859caSSoby Mathew	 */
66cc5859caSSoby Mathew	finish_console_register xxx putc=1, getc=1, flush=1
679536bae6SJulius Werner
689536bae6SJulius Werner	/* Jump here if hardware init fails or parameters are invalid. */
699536bae6SJulius Wernerregister_fail:
709536bae6SJulius Werner	mov	w0, #0
719c94d3b3SSoby Mathew	ret
729536bae6SJulius Wernerendfunc console_xxx_register
739c94d3b3SSoby Mathew
749c94d3b3SSoby Mathew	/* --------------------------------------------------------
759536bae6SJulius Werner	 * int console_xxx_putc(int c, console_xxx_t *console)
769c94d3b3SSoby Mathew	 * Function to output a character over the console. It
779c94d3b3SSoby Mathew	 * returns the character printed on success or -1 on error.
789c94d3b3SSoby Mathew	 * In : w0 - character to be printed
799536bae6SJulius Werner	 *      x1 - pointer to console_t struct
809536bae6SJulius Werner	 * Out: w0 - printed character on success, < 0 on error.
819536bae6SJulius Werner	 * Clobber list : x0, x1, x2
829c94d3b3SSoby Mathew	 * --------------------------------------------------------
839c94d3b3SSoby Mathew	 */
849536bae6SJulius Wernerfunc console_xxx_putc
859536bae6SJulius Werner	/*
869536bae6SJulius Werner	 * Retrieve values we need (e.g. hardware base address) from
879536bae6SJulius Werner	 * console_xxx_t structure pointed to by x1.
889536bae6SJulius Werner	 * Example:
899536bae6SJulius Werner	 */
90*e8ada80aSAndre Przywara	ldr	x1, [x1, #CONSOLE_T_BASE]
919536bae6SJulius Werner
929536bae6SJulius Werner	/*
939536bae6SJulius Werner	 * Write w0 to hardware.
949536bae6SJulius Werner	 */
959536bae6SJulius Werner
969c94d3b3SSoby Mathew	ret
979536bae6SJulius Werner
989536bae6SJulius Werner	/* Jump here if output fails for any reason. */
999c94d3b3SSoby Mathewputc_error:
1009c94d3b3SSoby Mathew	mov	w0, #-1
1019c94d3b3SSoby Mathew	ret
1029536bae6SJulius Wernerendfunc console_xxx_putc
1039c94d3b3SSoby Mathew
1049c94d3b3SSoby Mathew	/* ---------------------------------------------
1059536bae6SJulius Werner	 * int console_xxx_getc(console_xxx_t *console)
1069c94d3b3SSoby Mathew	 * Function to get a character from the console.
1079536bae6SJulius Werner	 * Even though console_getc() is blocking, this
1089536bae6SJulius Werner	 * callback has to be non-blocking and always
1099536bae6SJulius Werner	 * return immediately to allow polling multiple
1109536bae6SJulius Werner	 * drivers concurrently.
1119536bae6SJulius Werner	 * Returns the character grabbed on success,
1129536bae6SJulius Werner	 * ERROR_NO_PENDING_CHAR if no character was
1139536bae6SJulius Werner	 * available at this time, or any value
1149536bae6SJulius Werner	 * between -2 and -127 if there was an error.
1159536bae6SJulius Werner	 * In : x0 - pointer to console_t struct
1169536bae6SJulius Werner	 * Out: w0 - character on success,
1179536bae6SJulius Werner	 *           ERROR_NO_PENDING_CHAR if no char,
1189536bae6SJulius Werner	 *           < -1 on error
1199c94d3b3SSoby Mathew	 * Clobber list : x0, x1
1209c94d3b3SSoby Mathew	 * ---------------------------------------------
1219c94d3b3SSoby Mathew	 */
1229536bae6SJulius Wernerfunc console_xxx_getc
1239536bae6SJulius Werner	/*
1249536bae6SJulius Werner	 * Retrieve values we need (e.g. hardware base address) from
1259536bae6SJulius Werner	 * console_xxx_t structure pointed to by x0.
1269536bae6SJulius Werner	 * Example:
1279536bae6SJulius Werner	 */
128*e8ada80aSAndre Przywara	ldr	x1, [x0, #CONSOLE_T_BASE]
1299536bae6SJulius Werner
1309536bae6SJulius Werner	/*
1319536bae6SJulius Werner	 * Try to read character into w0 from hardware.
1329536bae6SJulius Werner	 */
1339536bae6SJulius Werner
1349c94d3b3SSoby Mathew	ret
1359536bae6SJulius Werner
1369536bae6SJulius Werner	/* Jump here if there is no character available at this time. */
1379536bae6SJulius Wernergetc_no_char:
1389536bae6SJulius Werner	mov	w0, #ERROR_NO_PENDING_CHAR
1399536bae6SJulius Werner	ret
1409536bae6SJulius Werner
1419536bae6SJulius Werner	/* Jump here if there was any hardware error. */
1429c94d3b3SSoby Mathewgetc_error:
1439536bae6SJulius Werner	mov	w0, #-2		/* may pick error codes between -2 and -127 */
1449c94d3b3SSoby Mathew	ret
1459536bae6SJulius Wernerendfunc console_xxx_getc
14673e05284SAntonio Nino Diaz
14773e05284SAntonio Nino Diaz	/* ---------------------------------------------
1489536bae6SJulius Werner	 * int console_xxx_flush(console_xxx_t *console)
14973e05284SAntonio Nino Diaz	 * Function to force a write of all buffered
15073e05284SAntonio Nino Diaz	 * data that hasn't been output.
1519536bae6SJulius Werner	 * In : x0 - pointer to console_xxx_t struct
1529536bae6SJulius Werner	 * Out: w0 - 0 on success, < 0 on error
1539536bae6SJulius Werner	 * Clobber list : x0, x1, x2, x3, x4, x5
15473e05284SAntonio Nino Diaz	 * ---------------------------------------------
15573e05284SAntonio Nino Diaz	 */
1569536bae6SJulius Wernerfunc console_xxx_flush
1579536bae6SJulius Werner	/*
1589536bae6SJulius Werner	 * Retrieve values we need (e.g. hardware base address) from
1599536bae6SJulius Werner	 * console_xxx_t structure pointed to by x0.
1609536bae6SJulius Werner	 * Example:
1619536bae6SJulius Werner	 */
162*e8ada80aSAndre Przywara	ldr	x1, [x0, #CONSOLE_T_BASE]
1639536bae6SJulius Werner
1649536bae6SJulius Werner	/*
1659536bae6SJulius Werner	 * Flush all remaining output from hardware FIFOs. Do not return until
1669536bae6SJulius Werner	 * all data has been flushed or there was an unrecoverable error.
1679536bae6SJulius Werner	 */
1689536bae6SJulius Werner
16973e05284SAntonio Nino Diaz	mov	w0, #0
17073e05284SAntonio Nino Diaz	ret
1719536bae6SJulius Werner
1729536bae6SJulius Werner	/* Jump here if an unrecoverable error has been encountered. */
17373e05284SAntonio Nino Diazflush_error:
17473e05284SAntonio Nino Diaz	mov	w0, #-1
17573e05284SAntonio Nino Diaz	ret
1769536bae6SJulius Wernerendfunc console_xxx_flush
177