summaryrefslogtreecommitdiffstats
path: root/src/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/x86')
-rw-r--r--src/arch/x86/include/bios.h7
-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
-rw-r--r--src/arch/x86/interface/syslinux/comboot_call.c2
-rw-r--r--src/arch/x86/prefix/libprefix.S14
-rw-r--r--src/arch/x86/prefix/romprefix.S4
-rw-r--r--src/arch/x86/scripts/pcbios.lds2
-rw-r--r--src/arch/x86/scripts/prefixonly.lds2
10 files changed, 101 insertions, 30 deletions
diff --git a/src/arch/x86/include/bios.h b/src/arch/x86/include/bios.h
index 14e7acbc7..6391a4958 100644
--- a/src/arch/x86/include/bios.h
+++ b/src/arch/x86/include/bios.h
@@ -6,6 +6,11 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define BDA_SEG 0x0040
#define BDA_EBDA 0x000e
#define BDA_EQUIPMENT_WORD 0x0010
+#define BDA_KB0 0x0017
+#define BDA_KB0_RSHIFT 0x01
+#define BDA_KB0_LSHIFT 0x02
+#define BDA_KB0_CTRL 0x04
+#define BDA_KB0_CAPSLOCK 0x040
#define BDA_FBMS 0x0013
#define BDA_TICKS 0x006c
#define BDA_MIDNIGHT 0x0070
@@ -13,5 +18,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define BDA_REBOOT_WARM 0x1234
#define BDA_NUM_DRIVES 0x0075
#define BDA_CHAR_HEIGHT 0x0085
+#define BDA_KB2 0x0096
+#define BDA_KB2_RALT 0x08
#endif /* BIOS_H */
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);
}
diff --git a/src/arch/x86/interface/syslinux/comboot_call.c b/src/arch/x86/interface/syslinux/comboot_call.c
index dc308dafe..b75e8ef7c 100644
--- a/src/arch/x86/interface/syslinux/comboot_call.c
+++ b/src/arch/x86/interface/syslinux/comboot_call.c
@@ -47,7 +47,7 @@ static char __bss16_array ( syslinux_version, [32] );
#define syslinux_version __use_data16 ( syslinux_version )
/** The "SYSLINUX" copyright string */
-static char __data16_array ( syslinux_copyright, [] ) = " http://ipxe.org";
+static char __data16_array ( syslinux_copyright, [] ) = " https://ipxe.org";
#define syslinux_copyright __use_data16 ( syslinux_copyright )
static char __data16_array ( syslinux_configuration_file, [] ) = "";
diff --git a/src/arch/x86/prefix/libprefix.S b/src/arch/x86/prefix/libprefix.S
index ffb211058..d7f261957 100644
--- a/src/arch/x86/prefix/libprefix.S
+++ b/src/arch/x86/prefix/libprefix.S
@@ -380,6 +380,11 @@ process_bytes:
pushl %eax
pushl %ebp
+ /* Construct ljmp code on stack (since .prefix may not be writable) */
+ .equ LJMP_LEN, 0x06
+ pushw %cs /* "nop ; ljmp %cs, $2f" */
+ pushw $2f
+ pushw $0xea90
/* Construct GDT on stack (since .prefix may not be writable) */
.equ GDT_LEN, 0x20
.equ PM_DS, 0x18 /* Flat data segment */
@@ -410,8 +415,9 @@ process_bytes:
pushw %es
pushw %ds
pushw %ss
- pushw %cs
- pushw $2f
+ pushw %ss /* Far pointer to ljmp code on stack */
+ leaw (GDT_LEN + 1)(%bp), %ax
+ pushw %ax
cli
data32 lgdt (%bp)
movl %cr0, %eax
@@ -438,7 +444,7 @@ process_bytes:
popfw
movl %eax, %cr0
lret
-2: /* lret will ljmp to here */
+2: /* lret will ljmp to here (via constructed ljmp on stack) */
popw %ss
popw %ds
popw %es
@@ -461,7 +467,7 @@ process_bytes:
/* Restore GDT */
data32 lgdt -8(%bp)
- leaw GDT_LEN(%bp), %sp
+ leaw (GDT_LEN + LJMP_LEN)(%bp), %sp
/* Restore registers and return */
popl %ebp
diff --git a/src/arch/x86/prefix/romprefix.S b/src/arch/x86/prefix/romprefix.S
index a9934a725..4e8793c21 100644
--- a/src/arch/x86/prefix/romprefix.S
+++ b/src/arch/x86/prefix/romprefix.S
@@ -161,7 +161,7 @@ pnpheader:
/* Manufacturer string */
mfgstr:
- .asciz "http://ipxe.org"
+ .asciz "https://ipxe.org"
.size mfgstr, . - mfgstr
/* Product string
@@ -607,7 +607,7 @@ get_pmm_decompress_to:
* strings PRODUCT_NAME and PRODUCT_SHORT_NAME in config/branding.h.
*
* While nothing in the GPL prevents you from removing all references
- * to iPXE or http://ipxe.org, we prefer you not to do so.
+ * to iPXE or https://ipxe.org, we prefer you not to do so.
*
* If you have an OEM-mandated branding requirement that cannot be
* satisfied simply by defining PRODUCT_NAME and PRODUCT_SHORT_NAME,
diff --git a/src/arch/x86/scripts/pcbios.lds b/src/arch/x86/scripts/pcbios.lds
index de59adca9..e208b174b 100644
--- a/src/arch/x86/scripts/pcbios.lds
+++ b/src/arch/x86/scripts/pcbios.lds
@@ -229,6 +229,8 @@ SECTIONS {
*(.einfo.*)
*(.discard)
*(.discard.*)
+ *(.sbat)
+ *(.sbat.*)
}
/*
diff --git a/src/arch/x86/scripts/prefixonly.lds b/src/arch/x86/scripts/prefixonly.lds
index dce0930b5..2fe5b03be 100644
--- a/src/arch/x86/scripts/prefixonly.lds
+++ b/src/arch/x86/scripts/prefixonly.lds
@@ -24,6 +24,8 @@ SECTIONS {
*(.einfo.*)
*(.discard)
*(.discard.*)
+ *(.sbat)
+ *(.sbat.*)
}
}