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 /* Macro to finish up registration and return (needs valid x0 + x30). */ 64 finish_console_register xxx 65 66 /* Jump here if hardware init fails or parameters are invalid. */ 67register_fail: 68 mov w0, #0 69 ret 70endfunc console_xxx_register 71 72 /* -------------------------------------------------------- 73 * int console_xxx_putc(int c, console_xxx_t *console) 74 * Function to output a character over the console. It 75 * returns the character printed on success or -1 on error. 76 * In : w0 - character to be printed 77 * x1 - pointer to console_t struct 78 * Out: w0 - printed character on success, < 0 on error. 79 * Clobber list : x0, x1, x2 80 * -------------------------------------------------------- 81 */ 82func console_xxx_putc 83 /* 84 * Retrieve values we need (e.g. hardware base address) from 85 * console_xxx_t structure pointed to by x1. 86 * Example: 87 */ 88 ldr x1, [x1, #CONSOLE_T_XXX_BASE] 89 90 /* 91 * Write w0 to hardware. 92 */ 93 94 ret 95 96 /* Jump here if output fails for any reason. */ 97putc_error: 98 mov w0, #-1 99 ret 100endfunc console_xxx_putc 101 102 /* --------------------------------------------- 103 * int console_xxx_getc(console_xxx_t *console) 104 * Function to get a character from the console. 105 * Even though console_getc() is blocking, this 106 * callback has to be non-blocking and always 107 * return immediately to allow polling multiple 108 * drivers concurrently. 109 * Returns the character grabbed on success, 110 * ERROR_NO_PENDING_CHAR if no character was 111 * available at this time, or any value 112 * between -2 and -127 if there was an error. 113 * In : x0 - pointer to console_t struct 114 * Out: w0 - character on success, 115 * ERROR_NO_PENDING_CHAR if no char, 116 * < -1 on error 117 * Clobber list : x0, x1 118 * --------------------------------------------- 119 */ 120func console_xxx_getc 121 /* 122 * Retrieve values we need (e.g. hardware base address) from 123 * console_xxx_t structure pointed to by x0. 124 * Example: 125 */ 126 ldr x1, [x0, #CONSOLE_T_XXX_BASE] 127 128 /* 129 * Try to read character into w0 from hardware. 130 */ 131 132 ret 133 134 /* Jump here if there is no character available at this time. */ 135getc_no_char: 136 mov w0, #ERROR_NO_PENDING_CHAR 137 ret 138 139 /* Jump here if there was any hardware error. */ 140getc_error: 141 mov w0, #-2 /* may pick error codes between -2 and -127 */ 142 ret 143endfunc console_xxx_getc 144 145 /* --------------------------------------------- 146 * int console_xxx_flush(console_xxx_t *console) 147 * Function to force a write of all buffered 148 * data that hasn't been output. 149 * In : x0 - pointer to console_xxx_t struct 150 * Out: w0 - 0 on success, < 0 on error 151 * Clobber list : x0, x1, x2, x3, x4, x5 152 * --------------------------------------------- 153 */ 154func console_xxx_flush 155 /* 156 * Retrieve values we need (e.g. hardware base address) from 157 * console_xxx_t structure pointed to by x0. 158 * Example: 159 */ 160 ldr x1, [x0, #CONSOLE_T_XXX_BASE] 161 162 /* 163 * Flush all remaining output from hardware FIFOs. Do not return until 164 * all data has been flushed or there was an unrecoverable error. 165 */ 166 167 mov w0, #0 168 ret 169 170 /* Jump here if an unrecoverable error has been encountered. */ 171flush_error: 172 mov w0, #-1 173 ret 174endfunc console_xxx_flush 175