bc3ad3a179
Runtime services require special execution environment for the call. Besides that, OS must inform firmware about runtime virtual memory map which will be active during the calls, with the SetVirtualAddressMap() runtime call, done while the 1:1 mapping is still used. There are two complication: the SetVirtualAddressMap() effectively must be done from loader, which needs to know kernel address map in advance. More, despite not explicitely mentioned in the specification, both 1:1 and the map passed to SetVirtualAddressMap() must be active during the SetVirtualAddressMap() call. Second, there are buggy BIOSes which require both mappings active during runtime calls as well, most likely because they fail to identify all relocations to perform. On amd64, we can get rid of both problems by providing 1:1 mapping for the duration of runtime calls, by temprorary remapping user addresses. As result, we avoid the need for loader to know about future kernel address map, and avoid bugs in BIOSes. Typically BIOS only maps something in low 4G. If not runtime bugs, we would take advantage of the DMAP, as previous versions of this patch did. Similar but more complicated trick can be used even for i386 and 32bit runtime, if and when the EFI boot on i386 is supported. We would need a trampoline page, since potentially whole 4G of VA would be switched on calls, instead of only userspace portion on amd64. Context switches are disabled for the duration of the call, FPU access is granted, and interrupts are not disabled. The later is possible because kernel is mapped during calls. To test, the sysctl mib debug.efi_time is provided, setting it to 1 makes one call to EFI get_time() runtime service, on success the efitm structure is printed to the control terminal. Load efirt.ko, or add EFIRT option to the kernel config, to enable code. Discussed with: emaste, imp Tested by: emaste (mac, qemu) Sponsored by: The FreeBSD Foundation MFC after: 2 weeks |
||
---|---|---|
.. | ||
pc | ||
xen | ||
_align.h | ||
_bus.h | ||
_inttypes.h | ||
_limits.h | ||
_stdint.h | ||
_types.h | ||
acpica_machdep.h | ||
apm_bios.h | ||
asm.h | ||
asmacros.h | ||
atomic.h | ||
bus_dma.h | ||
bus.h | ||
clock.h | ||
counter.h | ||
cpu.h | ||
cpufunc.h | ||
cputypes.h | ||
db_machdep.h | ||
dump.h | ||
efi.h | ||
elf.h | ||
endian.h | ||
exec.h | ||
fdt.h | ||
float.h | ||
floatingpoint.h | ||
fpu.h | ||
frame.h | ||
gdb_machdep.h | ||
ieeefp.h | ||
in_cksum.h | ||
intr_machdep.h | ||
iodev.h | ||
kdb.h | ||
limits.h | ||
md_var.h | ||
memdev.h | ||
metadata.h | ||
minidump.h | ||
mp_watchdog.h | ||
nexusvar.h | ||
npx.h | ||
ofw_machdep.h | ||
param.h | ||
pcb.h | ||
pci_cfgreg.h | ||
pcpu.h | ||
pmap.h | ||
pmc_mdep.h | ||
ppireg.h | ||
proc.h | ||
profile.h | ||
psl.h | ||
ptrace.h | ||
pvclock.h | ||
reg.h | ||
reloc.h | ||
resource.h | ||
runq.h | ||
segments.h | ||
setjmp.h | ||
sf_buf.h | ||
sigframe.h | ||
signal.h | ||
smp.h | ||
specialreg.h | ||
stack.h | ||
stdarg.h | ||
sysarch.h | ||
timerreg.h | ||
trap.h | ||
tss.h | ||
ucontext.h | ||
varargs.h | ||
vdso.h | ||
vm.h | ||
vmm_dev.h | ||
vmm_instruction_emul.h | ||
vmm.h | ||
vmparam.h |