From ce01c55c4bebd7822f3b3b6f60ab94e8c27cdde9 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Wed, 20 Aug 2008 15:53:27 +0300 Subject: [PATCH] kvm: testsuite: add minimal big real mode entry/exit Signed-off-by: Avi Kivity --- kvm/user/test/x86/realmode.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/kvm/user/test/x86/realmode.c b/kvm/user/test/x86/realmode.c index 6968175a48..6b04b3b9ab 100644 --- a/kvm/user/test/x86/realmode.c +++ b/kvm/user/test/x86/realmode.c @@ -1,6 +1,9 @@ asm(".code16gcc"); +typedef unsigned char u8; +typedef unsigned short u16; typedef unsigned u32; +typedef unsigned long long u64; static int strlen(const char *str) { @@ -29,9 +32,46 @@ struct regs { u32 eip, eflags; }; +static u64 gdt[] = { + 0, + 0x00cf9b000000ffffull, // flat 32-bit code segment + 0x00cf93000000ffffull, // flat 32-bit data segment +}; + +static struct { + u16 limit; + void *base; +} __attribute__((packed)) gdt_descr = { + sizeof(gdt) - 1, + gdt, +}; + +static void exec_in_big_real_mode(const struct regs *inregs, + struct regs *outregs, + const u8 *insn) +{ + unsigned long tmp; + + asm volatile( + "lgdtl %[gdt_descr] \n\t" + "mov %%cr0, %[tmp] \n\t" + "or $1, %[tmp] \n\t" + "mov %[tmp], %%cr0 \n\t" + "mov %[bigseg], %%gs \n\t" + "and $-2, %[tmp] \n\t" + "mov %[tmp], %%cr0 \n\t" + "xor %[tmp], %[tmp] \n\t" + "mov %[tmp], %%gs \n\t" + : [tmp]"=&r"(tmp) + : [gdt_descr]"m"(gdt_descr), [bigseg]"rm"((short)16) + : "cc", "memory" + ); +} + void start(void) { print_serial("abc\n"); + exec_in_big_real_mode(0, 0, 0); exit(0); } -- 2.11.4.GIT