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@novell.com> 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@lists.xensource.com http://lists.xensource.com/xen-devel