iPXE
bios_console.c File Reference
#include <assert.h>
#include <realmode.h>
#include <bios.h>
#include <biosint.h>
#include <ipxe/console.h>
#include <ipxe/ansiesc.h>
#include <ipxe/keys.h>
#include <ipxe/keymap.h>
#include <ipxe/init.h>
#include <config/console.h>

Go to the source code of this file.

Data Structures

struct  bios_key
 A BIOS key. More...

Macros

#define ATTR_BOLD   0x08
#define ATTR_FCOL_MASK   0x07
#define ATTR_FCOL_BLACK   0x00
#define ATTR_FCOL_BLUE   0x01
#define ATTR_FCOL_GREEN   0x02
#define ATTR_FCOL_CYAN   0x03
#define ATTR_FCOL_RED   0x04
#define ATTR_FCOL_MAGENTA   0x05
#define ATTR_FCOL_YELLOW   0x06
#define ATTR_FCOL_WHITE   0x07
#define ATTR_BLINK   0x80
#define ATTR_BCOL_MASK   0x70
#define ATTR_BCOL_BLACK   0x00
#define ATTR_BCOL_BLUE   0x10
#define ATTR_BCOL_GREEN   0x20
#define ATTR_BCOL_CYAN   0x30
#define ATTR_BCOL_RED   0x40
#define ATTR_BCOL_MAGENTA   0x50
#define ATTR_BCOL_YELLOW   0x60
#define ATTR_BCOL_WHITE   0x70
#define ATTR_DEFAULT   ATTR_FCOL_WHITE
#define SCANCODE_RSHIFT   0x36
 Maximum keycode subject to remapping.
#define SCANCODE_NON_US   0x56
 Scancode for the "non-US \ and |" key.
#define CONSOLE_PCBIOS   ( CONSOLE_USAGE_ALL & ~CONSOLE_USAGE_LOG )
#define bios_inject_lock   __use_text16 ( bios_inject_lock )
#define int16_vector   __use_text16 ( int16_vector )
#define BIOS_KEY(scancode, key)
 Define a BIOS key mapping.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
static uint8_t __text16 (bios_inject_lock)
 Keypress injection lock.
static struct segoff __text16 (int16_vector)
 Vector for chaining to other INT 16 handlers.
void int16_wrapper (void)
 Assembly wrapper.
static void bios_handle_cup (struct ansiesc_context *ctx __unused, unsigned int count __unused, int params[])
 Handle ANSI CUP (cursor position)
static void bios_handle_ed (struct ansiesc_context *ctx __unused, unsigned int count __unused, int params[] __unused)
 Handle ANSI ED (erase in page)
static void bios_handle_sgr (struct ansiesc_context *ctx __unused, unsigned int count, int params[])
 Handle ANSI SGR (set graphics rendition)
static void bios_handle_dectcem_set (struct ansiesc_context *ctx __unused, unsigned int count __unused, int params[] __unused)
 Handle ANSI DECTCEM set (show cursor)
static void bios_handle_dectcem_reset (struct ansiesc_context *ctx __unused, unsigned int count __unused, int params[] __unused)
 Handle ANSI DECTCEM reset (hide cursor)
static void bios_putchar (int character)
 Print a character to BIOS console.
static const char * bios_ansi_seq (unsigned int scancode)
 Get ANSI escape sequence corresponding to BIOS scancode.
static int bios_getchar (void)
 Get character from BIOS console.
static int bios_iskey (void)
 Check for character ready to read from BIOS console.
static __asmcall __used void bios_inject (struct i386_all_regs *ix86)
 Inject keypresses.
static void bios_inject_startup (void)
 Start up keypress injection.
static void bios_inject_shutdown (int booting __unused)
 Shut down keypress injection.
struct startup_fn bios_inject_startup_fn __startup_fn (STARTUP_NORMAL)
 Keypress injection startup function.

Variables

static unsigned int bios_attr = ATTR_DEFAULT
 Current character attribute.
static struct ansiesc_handler bios_ansiesc_handlers []
 BIOS console ANSI escape sequence handlers.
static struct ansiesc_context bios_ansiesc_ctx
 BIOS console ANSI escape sequence context.
static const char * bios_ansi_input = ""
 Pointer to current ANSI output sequence.
static const struct bios_key bios_keys []
 Mapping from BIOS scan codes to iPXE key codes.
struct console_driver bios_console __console_driver
 BIOS console.

Macro Definition Documentation

◆ ATTR_BOLD

#define ATTR_BOLD   0x08

Definition at line 37 of file bios_console.c.

◆ ATTR_FCOL_MASK

#define ATTR_FCOL_MASK   0x07

Definition at line 39 of file bios_console.c.

◆ ATTR_FCOL_BLACK

#define ATTR_FCOL_BLACK   0x00

Definition at line 40 of file bios_console.c.

◆ ATTR_FCOL_BLUE

#define ATTR_FCOL_BLUE   0x01

Definition at line 41 of file bios_console.c.

◆ ATTR_FCOL_GREEN

#define ATTR_FCOL_GREEN   0x02

Definition at line 42 of file bios_console.c.

◆ ATTR_FCOL_CYAN

#define ATTR_FCOL_CYAN   0x03

Definition at line 43 of file bios_console.c.

◆ ATTR_FCOL_RED

#define ATTR_FCOL_RED   0x04

Definition at line 44 of file bios_console.c.

◆ ATTR_FCOL_MAGENTA

#define ATTR_FCOL_MAGENTA   0x05

Definition at line 45 of file bios_console.c.

◆ ATTR_FCOL_YELLOW

#define ATTR_FCOL_YELLOW   0x06

Definition at line 46 of file bios_console.c.

◆ ATTR_FCOL_WHITE

#define ATTR_FCOL_WHITE   0x07

Definition at line 47 of file bios_console.c.

◆ ATTR_BLINK

#define ATTR_BLINK   0x80

Definition at line 49 of file bios_console.c.

Referenced by bios_handle_sgr().

◆ ATTR_BCOL_MASK

#define ATTR_BCOL_MASK   0x70

Definition at line 51 of file bios_console.c.

◆ ATTR_BCOL_BLACK

#define ATTR_BCOL_BLACK   0x00

Definition at line 52 of file bios_console.c.

◆ ATTR_BCOL_BLUE

#define ATTR_BCOL_BLUE   0x10

Definition at line 53 of file bios_console.c.

◆ ATTR_BCOL_GREEN

#define ATTR_BCOL_GREEN   0x20

Definition at line 54 of file bios_console.c.

◆ ATTR_BCOL_CYAN

#define ATTR_BCOL_CYAN   0x30

Definition at line 55 of file bios_console.c.

◆ ATTR_BCOL_RED

#define ATTR_BCOL_RED   0x40

Definition at line 56 of file bios_console.c.

◆ ATTR_BCOL_MAGENTA

#define ATTR_BCOL_MAGENTA   0x50

Definition at line 57 of file bios_console.c.

◆ ATTR_BCOL_YELLOW

#define ATTR_BCOL_YELLOW   0x60

Definition at line 58 of file bios_console.c.

◆ ATTR_BCOL_WHITE

#define ATTR_BCOL_WHITE   0x70

Definition at line 59 of file bios_console.c.

◆ ATTR_DEFAULT

#define ATTR_DEFAULT   ATTR_FCOL_WHITE

Definition at line 61 of file bios_console.c.

◆ SCANCODE_RSHIFT

#define SCANCODE_RSHIFT   0x36

Maximum keycode subject to remapping.

This allows us to avoid remapping the numeric keypad, which is necessary for keyboard layouts such as "fr" that swap the shifted and unshifted digit keys.

Definition at line 69 of file bios_console.c.

Referenced by bios_getchar().

◆ SCANCODE_NON_US

#define SCANCODE_NON_US   0x56

Scancode for the "non-US \ and |" key.

This is the key that appears between Left Shift and Z on non-US keyboards.

Definition at line 76 of file bios_console.c.

Referenced by bios_getchar().

◆ CONSOLE_PCBIOS

#define CONSOLE_PCBIOS   ( CONSOLE_USAGE_ALL & ~CONSOLE_USAGE_LOG )

Definition at line 81 of file bios_console.c.

◆ bios_inject_lock

#define bios_inject_lock   __use_text16 ( bios_inject_lock )

Definition at line 89 of file bios_console.c.

Referenced by __text16(), bios_getchar(), bios_inject(), and bios_iskey().

◆ int16_vector

#define int16_vector   __use_text16 ( int16_vector )

Definition at line 93 of file bios_console.c.

Referenced by __text16(), bios_inject_shutdown(), and bios_inject_startup().

◆ BIOS_KEY

#define BIOS_KEY ( scancode,
key )
Value:
{ scancode, KEY_REL ( key ) }
union @162305117151260234136356364136041353210355154177 key
Sense key.
Definition scsi.h:3
#define KEY_REL(key)
Construct relative key value for special key.
Definition keys.h:78

Define a BIOS key mapping.

Parameters
scancodeScancode
keyiPXE key code
bioskeyBIOS key mapping

Definition at line 304 of file bios_console.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ __text16() [1/2]

uint8_t __text16 ( bios_inject_lock )
static

Keypress injection lock.

References bios_inject_lock.

◆ __text16() [2/2]

struct segoff __text16 ( int16_vector )
static

Vector for chaining to other INT 16 handlers.

References __text16, and int16_vector.

◆ int16_wrapper()

void int16_wrapper ( void )
extern

Assembly wrapper.

Referenced by bios_inject_shutdown(), and bios_inject_startup().

◆ bios_handle_cup()

void bios_handle_cup ( struct ansiesc_context *ctx __unused,
unsigned int count __unused,
int params[] )
static

Handle ANSI CUP (cursor position)

Parameters
ctxANSI escape sequence context
countParameter count
params[0]Row (1 is top)
params[1]Column (1 is left)

Definition at line 106 of file bios_console.c.

107 {
108 int cx = ( params[1] - 1 );
109 int cy = ( params[0] - 1 );
110
111 if ( cx < 0 )
112 cx = 0;
113 if ( cy < 0 )
114 cy = 0;
115
116 __asm__ __volatile__ ( REAL_CODE ( "int $0x10\n\t" )
117 : : "a" ( 0x0200 ), "b" ( 1 ),
118 "d" ( ( cy << 8 ) | cx ) );
119}
__asm__ __volatile__("call *%9" :"=a"(result), "=c"(discard_ecx), "=d"(discard_edx) :"d"(0), "a"(code), "b"(0), "c"(in_phys), "D"(0), "S"(out_phys), "m"(hypercall))
#define REAL_CODE(asm_code_str)
Definition libkir.h:226
__asm__(".section \".rodata\", \"a\", " PROGBITS "\n\t" "\nprivate_key_data:\n\t" ".size private_key_data, ( . - private_key_data )\n\t" ".equ private_key_len, ( . - private_key_data )\n\t" ".previous\n\t")
uint16_t cx
Definition registers.h:37

References __asm__(), __unused, __volatile__(), count, ctx, cx, and REAL_CODE.

◆ bios_handle_ed()

void bios_handle_ed ( struct ansiesc_context *ctx __unused,
unsigned int count __unused,
int params[] __unused )
static

Handle ANSI ED (erase in page)

Parameters
ctxANSI escape sequence context
countParameter count
params[0]Region to erase

Definition at line 128 of file bios_console.c.

130 {
131 /* We assume that we always clear the whole screen */
132 assert ( params[0] == ANSIESC_ED_ALL );
133
134 __asm__ __volatile__ ( REAL_CODE ( "int $0x10\n\t" )
135 : : "a" ( 0x0600 ), "b" ( bios_attr << 8 ),
136 "c" ( 0 ),
137 "d" ( ( ( console_height - 1 ) << 8 ) |
138 ( console_width - 1 ) ) );
139}
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
static unsigned int bios_attr
Current character attribute.
unsigned int console_width
Console width.
Definition console.c:15
unsigned int console_height
Console height.
Definition console.c:18
#define ANSIESC_ED_ALL
Erase whole page.
Definition ansiesc.h:116

References __asm__(), __unused, __volatile__(), ANSIESC_ED_ALL, assert, bios_attr, console_height, console_width, count, ctx, and REAL_CODE.

◆ bios_handle_sgr()

void bios_handle_sgr ( struct ansiesc_context *ctx __unused,
unsigned int count,
int params[] )
static

Handle ANSI SGR (set graphics rendition)

Parameters
ctxANSI escape sequence context
countParameter count
paramsList of graphic rendition aspects

Definition at line 148 of file bios_console.c.

149 {
150 static const uint8_t bios_attr_fcols[10] = {
154 ATTR_FCOL_WHITE, ATTR_FCOL_WHITE /* defaults */
155 };
156 static const uint8_t bios_attr_bcols[10] = {
160 ATTR_BCOL_BLACK, ATTR_BCOL_BLACK /* defaults */
161 };
162 unsigned int i;
163 int aspect;
164
165 for ( i = 0 ; i < count ; i++ ) {
166 aspect = params[i];
167 if ( aspect == 0 ) {
169 } else if ( aspect == 1 ) {
171 } else if ( aspect == 5 ) {
173 } else if ( aspect == 22 ) {
175 } else if ( aspect == 25 ) {
177 } else if ( ( aspect >= 30 ) && ( aspect <= 39 ) ) {
179 bios_attr |= bios_attr_fcols[ aspect - 30 ];
180 } else if ( ( aspect >= 40 ) && ( aspect <= 49 ) ) {
182 bios_attr |= bios_attr_bcols[ aspect - 40 ];
183 }
184 }
185}
unsigned char uint8_t
Definition stdint.h:10
#define ATTR_BLINK
#define ATTR_FCOL_BLACK
Definition efi_console.c:39
#define ATTR_BCOL_CYAN
Definition efi_console.c:52
#define ATTR_FCOL_YELLOW
Definition efi_console.c:45
#define ATTR_BCOL_GREEN
Definition efi_console.c:51
#define ATTR_BOLD
Definition efi_console.c:36
#define ATTR_FCOL_MAGENTA
Definition efi_console.c:44
#define ATTR_BCOL_BLACK
Definition efi_console.c:49
#define ATTR_BCOL_WHITE
Definition efi_console.c:56
#define ATTR_FCOL_WHITE
Definition efi_console.c:46
#define ATTR_FCOL_CYAN
Definition efi_console.c:42
#define ATTR_BCOL_BLUE
Definition efi_console.c:50
#define ATTR_BCOL_MAGENTA
Definition efi_console.c:54
#define ATTR_BCOL_YELLOW
Definition efi_console.c:55
#define ATTR_FCOL_BLUE
Definition efi_console.c:40
#define ATTR_BCOL_RED
Definition efi_console.c:53
#define ATTR_FCOL_GREEN
Definition efi_console.c:41
#define ATTR_FCOL_MASK
Definition efi_console.c:38
#define ATTR_BCOL_MASK
Definition efi_console.c:48
#define ATTR_FCOL_RED
Definition efi_console.c:43
#define ATTR_DEFAULT
Definition efi_console.c:58
static unsigned int count
Number of entries.
Definition dwmac.h:220

References __unused, ATTR_BCOL_BLACK, ATTR_BCOL_BLUE, ATTR_BCOL_CYAN, ATTR_BCOL_GREEN, ATTR_BCOL_MAGENTA, ATTR_BCOL_MASK, ATTR_BCOL_RED, ATTR_BCOL_WHITE, ATTR_BCOL_YELLOW, ATTR_BLINK, ATTR_BOLD, ATTR_DEFAULT, ATTR_FCOL_BLACK, ATTR_FCOL_BLUE, ATTR_FCOL_CYAN, ATTR_FCOL_GREEN, ATTR_FCOL_MAGENTA, ATTR_FCOL_MASK, ATTR_FCOL_RED, ATTR_FCOL_WHITE, ATTR_FCOL_YELLOW, bios_attr, count, and ctx.

◆ bios_handle_dectcem_set()

void bios_handle_dectcem_set ( struct ansiesc_context *ctx __unused,
unsigned int count __unused,
int params[] __unused )
static

Handle ANSI DECTCEM set (show cursor)

Parameters
ctxANSI escape sequence context
countParameter count
paramsList of graphic rendition aspects

Definition at line 194 of file bios_console.c.

196 {
197 uint8_t height;
198
199 /* Get character height */
200 get_real ( height, BDA_SEG, BDA_CHAR_HEIGHT );
201
202 __asm__ __volatile__ ( REAL_CODE ( "int $0x10\n\t" )
203 : : "a" ( 0x0100 ),
204 "c" ( ( ( height - 2 ) << 8 ) |
205 ( height - 1 ) ) );
206}
#define BDA_SEG
Definition bios.h:6
#define BDA_CHAR_HEIGHT
Definition bios.h:20
#define get_real
Definition libkir.h:151

References __asm__(), __unused, __volatile__(), BDA_CHAR_HEIGHT, BDA_SEG, count, ctx, get_real, and REAL_CODE.

◆ bios_handle_dectcem_reset()

void bios_handle_dectcem_reset ( struct ansiesc_context *ctx __unused,
unsigned int count __unused,
int params[] __unused )
static

Handle ANSI DECTCEM reset (hide cursor)

Parameters
ctxANSI escape sequence context
countParameter count
paramsList of graphic rendition aspects

Definition at line 215 of file bios_console.c.

217 {
218
219 __asm__ __volatile__ ( REAL_CODE ( "int $0x10\n\t" )
220 : : "a" ( 0x0100 ), "c" ( 0x2000 ) );
221}

References __asm__(), __unused, __volatile__(), count, ctx, and REAL_CODE.

◆ bios_putchar()

void bios_putchar ( int character)
static

Print a character to BIOS console.

Parameters
characterCharacter to be printed

Definition at line 243 of file bios_console.c.

243 {
244 int discard_a, discard_b, discard_c;
245
246 /* Intercept ANSI escape sequences */
247 character = ansiesc_process ( &bios_ansiesc_ctx, character );
248 if ( character < 0 )
249 return;
250
251 /* Print character with attribute */
252 __asm__ __volatile__ ( REAL_CODE ( "pushl %%ebp\n\t" /* gcc bug */
253 /* Skip non-printable characters */
254 "cmpb $0x20, %%al\n\t"
255 "jb 1f\n\t"
256 /* Read attribute */
257 "movb %%al, %%cl\n\t"
258 "movb $0x08, %%ah\n\t"
259 "int $0x10\n\t"
260 "xchgb %%al, %%cl\n\t"
261 /* Skip if attribute matches */
262 "cmpb %%ah, %%bl\n\t"
263 "je 1f\n\t"
264 /* Set attribute */
265 "movw $0x0001, %%cx\n\t"
266 "movb $0x09, %%ah\n\t"
267 "int $0x10\n\t"
268 "\n1:\n\t"
269 /* Print character */
270 "xorw %%bx, %%bx\n\t"
271 "movb $0x0e, %%ah\n\t"
272 "int $0x10\n\t"
273 "popl %%ebp\n\t" /* gcc bug */ )
274 : "=a" ( discard_a ), "=b" ( discard_b ),
275 "=c" ( discard_c )
276 : "a" ( character ), "b" ( bios_attr ) );
277}
int ansiesc_process(struct ansiesc_context *ctx, int c)
Process character that may be part of ANSI escape sequence.
Definition ansiesc.c:75
long discard_c
Definition bigint.h:33
static struct ansiesc_context bios_ansiesc_ctx
BIOS console ANSI escape sequence context.

References __asm__(), __volatile__(), ansiesc_process(), bios_ansiesc_ctx, bios_attr, discard_c, and REAL_CODE.

◆ bios_ansi_seq()

const char * bios_ansi_seq ( unsigned int scancode)
static

Get ANSI escape sequence corresponding to BIOS scancode.

Parameters
scancodeBIOS scancode
Return values
ansi_seqANSI escape sequence, if any, otherwise NULL

Definition at line 333 of file bios_console.c.

333 {
334 static char buf[ 5 /* "[" + two digits + terminator + NUL */ ];
335 unsigned int rkey;
336 unsigned int terminator;
337 unsigned int n;
338 unsigned int i;
339 char *tmp = buf;
340
341 /* Construct ANSI escape sequence for scancode, if known */
342 for ( i = 0 ; i < ( sizeof ( bios_keys ) /
343 sizeof ( bios_keys[0] ) ) ; i++ ) {
344
345 /* Look for matching scancode */
346 if ( bios_keys[i].scancode != scancode )
347 continue;
348
349 /* Construct escape sequence */
350 rkey = bios_keys[i].rkey;
351 n = KEY_ANSI_N ( rkey );
353 *(tmp++) = '[';
354 if ( n )
355 tmp += sprintf ( tmp, "%d", n );
356 *(tmp++) = terminator;
357 *(tmp++) = '\0';
358 assert ( tmp <= &buf[ sizeof ( buf ) ] );
359 return buf;
360 }
361
362 DBG ( "Unrecognised BIOS scancode %02x\n", scancode );
363 return NULL;
364}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
static const struct bios_key bios_keys[]
Mapping from BIOS scan codes to iPXE key codes.
struct eth_slow_terminator_tlv terminator
Terminator.
Definition eth_slow.h:9
#define DBG(...)
Print a debugging message.
Definition compiler.h:498
#define KEY_ANSI_TERMINATOR(key)
Extract ANSI escape sequence terminating character.
Definition keys.h:104
#define KEY_ANSI_N(key)
Extract ANSI escape sequence numeric portion.
Definition keys.h:96
unsigned long tmp
Definition linux_pci.h:65
#define sprintf(buf, fmt,...)
Write a formatted string to a buffer.
Definition stdio.h:37

References assert, bios_keys, DBG, KEY_ANSI_N, KEY_ANSI_TERMINATOR, NULL, bios_key::rkey, bios_key::scancode, sprintf, terminator, and tmp.

Referenced by bios_getchar().

◆ bios_getchar()

int bios_getchar ( void )
static

Get character from BIOS console.

Return values
characterCharacter read from console

Definition at line 371 of file bios_console.c.

371 {
372 uint16_t keypress;
373 uint8_t kb0;
374 uint8_t kb2;
375 unsigned int scancode;
376 unsigned int character;
377 const char *ansi_seq;
378
379 /* If we are mid-sequence, pass out the next byte */
380 if ( ( character = *bios_ansi_input ) ) {
382 return character;
383 }
384
385 /* Do nothing if injection is in progress */
386 if ( bios_inject_lock )
387 return 0;
388
389 /* Read character from real BIOS console */
391 __asm__ __volatile__ ( REAL_CODE ( "sti\n\t"
392 "int $0x16\n\t"
393 "cli\n\t" )
394 : "=a" ( keypress )
395 : "a" ( 0x1000 ), "m" ( bios_inject_lock ) );
397 scancode = ( keypress >> 8 );
398 character = ( keypress & 0xff );
399 get_real ( kb0, BDA_SEG, BDA_KB0 );
400 get_real ( kb2, BDA_SEG, BDA_KB2 );
401
402 /* If it's a normal character, map (if applicable) and return it */
403 if ( character && ( character < 0x80 ) ) {
404
405 /* Handle special scancodes */
406 if ( scancode == SCANCODE_NON_US ) {
407 /* Treat as "\|" with high bit set */
408 character |= KEYMAP_PSEUDO;
409 } else if ( scancode >= SCANCODE_RSHIFT ) {
410 /* Non-remappable scancode (e.g. numeric keypad) */
411 return character;
412 }
413
414 /* Apply modifiers */
415 if ( kb0 & BDA_KB0_CTRL )
416 character |= KEYMAP_CTRL;
417 if ( kb0 & BDA_KB0_CAPSLOCK )
418 character |= KEYMAP_CAPSLOCK_REDO;
419 if ( kb2 & BDA_KB2_RALT )
420 character |= KEYMAP_ALTGR;
421
422 /* Treat LShift+RShift as AltGr since many BIOSes will
423 * not return ASCII characters when AltGr is pressed.
424 */
425 if ( ( kb0 & ( BDA_KB0_LSHIFT | BDA_KB0_RSHIFT ) ) ==
427 character |= KEYMAP_ALTGR;
428 }
429
430 /* Map and return */
431 return key_remap ( character );
432 }
433
434 /* Otherwise, check for a special key that we know about */
435 if ( ( ansi_seq = bios_ansi_seq ( keypress >> 8 ) ) ) {
436 /* Start of escape sequence: return ESC (0x1b) */
437 bios_ansi_input = ansi_seq;
438 return 0x1b;
439 }
440
441 return 0;
442}
unsigned short uint16_t
Definition stdint.h:11
#define BDA_KB0_CTRL
Definition bios.h:12
#define BDA_KB0_CAPSLOCK
Definition bios.h:13
#define BDA_KB0_LSHIFT
Definition bios.h:11
#define BDA_KB2
Definition bios.h:21
#define BDA_KB2_RALT
Definition bios.h:22
#define BDA_KB0
Definition bios.h:9
#define BDA_KB0_RSHIFT
Definition bios.h:10
#define bios_inject_lock
static const char * bios_ansi_input
Pointer to current ANSI output sequence.
static const char * bios_ansi_seq(unsigned int scancode)
Get ANSI escape sequence corresponding to BIOS scancode.
#define SCANCODE_NON_US
Scancode for the "non-US \ and |" key.
#define SCANCODE_RSHIFT
Maximum keycode subject to remapping.
unsigned int key_remap(unsigned int character)
Remap a key.
Definition keymap.c:62
#define KEYMAP_PSEUDO
Pseudo key flag.
Definition keymap.h:53
#define KEYMAP_ALTGR
AltGr key flag.
Definition keymap.h:74
#define KEYMAP_CTRL
Ctrl key flag.
Definition keymap.h:56
#define KEYMAP_CAPSLOCK_REDO
Undo and redo CapsLock key flags.
Definition keymap.h:71

References __asm__(), __volatile__(), BDA_KB0, BDA_KB0_CAPSLOCK, BDA_KB0_CTRL, BDA_KB0_LSHIFT, BDA_KB0_RSHIFT, BDA_KB2, BDA_KB2_RALT, BDA_SEG, bios_ansi_input, bios_ansi_seq(), bios_inject_lock, get_real, key_remap(), KEYMAP_ALTGR, KEYMAP_CAPSLOCK_REDO, KEYMAP_CTRL, KEYMAP_PSEUDO, REAL_CODE, bios_key::scancode, SCANCODE_NON_US, and SCANCODE_RSHIFT.

◆ bios_iskey()

int bios_iskey ( void )
static

Check for character ready to read from BIOS console.

Return values
TrueCharacter available to read
FalseNo character available to read

Definition at line 450 of file bios_console.c.

450 {
451 unsigned int discard_a;
452 unsigned int flags;
453
454 /* If we are mid-sequence, we are always ready */
455 if ( *bios_ansi_input )
456 return 1;
457
458 /* Do nothing if injection is in progress */
459 if ( bios_inject_lock )
460 return 0;
461
462 /* Otherwise check the real BIOS console */
464 __asm__ __volatile__ ( REAL_CODE ( "sti\n\t"
465 "int $0x16\n\t"
466 "pushfw\n\t"
467 "popw %w0\n\t"
468 "cli\n\t" )
469 : "=R" ( flags ), "=a" ( discard_a )
470 : "a" ( 0x1100 ), "m" ( bios_inject_lock ) );
472 return ( ! ( flags & ZF ) );
473}
uint8_t flags
Flags.
Definition ena.h:7
#define ZF
Definition registers.h:184

References __asm__(), __volatile__(), bios_ansi_input, bios_inject_lock, flags, REAL_CODE, and ZF.

◆ bios_inject()

__asmcall __used void bios_inject ( struct i386_all_regs * ix86)
static

Inject keypresses.

Parameters
ix86Registers as passed to INT 16

Definition at line 488 of file bios_console.c.

488 {
489 unsigned int discard_a;
490 unsigned int scancode;
491 unsigned int rkey;
492 unsigned int i;
493 uint16_t keypress;
494 int key;
495
496 /* If this is a blocking call, then loop until the
497 * non-blocking variant of the call indicates that a keypress
498 * is available. Do this without acquiring the injection
499 * lock, so that injection may take place.
500 */
501 if ( ( ix86->regs.ah & ~0x10 ) == 0x00 ) {
502 __asm__ __volatile__ ( REAL_CODE ( "sti\n\t"
503 "\n1:\n\t"
504 "pushw %%ax\n\t"
505 "int $0x16\n\t"
506 "popw %%ax\n\t"
507 "jc 2f\n\t"
508 "jz 1b\n\t"
509 "\n2:\n\t"
510 "cli\n\t" )
511 : "=a" ( discard_a )
512 : "a" ( ix86->regs.eax | 0x0100 ),
513 "m" ( bios_inject_lock ) );
514 }
515
516 /* Acquire injection lock */
518
519 /* Check for keypresses */
520 if ( iskey() ) {
521
522 /* Get key */
523 key = getkey ( 0 );
524
525 /* Reverse internal CR->LF mapping */
526 if ( key == '\n' )
527 key = '\r';
528
529 /* Convert to keypress */
530 keypress = ( ( key << 8 ) | key );
531
532 /* Handle special keys */
533 if ( key >= KEY_MIN ) {
534 rkey = KEY_REL ( key );
535 for ( i = 0 ; i < ( sizeof ( bios_keys ) /
536 sizeof ( bios_keys[0] ) ) ; i++ ) {
537 if ( bios_keys[i].rkey == rkey ) {
538 scancode = bios_keys[i].scancode;
539 keypress = ( scancode << 8 );
540 break;
541 }
542 }
543 }
544
545 /* Inject keypress */
546 DBGC ( &bios_console, "BIOS injecting keypress %04x\n",
547 keypress );
548 __asm__ __volatile__ ( REAL_CODE ( "int $0x16\n\t" )
549 : "=a" ( discard_a )
550 : "a" ( 0x0500 ), "c" ( keypress ),
551 "m" ( bios_inject_lock ) );
552 }
553
554 /* Release injection lock */
556}
int iskey(void)
Check for available input on any console.
Definition console.c:131
int getkey(unsigned long timeout)
Get single keypress.
Definition getkey.c:72
#define DBGC(...)
Definition compiler.h:505
#define KEY_MIN
Minimum value for special keypresses.
Definition keys.h:70
struct i386_regs regs
Definition registers.h:176
uint8_t ah
Definition registers.h:106
uint32_t eax
Definition registers.h:109
struct console_driver bios_console
Definition vesafb.c:45

References __asm__(), __asmcall, __used, __volatile__(), i386_regs::ah, bios_console, bios_inject_lock, bios_keys, DBGC, i386_regs::eax, getkey(), iskey(), key, KEY_MIN, KEY_REL, REAL_CODE, and i386_all_regs::regs.

Referenced by bios_inject_startup().

◆ bios_inject_startup()

void bios_inject_startup ( void )
static

Start up keypress injection.

Definition at line 562 of file bios_console.c.

562 {
563
564 /* Assembly wrapper to call bios_inject() */
566 TEXT16_CODE ( "\nint16_wrapper:\n\t"
567 "pushfw\n\t"
568 "cmpb $0, %%cs:bios_inject_lock\n\t"
569 "jnz 1f\n\t"
571 "\n1:\n\t"
572 "popfw\n\t"
573 "ljmp *%%cs:int16_vector\n\t" ) : );
574
575 /* Hook INT 16 */
577 &int16_vector );
578}
unsigned long intptr_t
Definition stdint.h:21
static __asmcall __used void bios_inject(struct i386_all_regs *ix86)
Inject keypresses.
void int16_wrapper(void)
Assembly wrapper.
#define int16_vector
void hook_bios_interrupt(unsigned int interrupt, unsigned int handler, struct segoff *chain_vector)
Hook INT vector.
Definition biosint.c:25
#define TEXT16_CODE(asm_code_str)
Definition libkir.h:217
#define VIRT_CALL(function)
Call C function from real-mode code.
Definition librm.h:72

References __asm__(), __volatile__(), bios_inject(), hook_bios_interrupt(), int16_vector, int16_wrapper(), TEXT16_CODE, and VIRT_CALL.

Referenced by __startup_fn().

◆ bios_inject_shutdown()

void bios_inject_shutdown ( int booting __unused)
static

Shut down keypress injection.

Parameters
bootingSystem is shutting down for OS boot

Definition at line 585 of file bios_console.c.

585 {
586
587 /* Unhook INT 16 */
589 &int16_vector );
590}
int unhook_bios_interrupt(unsigned int interrupt, unsigned int handler, struct segoff *chain_vector)
Unhook INT vector.
Definition biosint.c:70

References __unused, int16_vector, int16_wrapper(), and unhook_bios_interrupt().

Referenced by __startup_fn().

◆ __startup_fn()

struct startup_fn bios_inject_startup_fn __startup_fn ( STARTUP_NORMAL )

Keypress injection startup function.

References __startup_fn, bios_inject_shutdown(), bios_inject_startup(), and STARTUP_NORMAL.

Variable Documentation

◆ bios_attr

unsigned int bios_attr = ATTR_DEFAULT
static

Current character attribute.

Definition at line 85 of file bios_console.c.

Referenced by bios_handle_ed(), bios_handle_sgr(), and bios_putchar().

◆ bios_ansiesc_handlers

struct ansiesc_handler bios_ansiesc_handlers[]
static
Initial value:
= {
{ 0, NULL }
}
static void bios_handle_dectcem_reset(struct ansiesc_context *ctx __unused, unsigned int count __unused, int params[] __unused)
Handle ANSI DECTCEM reset (hide cursor)
static void bios_handle_dectcem_set(struct ansiesc_context *ctx __unused, unsigned int count __unused, int params[] __unused)
Handle ANSI DECTCEM set (show cursor)
static void bios_handle_cup(struct ansiesc_context *ctx __unused, unsigned int count __unused, int params[])
Handle ANSI CUP (cursor position)
static void bios_handle_ed(struct ansiesc_context *ctx __unused, unsigned int count __unused, int params[] __unused)
Handle ANSI ED (erase in page)
static void bios_handle_sgr(struct ansiesc_context *ctx __unused, unsigned int count, int params[])
Handle ANSI SGR (set graphics rendition)
#define ANSIESC_DECTCEM_SET
Show cursor.
Definition ansiesc.h:129
#define ANSIESC_ED
Erase in page.
Definition ansiesc.h:107
#define ANSIESC_DECTCEM_RESET
Hide cursor.
Definition ansiesc.h:132
#define ANSIESC_SGR
Select graphic rendition.
Definition ansiesc.h:119
#define ANSIESC_CUP
Cursor position.
Definition ansiesc.h:104

BIOS console ANSI escape sequence handlers.

Definition at line 224 of file bios_console.c.

◆ bios_ansiesc_ctx

struct ansiesc_context bios_ansiesc_ctx
static
Initial value:
= {
.handlers = bios_ansiesc_handlers,
}
static struct ansiesc_handler bios_ansiesc_handlers[]
BIOS console ANSI escape sequence handlers.

BIOS console ANSI escape sequence context.

Definition at line 234 of file bios_console.c.

234 {
235 .handlers = bios_ansiesc_handlers,
236};

Referenced by bios_putchar().

◆ bios_ansi_input

const char* bios_ansi_input = ""
static

Pointer to current ANSI output sequence.

While we are in the middle of returning an ANSI sequence for a special key, this will point to the next character to return. When not in the middle of such a sequence, this will point to a NUL (note: not "will be NULL").

Definition at line 287 of file bios_console.c.

Referenced by bios_getchar(), and bios_iskey().

◆ bios_keys

const struct bios_key bios_keys[]
static
Initial value:
= {
BIOS_KEY ( 0x53, KEY_DC ),
BIOS_KEY ( 0x48, KEY_UP ),
BIOS_KEY ( 0x50, KEY_DOWN ),
BIOS_KEY ( 0x4b, KEY_LEFT ),
BIOS_KEY ( 0x4d, KEY_RIGHT ),
BIOS_KEY ( 0x47, KEY_HOME ),
BIOS_KEY ( 0x4f, KEY_END ),
BIOS_KEY ( 0x49, KEY_PPAGE ),
BIOS_KEY ( 0x51, KEY_NPAGE ),
BIOS_KEY ( 0x3f, KEY_F5 ),
BIOS_KEY ( 0x40, KEY_F6 ),
BIOS_KEY ( 0x41, KEY_F7 ),
BIOS_KEY ( 0x42, KEY_F8 ),
BIOS_KEY ( 0x43, KEY_F9 ),
BIOS_KEY ( 0x44, KEY_F10 ),
BIOS_KEY ( 0x85, KEY_F11 ),
BIOS_KEY ( 0x86, KEY_F12 ),
}
#define BIOS_KEY(scancode, key)
Define a BIOS key mapping.
#define KEY_RIGHT
Right arrow.
Definition keys.h:108
#define KEY_DC
Delete.
Definition keys.h:113
#define KEY_F12
F12.
Definition keys.h:123
#define KEY_DOWN
Down arrow.
Definition keys.h:107
#define KEY_F5
F5.
Definition keys.h:116
#define KEY_PPAGE
Page up.
Definition keys.h:114
#define KEY_F9
F9.
Definition keys.h:120
#define KEY_F8
F8 (for PXE)
Definition keys.h:119
#define KEY_F7
F7.
Definition keys.h:118
#define KEY_NPAGE
Page down.
Definition keys.h:115
#define KEY_END
End.
Definition keys.h:110
#define KEY_F11
F11.
Definition keys.h:122
#define KEY_F6
F6.
Definition keys.h:117
#define KEY_F10
F10.
Definition keys.h:121
#define KEY_LEFT
Left arrow.
Definition keys.h:109
#define KEY_HOME
Home.
Definition keys.h:111
#define KEY_UP
Up arrow.
Definition keys.h:106

Mapping from BIOS scan codes to iPXE key codes.

Definition at line 307 of file bios_console.c.

307 {
308 BIOS_KEY ( 0x53, KEY_DC ),
309 BIOS_KEY ( 0x48, KEY_UP ),
310 BIOS_KEY ( 0x50, KEY_DOWN ),
311 BIOS_KEY ( 0x4b, KEY_LEFT ),
312 BIOS_KEY ( 0x4d, KEY_RIGHT ),
313 BIOS_KEY ( 0x47, KEY_HOME ),
314 BIOS_KEY ( 0x4f, KEY_END ),
315 BIOS_KEY ( 0x49, KEY_PPAGE ),
316 BIOS_KEY ( 0x51, KEY_NPAGE ),
317 BIOS_KEY ( 0x3f, KEY_F5 ),
318 BIOS_KEY ( 0x40, KEY_F6 ),
319 BIOS_KEY ( 0x41, KEY_F7 ),
320 BIOS_KEY ( 0x42, KEY_F8 ),
321 BIOS_KEY ( 0x43, KEY_F9 ),
322 BIOS_KEY ( 0x44, KEY_F10 ),
323 BIOS_KEY ( 0x85, KEY_F11 ),
324 BIOS_KEY ( 0x86, KEY_F12 ),
325};

Referenced by bios_ansi_seq(), and bios_inject().

◆ __console_driver

struct console_driver bios_console __console_driver
Initial value:
= {
.putchar = bios_putchar,
.getchar = bios_getchar,
.iskey = bios_iskey,
.usage = CONSOLE_PCBIOS,
}
static void bios_putchar(int character)
Print a character to BIOS console.
static int bios_getchar(void)
Get character from BIOS console.
static int bios_iskey(void)
Check for character ready to read from BIOS console.
#define CONSOLE_PCBIOS

BIOS console.

Definition at line 476 of file bios_console.c.

476 {
477 .putchar = bios_putchar,
478 .getchar = bios_getchar,
479 .iskey = bios_iskey,
480 .usage = CONSOLE_PCBIOS,
481};