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