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