Add infrastructure to return back to real mode in order to obtain
certain pieces of information from the BIOS.
Along the way it turned out helpful to convert x86-32's boot code to
use SYM_PHYS() just like x86-64 has been doing for a while.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>
Index: 2007-02-27/xen/arch/x86/Makefile
===================================================================
--- 2007-02-27.orig/xen/arch/x86/Makefile 2007-02-28 12:08:24.000000000
+0100
+++ 2007-02-27/xen/arch/x86/Makefile 2007-02-20 15:52:10.000000000 +0100
@@ -78,6 +78,8 @@ xen.lds: $(TARGET_SUBARCH)/xen.lds.S $(H
boot/mkelf32: boot/mkelf32.c
$(HOSTCC) $(HOSTCFLAGS) -o $@ $<
+boot/$(TARGET_SUBARCH).o: boot/realmode.S
+
.PHONY: clean
clean::
rm -f asm-offsets.s xen.lds boot/*.o boot/*~ boot/core boot/mkelf32
Index: 2007-02-27/xen/arch/x86/boot/realmode.S
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ 2007-02-27/xen/arch/x86/boot/realmode.S 2007-02-22 13:35:18.000000000
+0100
@@ -0,0 +1,120 @@
+#define REALMODE_SEG 0x1000
+#define REALMODE_BASE (REALMODE_SEG << 4)
+
+ .section .init.data, "aw"
+ .align 8
+gdt16_table:
+ .quad 0
+ .quad 0x00cf9a000000ffff /* 0xe008 ring 0 4.00GB code at 0x0 */
+ .quad 0x00cf92000000ffff /* 0xe010 ring 0 4.00GB data at 0x0 */
+ /* 0xe018 ring 0 64kB 16-bit code at REALMODE_BASE */
+#define __HYPERVISOR_CS16 (__HYPERVISOR_CS + 0x10)
+ .quad 0x00009a000000ffff + (REALMODE_BASE << 16)
+ /* 0xe020 ring 0 64kB 16-bit data at REALMODE_BASE */
+#define __HYPERVISOR_DS16 (__HYPERVISOR_DS32 + 0x10)
+ .quad 0x000092000000ffff + (REALMODE_BASE << 16)
+#if __HYPERVISOR_CS32 != __HYPERVISOR_CS
+/* This doesn't work properly with gas up to at least 2.17.50 as of Feb 2007.
+ Using .skip or .fill also doesn't work up to 2.15 or 2.16. Use as' -K
+ option to be pointed at the problematic construct (.word with its operand
+ being the difference of two symbols) below.
+ .org gdt16_table + (__HYPERVISOR_CS32 - FIRST_RESERVED_GDT_BYTE) */
+ .rept (__HYPERVISOR_CS32 - __HYPERVISOR_DS16) / 8 - 1
+ .quad 0
+ .endr
+ .quad 0x00cf9a000000ffff /* 0xe038 ring 0 4.00GB code at 0x0 */
+#endif
+.Lgdt16_end:
+
+ .word 0
+gdt16: .word FIRST_RESERVED_GDT_BYTE + .Lgdt16_end - gdt16_table - 1
+ .long SYM_PHYS(gdt16_table) - FIRST_RESERVED_GDT_BYTE
+
+#define SYM_REAL(x) ((x) - .L__realtext)
+
+ .section .init.text, "ax"
+ .code32
+realmode:
+ pushal
+ movl %esp, %ebp
+ sgdt SYM_PHYS(.Lgdt)
+ sidt SYM_PHYS(.Lidt)
+ testl $MBI_CMDLINE, MBI_flags(%ebx)
+ movl MBI_cmdline(%ebx), %esi
+ jz 1f
+ testl %esi, %esi
+ jz 1f
+ movl $REALMODE_BASE + 0x10000, %edi
+ movl %edi, SYM_PHYS(cmd_line_ptr)
+0:
+ lodsb
+ stosb
+ testb %al, %al
+ jnz 0b
+1:
+ movl $SYM_PHYS(.L__realtext), %esi
+ movl $REALMODE_BASE, %edi
+ movl $SYM_PHYS(__end_realmode), %ecx
+ subl %esi, %ecx
+ rep movsb
+ movl 9*4(%ebp), %edi
+ subl $SYM_PHYS(.L__realtext), %edi
+ lgdt SYM_PHYS(gdt16)
+ movl $__HYPERVISOR_DS16, %ecx
+ mov %ecx, %ss
+ xorl %esp, %esp
+ mov %ecx, %ds
+ mov %ecx, %es
+ ljmpl $__HYPERVISOR_CS16, $SYM_REAL(.Ltext16)
+
+protmode:
+ movl $__HYPERVISOR_DS32, %ecx
+ mov %ecx, %ss
+ movl %ebp, %esp
+ mov %ecx, %ds
+ mov %ecx, %es
+ movl $REALMODE_BASE + SYM_PHYS(.L__realdata), %esi
+ subl $SYM_PHYS(.L__realtext), %esi
+ movl $SYM_PHYS(.L__realdata), %edi
+ movl $SYM_PHYS(__end_realmode), %ecx
+ subl %edi, %ecx
+ rep movsb
+ mov %ecx, %fs
+ mov %ecx, %gs
+ popal
+ ret $4
+
+ .section .real.text, "ax"
+.L__realtext:
+ .code16
+.Ltext16:
+ mov %cr0, %eax
+ andb $~1, %al
+ mov %eax, %cr0
+ ljmpw $REALMODE_SEG, $SYM_REAL(.Lrealmode)
+.Lrealmode:
+ mov %cs, %cx
+ mov %cx, %ss
+ mov %cx, %ds
+ mov %cx, %es
+
+ pushal
+ callw *%di
+ popal
+
+ pushw $0
+ popfw
+ lgdtl %cs:SYM_REAL(.Lgdt)
+ lidtl %cs:SYM_REAL(.Lidt)
+ mov %cr0, %eax
+ orb $1, %al
+ mov %eax, %cr0
+ ljmpl $__HYPERVISOR_CS32, $SYM_PHYS(protmode)
+
+ .section .real.data, "aw"
+.L__realdata:
+ .align 4
+cmd_line_ptr: .long 0
+.Lgdt: .skip 2+4
+.Lidt: .skip 2+4
+ .previous
Index: 2007-02-27/xen/arch/x86/boot/x86_32.S
===================================================================
--- 2007-02-27.orig/xen/arch/x86/boot/x86_32.S 2007-02-28 12:08:24.000000000
+0100
+++ 2007-02-27/xen/arch/x86/boot/x86_32.S 2007-02-21 18:08:18.000000000
+0100
@@ -10,6 +10,8 @@
.text
+#define SYM_PHYS(sym) (sym - __PAGE_OFFSET)
+
ENTRY(start)
jmp __start
@@ -28,7 +30,7 @@ ENTRY(start)
not_multiboot_msg:
.asciz "ERR: Not a Multiboot bootloader!"
not_multiboot:
- mov $not_multiboot_msg-__PAGE_OFFSET,%esi
+ mov $SYM_PHYS(not_multiboot_msg),%esi
mov $0xB8000,%edi # VGA framebuffer
1: mov (%esi),%bl
test %bl,%bl # Terminate on '\0' sentinel
@@ -47,14 +49,14 @@ not_multiboot:
__start:
/* Set up a few descriptors: on entry only CS is guaranteed good. */
- lgdt %cs:nopaging_gdt_descr-__PAGE_OFFSET
+ lgdt %cs:SYM_PHYS(nopaging_gdt_descr)
mov $(__HYPERVISOR_DS),%ecx
mov %ecx,%ds
mov %ecx,%es
mov %ecx,%fs
mov %ecx,%gs
- ljmp $(__HYPERVISOR_CS),$(1f)-__PAGE_OFFSET
-1: lss stack_start-__PAGE_OFFSET,%esp
+ ljmp $(__HYPERVISOR_CS),$SYM_PHYS(1f)
+1: lss SYM_PHYS(stack_start),%esp
add $(STACK_SIZE-CPUINFO_sizeof-__PAGE_OFFSET),%esp
/* Reset EFLAGS (subsumes CLI and CLD). */
@@ -66,7 +68,7 @@ __start:
/* Set up CR4, except global flag which Intel requires should be */
/* left until after paging is enabled (IA32 Manual Vol. 3, Sec. 2.5) */
- mov mmu_cr4_features-__PAGE_OFFSET,%ecx
+ mov SYM_PHYS(mmu_cr4_features),%ecx
and $0x7f,%cl # CR4.PGE (global enable)
mov %ecx,%cr4
@@ -78,19 +80,19 @@ __start:
jne not_multiboot
/* Initialize BSS (no nasty surprises!) */
- mov $__bss_start-__PAGE_OFFSET,%edi
- mov $_end-__PAGE_OFFSET,%ecx
+ mov $SYM_PHYS(__bss_start),%edi
+ mov $SYM_PHYS(_end),%ecx
sub %edi,%ecx
xor %eax,%eax
rep stosb
/* Save the Multiboot info structure for later use. */
- add $__PAGE_OFFSET,%ebx
- push %ebx
+ lea __PAGE_OFFSET(%ebx),%eax
+ push %eax
#ifdef CONFIG_X86_PAE
/* Initialize low and high mappings of all memory with 2MB pages */
- mov $idle_pg_table_l2-__PAGE_OFFSET,%edi
+ mov $SYM_PHYS(idle_pg_table_l2),%edi
mov $0xe3,%eax /* PRESENT+RW+A+D+2MB */
1: mov %eax,__PAGE_OFFSET>>18(%edi) /* high mapping */
stosl /* low mapping */
@@ -105,7 +107,7 @@ __start:
jne 1b
#else
/* Initialize low and high mappings of all memory with 4MB pages */
- mov $idle_pg_table-__PAGE_OFFSET,%edi
+ mov $SYM_PHYS(idle_pg_table),%edi
mov $0xe3,%eax /* PRESENT+RW+A+D+4MB */
1: mov %eax,__PAGE_OFFSET>>20(%edi) /* high mapping */
stosl /* low mapping */
@@ -123,7 +125,7 @@ __start:
mov $(__HYPERVISOR_CS << 16),%eax
mov %dx,%ax /* selector = 0x0010 = cs */
mov $0x8E00,%dx /* interrupt gate - dpl=0, present */
- lea idt_table-__PAGE_OFFSET,%edi
+ lea SYM_PHYS(idt_table),%edi
mov $256,%ecx
1: mov %eax,(%edi)
mov %edx,4(%edi)
@@ -149,7 +151,7 @@ start_paging:
no_execute_disable:
pop %ebx
#endif
- mov $idle_pg_table-__PAGE_OFFSET,%eax
+ mov $SYM_PHYS(idle_pg_table),%eax
mov %eax,%cr3
mov $0x80050033,%eax /* hi-to-lo: PG,AM,WP,NE,ET,MP,PE */
mov %eax,%cr0
@@ -212,7 +214,7 @@ gdt_descr:
.word 0
nopaging_gdt_descr:
.word LAST_RESERVED_GDT_BYTE
- .long gdt_table - FIRST_RESERVED_GDT_BYTE - __PAGE_OFFSET
+ .long SYM_PHYS(gdt_table) - FIRST_RESERVED_GDT_BYTE
.align PAGE_SIZE, 0
/* NB. Rings != 0 get access up to MACH2PHYS_VIRT_END. This allows access to */
@@ -236,10 +238,10 @@ ENTRY(gdt_table)
#ifdef CONFIG_X86_PAE
ENTRY(idle_pg_table)
ENTRY(idle_pg_table_l3)
- .long idle_pg_table_l2 + 0*PAGE_SIZE + 0x01 - __PAGE_OFFSET, 0
- .long idle_pg_table_l2 + 1*PAGE_SIZE + 0x01 - __PAGE_OFFSET, 0
- .long idle_pg_table_l2 + 2*PAGE_SIZE + 0x01 - __PAGE_OFFSET, 0
- .long idle_pg_table_l2 + 3*PAGE_SIZE + 0x01 - __PAGE_OFFSET, 0
+ .long SYM_PHYS(idle_pg_table_l2) + 0*PAGE_SIZE + 0x01, 0
+ .long SYM_PHYS(idle_pg_table_l2) + 1*PAGE_SIZE + 0x01, 0
+ .long SYM_PHYS(idle_pg_table_l2) + 2*PAGE_SIZE + 0x01, 0
+ .long SYM_PHYS(idle_pg_table_l2) + 3*PAGE_SIZE + 0x01, 0
.section ".bss.page_aligned","w"
ENTRY(idle_pg_table_l2)
.fill 4*PAGE_SIZE,1,0
@@ -253,3 +255,8 @@ ENTRY(idle_pg_table_l2)
.section ".bss.stack_aligned","w"
ENTRY(cpu0_stack)
.fill STACK_SIZE,1,0
+
+#define __HYPERVISOR_CS32 __HYPERVISOR_CS
+#define __HYPERVISOR_DS32 __HYPERVISOR_DS
+
+#include "realmode.S"
Index: 2007-02-27/xen/arch/x86/boot/x86_64.S
===================================================================
--- 2007-02-27.orig/xen/arch/x86/boot/x86_64.S 2007-02-28 12:08:24.000000000
+0100
+++ 2007-02-27/xen/arch/x86/boot/x86_64.S 2007-02-21 17:54:29.000000000
+0100
@@ -72,6 +72,8 @@ __start:
/* Save the Multiboot info structure for later use. */
mov %ebx,SYM_PHYS(multiboot_ptr)
+ lss SYM_PHYS(.Lstack_start),%esp
+
/* We begin by interrogating the CPU for the presence of long mode. */
mov $0x80000000,%eax
cpuid
@@ -200,7 +202,7 @@ multiboot_ptr:
.word 0
nopaging_gdt_descr:
.word LAST_RESERVED_GDT_BYTE
- .quad gdt_table - FIRST_RESERVED_GDT_BYTE - __PAGE_OFFSET
+ .quad SYM_PHYS(gdt_table) - FIRST_RESERVED_GDT_BYTE
cpuid_ext_features:
.long 0
@@ -217,6 +219,9 @@ idt_descr:
ENTRY(stack_start)
.quad cpu0_stack
+.Lstack_start:
+ .long SYM_PHYS(cpu0_stack) + STACK_SIZE - CPUINFO_sizeof
+ .word __HYPERVISOR_DS32
high_start:
.quad __high_start
@@ -256,14 +261,14 @@ ENTRY(compat_gdt_table)
.align PAGE_SIZE, 0
ENTRY(idle_pg_table)
ENTRY(idle_pg_table_4)
- .quad idle_pg_table_l3 - __PAGE_OFFSET + 7 # PML4[0]
+ .quad SYM_PHYS(idle_pg_table_l3) + 7 # PML4[0]
.fill 261,8,0
- .quad idle_pg_table_l3 - __PAGE_OFFSET + 7 # PML4[262]
+ .quad SYM_PHYS(idle_pg_table_l3) + 7 # PML4[262]
/* Initial PDP -- level-3 page table. */
.align PAGE_SIZE, 0
ENTRY(idle_pg_table_l3)
- .quad idle_pg_table_l2 - __PAGE_OFFSET + 7
+ .quad SYM_PHYS(idle_pg_table_l2) + 7
/* Initial PDE -- level-2 page table. Maps first 1GB physical memory. */
.align PAGE_SIZE, 0
@@ -283,3 +288,5 @@ ENTRY(idle_pg_table_l2)
.section ".bss.stack_aligned","w"
ENTRY(cpu0_stack)
.fill STACK_SIZE,1,0
+
+#include "realmode.S"
Index: 2007-02-27/xen/arch/x86/x86_32/asm-offsets.c
===================================================================
--- 2007-02-27.orig/xen/arch/x86/x86_32/asm-offsets.c 2007-02-28
12:08:44.000000000 +0100
+++ 2007-02-27/xen/arch/x86/x86_32/asm-offsets.c 2007-02-28
12:09:45.000000000 +0100
@@ -7,6 +7,7 @@
#include <xen/config.h>
#include <xen/perfc.h>
#include <xen/sched.h>
+#include <xen/multiboot.h>
#include <asm/fixmap.h>
#include <asm/hardirq.h>
@@ -100,6 +101,10 @@ void __dummy__(void)
DEFINE(CPUINFO_sizeof, sizeof(struct cpu_info));
BLANK();
+ OFFSET(MBI_flags, multiboot_info_t, flags);
+ OFFSET(MBI_cmdline, multiboot_info_t, cmdline);
+ BLANK();
+
OFFSET(TRAPBOUNCE_error_code, struct trap_bounce, error_code);
OFFSET(TRAPBOUNCE_flags, struct trap_bounce, flags);
OFFSET(TRAPBOUNCE_cs, struct trap_bounce, cs);
Index: 2007-02-27/xen/arch/x86/x86_32/xen.lds.S
===================================================================
--- 2007-02-27.orig/xen/arch/x86/x86_32/xen.lds.S 2007-02-28
12:08:24.000000000 +0100
+++ 2007-02-27/xen/arch/x86/x86_32/xen.lds.S 2007-02-21 09:58:21.000000000
+0100
@@ -63,6 +63,10 @@ SECTIONS
__initcall_start = .;
.initcall.init : { *(.initcall1.init) } :text
__initcall_end = .;
+ . = ALIGN(16);
+ .real.text : { *(.real.text) } :text
+ .real.data : { *(.real.data) } :text
+ __end_realmode = .;
. = ALIGN(PAGE_SIZE);
__init_end = .;
Index: 2007-02-27/xen/arch/x86/x86_64/asm-offsets.c
===================================================================
--- 2007-02-27.orig/xen/arch/x86/x86_64/asm-offsets.c 2007-02-28
12:08:44.000000000 +0100
+++ 2007-02-27/xen/arch/x86/x86_64/asm-offsets.c 2007-02-28
12:09:50.000000000 +0100
@@ -7,6 +7,7 @@
#include <xen/config.h>
#include <xen/perfc.h>
#include <xen/sched.h>
+#include <xen/multiboot.h>
#ifdef CONFIG_COMPAT
#include <compat/xen.h>
#endif
@@ -113,6 +114,10 @@ void __dummy__(void)
DEFINE(CPUINFO_sizeof, sizeof(struct cpu_info));
BLANK();
+ OFFSET(MBI_flags, multiboot_info_t, flags);
+ OFFSET(MBI_cmdline, multiboot_info_t, cmdline);
+ BLANK();
+
OFFSET(TRAPBOUNCE_error_code, struct trap_bounce, error_code);
OFFSET(TRAPBOUNCE_flags, struct trap_bounce, flags);
OFFSET(TRAPBOUNCE_cs, struct trap_bounce, cs);
Index: 2007-02-27/xen/arch/x86/x86_64/xen.lds.S
===================================================================
--- 2007-02-27.orig/xen/arch/x86/x86_64/xen.lds.S 2007-02-28
12:08:24.000000000 +0100
+++ 2007-02-27/xen/arch/x86/x86_64/xen.lds.S 2007-02-21 10:10:04.000000000
+0100
@@ -61,6 +61,10 @@ SECTIONS
__initcall_start = .;
.initcall.init : { *(.initcall1.init) } :text
__initcall_end = .;
+ . = ALIGN(16);
+ .real.text : { *(.real.text) } :text
+ .real.data : { *(.real.data) } :text
+ __end_realmode = .;
. = ALIGN(PAGE_SIZE);
__init_end = .;
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|