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*cc5859caSSoby Mathew#define USE_FINISH_CONSOLE_REG_2 89536bae6SJulius Werner#include <console_macros.S> 99c94d3b3SSoby Mathew 109c94d3b3SSoby Mathew /* 119536bae6SJulius Werner * This file contains a skeleton console driver that can be used as 129536bae6SJulius Werner * basis for a real console driver. Console drivers in Trusted Firmware 139536bae6SJulius Werner * can be instantiated multiple times. Each instance is described by a 149536bae6SJulius Werner * separate console_t structure which must be registered with the common 159536bae6SJulius Werner * console framework via console_register(). Console drivers should 169536bae6SJulius Werner * define a console_xxx_register() function that initializes a new 179536bae6SJulius Werner * console_t structure passed in from the caller and registers it after 189536bae6SJulius Werner * initializing the console hardware. Drivers may define their own 199536bae6SJulius Werner * structures extending console_t to store private driver information. 209536bae6SJulius Werner * Console drivers *MUST* take care that the console callbacks they 219536bae6SJulius Werner * implement only change registers allowed in the clobber lists defined 229536bae6SJulius Werner * in this file. (Note that in addition to the explicit clobber lists, 239536bae6SJulius Werner * any function may always clobber the intra-procedure-call registers 249536bae6SJulius Werner * X16 and X17, but may never depend on them retaining their values 259536bae6SJulius Werner * across any function call.) 269536bae6SJulius Werner * Platforms using drivers based on this template need to enable 279536bae6SJulius Werner * MULTI_CONSOLE_API := 1 in their platform.mk. 289c94d3b3SSoby Mathew */ 299c94d3b3SSoby Mathew 309536bae6SJulius Werner .globl console_xxx_register 319536bae6SJulius Werner .globl console_xxx_putc 329536bae6SJulius Werner .globl console_xxx_getc 339536bae6SJulius Werner .globl console_xxx_flush 349c94d3b3SSoby Mathew 359c94d3b3SSoby Mathew /* ----------------------------------------------- 369536bae6SJulius Werner * int console_xxx_register(console_xxx_t *console, 379536bae6SJulius Werner * ...additional parameters as desired...) 389536bae6SJulius Werner * Function to initialize and register the console. 399536bae6SJulius Werner * The caller needs to pass an empty console_xxx_t 409536bae6SJulius Werner * structure in which *MUST* be allocated in 419536bae6SJulius Werner * persistent memory (e.g. a global or static local 429536bae6SJulius Werner * variable, *NOT* on the stack). 439536bae6SJulius Werner * In : x0 - pointer to empty console_t structure 449536bae6SJulius Werner * x1 through x7: additional parameters as desired 459536bae6SJulius Werner * Out: x0 - 1 on success, 0 on error 469536bae6SJulius Werner * Clobber list : x0 - x7 479c94d3b3SSoby Mathew * ----------------------------------------------- 489c94d3b3SSoby Mathew */ 499536bae6SJulius Wernerfunc console_xxx_register 509536bae6SJulius Werner /* 519536bae6SJulius Werner * Store parameters (e.g. hardware base address) in driver-specific 529536bae6SJulius Werner * console_xxx_t structure field if they will need to be retrieved 539536bae6SJulius Werner * by later console callback (e.g. putc). 549536bae6SJulius Werner * Example: 559536bae6SJulius Werner */ 569536bae6SJulius Werner str x1, [x0, #CONSOLE_T_XXX_BASE] 579536bae6SJulius Werner str x2, [x0, #CONSOLE_T_XXX_SOME_OTHER_VALUE] 589536bae6SJulius Werner 599536bae6SJulius Werner /* 609536bae6SJulius Werner * Initialize console hardware, using x1 - x7 parameters as needed. 619536bae6SJulius Werner * Keep console_t pointer in x0 for later. 629536bae6SJulius Werner */ 639536bae6SJulius Werner 64*cc5859caSSoby Mathew /* 65*cc5859caSSoby Mathew * Macro to finish up registration and return (needs valid x0 + x30). 66*cc5859caSSoby Mathew * If any of the argument is unspecified, then the corresponding 67*cc5859caSSoby Mathew * entry in console_t is set to 0. 68*cc5859caSSoby Mathew */ 69*cc5859caSSoby Mathew finish_console_register xxx putc=1, getc=1, flush=1 709536bae6SJulius Werner 719536bae6SJulius Werner /* Jump here if hardware init fails or parameters are invalid. */ 729536bae6SJulius Wernerregister_fail: 739536bae6SJulius Werner mov w0, #0 749c94d3b3SSoby Mathew ret 759536bae6SJulius Wernerendfunc console_xxx_register 769c94d3b3SSoby Mathew 779c94d3b3SSoby Mathew /* -------------------------------------------------------- 789536bae6SJulius Werner * int console_xxx_putc(int c, console_xxx_t *console) 799c94d3b3SSoby Mathew * Function to output a character over the console. It 809c94d3b3SSoby Mathew * returns the character printed on success or -1 on error. 819c94d3b3SSoby Mathew * In : w0 - character to be printed 829536bae6SJulius Werner * x1 - pointer to console_t struct 839536bae6SJulius Werner * Out: w0 - printed character on success, < 0 on error. 849536bae6SJulius Werner * Clobber list : x0, x1, x2 859c94d3b3SSoby Mathew * -------------------------------------------------------- 869c94d3b3SSoby Mathew */ 879536bae6SJulius Wernerfunc console_xxx_putc 889536bae6SJulius Werner /* 899536bae6SJulius Werner * Retrieve values we need (e.g. hardware base address) from 909536bae6SJulius Werner * console_xxx_t structure pointed to by x1. 919536bae6SJulius Werner * Example: 929536bae6SJulius Werner */ 939536bae6SJulius Werner ldr x1, [x1, #CONSOLE_T_XXX_BASE] 949536bae6SJulius Werner 959536bae6SJulius Werner /* 969536bae6SJulius Werner * Write w0 to hardware. 979536bae6SJulius Werner */ 989536bae6SJulius Werner 999c94d3b3SSoby Mathew ret 1009536bae6SJulius Werner 1019536bae6SJulius Werner /* Jump here if output fails for any reason. */ 1029c94d3b3SSoby Mathewputc_error: 1039c94d3b3SSoby Mathew mov w0, #-1 1049c94d3b3SSoby Mathew ret 1059536bae6SJulius Wernerendfunc console_xxx_putc 1069c94d3b3SSoby Mathew 1079c94d3b3SSoby Mathew /* --------------------------------------------- 1089536bae6SJulius Werner * int console_xxx_getc(console_xxx_t *console) 1099c94d3b3SSoby Mathew * Function to get a character from the console. 1109536bae6SJulius Werner * Even though console_getc() is blocking, this 1119536bae6SJulius Werner * callback has to be non-blocking and always 1129536bae6SJulius Werner * return immediately to allow polling multiple 1139536bae6SJulius Werner * drivers concurrently. 1149536bae6SJulius Werner * Returns the character grabbed on success, 1159536bae6SJulius Werner * ERROR_NO_PENDING_CHAR if no character was 1169536bae6SJulius Werner * available at this time, or any value 1179536bae6SJulius Werner * between -2 and -127 if there was an error. 1189536bae6SJulius Werner * In : x0 - pointer to console_t struct 1199536bae6SJulius Werner * Out: w0 - character on success, 1209536bae6SJulius Werner * ERROR_NO_PENDING_CHAR if no char, 1219536bae6SJulius Werner * < -1 on error 1229c94d3b3SSoby Mathew * Clobber list : x0, x1 1239c94d3b3SSoby Mathew * --------------------------------------------- 1249c94d3b3SSoby Mathew */ 1259536bae6SJulius Wernerfunc console_xxx_getc 1269536bae6SJulius Werner /* 1279536bae6SJulius Werner * Retrieve values we need (e.g. hardware base address) from 1289536bae6SJulius Werner * console_xxx_t structure pointed to by x0. 1299536bae6SJulius Werner * Example: 1309536bae6SJulius Werner */ 1319536bae6SJulius Werner ldr x1, [x0, #CONSOLE_T_XXX_BASE] 1329536bae6SJulius Werner 1339536bae6SJulius Werner /* 1349536bae6SJulius Werner * Try to read character into w0 from hardware. 1359536bae6SJulius Werner */ 1369536bae6SJulius Werner 1379c94d3b3SSoby Mathew ret 1389536bae6SJulius Werner 1399536bae6SJulius Werner /* Jump here if there is no character available at this time. */ 1409536bae6SJulius Wernergetc_no_char: 1419536bae6SJulius Werner mov w0, #ERROR_NO_PENDING_CHAR 1429536bae6SJulius Werner ret 1439536bae6SJulius Werner 1449536bae6SJulius Werner /* Jump here if there was any hardware error. */ 1459c94d3b3SSoby Mathewgetc_error: 1469536bae6SJulius Werner mov w0, #-2 /* may pick error codes between -2 and -127 */ 1479c94d3b3SSoby Mathew ret 1489536bae6SJulius Wernerendfunc console_xxx_getc 14973e05284SAntonio Nino Diaz 15073e05284SAntonio Nino Diaz /* --------------------------------------------- 1519536bae6SJulius Werner * int console_xxx_flush(console_xxx_t *console) 15273e05284SAntonio Nino Diaz * Function to force a write of all buffered 15373e05284SAntonio Nino Diaz * data that hasn't been output. 1549536bae6SJulius Werner * In : x0 - pointer to console_xxx_t struct 1559536bae6SJulius Werner * Out: w0 - 0 on success, < 0 on error 1569536bae6SJulius Werner * Clobber list : x0, x1, x2, x3, x4, x5 15773e05284SAntonio Nino Diaz * --------------------------------------------- 15873e05284SAntonio Nino Diaz */ 1599536bae6SJulius Wernerfunc console_xxx_flush 1609536bae6SJulius Werner /* 1619536bae6SJulius Werner * Retrieve values we need (e.g. hardware base address) from 1629536bae6SJulius Werner * console_xxx_t structure pointed to by x0. 1639536bae6SJulius Werner * Example: 1649536bae6SJulius Werner */ 1659536bae6SJulius Werner ldr x1, [x0, #CONSOLE_T_XXX_BASE] 1669536bae6SJulius Werner 1679536bae6SJulius Werner /* 1689536bae6SJulius Werner * Flush all remaining output from hardware FIFOs. Do not return until 1699536bae6SJulius Werner * all data has been flushed or there was an unrecoverable error. 1709536bae6SJulius Werner */ 1719536bae6SJulius Werner 17273e05284SAntonio Nino Diaz mov w0, #0 17373e05284SAntonio Nino Diaz ret 1749536bae6SJulius Werner 1759536bae6SJulius Werner /* Jump here if an unrecoverable error has been encountered. */ 17673e05284SAntonio Nino Diazflush_error: 17773e05284SAntonio Nino Diaz mov w0, #-1 17873e05284SAntonio Nino Diaz ret 1799536bae6SJulius Wernerendfunc console_xxx_flush 180