1/* 2 * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6#include <asm_macros.S> 7#include <console_macros.S> 8 9 /* 10 * This file contains a skeleton console driver that can be used as 11 * basis for a real console driver. Console drivers in Trusted Firmware 12 * can be instantiated multiple times. Each instance is described by a 13 * separate console_t structure which must be registered with the common 14 * console framework via console_register(). Console drivers should 15 * define a console_xxx_register() function that initializes a new 16 * console_t structure passed in from the caller and registers it after 17 * initializing the console hardware. Drivers may define their own 18 * structures extending console_t to store private driver information. 19 * Console drivers *MUST* take care that the console callbacks they 20 * implement only change registers allowed in the clobber lists defined 21 * in this file. (Note that in addition to the explicit clobber lists, 22 * any function may always clobber the intra-procedure-call registers 23 * X16 and X17, but may never depend on them retaining their values 24 * across any function call.) 25 * Platforms using drivers based on this template need to enable 26 * MULTI_CONSOLE_API := 1 in their platform.mk. 27 */ 28 29 .globl console_xxx_register 30 .globl console_xxx_putc 31 .globl console_xxx_getc 32 .globl console_xxx_flush 33 34 /* ----------------------------------------------- 35 * int console_xxx_register(console_xxx_t *console, 36 * ...additional parameters as desired...) 37 * Function to initialize and register the console. 38 * The caller needs to pass an empty console_xxx_t 39 * structure in which *MUST* be allocated in 40 * persistent memory (e.g. a global or static local 41 * variable, *NOT* on the stack). 42 * In : x0 - pointer to empty console_t structure 43 * x1 through x7: additional parameters as desired 44 * Out: x0 - 1 on success, 0 on error 45 * Clobber list : x0 - x7 46 * ----------------------------------------------- 47 */ 48func console_xxx_register 49 /* 50 * Store parameters (e.g. hardware base address) in driver-specific 51 * console_xxx_t structure field if they will need to be retrieved 52 * by later console callback (e.g. putc). 53 * Example: 54 */ 55 str x1, [x0, #CONSOLE_T_XXX_BASE] 56 str x2, [x0, #CONSOLE_T_XXX_SOME_OTHER_VALUE] 57 58 /* 59 * Initialize console hardware, using x1 - x7 parameters as needed. 60 * Keep console_t pointer in x0 for later. 61 */ 62 63 /* 64 * Macro to finish up registration and return (needs valid x0 + x30). 65 * If any of the argument is unspecified, then the corresponding 66 * entry in console_t is set to 0. 67 */ 68 finish_console_register xxx putc=1, getc=1, flush=1 69 70 /* Jump here if hardware init fails or parameters are invalid. */ 71register_fail: 72 mov w0, #0 73 ret 74endfunc console_xxx_register 75 76 /* -------------------------------------------------------- 77 * int console_xxx_putc(int c, console_xxx_t *console) 78 * Function to output a character over the console. It 79 * returns the character printed on success or -1 on error. 80 * In : w0 - character to be printed 81 * x1 - pointer to console_t struct 82 * Out: w0 - printed character on success, < 0 on error. 83 * Clobber list : x0, x1, x2 84 * -------------------------------------------------------- 85 */ 86func console_xxx_putc 87 /* 88 * Retrieve values we need (e.g. hardware base address) from 89 * console_xxx_t structure pointed to by x1. 90 * Example: 91 */ 92 ldr x1, [x1, #CONSOLE_T_XXX_BASE] 93 94 /* 95 * Write w0 to hardware. 96 */ 97 98 ret 99 100 /* Jump here if output fails for any reason. */ 101putc_error: 102 mov w0, #-1 103 ret 104endfunc console_xxx_putc 105 106 /* --------------------------------------------- 107 * int console_xxx_getc(console_xxx_t *console) 108 * Function to get a character from the console. 109 * Even though console_getc() is blocking, this 110 * callback has to be non-blocking and always 111 * return immediately to allow polling multiple 112 * drivers concurrently. 113 * Returns the character grabbed on success, 114 * ERROR_NO_PENDING_CHAR if no character was 115 * available at this time, or any value 116 * between -2 and -127 if there was an error. 117 * In : x0 - pointer to console_t struct 118 * Out: w0 - character on success, 119 * ERROR_NO_PENDING_CHAR if no char, 120 * < -1 on error 121 * Clobber list : x0, x1 122 * --------------------------------------------- 123 */ 124func console_xxx_getc 125 /* 126 * Retrieve values we need (e.g. hardware base address) from 127 * console_xxx_t structure pointed to by x0. 128 * Example: 129 */ 130 ldr x1, [x0, #CONSOLE_T_XXX_BASE] 131 132 /* 133 * Try to read character into w0 from hardware. 134 */ 135 136 ret 137 138 /* Jump here if there is no character available at this time. */ 139getc_no_char: 140 mov w0, #ERROR_NO_PENDING_CHAR 141 ret 142 143 /* Jump here if there was any hardware error. */ 144getc_error: 145 mov w0, #-2 /* may pick error codes between -2 and -127 */ 146 ret 147endfunc console_xxx_getc 148 149 /* --------------------------------------------- 150 * int console_xxx_flush(console_xxx_t *console) 151 * Function to force a write of all buffered 152 * data that hasn't been output. 153 * In : x0 - pointer to console_xxx_t struct 154 * Out: w0 - 0 on success, < 0 on error 155 * Clobber list : x0, x1, x2, x3, x4, x5 156 * --------------------------------------------- 157 */ 158func console_xxx_flush 159 /* 160 * Retrieve values we need (e.g. hardware base address) from 161 * console_xxx_t structure pointed to by x0. 162 * Example: 163 */ 164 ldr x1, [x0, #CONSOLE_T_XXX_BASE] 165 166 /* 167 * Flush all remaining output from hardware FIFOs. Do not return until 168 * all data has been flushed or there was an unrecoverable error. 169 */ 170 171 mov w0, #0 172 ret 173 174 /* Jump here if an unrecoverable error has been encountered. */ 175flush_error: 176 mov w0, #-1 177 ret 178endfunc console_xxx_flush 179