aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2012-09-12 10:17:34 +0200
committerJan Beulich <jbeulich@suse.com>2012-09-12 10:17:34 +0200
commit7aa9625cc4b549a6316b43c5f07cc2dec1d7a8ce (patch)
treeef21c0647953f717ea89209808c7ddbd5b5adf88
parent9badeb5dcd4deaebcab6d736943b8ffc2afdacb3 (diff)
downloadxen-7aa9625cc4b549a6316b43c5f07cc2dec1d7a8ce.tar.gz
xen-7aa9625cc4b549a6316b43c5f07cc2dec1d7a8ce.tar.bz2
xen-7aa9625cc4b549a6316b43c5f07cc2dec1d7a8ce.zip
x86: retrieve keyboard shift status flags from BIOS
Recent Linux tries to make use of this, and has no way of getting at these bits without Xen assisting it. There doesn't appear to be a way to obtain the same information from UEFI. Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Keir Fraser <keir@xen.org>
-rw-r--r--xen/arch/x86/boot/trampoline.S9
-rw-r--r--xen/arch/x86/platform_hypercall.c13
-rw-r--r--xen/include/asm-x86/setup.h2
-rw-r--r--xen/include/public/platform.h4
4 files changed, 28 insertions, 0 deletions
diff --git a/xen/arch/x86/boot/trampoline.S b/xen/arch/x86/boot/trampoline.S
index 4421fc2c69..c6bda28103 100644
--- a/xen/arch/x86/boot/trampoline.S
+++ b/xen/arch/x86/boot/trampoline.S
@@ -184,11 +184,16 @@ trampoline_boot_cpu_entry:
* 1. Get memory map.
* 2. Get Enhanced Disk Drive (EDD) information.
* 3. Set video mode.
+ * 4. Get keyboard shift flags.
*/
call get_memory_map
call get_edd
call video
+ mov $0x0200,%ax
+ int $0x16
+ mov %al,bootsym(kbd_shift_flags)
+
/* Disable irqs before returning to protected mode. */
cli
@@ -221,6 +226,10 @@ trampoline_boot_cpu_entry:
skip_realmode:
.byte 0
+ .globl kbd_shift_flags
+kbd_shift_flags:
+ .byte 0
+
rm_idt: .word 256*4-1, 0, 0
#include "mem.S"
diff --git a/xen/arch/x86/platform_hypercall.c b/xen/arch/x86/platform_hypercall.c
index 88880b0d63..d75a83f2bc 100644
--- a/xen/arch/x86/platform_hypercall.c
+++ b/xen/arch/x86/platform_hypercall.c
@@ -29,6 +29,7 @@
#include <asm/edd.h>
#include <asm/mtrr.h>
#include <asm/io_apic.h>
+#include <asm/setup.h>
#include "cpu/mtrr/mtrr.h"
#include <xsm/xsm.h>
@@ -319,6 +320,18 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op)
u.firmware_info.u.efi_info) )
ret = -EFAULT;
break;
+ case XEN_FW_KBD_SHIFT_FLAGS:
+ ret = -ESRCH;
+ if ( op->u.firmware_info.index != 0 )
+ break;
+
+ op->u.firmware_info.u.kbd_shift_flags = bootsym(kbd_shift_flags);
+
+ ret = 0;
+ if ( copy_field_to_guest(u_xenpf_op, op,
+ u.firmware_info.u.kbd_shift_flags) )
+ ret = -EFAULT;
+ break;
default:
ret = -EINVAL;
break;
diff --git a/xen/include/asm-x86/setup.h b/xen/include/asm-x86/setup.h
index abbab23afe..4580f807c8 100644
--- a/xen/include/asm-x86/setup.h
+++ b/xen/include/asm-x86/setup.h
@@ -41,4 +41,6 @@ int xen_in_range(unsigned long mfn);
void microcode_grab_module(
unsigned long *, const multiboot_info_t *, void *(*)(const module_t *));
+extern uint8_t kbd_shift_flags;
+
#endif
diff --git a/xen/include/public/platform.h b/xen/include/public/platform.h
index ad51634abd..6af70ef424 100644
--- a/xen/include/public/platform.h
+++ b/xen/include/public/platform.h
@@ -218,6 +218,7 @@ DEFINE_XEN_GUEST_HANDLE(xenpf_efi_runtime_call_t);
#define XEN_FW_EFI_VENDOR 2
#define XEN_FW_EFI_MEM_INFO 3
#define XEN_FW_EFI_RT_VERSION 4
+#define XEN_FW_KBD_SHIFT_FLAGS 5
struct xenpf_firmware_info {
/* IN variables. */
uint32_t type;
@@ -266,6 +267,9 @@ struct xenpf_firmware_info {
uint32_t type;
} mem;
} efi_info; /* XEN_FW_EFI_INFO */
+
+ /* Int16, Fn02: Get keyboard shift flags. */
+ uint8_t kbd_shift_flags; /* XEN_FW_KBD_SHIFT_FLAGS */
} u;
};
typedef struct xenpf_firmware_info xenpf_firmware_info_t;