[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 1/3] x86: real mode support
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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |