[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [RFC PATCH 6/7] x86/boot: Copy 16-bit boot variables back up to Xen image
From: David Woodhouse <dwmw@xxxxxxxxxxxx> Ditch the bootsym() access from C code for the variables populated by 16-bit boot code. As well as being cleaner this also paves the way for not having the 16-bit boot code in low memory for no-real-mode or EFI loader boots at all. Signed-off-by: David Woodhouse <dwmw@xxxxxxxxxxxx> --- xen/arch/x86/boot/edd.S | 2 ++ xen/arch/x86/boot/head.S | 16 +++++++++++++++ xen/arch/x86/boot/mem.S | 2 ++ xen/arch/x86/boot/trampoline.S | 33 ++++++++++++++++++++++++++++--- xen/arch/x86/boot/video.S | 30 +++++++++++++++------------- xen/arch/x86/platform_hypercall.c | 18 ++++++++--------- xen/arch/x86/setup.c | 23 +++++++++++---------- xen/arch/x86/xen.lds.S | 8 +++++++- xen/include/asm-x86/edd.h | 1 - 9 files changed, 93 insertions(+), 40 deletions(-) diff --git a/xen/arch/x86/boot/edd.S b/xen/arch/x86/boot/edd.S index 434bbbd960..138d04c964 100644 --- a/xen/arch/x86/boot/edd.S +++ b/xen/arch/x86/boot/edd.S @@ -163,6 +163,7 @@ edd_done: .Ledd_mbr_sig_skip: ret + .pushsection .data.boot16, "aw", @progbits GLOBAL(boot_edd_info_nr) .byte 0 GLOBAL(boot_mbr_signature_nr) @@ -171,3 +172,4 @@ GLOBAL(boot_mbr_signature) .fill EDD_MBR_SIG_MAX*8,1,0 GLOBAL(boot_edd_info) .fill EDD_INFO_MAX * (EDDEXTSIZE + EDDPARMSIZE), 1, 0 + .popsection diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S index 82342769c7..7d6c8d3292 100644 --- a/xen/arch/x86/boot/head.S +++ b/xen/arch/x86/boot/head.S @@ -732,6 +732,17 @@ trampoline_setup: cmp $sym_offs(__bootsym_seg_stop),%edi jb 1b + /* Relocations for the boot data section. */ + mov sym_fs(trampoline_phys),%edx + add $(boot_trampoline_end - boot_trampoline_start),%edx + mov $sym_offs(__bootdatasym_rel_start),%edi +1: + mov %fs:(%edi),%eax + add %edx,%fs:(%edi,%eax) + add $4,%edi + cmp $sym_offs(__bootdatasym_rel_stop),%edi + jb 1b + /* Do not parse command line on EFI platform here. */ cmpb $0,sym_fs(efi_platform) jnz 1f @@ -769,6 +780,11 @@ trampoline_setup: mov $((boot_trampoline_end - boot_trampoline_start) / 4),%ecx rep movsl %fs:(%esi),%es:(%edi) + /* Copy boot data template to low memory. */ + mov $sym_offs(bootdata_start),%esi + mov $((bootdata_end - bootdata_start + 3) / 4),%ecx + rep movsl %fs:(%esi),%es:(%edi) + /* Jump into the relocated trampoline. */ lret diff --git a/xen/arch/x86/boot/mem.S b/xen/arch/x86/boot/mem.S index aa39608442..86f0fa9af7 100644 --- a/xen/arch/x86/boot/mem.S +++ b/xen/arch/x86/boot/mem.S @@ -67,6 +67,7 @@ get_memory_map: ret .align 4 + .pushsection .data.boot16, "aw", @progbits GLOBAL(bios_e820map) .fill E820_BIOS_MAX*20,1,0 GLOBAL(bios_e820nr) @@ -75,3 +76,4 @@ GLOBAL(lowmem_kb) .long 0 GLOBAL(highmem_kb) .long 0 + .popsection diff --git a/xen/arch/x86/boot/trampoline.S b/xen/arch/x86/boot/trampoline.S index 0f4a740fcb..fdfee2edb1 100644 --- a/xen/arch/x86/boot/trampoline.S +++ b/xen/arch/x86/boot/trampoline.S @@ -47,11 +47,15 @@ .long 111b - (off) - .; \ .popsection -#define bootdatasym(s) ((s)-boot_trampoline_start) + .pushsection .data.boot16, "aw", @progbits +GLOBAL(bootdata_start) + .popsection + +#define bootdatasym(s) ((s)-bootdata_start+(boot_trampoline_end-boot_trampoline_start)) #define bootdatasym_rel(sym, off, opnd...) \ bootdatasym(sym),##opnd; \ 111:; \ - .pushsection .bootdatasym_rel, "a";\ + .pushsection .bootsym_rel, "a";\ .long 111b - (off) - .; \ .popsection @@ -100,7 +104,7 @@ GLOBAL(trampoline_cpu_started) .word 0 idt_48: .word 0, 0, 0 # base = limit = 0 .word 0 -gdt_48: .word 6*8-1 +gdt_48: .word 7*8-1 .long tramp32sym_rel(trampoline_gdt,4) /* Start of tramp32sym section which can be used in place during boot */ @@ -312,6 +316,23 @@ trampoline_boot_cpu_entry: mov %eax,%gs mov %eax,%ss + /* + * Copy locally-gathered data back up into the Xen physical image + */ + mov $BOOT_FS,%eax + mov %eax,%es + + mov $sym_offs(bootdata_end),%ecx + mov $sym_offs(bootdata_start),%edi + sub %edi,%ecx + mov $bootdatasym_rel(bootdata_start,4,%esi) + rep movsb %ds:(%esi),%es:(%edi) + + /* + * %es still points to BOOT_FS but trampoline_protmode_entry + * reloads it anyway. + */ + /* EBX == 0 indicates we are the BP (Boot Processor). */ xor %ebx,%ebx @@ -339,8 +360,10 @@ vesa_size: .word 0,0,0 /* width x depth x height */ #endif + .pushsection .data.boot16, "aw", @progbits GLOBAL(kbd_shift_flags) .byte 0 + .popsection rm_idt: .word 256*4-1, 0, 0 @@ -349,3 +372,7 @@ rm_idt: .word 256*4-1, 0, 0 #ifdef CONFIG_VIDEO #include "video.S" #endif + + .pushsection .data.boot16, "aw", @progbits +GLOBAL(bootdata_end) + .popsection diff --git a/xen/arch/x86/boot/video.S b/xen/arch/x86/boot/video.S index 5087c6a4d5..4608464b77 100644 --- a/xen/arch/x86/boot/video.S +++ b/xen/arch/x86/boot/video.S @@ -15,10 +15,10 @@ #include "video.h" -/* Scratch space layout: boot_trampoline_end to boot_trampoline_end+0x1000. */ -#define modelist bootsym(boot_trampoline_end) /* 2kB (256 entries) */ -#define vesa_glob_info (modelist + 0x800) /* 1kB */ -#define vesa_mode_info (vesa_glob_info + 0x400) /* 1kB */ +/* Scratch space layout: bootdata_end to bootdata_end+0x1000. */ +#define modelist(t) bootdatasym_rel(bootdata_end,2,t) /* 2KiB (256 entries) */ +#define vesa_glob_info(t) bootdatasym_rel((bootdata_end+0x800),2,t) /* 1KiB */ +#define vesa_mode_info(t) bootdatasym_rel((bootdata_end+0xc00),2,t) /* 1KiB */ /* Retrieve Extended Display Identification Data. */ #define CONFIG_FIRMWARE_EDID @@ -113,7 +113,7 @@ mopar2: movb %al, _param(PARAM_VIDEO_LINES) # Fetching of VESA frame buffer parameters mopar_gr: - leaw vesa_mode_info, %di + leaw vesa_mode_info(%di) movb $0x23, _param(PARAM_HAVE_VGA) movw 16(%di), %ax movw %ax, _param(PARAM_LFB_LINELENGTH) @@ -134,7 +134,7 @@ mopar_gr: movw %ax, _param(PARAM_VESA_ATTRIB) # get video mem size - leaw vesa_glob_info, %di + leaw vesa_glob_info(%di) xorl %eax, %eax movw 18(%di), %ax movl %eax, _param(PARAM_LFB_SIZE) @@ -226,7 +226,7 @@ an1: call prtstr leaw bootsym(listhdr), %si # Table header call prtstr movb $0x30, %dl # DL holds mode number - leaw modelist, %si + leaw modelist(%si) lm1: cmpw $ASK_VGA, (%si) # End? jz lm2 @@ -435,13 +435,13 @@ setmenu: jmp mode_set check_vesa: - leaw vesa_glob_info, %di + leaw vesa_glob_info(%di) movw $0x4f00, %ax int $0x10 cmpw $0x004f, %ax jnz setbad - leaw vesa_mode_info, %di + leaw vesa_mode_info(%di) subb $VIDEO_FIRST_VESA>>8, %bh movw %bx, %cx # Get mode information structure movw $0x4f01, %ax @@ -509,7 +509,7 @@ inidx: outb %al, %dx # Read from indexed VGA register setvesabysize: call mode_table - leaw modelist,%si + leaw modelist(%si) 1: add $8,%si cmpw $ASK_VGA,-8(%si) # End? je _setbad @@ -669,7 +669,7 @@ mode_table: orw %di, %di jnz mtab1 - leaw modelist, %di # Store standard modes: + leaw modelist(%di) # Store standard modes: movw $VIDEO_80x25,(%di) # The 80x25 mode (ALL) movw $0x50,2(%di) movw $0x19,4(%di) @@ -684,7 +684,7 @@ mode_table: movw $ASK_VGA, (%di) # End marker movw %di, bootsym(mt_end) -mtab1: leaw modelist, %si # SI=mode list, DI=list end +mtab1: leaw modelist(%si) # SI=mode list, DI=list end ret0: ret # Modes usable on all standard VGAs @@ -700,7 +700,7 @@ vga_modes_end: # Detect VESA modes. vesa_modes: movw %di, %bp # BP=original mode table end - leaw vesa_glob_info, %di + leaw vesa_glob_info(%di) movw $0x4f00, %ax # VESA Get card info call int $0x10 movw %di, %si @@ -897,7 +897,7 @@ store_edid: cmpb $1, bootsym(opt_edid) # EDID disabled on cmdline (edid=no)? je .Lno_edid - leaw vesa_glob_info, %di + leaw vesa_glob_info(%di) movw $0x4f00, %ax int $0x10 cmpw $0x004f, %ax @@ -990,6 +990,7 @@ name_bann: .asciz "Video adapter: " force_size: .word 0 # Use this size instead of the one in BIOS vars + .pushsection .data.boot16, "aw", @progbits GLOBAL(boot_vid_info) .byte 0, 0 /* orig_x, orig_y */ .byte 3 /* text mode 3 */ @@ -1001,3 +1002,4 @@ GLOBAL(boot_edid_info) .fill 128,1,0x13 GLOBAL(boot_edid_caps) .word 0x1313 + .popsection diff --git a/xen/arch/x86/platform_hypercall.c b/xen/arch/x86/platform_hypercall.c index ea18c3215a..5c8953ae19 100644 --- a/xen/arch/x86/platform_hypercall.c +++ b/xen/arch/x86/platform_hypercall.c @@ -333,10 +333,10 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) u16 length; ret = -ESRCH; - if ( op->u.firmware_info.index >= bootsym(boot_edd_info_nr) ) + if ( op->u.firmware_info.index >= boot_edd_info_nr ) break; - info = bootsym(boot_edd_info) + op->u.firmware_info.index; + info = boot_edd_info + op->u.firmware_info.index; /* Transfer the EDD info block. */ ret = -EFAULT; @@ -372,10 +372,10 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) const struct mbr_signature *sig; ret = -ESRCH; - if ( op->u.firmware_info.index >= bootsym(boot_mbr_signature_nr) ) + if ( op->u.firmware_info.index >= boot_mbr_signature_nr ) break; - sig = bootsym(boot_mbr_signature) + op->u.firmware_info.index; + sig = boot_mbr_signature + op->u.firmware_info.index; op->u.firmware_info.u.disk_mbr_signature.device = sig->device; op->u.firmware_info.u.disk_mbr_signature.mbr_signature = @@ -391,13 +391,13 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) #ifdef CONFIG_VIDEO if ( op->u.firmware_info.index != 0 ) break; - if ( *(u32 *)bootsym(boot_edid_info) == 0x13131313 ) + if ( *(u32 *)boot_edid_info == 0x13131313 ) break; op->u.firmware_info.u.vbeddc_info.capabilities = - bootsym(boot_edid_caps); + boot_edid_caps; op->u.firmware_info.u.vbeddc_info.edid_transfer_time = - bootsym(boot_edid_caps) >> 8; + boot_edid_caps >> 8; ret = 0; if ( __copy_field_to_guest(u_xenpf_op, op, u.firmware_info. @@ -405,7 +405,7 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) __copy_field_to_guest(u_xenpf_op, op, u.firmware_info. u.vbeddc_info.edid_transfer_time) || copy_to_compat(op->u.firmware_info.u.vbeddc_info.edid, - bootsym(boot_edid_info), 128) ) + boot_edid_info, 128) ) ret = -EFAULT; #endif break; @@ -422,7 +422,7 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) if ( op->u.firmware_info.index != 0 ) break; - op->u.firmware_info.u.kbd_shift_flags = bootsym(kbd_shift_flags); + op->u.firmware_info.u.kbd_shift_flags = kbd_shift_flags; ret = 0; if ( __copy_field_to_guest(u_xenpf_op, op, diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index b714e3c237..4dd4c4161c 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -507,7 +507,7 @@ extern struct boot_video_info boot_vid_info; static void __init parse_video_info(void) { #ifdef CONFIG_VIDEO - struct boot_video_info *bvi = &bootsym(boot_vid_info); + struct boot_video_info *bvi = &boot_vid_info; /* vga_console_info is filled directly on EFI platform. */ if ( efi_enabled(EFI_BOOT) ) @@ -666,12 +666,11 @@ static char * __init cmdline_cook(char *p, const char *loader_name) static int copy_bios_e820(struct e820entry *map, unsigned int limit) { - unsigned int n = bootsym(bios_e820nr); + unsigned int n = bios_e820nr; if (n > limit) n = limit; - if (n) - memcpy(map, bootsym(bios_e820map), sizeof(*map) * n); + memcpy(map, bios_e820map, sizeof(*map) * n); return n; } @@ -802,15 +801,15 @@ void __init noreturn __start_xen(unsigned long mbi_p) } /* Print VBE/DDC EDID information. */ - if ( bootsym(boot_edid_caps) != 0x1313 ) + if ( boot_edid_caps != 0x1313 ) { - u16 caps = bootsym(boot_edid_caps); + u16 caps = boot_edid_caps; printk(" VBE/DDC methods:%s%s%s; ", (caps & 1) ? " V1" : "", (caps & 2) ? " V2" : "", !(caps & 3) ? " none" : ""); printk("EDID transfer time: %d seconds\n", caps >> 8); - if ( *(u32 *)bootsym(boot_edid_info) == 0x13131313 ) + if ( *(u32 *)boot_edid_info == 0x13131313 ) { printk(" EDID info not retrieved because "); if ( !(caps & 3) ) @@ -825,9 +824,9 @@ void __init noreturn __start_xen(unsigned long mbi_p) printk("Disc information:\n"); printk(" Found %d MBR signatures\n", - bootsym(boot_mbr_signature_nr)); + boot_mbr_signature_nr); printk(" Found %d EDD information structures\n", - bootsym(boot_edd_info_nr)); + boot_edd_info_nr); /* Check that we have at least one Multiboot module. */ if ( !(mbi->flags & MBI_MODULES) || (mbi->mods_count == 0) ) @@ -899,14 +898,14 @@ void __init noreturn __start_xen(unsigned long mbi_p) bytes += map->size + 4; } } - else if ( bootsym(lowmem_kb) ) + else if ( lowmem_kb ) { memmap_type = "Xen-e801"; e820_raw.map[0].addr = 0; - e820_raw.map[0].size = bootsym(lowmem_kb) << 10; + e820_raw.map[0].size = lowmem_kb << 10; e820_raw.map[0].type = E820_RAM; e820_raw.map[1].addr = 0x100000; - e820_raw.map[1].size = bootsym(highmem_kb) << 10; + e820_raw.map[1].size = highmem_kb << 10; e820_raw.map[1].type = E820_RAM; e820_raw.nr_map = 2; } diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S index 5f36b88b92..436781cefa 100644 --- a/xen/arch/x86/xen.lds.S +++ b/xen/arch/x86/xen.lds.S @@ -228,11 +228,13 @@ SECTIONS __trampoline32_rel_stop = .; __bootsym_rel_start = .; *(.bootsym_rel) - *(.bootdatasym_rel) __bootsym_rel_stop = .; __bootsym_seg_start = .; *(.bootsym_seg) __bootsym_seg_stop = .; + __bootdatasym_rel_start = .; + *(.bootdatasym_rel) + __bootdatasym_rel_stop = .; /* * struct alt_inst entries. From the header (alternative.h): * "Alternative instructions for different CPU types or capabilities" @@ -275,6 +277,10 @@ SECTIONS DECL_SECTION(.data) { *(.data.page_aligned) *(.data) + . = ALIGN(16); + __bootdata_start = .; + *(.data.boot16) + __bootdata_end = .; *(.data.rel) *(.data.rel.*) CONSTRUCTORS diff --git a/xen/include/asm-x86/edd.h b/xen/include/asm-x86/edd.h index afaa23732a..a4d6b4d90e 100644 --- a/xen/include/asm-x86/edd.h +++ b/xen/include/asm-x86/edd.h @@ -143,7 +143,6 @@ struct __packed mbr_signature { u32 signature; }; -/* These all reside in the boot trampoline. Access via bootsym(). */ extern struct mbr_signature boot_mbr_signature[]; extern u8 boot_mbr_signature_nr; extern struct edd_info boot_edd_info[]; -- 2.17.2 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |