iPXE
Data Structures | Macros | Functions | Variables
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. More...
 
#define SCANCODE_NON_US   0x56
 Scancode for the "non-US \ and |" key. More...
 
#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 )
 

Functions

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

Variables

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

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.

◆ 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.

◆ 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.

◆ 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.

◆ int16_vector

#define int16_vector   __use_text16 ( int16_vector )

Definition at line 93 of file bios_console.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ __text16() [1/2]

static uint8_t __text16 ( bios_inject_lock  )
static

Keypress injection lock.

◆ __text16() [2/2]

static struct segoff __text16 ( int16_vector  )
static

Vector for chaining to other INT 16 handlers.

◆ int16_wrapper()

void int16_wrapper ( void  )

Assembly wrapper.

Referenced by bios_inject_shutdown(), and bios_inject_startup().

◆ bios_handle_cup()

static 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 }
uint16_t cx
Definition: registers.h:51
__asm__ __volatile__("\n1:\n\t" "movb -1(%3,%1), %%al\n\t" "stosb\n\t" "loop 1b\n\t" "xorl %%eax, %%eax\n\t" "mov %4, %1\n\t" "rep stosb\n\t" :"=&D"(discard_D), "=&c"(discard_c), "+m"(*value) :"r"(data), "g"(pad_len), "0"(value0), "1"(len) :"eax")
__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")
#define REAL_CODE(asm_code_str)
Definition: libkir.h:226

References __asm__(), __volatile__(), cx, and REAL_CODE.

◆ bios_handle_ed()

static 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 }
unsigned int console_height
Console height.
Definition: console.c:17
static unsigned int bios_attr
Current character attribute.
Definition: bios_console.c:85
#define ANSIESC_ED_ALL
Erase whole page.
Definition: ansiesc.h:115
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
__asm__ __volatile__("\n1:\n\t" "movb -1(%3,%1), %%al\n\t" "stosb\n\t" "loop 1b\n\t" "xorl %%eax, %%eax\n\t" "mov %4, %1\n\t" "rep stosb\n\t" :"=&D"(discard_D), "=&c"(discard_c), "+m"(*value) :"r"(data), "g"(pad_len), "0"(value0), "1"(len) :"eax")
__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")
#define REAL_CODE(asm_code_str)
Definition: libkir.h:226
unsigned int console_width
Console width.
Definition: console.c:14

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

◆ bios_handle_sgr()

static 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 ) {
170  bios_attr |= ATTR_BOLD;
171  } else if ( aspect == 5 ) {
173  } else if ( aspect == 22 ) {
174  bios_attr &= ~ATTR_BOLD;
175  } else if ( aspect == 25 ) {
176  bios_attr &= ~ATTR_BLINK;
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 }
#define ATTR_FCOL_BLACK
Definition: bios_console.c:40
#define ATTR_FCOL_RED
Definition: bios_console.c:44
#define ATTR_BCOL_MASK
Definition: bios_console.c:51
#define ATTR_BOLD
Definition: bios_console.c:37
#define ATTR_BCOL_YELLOW
Definition: bios_console.c:58
#define ATTR_BCOL_WHITE
Definition: bios_console.c:59
#define ATTR_BCOL_GREEN
Definition: bios_console.c:54
static unsigned int bios_attr
Current character attribute.
Definition: bios_console.c:85
#define ATTR_FCOL_GREEN
Definition: bios_console.c:42
#define ATTR_BLINK
Definition: bios_console.c:49
#define ATTR_BCOL_BLACK
Definition: bios_console.c:52
#define ATTR_DEFAULT
Definition: bios_console.c:61
#define ATTR_BCOL_MAGENTA
Definition: bios_console.c:57
#define ATTR_FCOL_MASK
Definition: bios_console.c:39
#define ATTR_BCOL_CYAN
Definition: bios_console.c:55
unsigned char uint8_t
Definition: stdint.h:10
#define ATTR_FCOL_BLUE
Definition: bios_console.c:41
#define ATTR_BCOL_BLUE
Definition: bios_console.c:53
#define ATTR_FCOL_MAGENTA
Definition: bios_console.c:45
#define ATTR_FCOL_YELLOW
Definition: bios_console.c:46
uint16_t count
Number of entries.
Definition: ena.h:22
#define ATTR_BCOL_RED
Definition: bios_console.c:56
#define ATTR_FCOL_WHITE
Definition: bios_console.c:47
#define ATTR_FCOL_CYAN
Definition: bios_console.c:43

References 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, and count.

◆ bios_handle_dectcem_set()

static 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 get_real
Definition: libkir.h:151
#define BDA_CHAR_HEIGHT
Definition: bios.h:20
unsigned char uint8_t
Definition: stdint.h:10
__asm__ __volatile__("\n1:\n\t" "movb -1(%3,%1), %%al\n\t" "stosb\n\t" "loop 1b\n\t" "xorl %%eax, %%eax\n\t" "mov %4, %1\n\t" "rep stosb\n\t" :"=&D"(discard_D), "=&c"(discard_c), "+m"(*value) :"r"(data), "g"(pad_len), "0"(value0), "1"(len) :"eax")
#define BDA_SEG
Definition: bios.h:6
__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")
#define REAL_CODE(asm_code_str)
Definition: libkir.h:226

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

◆ bios_handle_dectcem_reset()

static 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 }
__asm__ __volatile__("\n1:\n\t" "movb -1(%3,%1), %%al\n\t" "stosb\n\t" "loop 1b\n\t" "xorl %%eax, %%eax\n\t" "mov %4, %1\n\t" "rep stosb\n\t" :"=&D"(discard_D), "=&c"(discard_c), "+m"(*value) :"r"(data), "g"(pad_len), "0"(value0), "1"(len) :"eax")
__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")
#define REAL_CODE(asm_code_str)
Definition: libkir.h:226

References __asm__(), __volatile__(), and REAL_CODE.

◆ bios_putchar()

static 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 }
static unsigned int bios_attr
Current character attribute.
Definition: bios_console.c:85
int ansiesc_process(struct ansiesc_context *ctx, int c)
Process character that may be part of ANSI escape sequence.
Definition: ansiesc.c:74
static struct ansiesc_context bios_ansiesc_ctx
BIOS console ANSI escape sequence context.
Definition: bios_console.c:234
__asm__ __volatile__("\n1:\n\t" "movb -1(%3,%1), %%al\n\t" "stosb\n\t" "loop 1b\n\t" "xorl %%eax, %%eax\n\t" "mov %4, %1\n\t" "rep stosb\n\t" :"=&D"(discard_D), "=&c"(discard_c), "+m"(*value) :"r"(data), "g"(pad_len), "0"(value0), "1"(len) :"eax")
__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")
long discard_c
Definition: bigint.h:32
#define REAL_CODE(asm_code_str)
Definition: libkir.h:226

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

◆ bios_ansi_seq()

static 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 324 of file bios_console.c.

324  {
325  static char buf[ 5 /* "[" + two digits + terminator + NUL */ ];
326  unsigned int key;
327  unsigned int terminator;
328  unsigned int n;
329  unsigned int i;
330  char *tmp = buf;
331 
332  /* Construct ANSI escape sequence for scancode, if known */
333  for ( i = 0 ; i < ( sizeof ( bios_keys ) /
334  sizeof ( bios_keys[0] ) ) ; i++ ) {
335 
336  /* Look for matching scancode */
337  if ( bios_keys[i].scancode != scancode )
338  continue;
339 
340  /* Construct escape sequence */
341  key = bios_keys[i].key;
342  n = KEY_ANSI_N ( key );
344  *(tmp++) = '[';
345  if ( n )
346  tmp += sprintf ( tmp, "%d", n );
347  *(tmp++) = terminator;
348  *(tmp++) = '\0';
349  assert ( tmp <= &buf[ sizeof ( buf ) ] );
350  return buf;
351  }
352 
353  DBG ( "Unrecognised BIOS scancode %02x\n", scancode );
354  return NULL;
355 }
#define sprintf(buf, fmt,...)
Write a formatted string to a buffer.
Definition: stdio.h:36
#define KEY_ANSI_TERMINATOR(key)
Definition: keys.h:62
unsigned long tmp
Definition: linux_pci.h:53
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
uint16_t key
Key code.
Definition: bios_console.c:294
#define KEY_ANSI_N(key)
Definition: keys.h:61
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
struct eth_slow_terminator_tlv terminator
Terminator.
Definition: eth_slow.h:20
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
union @382 key
Sense key.
Definition: scsi.h:18
static const struct bios_key bios_keys[]
Mapping from BIOS scan codes to iPXE key codes.
Definition: bios_console.c:298

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

Referenced by bios_getchar().

◆ bios_getchar()

static int bios_getchar ( void  )
static

Get character from BIOS console.

Return values
characterCharacter read from console

Definition at line 362 of file bios_console.c.

362  {
363  uint16_t keypress;
364  uint8_t kb0;
365  uint8_t kb2;
366  unsigned int scancode;
367  unsigned int character;
368  const char *ansi_seq;
369 
370  /* If we are mid-sequence, pass out the next byte */
371  if ( ( character = *bios_ansi_input ) ) {
372  bios_ansi_input++;
373  return character;
374  }
375 
376  /* Do nothing if injection is in progress */
377  if ( bios_inject_lock )
378  return 0;
379 
380  /* Read character from real BIOS console */
382  __asm__ __volatile__ ( REAL_CODE ( "sti\n\t"
383  "int $0x16\n\t"
384  "cli\n\t" )
385  : "=a" ( keypress )
386  : "a" ( 0x1000 ), "m" ( bios_inject_lock ) );
388  scancode = ( keypress >> 8 );
389  character = ( keypress & 0xff );
390  get_real ( kb0, BDA_SEG, BDA_KB0 );
391  get_real ( kb2, BDA_SEG, BDA_KB2 );
392 
393  /* If it's a normal character, map (if applicable) and return it */
394  if ( character && ( character < 0x80 ) ) {
395 
396  /* Handle special scancodes */
397  if ( scancode == SCANCODE_NON_US ) {
398  /* Treat as "\|" with high bit set */
399  character |= KEYMAP_PSEUDO;
400  } else if ( scancode >= SCANCODE_RSHIFT ) {
401  /* Non-remappable scancode (e.g. numeric keypad) */
402  return character;
403  }
404 
405  /* Apply modifiers */
406  if ( kb0 & BDA_KB0_CTRL )
407  character |= KEYMAP_CTRL;
408  if ( kb0 & BDA_KB0_CAPSLOCK )
409  character |= KEYMAP_CAPSLOCK_REDO;
410  if ( kb2 & BDA_KB2_RALT )
411  character |= KEYMAP_ALTGR;
412 
413  /* Treat LShift+RShift as AltGr since many BIOSes will
414  * not return ASCII characters when AltGr is pressed.
415  */
416  if ( ( kb0 & ( BDA_KB0_LSHIFT | BDA_KB0_RSHIFT ) ) ==
418  character |= KEYMAP_ALTGR;
419  }
420 
421  /* Map and return */
422  return key_remap ( character );
423  }
424 
425  /* Otherwise, check for a special key that we know about */
426  if ( ( ansi_seq = bios_ansi_seq ( keypress >> 8 ) ) ) {
427  /* Start of escape sequence: return ESC (0x1b) */
428  bios_ansi_input = ansi_seq;
429  return 0x1b;
430  }
431 
432  return 0;
433 }
unsigned short uint16_t
Definition: stdint.h:11
#define BDA_KB0_CAPSLOCK
Definition: bios.h:13
static const char * bios_ansi_input
Pointer to current ANSI output sequence.
Definition: bios_console.c:287
#define KEYMAP_CTRL
Ctrl key flag.
Definition: keymap.h:55
#define BDA_KB2
Definition: bios.h:21
#define get_real
Definition: libkir.h:151
static const char * bios_ansi_seq(unsigned int scancode)
Get ANSI escape sequence corresponding to BIOS scancode.
Definition: bios_console.c:324
#define BDA_KB0_RSHIFT
Definition: bios.h:10
#define KEYMAP_ALTGR
AltGr key flag.
Definition: keymap.h:73
#define BDA_KB2_RALT
Definition: bios.h:22
#define KEYMAP_PSEUDO
Pseudo key flag.
Definition: keymap.h:52
#define SCANCODE_RSHIFT
Maximum keycode subject to remapping.
Definition: bios_console.c:69
unsigned int key_remap(unsigned int character)
Remap a key.
Definition: keymap.c:61
#define BDA_KB0_LSHIFT
Definition: bios.h:11
unsigned char uint8_t
Definition: stdint.h:10
#define KEYMAP_CAPSLOCK_REDO
Undo and redo CapsLock key flags.
Definition: keymap.h:70
__asm__ __volatile__("\n1:\n\t" "movb -1(%3,%1), %%al\n\t" "stosb\n\t" "loop 1b\n\t" "xorl %%eax, %%eax\n\t" "mov %4, %1\n\t" "rep stosb\n\t" :"=&D"(discard_D), "=&c"(discard_c), "+m"(*value) :"r"(data), "g"(pad_len), "0"(value0), "1"(len) :"eax")
#define bios_inject_lock
Definition: bios_console.c:89
#define BDA_SEG
Definition: bios.h:6
__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")
#define BDA_KB0_CTRL
Definition: bios.h:12
#define BDA_KB0
Definition: bios.h:9
#define SCANCODE_NON_US
Scancode for the "non-US \ and |" key.
Definition: bios_console.c:76
#define REAL_CODE(asm_code_str)
Definition: libkir.h:226

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()

static 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 441 of file bios_console.c.

441  {
442  unsigned int discard_a;
443  unsigned int flags;
444 
445  /* If we are mid-sequence, we are always ready */
446  if ( *bios_ansi_input )
447  return 1;
448 
449  /* Do nothing if injection is in progress */
450  if ( bios_inject_lock )
451  return 0;
452 
453  /* Otherwise check the real BIOS console */
455  __asm__ __volatile__ ( REAL_CODE ( "sti\n\t"
456  "int $0x16\n\t"
457  "pushfw\n\t"
458  "popw %w0\n\t"
459  "cli\n\t" )
460  : "=R" ( flags ), "=a" ( discard_a )
461  : "a" ( 0x1100 ), "m" ( bios_inject_lock ) );
463  return ( ! ( flags & ZF ) );
464 }
static const char * bios_ansi_input
Pointer to current ANSI output sequence.
Definition: bios_console.c:287
#define ZF
Definition: registers.h:184
__asm__ __volatile__("\n1:\n\t" "movb -1(%3,%1), %%al\n\t" "stosb\n\t" "loop 1b\n\t" "xorl %%eax, %%eax\n\t" "mov %4, %1\n\t" "rep stosb\n\t" :"=&D"(discard_D), "=&c"(discard_c), "+m"(*value) :"r"(data), "g"(pad_len), "0"(value0), "1"(len) :"eax")
#define bios_inject_lock
Definition: bios_console.c:89
__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")
#define REAL_CODE(asm_code_str)
Definition: libkir.h:226
uint8_t flags
Flags.
Definition: ena.h:18

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

◆ bios_inject()

static __asmcall __used void bios_inject ( struct i386_all_regs ix86)
static

Inject keypresses.

Parameters
ix86Registers as passed to INT 16

Definition at line 479 of file bios_console.c.

479  {
480  unsigned int discard_a;
481  unsigned int scancode;
482  unsigned int i;
483  uint16_t keypress;
484  int key;
485 
486  /* If this is a blocking call, then loop until the
487  * non-blocking variant of the call indicates that a keypress
488  * is available. Do this without acquiring the injection
489  * lock, so that injection may take place.
490  */
491  if ( ( ix86->regs.ah & ~0x10 ) == 0x00 ) {
492  __asm__ __volatile__ ( REAL_CODE ( "sti\n\t"
493  "\n1:\n\t"
494  "pushw %%ax\n\t"
495  "int $0x16\n\t"
496  "popw %%ax\n\t"
497  "jc 2f\n\t"
498  "jz 1b\n\t"
499  "\n2:\n\t"
500  "cli\n\t" )
501  : "=a" ( discard_a )
502  : "a" ( ix86->regs.eax | 0x0100 ),
503  "m" ( bios_inject_lock ) );
504  }
505 
506  /* Acquire injection lock */
508 
509  /* Check for keypresses */
510  if ( iskey() ) {
511 
512  /* Get key */
513  key = getkey ( 0 );
514 
515  /* Reverse internal CR->LF mapping */
516  if ( key == '\n' )
517  key = '\r';
518 
519  /* Convert to keypress */
520  keypress = ( ( key << 8 ) | key );
521 
522  /* Handle special keys */
523  if ( key >= KEY_MIN ) {
524  for ( i = 0 ; i < ( sizeof ( bios_keys ) /
525  sizeof ( bios_keys[0] ) ) ; i++ ) {
526  if ( bios_keys[i].key == key ) {
527  scancode = bios_keys[i].scancode;
528  keypress = ( scancode << 8 );
529  break;
530  }
531  }
532  }
533 
534  /* Inject keypress */
535  DBGC ( &bios_console, "BIOS injecting keypress %04x\n",
536  keypress );
537  __asm__ __volatile__ ( REAL_CODE ( "int $0x16\n\t" )
538  : "=a" ( discard_a )
539  : "a" ( 0x0500 ), "c" ( keypress ),
540  "m" ( bios_inject_lock ) );
541  }
542 
543  /* Release injection lock */
545 }
int getkey(unsigned long timeout)
Get single keypress.
Definition: getkey.c:71
unsigned short uint16_t
Definition: stdint.h:11
uint8_t scancode
Scancode.
Definition: bios_console.c:292
#define DBGC(...)
Definition: compiler.h:505
uint32_t eax
Definition: registers.h:109
#define KEY_MIN
Definition: keys.h:64
struct i386_regs regs
Definition: registers.h:176
struct console_driver bios_console
Definition: vesafb.c:45
uint8_t ah
Definition: registers.h:106
__asm__ __volatile__("\n1:\n\t" "movb -1(%3,%1), %%al\n\t" "stosb\n\t" "loop 1b\n\t" "xorl %%eax, %%eax\n\t" "mov %4, %1\n\t" "rep stosb\n\t" :"=&D"(discard_D), "=&c"(discard_c), "+m"(*value) :"r"(data), "g"(pad_len), "0"(value0), "1"(len) :"eax")
#define bios_inject_lock
Definition: bios_console.c:89
__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")
#define REAL_CODE(asm_code_str)
Definition: libkir.h:226
int iskey(void)
Check for available input on any console.
Definition: console.c:130
union @382 key
Sense key.
Definition: scsi.h:18
static const struct bios_key bios_keys[]
Mapping from BIOS scan codes to iPXE key codes.
Definition: bios_console.c:298

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

Referenced by bios_inject_startup().

◆ bios_inject_startup()

static void bios_inject_startup ( void  )
static

Start up keypress injection.

Definition at line 551 of file bios_console.c.

551  {
552 
553  /* Assembly wrapper to call bios_inject() */
555  TEXT16_CODE ( "\nint16_wrapper:\n\t"
556  "pushfw\n\t"
557  "cmpb $0, %%cs:bios_inject_lock\n\t"
558  "jnz 1f\n\t"
560  "\n1:\n\t"
561  "popfw\n\t"
562  "ljmp *%%cs:int16_vector\n\t" ) : );
563 
564  /* Hook INT 16 */
566  &int16_vector );
567 }
#define VIRT_CALL(function)
Call C function from real-mode code.
Definition: librm.h:78
unsigned long intptr_t
Definition: stdint.h:21
void hook_bios_interrupt(unsigned int interrupt, unsigned int handler, struct segoff *chain_vector)
Hook INT vector.
Definition: biosint.c:24
static __asmcall __used void bios_inject(struct i386_all_regs *ix86)
Inject keypresses.
Definition: bios_console.c:479
__asm__ __volatile__("\n1:\n\t" "movb -1(%3,%1), %%al\n\t" "stosb\n\t" "loop 1b\n\t" "xorl %%eax, %%eax\n\t" "mov %4, %1\n\t" "rep stosb\n\t" :"=&D"(discard_D), "=&c"(discard_c), "+m"(*value) :"r"(data), "g"(pad_len), "0"(value0), "1"(len) :"eax")
__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")
void int16_wrapper(void)
Assembly wrapper.
#define int16_vector
Definition: bios_console.c:93
#define TEXT16_CODE(asm_code_str)
Definition: libkir.h:217

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

◆ bios_inject_shutdown()

static void bios_inject_shutdown ( int booting  __unused)
static

Shut down keypress injection.

Parameters
bootingSystem is shutting down for OS boot

Definition at line 574 of file bios_console.c.

574  {
575 
576  /* Unhook INT 16 */
578  &int16_vector );
579 }
unsigned long intptr_t
Definition: stdint.h:21
int unhook_bios_interrupt(unsigned int interrupt, unsigned int handler, struct segoff *chain_vector)
Unhook INT vector.
Definition: biosint.c:69
void int16_wrapper(void)
Assembly wrapper.
#define int16_vector
Definition: bios_console.c:93

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

◆ __startup_fn()

struct startup_fn bios_inject_startup_fn __startup_fn ( STARTUP_NORMAL  )

Keypress injection startup function.

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_ed(struct ansiesc_context *ctx __unused, unsigned int count __unused, int params[] __unused)
Handle ANSI ED (erase in page)
Definition: bios_console.c:128
#define ANSIESC_ED
Erase in page.
Definition: ansiesc.h:106
#define ANSIESC_CUP
Cursor position.
Definition: ansiesc.h:103
#define ANSIESC_SGR
Select graphic rendition.
Definition: ansiesc.h:118
static void bios_handle_dectcem_set(struct ansiesc_context *ctx __unused, unsigned int count __unused, int params[] __unused)
Handle ANSI DECTCEM set (show cursor)
Definition: bios_console.c:194
static void bios_handle_dectcem_reset(struct ansiesc_context *ctx __unused, unsigned int count __unused, int params[] __unused)
Handle ANSI DECTCEM reset (hide cursor)
Definition: bios_console.c:215
#define ANSIESC_DECTCEM_RESET
Hide cursor.
Definition: ansiesc.h:131
#define ANSIESC_DECTCEM_SET
Show cursor.
Definition: ansiesc.h:128
static void bios_handle_sgr(struct ansiesc_context *ctx __unused, unsigned int count, int params[])
Handle ANSI SGR (set graphics rendition)
Definition: bios_console.c:148
static void bios_handle_cup(struct ansiesc_context *ctx __unused, unsigned int count __unused, int params[])
Handle ANSI CUP (cursor position)
Definition: bios_console.c:106
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

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.
Definition: bios_console.c:224

BIOS console ANSI escape sequence context.

Definition at line 234 of file bios_console.c.

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:
= {
{ 0x53, KEY_DC },
{ 0x48, KEY_UP },
{ 0x50, KEY_DOWN },
{ 0x4b, KEY_LEFT },
{ 0x4d, KEY_RIGHT },
{ 0x47, KEY_HOME },
{ 0x4f, KEY_END },
{ 0x49, KEY_PPAGE },
{ 0x51, KEY_NPAGE },
{ 0x3f, KEY_F5 },
{ 0x40, KEY_F6 },
{ 0x41, KEY_F7 },
{ 0x42, KEY_F8 },
{ 0x43, KEY_F9 },
{ 0x44, KEY_F10 },
{ 0x85, KEY_F11 },
{ 0x86, KEY_F12 },
}
#define KEY_F6
F6.
Definition: keys.h:76
#define KEY_F11
F11.
Definition: keys.h:81
#define KEY_F12
F12.
Definition: keys.h:82
#define KEY_F8
F8 (for PXE)
Definition: keys.h:78
#define KEY_NPAGE
Page down.
Definition: keys.h:74
#define KEY_HOME
Home.
Definition: keys.h:70
#define KEY_F9
F9.
Definition: keys.h:79
#define KEY_DOWN
Down arrow.
Definition: keys.h:66
#define KEY_UP
Up arrow.
Definition: keys.h:65
#define KEY_PPAGE
Page up.
Definition: keys.h:73
#define KEY_END
End.
Definition: keys.h:69
#define KEY_DC
Delete.
Definition: keys.h:72
#define KEY_F10
F10.
Definition: keys.h:80
#define KEY_RIGHT
Right arrow.
Definition: keys.h:67
#define KEY_F7
F7.
Definition: keys.h:77
#define KEY_LEFT
Left arrow.
Definition: keys.h:68
#define KEY_F5
F5.
Definition: keys.h:75

Mapping from BIOS scan codes to iPXE key codes.

Definition at line 298 of file bios_console.c.

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,
}
#define CONSOLE_PCBIOS
Definition: bios_console.c:81
static int bios_getchar(void)
Get character from BIOS console.
Definition: bios_console.c:362
static void bios_putchar(int character)
Print a character to BIOS console.
Definition: bios_console.c:243
static int bios_iskey(void)
Check for character ready to read from BIOS console.
Definition: bios_console.c:441

BIOS console.

Definition at line 467 of file bios_console.c.