1/* 2 * Copyright (c) 2016-2020, 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 a 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* ensure 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 register 23 * r12, but may never depend on it retaining its value across any 24 * function call.) 25 */ 26 27 .globl console_xxx_register 28 .globl console_xxx_putc 29 .globl console_xxx_getc 30 .globl console_xxx_flush 31 32 /* ----------------------------------------------- 33 * int console_xxx_register(console_xxx_t *console, 34 * ...additional parameters as desired...) 35 * Function to initialize and register the console. 36 * The caller needs to pass an empty console_xxx_t 37 * structure in which *MUST* be allocated in 38 * persistent memory (e.g. a global or static local 39 * variable, *NOT* on the stack). 40 * In : r0 - pointer to empty console_t structure 41 * r1 through r7: additional parameters as desired 42 * Out: r0 - 1 on success, 0 on error 43 * Clobber list : r0 - r7 44 * ----------------------------------------------- 45 */ 46func console_xxx_register 47 /* 48 * Store parameters (e.g. hardware base address) in driver-specific 49 * console_xxx_t structure field if they will need to be retrieved 50 * by later console callback (e.g. putc). 51 * Example: 52 */ 53 str r1, [r0, #CONSOLE_T_BASE] 54 str r2, [r0, #CONSOLE_T_XXX_SOME_OTHER_VALUE] 55 56 /* 57 * Initialize console hardware, using r1 - r7 parameters as needed. 58 * Keep console_t pointer in r0 for later. 59 */ 60 61 /* 62 * Macro to finish up registration and return (needs valid r0 + lr). 63 * If any of the argument is unspecified, then the corresponding 64 * entry in console_t is set to 0. 65 */ 66 finish_console_register xxx putc=1, getc=1, flush=1 67 68 /* Jump here if hardware init fails or parameters are invalid. */ 69register_fail: 70 mov r0, #0 71 bx lr 72endfunc console_xxx_register 73 74 /* -------------------------------------------------------- 75 * int console_xxx_putc(int c, console_xxx_t *console) 76 * Function to output a character over the console. It 77 * returns the character printed on success or -1 on error. 78 * In : r0 - character to be printed 79 * r1 - pointer to console_t struct 80 * Out: r0 - printed character on success, < 0 on error. 81 * Clobber list : r0, r1, r2 82 * -------------------------------------------------------- 83 */ 84func console_xxx_putc 85 /* 86 * Retrieve values we need (e.g. hardware base address) from 87 * console_xxx_t structure pointed to by r1. 88 * Example: 89 */ 90 ldr r1, [r1, #CONSOLE_T_BASE] 91 92 /* 93 * Write r0 to hardware. 94 */ 95 96 bx lr 97 98 /* Jump here if output fails for any reason. */ 99putc_error: 100 mov r0, #-1 101 bx lr 102endfunc console_xxx_putc 103 104 /* --------------------------------------------- 105 * int console_xxx_getc(console_xxx_t *console) 106 * Function to get a character from the console. 107 * Even though console_getc() is blocking, this 108 * callback has to be non-blocking and always 109 * return immediately to allow polling multiple 110 * drivers concurrently. 111 * Returns the character grabbed on success, 112 * ERROR_NO_PENDING_CHAR if no character was 113 * available at this time, or any value 114 * between -2 and -127 if there was an error. 115 * In : r0 - pointer to console_t struct 116 * Out: r0 - character on success, 117 * ERROR_NO_PENDING_CHAR if no char, 118 * < -1 on error 119 * Clobber list : r0, r1 120 * --------------------------------------------- 121 */ 122func console_xxx_getc 123 /* 124 * Retrieve values we need (e.g. hardware base address) from 125 * console_xxx_t structure pointed to by r0. 126 * Example: 127 */ 128 ldr r1, [r0, #CONSOLE_T_BASE] 129 130 /* 131 * Try to read character into r0 from hardware. 132 */ 133 134 bx lr 135 136 /* Jump here if there is no character available at this time. */ 137getc_no_char: 138 mov r0, #ERROR_NO_PENDING_CHAR 139 bx lr 140 141 /* Jump here if there was any hardware error. */ 142getc_error: 143 mov r0, #-2 /* may pick error codes between -2 and -127 */ 144 bx lr 145endfunc console_xxx_getc 146 147 /* --------------------------------------------- 148 * int console_xxx_flush(console_xxx_t *console) 149 * Function to force a write of all buffered 150 * data that hasn't been output. 151 * In : r0 - pointer to console_xxx_t struct 152 * Out: void 153 * Clobber list : r0, r1, r2, r3, r4, r5 154 * --------------------------------------------- 155 */ 156func console_xxx_flush 157 /* 158 * Retrieve values we need (e.g. hardware base address) from 159 * console_xxx_t structure pointed to by r0. 160 * Example: 161 */ 162 ldr r1, [r0, #CONSOLE_T_BASE] 163 164 /* 165 * Flush all remaining output from hardware FIFOs. Do not return until 166 * all data has been flushed or there was an unrecoverable error. 167 */ 168 169 bx lr 170endfunc console_xxx_flush 171