Soby Mathew | 7abebe8 | 2016-08-08 12:38:52 +0100 | [diff] [blame] | 1 | /* |
Antonio Nino Diaz | 8377ae4 | 2017-02-06 16:03:41 +0000 | [diff] [blame] | 2 | * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. |
Soby Mathew | 7abebe8 | 2016-08-08 12:38:52 +0100 | [diff] [blame] | 3 | * |
dp-arm | fa3cf0b | 2017-05-03 09:38:09 +0100 | [diff] [blame] | 4 | * SPDX-License-Identifier: BSD-3-Clause |
Soby Mathew | 7abebe8 | 2016-08-08 12:38:52 +0100 | [diff] [blame] | 5 | */ |
| 6 | #include <asm_macros.S> |
Julius Werner | 94f8907 | 2017-07-31 18:15:11 -0700 | [diff] [blame] | 7 | #include <console_macros.S> |
Soby Mathew | 7abebe8 | 2016-08-08 12:38:52 +0100 | [diff] [blame] | 8 | |
| 9 | /* |
Ambroise Vincent | 35e08da | 2019-05-31 16:21:59 +0100 | [diff] [blame] | 10 | * This file contains a skeleton console driver that can be used as a |
Julius Werner | 94f8907 | 2017-07-31 18:15:11 -0700 | [diff] [blame] | 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. |
Ambroise Vincent | 35e08da | 2019-05-31 16:21:59 +0100 | [diff] [blame] | 19 | * Console drivers *MUST* ensure that the console callbacks they |
Julius Werner | 94f8907 | 2017-07-31 18:15:11 -0700 | [diff] [blame] | 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.) |
Soby Mathew | 7abebe8 | 2016-08-08 12:38:52 +0100 | [diff] [blame] | 25 | */ |
| 26 | |
Julius Werner | 94f8907 | 2017-07-31 18:15:11 -0700 | [diff] [blame] | 27 | .globl console_xxx_register |
| 28 | .globl console_xxx_putc |
| 29 | .globl console_xxx_getc |
| 30 | .globl console_xxx_flush |
Soby Mathew | 7abebe8 | 2016-08-08 12:38:52 +0100 | [diff] [blame] | 31 | |
| 32 | /* ----------------------------------------------- |
Julius Werner | 94f8907 | 2017-07-31 18:15:11 -0700 | [diff] [blame] | 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 : x0 - pointer to empty console_t structure |
| 41 | * x1 through x7: additional parameters as desired |
| 42 | * Out: x0 - 1 on success, 0 on error |
| 43 | * Clobber list : x0 - x7 |
Soby Mathew | 7abebe8 | 2016-08-08 12:38:52 +0100 | [diff] [blame] | 44 | * ----------------------------------------------- |
| 45 | */ |
Julius Werner | 94f8907 | 2017-07-31 18:15:11 -0700 | [diff] [blame] | 46 | func 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 x1, [x0, #CONSOLE_T_XXX_BASE] |
| 54 | str x2, [x0, #CONSOLE_T_XXX_SOME_OTHER_VALUE] |
| 55 | |
| 56 | /* |
| 57 | * Initialize console hardware, using x1 - x7 parameters as needed. |
| 58 | * Keep console_t pointer in x0 for later. |
| 59 | */ |
| 60 | |
Soby Mathew | 58873ae | 2018-10-10 16:03:09 +0100 | [diff] [blame] | 61 | /* |
| 62 | * Macro to finish up registration and return (needs valid x0 + x30). |
| 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 |
Julius Werner | 94f8907 | 2017-07-31 18:15:11 -0700 | [diff] [blame] | 67 | |
| 68 | /* Jump here if hardware init fails or parameters are invalid. */ |
| 69 | register_fail: |
| 70 | mov w0, #0 |
Soby Mathew | 7abebe8 | 2016-08-08 12:38:52 +0100 | [diff] [blame] | 71 | ret |
Julius Werner | 94f8907 | 2017-07-31 18:15:11 -0700 | [diff] [blame] | 72 | endfunc console_xxx_register |
Soby Mathew | 7abebe8 | 2016-08-08 12:38:52 +0100 | [diff] [blame] | 73 | |
| 74 | /* -------------------------------------------------------- |
Julius Werner | 94f8907 | 2017-07-31 18:15:11 -0700 | [diff] [blame] | 75 | * int console_xxx_putc(int c, console_xxx_t *console) |
Soby Mathew | 7abebe8 | 2016-08-08 12:38:52 +0100 | [diff] [blame] | 76 | * Function to output a character over the console. It |
| 77 | * returns the character printed on success or -1 on error. |
| 78 | * In : w0 - character to be printed |
Julius Werner | 94f8907 | 2017-07-31 18:15:11 -0700 | [diff] [blame] | 79 | * x1 - pointer to console_t struct |
| 80 | * Out: w0 - printed character on success, < 0 on error. |
| 81 | * Clobber list : x0, x1, x2 |
Soby Mathew | 7abebe8 | 2016-08-08 12:38:52 +0100 | [diff] [blame] | 82 | * -------------------------------------------------------- |
| 83 | */ |
Julius Werner | 94f8907 | 2017-07-31 18:15:11 -0700 | [diff] [blame] | 84 | func console_xxx_putc |
| 85 | /* |
| 86 | * Retrieve values we need (e.g. hardware base address) from |
| 87 | * console_xxx_t structure pointed to by x1. |
| 88 | * Example: |
| 89 | */ |
| 90 | ldr x1, [x1, #CONSOLE_T_XXX_BASE] |
| 91 | |
| 92 | /* |
| 93 | * Write w0 to hardware. |
| 94 | */ |
| 95 | |
Soby Mathew | 7abebe8 | 2016-08-08 12:38:52 +0100 | [diff] [blame] | 96 | ret |
Julius Werner | 94f8907 | 2017-07-31 18:15:11 -0700 | [diff] [blame] | 97 | |
| 98 | /* Jump here if output fails for any reason. */ |
Soby Mathew | 7abebe8 | 2016-08-08 12:38:52 +0100 | [diff] [blame] | 99 | putc_error: |
| 100 | mov w0, #-1 |
| 101 | ret |
Julius Werner | 94f8907 | 2017-07-31 18:15:11 -0700 | [diff] [blame] | 102 | endfunc console_xxx_putc |
Soby Mathew | 7abebe8 | 2016-08-08 12:38:52 +0100 | [diff] [blame] | 103 | |
| 104 | /* --------------------------------------------- |
Julius Werner | 94f8907 | 2017-07-31 18:15:11 -0700 | [diff] [blame] | 105 | * int console_xxx_getc(console_xxx_t *console) |
Soby Mathew | 7abebe8 | 2016-08-08 12:38:52 +0100 | [diff] [blame] | 106 | * Function to get a character from the console. |
Julius Werner | 94f8907 | 2017-07-31 18:15:11 -0700 | [diff] [blame] | 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 : x0 - pointer to console_t struct |
| 116 | * Out: w0 - character on success, |
| 117 | * ERROR_NO_PENDING_CHAR if no char, |
| 118 | * < -1 on error |
Soby Mathew | 7abebe8 | 2016-08-08 12:38:52 +0100 | [diff] [blame] | 119 | * Clobber list : x0, x1 |
| 120 | * --------------------------------------------- |
| 121 | */ |
Julius Werner | 94f8907 | 2017-07-31 18:15:11 -0700 | [diff] [blame] | 122 | func console_xxx_getc |
| 123 | /* |
| 124 | * Retrieve values we need (e.g. hardware base address) from |
| 125 | * console_xxx_t structure pointed to by x0. |
| 126 | * Example: |
| 127 | */ |
| 128 | ldr x1, [x0, #CONSOLE_T_XXX_BASE] |
| 129 | |
| 130 | /* |
| 131 | * Try to read character into w0 from hardware. |
| 132 | */ |
| 133 | |
Soby Mathew | 7abebe8 | 2016-08-08 12:38:52 +0100 | [diff] [blame] | 134 | ret |
Julius Werner | 94f8907 | 2017-07-31 18:15:11 -0700 | [diff] [blame] | 135 | |
| 136 | /* Jump here if there is no character available at this time. */ |
| 137 | getc_no_char: |
| 138 | mov w0, #ERROR_NO_PENDING_CHAR |
| 139 | ret |
| 140 | |
| 141 | /* Jump here if there was any hardware error. */ |
Soby Mathew | 7abebe8 | 2016-08-08 12:38:52 +0100 | [diff] [blame] | 142 | getc_error: |
Julius Werner | 94f8907 | 2017-07-31 18:15:11 -0700 | [diff] [blame] | 143 | mov w0, #-2 /* may pick error codes between -2 and -127 */ |
Soby Mathew | 7abebe8 | 2016-08-08 12:38:52 +0100 | [diff] [blame] | 144 | ret |
Julius Werner | 94f8907 | 2017-07-31 18:15:11 -0700 | [diff] [blame] | 145 | endfunc console_xxx_getc |
Antonio Nino Diaz | 8377ae4 | 2017-02-06 16:03:41 +0000 | [diff] [blame] | 146 | |
| 147 | /* --------------------------------------------- |
Julius Werner | 94f8907 | 2017-07-31 18:15:11 -0700 | [diff] [blame] | 148 | * int console_xxx_flush(console_xxx_t *console) |
Antonio Nino Diaz | 8377ae4 | 2017-02-06 16:03:41 +0000 | [diff] [blame] | 149 | * Function to force a write of all buffered |
| 150 | * data that hasn't been output. |
Julius Werner | 94f8907 | 2017-07-31 18:15:11 -0700 | [diff] [blame] | 151 | * In : x0 - pointer to console_xxx_t struct |
| 152 | * Out: w0 - 0 on success, < 0 on error |
| 153 | * Clobber list : x0, x1, x2, x3, x4, x5 |
Antonio Nino Diaz | 8377ae4 | 2017-02-06 16:03:41 +0000 | [diff] [blame] | 154 | * --------------------------------------------- |
| 155 | */ |
Julius Werner | 94f8907 | 2017-07-31 18:15:11 -0700 | [diff] [blame] | 156 | func console_xxx_flush |
| 157 | /* |
| 158 | * Retrieve values we need (e.g. hardware base address) from |
| 159 | * console_xxx_t structure pointed to by x0. |
| 160 | * Example: |
| 161 | */ |
| 162 | ldr x1, [x0, #CONSOLE_T_XXX_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 | |
Antonio Nino Diaz | 8377ae4 | 2017-02-06 16:03:41 +0000 | [diff] [blame] | 169 | mov w0, #0 |
| 170 | ret |
Julius Werner | 94f8907 | 2017-07-31 18:15:11 -0700 | [diff] [blame] | 171 | |
| 172 | /* Jump here if an unrecoverable error has been encountered. */ |
Antonio Nino Diaz | 8377ae4 | 2017-02-06 16:03:41 +0000 | [diff] [blame] | 173 | flush_error: |
| 174 | mov w0, #-1 |
| 175 | ret |
Julius Werner | 94f8907 | 2017-07-31 18:15:11 -0700 | [diff] [blame] | 176 | endfunc console_xxx_flush |