summaryrefslogtreecommitdiffstats
path: root/src/arch/x86/interface/pcbios
diff options
context:
space:
mode:
authorSimon Rettberg2022-05-11 10:41:01 +0200
committerSimon Rettberg2022-05-11 10:41:01 +0200
commita12e3c379cf2e5946c7316259ef46736cdd5f222 (patch)
tree49638dad528a4490e293ea4a0f87e39ce862a75b /src/arch/x86/interface/pcbios
parentLocal UEFI disk boot support (diff)
parent[cloud] Allow aws-import script to run on Python 3.6 (diff)
downloadipxe-a12e3c379cf2e5946c7316259ef46736cdd5f222.tar.gz
ipxe-a12e3c379cf2e5946c7316259ef46736cdd5f222.tar.xz
ipxe-a12e3c379cf2e5946c7316259ef46736cdd5f222.zip
Merge branch 'master' into openslx
Diffstat (limited to 'src/arch/x86/interface/pcbios')
-rw-r--r--src/arch/x86/interface/pcbios/acpi_timer.c2
-rw-r--r--src/arch/x86/interface/pcbios/acpipwr.c2
-rw-r--r--src/arch/x86/interface/pcbios/bios_console.c71
-rw-r--r--src/arch/x86/interface/pcbios/vesafb.c25
4 files changed, 77 insertions, 23 deletions
diff --git a/src/arch/x86/interface/pcbios/acpi_timer.c b/src/arch/x86/interface/pcbios/acpi_timer.c
index 82e85a034..2e4047e38 100644
--- a/src/arch/x86/interface/pcbios/acpi_timer.c
+++ b/src/arch/x86/interface/pcbios/acpi_timer.c
@@ -107,7 +107,7 @@ static int acpi_timer_probe ( void ) {
unsigned int pm_tmr_blk;
/* Locate FADT */
- fadt = acpi_find ( FADT_SIGNATURE, 0 );
+ fadt = acpi_table ( FADT_SIGNATURE, 0 );
if ( ! fadt ) {
DBGC ( &acpi_timer, "ACPI could not find FADT\n" );
return -ENOENT;
diff --git a/src/arch/x86/interface/pcbios/acpipwr.c b/src/arch/x86/interface/pcbios/acpipwr.c
index 3dac6b605..f08b4af25 100644
--- a/src/arch/x86/interface/pcbios/acpipwr.c
+++ b/src/arch/x86/interface/pcbios/acpipwr.c
@@ -123,7 +123,7 @@ int acpi_poweroff ( void ) {
int rc;
/* Locate FADT */
- fadt = acpi_find ( FADT_SIGNATURE, 0 );
+ fadt = acpi_table ( FADT_SIGNATURE, 0 );
if ( ! fadt ) {
DBGC ( colour, "ACPI could not find FADT\n" );
return -ENOENT;
diff --git a/src/arch/x86/interface/pcbios/bios_console.c b/src/arch/x86/interface/pcbios/bios_console.c
index 80ebf330e..0220c8564 100644
--- a/src/arch/x86/interface/pcbios/bios_console.c
+++ b/src/arch/x86/interface/pcbios/bios_console.c
@@ -60,6 +60,21 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define ATTR_DEFAULT ATTR_FCOL_WHITE
+/** 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.
+ */
+#define SCANCODE_RSHIFT 0x36
+
+/** Scancode for the "non-US \ and |" key
+ *
+ * This is the key that appears between Left Shift and Z on non-US
+ * keyboards.
+ */
+#define SCANCODE_NON_US 0x56
+
/* Set default console usage if applicable */
#if ! ( defined ( CONSOLE_PCBIOS ) && CONSOLE_EXPLICIT ( CONSOLE_PCBIOS ) )
#undef CONSOLE_PCBIOS
@@ -340,28 +355,15 @@ static const char * bios_ansi_seq ( unsigned int scancode ) {
}
/**
- * Map a key
- *
- * @v character Character read from console
- * @ret character Mapped character
- */
-static int bios_keymap ( unsigned int character ) {
- struct key_mapping *mapping;
-
- for_each_table_entry ( mapping, KEYMAP ) {
- if ( mapping->from == character )
- return mapping->to;
- }
- return character;
-}
-
-/**
* Get character from BIOS console
*
* @ret character Character read from console
*/
static int bios_getchar ( void ) {
uint16_t keypress;
+ uint8_t kb0;
+ uint8_t kb2;
+ unsigned int scancode;
unsigned int character;
const char *ansi_seq;
@@ -383,11 +385,42 @@ static int bios_getchar ( void ) {
: "=a" ( keypress )
: "a" ( 0x1000 ), "m" ( bios_inject_lock ) );
bios_inject_lock--;
+ scancode = ( keypress >> 8 );
character = ( keypress & 0xff );
+ get_real ( kb0, BDA_SEG, BDA_KB0 );
+ get_real ( kb2, BDA_SEG, BDA_KB2 );
+
+ /* If it's a normal character, map (if applicable) and return it */
+ if ( character && ( character < 0x80 ) ) {
+
+ /* Handle special scancodes */
+ if ( scancode == SCANCODE_NON_US ) {
+ /* Treat as "\|" with high bit set */
+ character |= KEYMAP_PSEUDO;
+ } else if ( scancode >= SCANCODE_RSHIFT ) {
+ /* Non-remappable scancode (e.g. numeric keypad) */
+ return character;
+ }
+
+ /* Apply modifiers */
+ if ( kb0 & BDA_KB0_CTRL )
+ character |= KEYMAP_CTRL;
+ if ( kb0 & BDA_KB0_CAPSLOCK )
+ character |= KEYMAP_CAPSLOCK_REDO;
+ if ( kb2 & BDA_KB2_RALT )
+ character |= KEYMAP_ALTGR;
+
+ /* Treat LShift+RShift as AltGr since many BIOSes will
+ * not return ASCII characters when AltGr is pressed.
+ */
+ if ( ( kb0 & ( BDA_KB0_LSHIFT | BDA_KB0_RSHIFT ) ) ==
+ ( BDA_KB0_LSHIFT | BDA_KB0_RSHIFT ) ) {
+ character |= KEYMAP_ALTGR;
+ }
- /* If it's a normal character, just map and return it */
- if ( character && ( character < 0x80 ) )
- return bios_keymap ( character );
+ /* Map and return */
+ return key_remap ( character );
+ }
/* Otherwise, check for a special key that we know about */
if ( ( ansi_seq = bios_ansi_seq ( keypress >> 8 ) ) ) {
diff --git a/src/arch/x86/interface/pcbios/vesafb.c b/src/arch/x86/interface/pcbios/vesafb.c
index 21b3e74c4..1b4198129 100644
--- a/src/arch/x86/interface/pcbios/vesafb.c
+++ b/src/arch/x86/interface/pcbios/vesafb.c
@@ -78,6 +78,15 @@ struct console_driver bios_console __attribute__ (( weak ));
/** Font corresponding to selected character width and height */
#define VESAFB_FONT VBE_FONT_8x16
+/** Number of ASCII glyphs within the font */
+#define VESAFB_ASCII 128
+
+/** Glyph to render for non-ASCII characters
+ *
+ * We choose to use one of the box-drawing glyphs.
+ */
+#define VESAFB_UNKNOWN 0xfe
+
/* Forward declaration */
struct console_driver vesafb_console __console_driver;
@@ -130,12 +139,24 @@ static int vesafb_rc ( unsigned int status ) {
/**
* Get character glyph
*
- * @v character Character
+ * @v character Unicode character
* @v glyph Character glyph to fill in
*/
static void vesafb_glyph ( unsigned int character, uint8_t *glyph ) {
- size_t offset = ( character * VESAFB_CHAR_HEIGHT );
+ unsigned int index;
+ size_t offset;
+
+ /* Identify glyph */
+ if ( character < VESAFB_ASCII ) {
+ /* ASCII character: use corresponding glyph */
+ index = character;
+ } else {
+ /* Non-ASCII character: use "unknown" glyph */
+ index = VESAFB_UNKNOWN;
+ }
+ /* Copy glyph from BIOS font table */
+ offset = ( index * VESAFB_CHAR_HEIGHT );
copy_from_real ( glyph, vesafb.glyphs.segment,
( vesafb.glyphs.offset + offset ), VESAFB_CHAR_HEIGHT);
}