head.o: reloc.S
-BOOT_TRAMPOLINE := $(shell sed -n 's,^\#define[[:space:]]\{1\,\}BOOT_TRAMPOLINE[[:space:]]\{1\,\},,p' $(BASEDIR)/include/asm-x86/config.h)
+BOOT_TRAMPOLINE := $(shell sed -n 's,^\#define[[:space:]]\{1\,\}BOOT_TRAMPOLINE[[:space:]]\{1\,\},,p' head.S)
%.S: %.c
RELOC=$(BOOT_TRAMPOLINE) $(MAKE) -f build32.mk $@
-reloc.S: $(BASEDIR)/include/asm-x86/config.h
+reloc.S: head.S
.text
.code32
-#undef bootsym_phys
+#define BOOT_TRAMPOLINE 0x7c000
#define sym_phys(sym) ((sym) - __XEN_VIRT_START)
#define bootsym_phys(sym) ((sym) - trampoline_start + BOOT_TRAMPOLINE)
mov %edi,sym_phys(idle_pg_table_l2) + (__PAGE_OFFSET>>18)
#endif
+ /* Apply relocations to bootstrap trampoline. */
+ mov $BOOT_TRAMPOLINE,%edx
+ mov $sym_phys(__trampoline_rel_start),%edi
+ mov %edx,sym_phys(trampoline_phys)
+1:
+ mov (%edi),%eax
+ add %edx,(%edi,%eax)
+ add $4,%edi
+ cmp $sym_phys(__trampoline_rel_stop),%edi
+ jb 1b
+
/* Copy bootstrap trampoline to low memory, below 1MB. */
mov $sym_phys(trampoline_start),%esi
mov $bootsym_phys(trampoline_start),%edi
#undef bootsym
#define bootsym(s) ((s)-trampoline_start)
+#define bootsym_rel(sym, off, opnd...) \
+ bootsym(sym),##opnd; \
+111:; \
+ .pushsection .trampoline_rel, "a"; \
+ .long 111b - (off) - .; \
+ .popsection
+
.globl trampoline_realmode_entry
trampoline_realmode_entry:
mov %cs,%ax
xor %ax, %ax
inc %ax
lmsw %ax # CR0.PE = 1 (enter protected mode)
- ljmpl $BOOT_CS32,$bootsym_phys(trampoline_protmode_entry)
+ ljmpl $BOOT_CS32,$bootsym_rel(trampoline_protmode_entry,6)
idt_48: .word 0, 0, 0 # base = limit = 0
gdt_48: .word 6*8-1
- .long bootsym_phys(trampoline_gdt)
+ .long bootsym_rel(trampoline_gdt,4)
trampoline_gdt:
/* 0x0000: unused */
.quad 0x0000000000000000
/* 0x0018: ring 0 data */
.quad 0x00cf92000000ffff
/* 0x0020: real-mode code @ BOOT_TRAMPOLINE */
- .long 0x0000ffff | ((BOOT_TRAMPOLINE & 0x00ffff) << 16)
- .long 0x00009a00 | ((BOOT_TRAMPOLINE & 0xff0000) >> 16)
+ .long 0x0000ffff
+ .long 0x00009a00
/* 0x0028: real-mode data @ BOOT_TRAMPOLINE */
- .long 0x0000ffff | ((BOOT_TRAMPOLINE & 0x00ffff) << 16)
- .long 0x00009200 | ((BOOT_TRAMPOLINE & 0xff0000) >> 16)
+ .long 0x0000ffff
+ .long 0x00009200
+
+ .pushsection .trampoline_rel, "a"
+ .long trampoline_gdt + BOOT_PSEUDORM_CS + 2 - .
+ .long trampoline_gdt + BOOT_PSEUDORM_DS + 2 - .
+ .popsection
.globl cpuid_ext_features
cpuid_ext_features:
/* Load pagetable base register. */
mov $sym_phys(idle_pg_table),%eax
- add bootsym_phys(trampoline_xen_phys_start),%eax
+ add bootsym_rel(trampoline_xen_phys_start,4,%eax)
mov %eax,%cr3
/* Set up EFER (Extended Feature Enable Register). */
- mov bootsym_phys(cpuid_ext_features),%edi
+ mov bootsym_rel(cpuid_ext_features,4,%edi)
test $0x20100800,%edi /* SYSCALL/SYSRET, No Execute, Long Mode? */
jz .Lskip_efer
movl $MSR_EFER,%ecx
#if defined(__x86_64__)
/* Now in compatibility mode. Long-jump into 64-bit mode. */
- ljmp $BOOT_CS64,$bootsym_phys(start64)
+ ljmp $BOOT_CS64,$bootsym_rel(start64,6)
.code64
start64:
# boot trampoline is under 1M, and shift its start into
# %fs to reference symbols in that area
- movl $BOOT_TRAMPOLINE, %eax
- shrl $4, %eax
- movl %eax, %fs
+ mov wakesym(trampoline_seg), %fs
lidt %fs:bootsym(idt_48)
lgdt %fs:bootsym(gdt_48)
movw $1, %ax
lmsw %ax # Turn on CR0.PE
- ljmpl $BOOT_CS32, $bootsym_phys(wakeup_32)
+ ljmpl $BOOT_CS32, $bootsym_rel(wakeup_32, 6)
/* This code uses an extended set of video mode numbers. These include:
* Aliases for standard modes
.globl video_mode, video_flags
video_mode: .long 0
video_flags: .long 0
+trampoline_seg: .word BOOT_TRAMPOLINE >> 4
+ .pushsection .trampoline_seg, "a"
+ .long trampoline_seg - .
+ .popsection
.code32
mov $BOOT_DS, %eax
mov %eax, %ds
mov %eax, %ss
- mov $bootsym_phys(early_stack), %esp
+ mov $bootsym_rel(early_stack, 4, %esp)
# check saved magic again
mov $sym_phys(saved_magic), %eax
- add bootsym_phys(trampoline_xen_phys_start), %eax
+ add bootsym_rel(trampoline_xen_phys_start, 4, %eax)
mov (%eax), %eax
cmp $0x9abcdef0, %eax
jne bogus_saved_magic
/* Load pagetable base register */
mov $sym_phys(idle_pg_table),%eax
- add bootsym_phys(trampoline_xen_phys_start),%eax
+ add bootsym_rel(trampoline_xen_phys_start,4,%eax)
mov %eax,%cr3
/* Will cpuid feature change after resume? */
/* Set up EFER (Extended Feature Enable Register). */
- mov bootsym_phys(cpuid_ext_features),%edi
+ mov bootsym_rel(cpuid_ext_features,4,%edi)
test $0x20100800,%edi /* SYSCALL/SYSRET, No Execute, Long Mode? */
jz .Lskip_eferw
movl $MSR_EFER,%ecx
#if defined(__x86_64__)
/* Now in compatibility mode. Long-jump to 64-bit mode */
- ljmp $BOOT_CS64, $bootsym_phys(wakeup_64)
+ ljmp $BOOT_CS64, $bootsym_rel(wakeup_64,6)
.code64
wakeup_64:
}
}
+extern const s32 __trampoline_rel_start[], __trampoline_rel_stop[];
+extern const s32 __trampoline_seg_start[], __trampoline_seg_stop[];
+
void EFIAPI __init __attribute__((__noreturn__))
efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *mode_info;
EFI_FILE_HANDLE dir_handle;
union string section = { NULL }, name;
+ const s32 *trampoline_ptr;
struct e820entry *e;
u64 efer;
- bool_t base_video = 0, trampoline_okay = 0;
+ bool_t base_video = 0;
efi_ih = ImageHandle;
efi_bs = SystemTable->BootServices;
dmi_efi_get_table((void *)(long)efi.smbios);
/* Allocate space for trampoline (in first Mb). */
- cfg.addr = BOOT_TRAMPOLINE;
+ cfg.addr = 0x100000;
cfg.size = trampoline_end - trampoline_start;
- status = efi_bs->AllocatePages(AllocateAddress, EfiLoaderData,
+ status = efi_bs->AllocatePages(AllocateMaxAddress, EfiLoaderData,
PFN_UP(cfg.size), &cfg.addr);
if ( EFI_ERROR(status) )
{
cfg.addr = 0;
- PrintErr(L"Note: Trampoline area is in use\r\n");
+ blexit(L"No memory for trampoline\r\n");
}
+ trampoline_phys = cfg.addr;
+ /* Apply relocations to trampoline. */
+ for ( trampoline_ptr = __trampoline_rel_start;
+ trampoline_ptr < __trampoline_rel_stop;
+ ++trampoline_ptr )
+ *(u32 *)(*trampoline_ptr + (long)trampoline_ptr) +=
+ trampoline_phys;
+ for ( trampoline_ptr = __trampoline_seg_start;
+ trampoline_ptr < __trampoline_seg_stop;
+ ++trampoline_ptr )
+ *(u16 *)(*trampoline_ptr + (long)trampoline_ptr) =
+ trampoline_phys >> 4;
/* Initialise L2 identity-map and xen page table entries (16MB). */
for ( i = 0; i < 8; ++i )
e->type = type;
++e820nr;
}
- if ( type == E820_RAM && e->addr <= BOOT_TRAMPOLINE &&
- e->addr + e->size >= BOOT_TRAMPOLINE + cfg.size )
- trampoline_okay = 1;
}
- if ( !trampoline_okay )
- blexit(L"Trampoline area unavailable\r\n");
-
status = efi_bs->ExitBootServices(ImageHandle, map_key);
if ( EFI_ERROR(status) )
PrintErrMesg(L"Cannot exit boot services", status);
efi_fw_vendor = (void *)efi_fw_vendor + DIRECTMAP_VIRT_START;
relocate_image(__XEN_VIRT_START - xen_phys_start);
- memcpy((void *)(long)BOOT_TRAMPOLINE, trampoline_start, cfg.size);
+ memcpy((void *)trampoline_phys, trampoline_start, cfg.size);
/* Set system registers and transfer control. */
asm volatile("pushq $0\n\tpopfq");
#define setup_trampoline() (bootsym_phys(trampoline_realmode_entry))
+unsigned long __read_mostly trampoline_phys;
+
/* representing HT siblings of each logical CPU */
DEFINE_PER_CPU_READ_MOSTLY(cpumask_t, cpu_sibling_map);
/* representing HT and core siblings of each logical CPU */
flush_all(FLUSH_TLB_GLOBAL);
/* Replace with mapping of the boot trampoline only. */
- map_pages_to_xen(BOOT_TRAMPOLINE, BOOT_TRAMPOLINE >> PAGE_SHIFT,
- 0x10, __PAGE_HYPERVISOR);
+ map_pages_to_xen(trampoline_phys, trampoline_phys >> PAGE_SHIFT,
+ PFN_UP(trampoline_end - trampoline_start),
+ __PAGE_HYPERVISOR);
}
void __init subarch_init_memory(void)
flush_local(FLUSH_TLB_GLOBAL);
/* Replace with mapping of the boot trampoline only. */
- map_pages_to_xen(BOOT_TRAMPOLINE, BOOT_TRAMPOLINE >> PAGE_SHIFT,
+ map_pages_to_xen(trampoline_phys, trampoline_phys >> PAGE_SHIFT,
PFN_UP(trampoline_end - trampoline_start),
__PAGE_HYPERVISOR);
}
*(.init.data)
*(.init.data.rel)
*(.init.data.rel.*)
+ . = ALIGN(4);
+ __trampoline_rel_start = .;
+ *(.trampoline_rel)
+ __trampoline_rel_stop = .;
+ __trampoline_seg_start = .;
+ *(.trampoline_seg)
+ __trampoline_seg_stop = .;
} :text
. = ALIGN(32);
.init.setup : {
/* Primary stack is restricted to 8kB by guard pages. */
#define PRIMARY_STACK_SIZE 8192
-#define BOOT_TRAMPOLINE 0x7c000
+#ifndef __ASSEMBLY__
+extern unsigned long trampoline_phys;
#define bootsym_phys(sym) \
- (((unsigned long)&(sym)-(unsigned long)&trampoline_start)+BOOT_TRAMPOLINE)
+ (((unsigned long)&(sym)-(unsigned long)&trampoline_start)+trampoline_phys)
#define bootsym(sym) \
(*RELOC_HIDE((typeof(&(sym)))__va(__pa(&(sym))), \
- BOOT_TRAMPOLINE-__pa(trampoline_start)))
-#ifndef __ASSEMBLY__
+ trampoline_phys-__pa(trampoline_start)))
extern char trampoline_start[], trampoline_end[];
extern char trampoline_realmode_entry[];
extern unsigned int trampoline_xen_phys_start;