iPXE
console.c
Go to the documentation of this file.
1#include "stddef.h"
2#include <ipxe/console.h>
3#include <ipxe/process.h>
4#include <ipxe/nap.h>
5
6/** @file */
7
8FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
9FILE_SECBOOT ( PERMITTED );
10
11/** Current console usage */
13
14/** Console width */
16
17/** Console height */
19
20/**
21 * Write a single character to each console device
22 *
23 * @v character Character to be written
24 * @ret character Character written
25 *
26 * The character is written out to all enabled console devices, using
27 * each device's console_driver::putchar() method.
28 */
29int putchar ( int character ) {
30 struct console_driver *console;
31
32 /* Automatic LF -> CR,LF translation */
33 if ( character == '\n' )
34 putchar ( '\r' );
35
36 for_each_table_entry ( console, CONSOLES ) {
37 if ( ( ! ( console->disabled & CONSOLE_DISABLED_OUTPUT ) ) &&
38 ( console_usage & console->usage ) &&
39 console->putchar )
40 console->putchar ( character );
41 }
42
43 return character;
44}
45
46/**
47 * Check to see if any input is available on any console
48 *
49 * @ret console Console device that has input available, or NULL
50 *
51 * All enabled console devices are checked once for available input
52 * using each device's console_driver::iskey() method. The first
53 * console device that has available input will be returned, if any.
54 */
55static struct console_driver * has_input ( void ) {
56 struct console_driver *console;
57
58 for_each_table_entry ( console, CONSOLES ) {
59 if ( ( ! ( console->disabled & CONSOLE_DISABLED_INPUT ) ) &&
60 console->iskey ) {
61 if ( console->iskey () )
62 return console;
63 }
64 }
65 return NULL;
66}
67
68/**
69 * Read a single character from any console
70 *
71 * @ret character Character read from a console.
72 *
73 * A character will be read from the first enabled console device that
74 * has input available using that console's console_driver::getchar()
75 * method. If no console has input available to be read, this method
76 * will block. To perform a non-blocking read, use something like
77 *
78 * @code
79 *
80 * int key = iskey() ? getchar() : -1;
81 *
82 * @endcode
83 *
84 * The character read will not be echoed back to any console.
85 */
86int getchar ( void ) {
87 struct console_driver *console;
88 int character;
89
90 while ( 1 ) {
91 console = has_input();
92 if ( console && console->getchar ) {
93 character = console->getchar ();
94 break;
95 }
96
97 /* Doze for a while (until the next interrupt). This works
98 * fine, because the keyboard is interrupt-driven, and the
99 * timer interrupt (approx. every 50msec) takes care of the
100 * serial port, which is read by polling. This reduces the
101 * power dissipation of a modern CPU considerably, and also
102 * makes Etherboot waiting for user interaction waste a lot
103 * less CPU time in a VMware session.
104 */
105 cpu_nap();
106
107 /* Keep processing background tasks while we wait for
108 * input.
109 */
110 step();
111 }
112
113 /* CR -> LF translation */
114 if ( character == '\r' )
115 character = '\n';
116
117 return character;
118}
119
120/**
121 * Check for available input on any console
122 *
123 * @ret is_available Input is available on a console
124 *
125 * All enabled console devices are checked once for available input
126 * using each device's console_driver::iskey() method. If any console
127 * device has input available, this call will return true. If this
128 * call returns true, you can then safely call getchar() without
129 * blocking.
130 */
131int iskey ( void ) {
132 return has_input() ? 1 : 0;
133}
134
135/**
136 * Configure console
137 *
138 * @v config Console configuration
139 * @ret rc Return status code
140 *
141 * The configuration is passed to all configurable consoles, including
142 * those which are currently disabled. Consoles may choose to enable
143 * or disable themselves depending upon the configuration.
144 *
145 * If configuration fails, then all consoles will be reset.
146 */
148 struct console_driver *console;
149 int rc;
150
151 /* Reset console width and height */
153
154 /* Try to configure each console */
155 for_each_table_entry ( console, CONSOLES ) {
156 if ( ( console->configure ) &&
157 ( ( rc = console->configure ( config ) ) != 0 ) )
158 goto err;
159 }
160
161 return 0;
162
163 err:
164 /* Reset all consoles, avoiding a potential infinite loop */
165 if ( config )
167 return rc;
168}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
int console_configure(struct console_configuration *config)
Configure console.
Definition console.c:147
unsigned int console_width
Console width.
Definition console.c:15
int getchar(void)
Read a single character from any console.
Definition console.c:86
int iskey(void)
Check for available input on any console.
Definition console.c:131
unsigned int console_height
Console height.
Definition console.c:18
int console_usage
Current console usage.
Definition console.c:12
int putchar(int character)
Write a single character to each console device.
Definition console.c:29
static struct console_driver * has_input(void)
Check to see if any input is available on any console.
Definition console.c:55
#define CONSOLE_USAGE_STDOUT
Standard output.
Definition console.h:142
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
User interaction.
#define CONSOLE_DEFAULT_WIDTH
Default console width.
Definition console.h:172
#define CONSOLE_DISABLED_OUTPUT
Console is disabled for output.
Definition console.h:109
static void console_reset(void)
Reset console.
Definition console.h:215
#define CONSOLES
Console driver table.
Definition console.h:115
#define CONSOLE_DISABLED_INPUT
Console is disabled for input.
Definition console.h:106
#define CONSOLE_DEFAULT_HEIGHT
Default console height.
Definition console.h:175
static void console_set_size(unsigned int width, unsigned int height)
Set console size.
Definition console.h:202
CPU sleeping.
void cpu_nap(void)
Sleep with interrupts enabled until next CPU interrupt.
void step(void)
Single-step a single process.
Definition process.c:99
Processes.
A console configuration.
Definition console.h:25
A console driver.
Definition console.h:56
int(* iskey)(void)
Check for available input.
Definition console.h:88
void(* putchar)(int character)
Write a character to the console.
Definition console.h:69
int(* configure)(struct console_configuration *config)
Configure console.
Definition console.h:95
int usage
Console usage bitmask.
Definition console.h:102
int(* getchar)(void)
Read a character from the console.
Definition console.h:79
int disabled
Console disabled flags.
Definition console.h:63
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition tables.h:386