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 )
 
#define BIOS_KEY(scancode, key)   { scancode, KEY_REL ( key ) }
 Define a BIOS key mapping. More...
 

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.

◆ BIOS_KEY

#define BIOS_KEY (   scancode,
  key 
)    { scancode, KEY_REL ( key ) }

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]

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 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 );
352  terminator = KEY_ANSI_TERMINATOR ( 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 }
uint16_t rkey
Relative key value.
Definition: bios_console.c:294
#define sprintf(buf, fmt,...)
Write a formatted string to a buffer.
Definition: stdio.h:36
#define KEY_ANSI_TERMINATOR(key)
Extract ANSI escape sequence terminating character.
Definition: keys.h:102
unsigned long tmp
Definition: linux_pci.h:53
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define KEY_ANSI_N(key)
Extract ANSI escape sequence numeric portion.
Definition: keys.h:94
#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
static const struct bios_key bios_keys[]
Mapping from BIOS scan codes to iPXE key codes.
Definition: bios_console.c:307

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

static 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 ) ) {
381  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_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:333
#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 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 }
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 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 getkey(unsigned long timeout)
Get single keypress.
Definition: getkey.c:71
unsigned short uint16_t
Definition: stdint.h:11
#define KEY_REL(key)
Construct relative key value for special key.
Definition: keys.h:76
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
Minimum value for special keypresses.
Definition: keys.h:68
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: crypto.h:284
static const struct bios_key bios_keys[]
Mapping from BIOS scan codes to iPXE key codes.
Definition: bios_console.c:307

References __asm__(), __volatile__(), i386_regs::ah, bios_console, bios_inject_lock, bios_keys, DBGC, i386_regs::eax, getkey(), iskey(), key, KEY_MIN, KEY_REL, 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 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 }
#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:488
__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 585 of file bios_console.c.

585  {
586 
587  /* Unhook INT 16 */
589  &int16_vector );
590 }
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:
= {
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 KEY_F6
F6.
Definition: keys.h:115
#define BIOS_KEY(scancode, key)
Define a BIOS key mapping.
Definition: bios_console.c:304
#define KEY_F11
F11.
Definition: keys.h:120
#define KEY_F12
F12.
Definition: keys.h:121
#define KEY_F8
F8 (for PXE)
Definition: keys.h:117
#define KEY_NPAGE
Page down.
Definition: keys.h:113
#define KEY_HOME
Home.
Definition: keys.h:109
#define KEY_F9
F9.
Definition: keys.h:118
#define KEY_DOWN
Down arrow.
Definition: keys.h:105
#define KEY_UP
Up arrow.
Definition: keys.h:104
#define KEY_PPAGE
Page up.
Definition: keys.h:112
#define KEY_END
End.
Definition: keys.h:108
#define KEY_DC
Delete.
Definition: keys.h:111
#define KEY_F10
F10.
Definition: keys.h:119
#define KEY_RIGHT
Right arrow.
Definition: keys.h:106
#define KEY_F7
F7.
Definition: keys.h:116
#define KEY_LEFT
Left arrow.
Definition: keys.h:107
#define KEY_F5
F5.
Definition: keys.h:114

Mapping from BIOS scan codes to iPXE key codes.

Definition at line 307 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:371
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:450

BIOS console.

Definition at line 476 of file bios_console.c.