summaryrefslogtreecommitdiffstats
path: root/src/arch/i386/transitions
Commit message (Collapse)AuthorAgeFilesLines
* [bios] Add bin-x86_64-pcbios build platformMichael Brown2016-02-166-1526/+0Star
| | | | | | | | | | | | | | Move most arch/i386 files to arch/x86, and adjust the contents of the Makefiles and the include/bits/*.h headers to reflect the new locations. This patch makes no substantive code changes, as can be seen using a rename-aware diff (e.g. "git show -M5"). This patch does not make the pcbios platform functional for x86_64; it merely allows it to compile without errors. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [bios] Allow librm to be compiled for x86_64Michael Brown2016-02-162-12/+18
| | | | | | | This commit does not make librm functional for x86_64; it merely allows it to compile without errors. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [build] Fix compiler warning on OpenBSD 5.7Michael Brown2015-04-181-1/+1
| | | | | | Reported-by: Jiri B <jirib@devio.us> Tested-by: Jiri B <jirib@devio.us> Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [build] Fix the REQUIRE_SYMBOL mechanismMichael Brown2015-03-051-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | At some point in the past few years, binutils became more aggressive at removing unused symbols. To function as a symbol requirement, a relocation record must now be in a section marked with @progbits and must not be in a section which gets discarded during the link (either via --gc-sections or via /DISCARD/). Update REQUIRE_SYMBOL() to generate relocation records meeting these criteria. To minimise the impact upon the final binary size, we use existing symbols (specified via the REQUIRING_SYMBOL() macro) as the relocation targets where possible. We use R_386_NONE or R_X86_64_NONE relocation types to prevent any actual unwanted relocation taking place. Where no suitable symbol exists for REQUIRING_SYMBOL() (such as in config.c), the macro PROVIDE_REQUIRING_SYMBOL() can be used to generate a one-byte-long symbol to act as the relocation target. If there are versions of binutils for which this approach fails, then the fallback will probably involve killing off REQUEST_SYMBOL(), redefining REQUIRE_SYMBOL() to use the current definition of REQUEST_SYMBOL(), and postprocessing the linked ELF file with something along the lines of "nm -u | wc -l" to check that there are no undefined symbols remaining. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [legal] Relicense files under GPL2_OR_LATER_OR_UBDLMichael Brown2015-03-022-2/+2
| | | | | | | | | | These files cannot be automatically relicensed by util/relicense.pl since they either contain unusual but trivial contributions (such as the addition of __nonnull function attributes), or contain lines dating back to the initial git revision (and so require manual knowledge of the code's origin). Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [legal] Relicense files under GPL2_OR_LATER_OR_UBDLMichael Brown2015-03-023-3/+11
| | | | | | | Relicense files for which I am the sole author (as identified by util/relicense.pl). Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [librm] Allow for the PIC interrupt vector offset to be changedMichael Brown2014-05-271-5/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | Some external code (observed with FreeBSD's bootloader) will continue to make INT 13 calls after reconfiguring the 8259 PIC to change the vector offsets for IRQs. If an IRQ (e.g. the timer IRQ) subsequently occurs while iPXE is in protected mode, this will cause a general protection fault since the corresponding IDT entry is empty. A general protection fault is INT 0x0d, which happens to overlap with the original IRQ5. We therefore do have an ISR set up to handle a general protection fault, but this ISR simply reflects the interrupt down to the real-mode INT 0x0d and then attempts to return. Since our ISR is expecting a hardware interrupt rather than a general protection fault, it doesn't remove the error code from the stack before issuing the iret instruction; it therefore attempts to return to a garbage address. Since the segment part of this address is likely to be invalid, a second general protection fault occurs. This cycle continues until we run out of stack space and triple fault. Fix by reflecting all INTs down to real mode. This actually reduces the code size by four bytes (but increases the bss size by almost 2kB). Reported-by: Brian Rak <dn@devicenull.org> Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [profile] Allow interrupts to be excluded from profiling resultsMichael Brown2014-05-041-3/+30
| | | | | | | | | Interrupt processing adds noise to profiling results. Allow interrupts (from within protected mode) to be profiled separately, with time spent within the interrupt handler being excluded from any other profiling currently in progress. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [librm] Add profiling self-tests for complete real_call and prot_call cyclesMichael Brown2014-05-031-0/+38
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [profile] Provide methods for profiling individual stages of operationsMichael Brown2014-05-031-4/+6
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [librm] Speed up protected-mode calls under KVMMichael Brown2014-05-021-19/+35
| | | | | | | | | | | | | When making a call from real mode to protected mode, we save and restore the global and interrupt descriptor table registers. The restore currently takes place after returning to real mode, which generates two EXCEPTION_NMIs and corresponding VM exits when running under KVM on an Intel CPU. Avoid the VM exits by restoring the descriptor table registers inside prot_to_real, while still running in protected mode. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [librm] Speed up real-to-protected mode transition under KVMMichael Brown2014-05-022-4/+18
| | | | | | | | | | | | | | | Ensure that all segment registers have zero in the low two bits before transitioning to protected mode. This allows the CPU state to immediately be deemed to be "valid", and eliminates the need for any further emulated instructions. Load the protected-mode interrupt descriptor table after switching to protected mode, since this avoids triggering an EXCEPTION_NMI and corresponding VM exit. This reduces the time taken by real_to_prot under KVM by around 50%. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [librm] Speed up protected-to-real mode transition under KVMMichael Brown2014-05-021-20/+18Star
| | | | | | | | | | | | | | | | | | | | | | | | | | | | On an Intel CPU supporting VMX, KVM will emulate instructions while the CPU state remains "invalid". In real mode, the CPU state is defined to be "invalid" if any segment register has a base which is not equal to (sreg<<4) or a limit which is not equal to 64kB. We don't actually use the base stored in the REAL_DS descriptor for any significant purpose. Change the base stored in this descriptor to be equal to (REAL_DS<<4). A segment register loaded with REAL_DS is then automatically valid in both real and protected modes. This allows KVM to stop emulating instructions much sooner. The only use of REAL_DS for memory accesses currently occurs in the indirect ljmp within prot_to_real. Change this to a direct ljmp, storing rm_cs in .text16 as part of the ljmp instruction. This removes the only memory access via REAL_DS (thereby allowing for the above descriptor base address hack), and also simplifies the ljmp instruction (which will still have to be emulated). Load the real-mode interrupt descriptor table register before switching to real mode, since this avoids triggering an EXCEPTION_NMI and corresponding VM exit. This reduces the time taken by prot_to_real under KVM by around 65%. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [librm] Add meaningful labels at section changesMichael Brown2014-05-021-12/+12
| | | | | | | | | | | | | The mode-transition code involves paths which switch back and forth between the .text and .text16 sections. At present, only the start of each function is labelled, which makes it difficult to decode addresses within the parts of the function existing in a different section. Add explicit labels at the start of each section change, so that addresses can be meaningfully decoded to the nearest label. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [librm] Add a profiling self-test for measuring mode transition timesMichael Brown2014-05-021-0/+77
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [librm] Allow interrupts in protected modeMichael Brown2014-04-292-12/+126
| | | | | | | | When running in a virtual machine, switching to real mode may be expensive. Allow interrupts to be enabled while in protected mode and reflected down to the real-mode interrupt handlers. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [librm] Use genuine real mode to accelerate operation in virtual machinesMichael Brown2014-04-281-5/+35
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We currently use flat real mode wherever real mode is required. This guarantees that we will not surprise some unsuspecting external caller which has carefully set up flat real mode by suddenly reducing the segment limits to 64kB. However, operating in flat real mode imposes a severe performance penalty in some virtualisation environments, since some CPUs cannot fully virtualise flat real mode and so the hypervisor must fall back to emulation. In particular, operating under KVM on a pre-Westmere Intel CPU will be at least an order of magnitude slower, to the point that there is a visible teletype effect when printing anything to the BIOS console. (Older versions of KVM used to cheat and ignore the "flat" part of flat real mode, which masked the problem.) Switch (back) to using genuine real mode with 64kB segment limits instead of flat real mode. Hopefully this won't break anything. Add an explicit switch to flat real mode before returning to the BIOS from the ROM prefix, since we know that a PMM BIOS will call the ROM initialisation point (and potentially the BEV) in flat real mode. As noted in previous commit messages, it is not possible to restore the real-mode segment limits after a transition to protected mode, since there is no way to know which protected-mode segment descriptor was originally used to initialise the limit portion of the segment register. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [legal] Update FSF mailing address in GPL licence textsMichael Brown2012-07-201-1/+2
| | | | | Suggested-by: Daniel P. Berrange <berrange@redhat.com> Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [liba20] Preserve all non-segment registers when calling INT 15,2401Michael Brown2011-10-251-3/+6
| | | | | | | | Some BIOSes are reported to corrupt %ebx when using INT 15,2401 (see http://opensolaris.org/jive/thread.jspa?messageID=377026). Guard against this by preserving all (non-segment) registers. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [librm] Avoid (harmless) collisions with linker symbolsMichael Brown2011-10-251-14/+14
| | | | | | | | The symbol_text16 is defined globally by the linker. Use rm_text16 instead of _text16 for the local variable within librm.S to avoid confusion when reading linker maps. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [liba20] Rename libflat to liba20Michael Brown2011-01-271-0/+0
| | | | | | | libflat no longer has anything to do with flat real mode; it handles only the A20 gate. Update library name to match. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [libflat] Remove now-obsolete flatten_real_mode callMichael Brown2011-01-271-121/+1Star
| | | | | | | | Flat real mode will have been set up as a side-effect of the protected-mode call invoked during install_block() for .text16.early; there is no need to do so explicitly. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [libflat] Test A20 gate without switching to flat real modeMichael Brown2010-12-031-12/+18
| | | | | | | | | | | | | | | | | | | | | | | | | Use the real-mode address ffff:0010 to access the linear address 0x100000, and so test whether or not the A20 gate is enabled without requiring a switch into flat real mode (or some other addressing mode). This speeds up CPU mode transitions, and also avoids breaking the NBP from IBM's Tivoli Provisioning Manager for Operating System Deployment. This NBP makes some calls to iPXE in VM86 mode rather than true real mode and does not correctly emulate our transition into flat real mode. Interestingly, Tivoli's VMM *does* allow us to switch into protected mode (though it patches our GDT so that we execute in ring 1 rather than ring 0). However, paging is still disabled and we have a 4GB segment limit. Being in ring 1 does not, therefore, restrict us in any meaningful way; this has been verified by deliberately writing garbage over Tivoli's own GDT (at address 0x02201010) during a nominally VM86-mode PXE API call. It's unclear precisely what protection this VMM is supposed to be offering. Suggested-by: Joshua Oreman <oremanj@rwcr.net> Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [librm] Use libflat to enable A20 line on each real-to-protected transitionMichael Brown2010-04-202-12/+12
| | | | | | | | | | | | | Use the shared code in libflat to perform the A20 transitions automatically on each transition from real to protected mode. This allows us to remove all explicit calls to gateA20_set(). The old warnings about avoiding automatically enabling A20 are essentially redundant; they date back to the time when we would always start hammering the keyboard controller without first checking to see if gate A20 was already enabled (which it almost always is). Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [prefix] Add A20-enabling code in libflatMichael Brown2010-04-201-3/+280
| | | | | | | | | | | | | | | | iPXE currently insists on residing in an even megabyte. This imposes undesirably severe constraints upon our PMM allocation strategy, and limits our options for mechanisms to access ROMs greater than 64kB in size. Add A20 handling code to libflat so that prefixes are able to access memory even in odd megabytes. The algorithms and tuning parameters in the new A20 handling code are based upon a mixture of the existing iPXE A20 code and the A20 code from the 2.6.32 Linux kernel. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [prefix] Move flatten_real_mode to libflat.SMichael Brown2010-04-201-0/+141
| | | | Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [prefix] Use flat real mode instead of real modeMichael Brown2010-04-201-13/+4Star
| | | | | | | | | | | | | | | | | | | | When returning to real mode, set 4GB segment limits instead of 64kB limits. This change improves our chances of successfully returning to a PMM-capable BIOS aftering entering iPXE during POST; the BIOS will have set up flat real mode before calling our initialisation point, and may be disconcerted if we then return in genuine real mode. This change is unlikely to break anything, since any code that might potentially access beyond 64kB must use addr32 prefixes to do so; if this is the case then it is almost certainly code written to expect flat real mode anyway. Note that it is not possible to restore the real-mode segment limits to their original values, since it is not possible to know which protected-mode segment descriptor was originally used to initialise the limit portion of the segment register. Signed-off-by: Michael Brown <mcb30@ipxe.org>
* [misc] Fix source files erroneously marked as executableMichael Brown2009-06-022-0/+0
|
* [legal] Add a selection of FILE_LICENCE declarationsMichael Brown2009-05-183-0/+6
| | | | | Add FILE_LICENCE declarations to almost all files that make up the various standard builds of gPXE.
* [i386] Add explicit flags and type on all .section declarationsMichael Brown2009-02-151-23/+20Star
| | | | | | | | | | | | | | | | | | | | | | | Try to avoid future problems caused by implicit section flags and/or type information by instituting a policy that all .section declarations must explicitly state the flags and type. Most of this change was achieved using perl -pi \ -e 's/".text"$/".text", "ax", \@progbits/ ; ' \ -e 's/".text16"$/".text16", "ax", \@progbits/ ; ' \ -e 's/".text16.null"$/".text16.null", "ax", \@progbits/ ; ' \ -e 's/".text16.data"$/".text16.data", "aw", \@progbits/ ; ' \ -e 's/".data"$/".data", "aw", \@progbits/ ; ' \ -e 's/".data16"$/".data16", "aw", \@progbits/ ; ' \ -e 's/".bss"$/".bss", "aw", \@nobits/ ; ' \ -e 's/".bss16"$/".bss16", "aw", \@nobits/ ; ' \ -e 's/".prefix"$/".prefix", "ax", \@progbits/ ; ' \ -e 's/".prefix.lib"$/".prefix.lib", "awx", \@progbits/ ; ' \ -e 's/".prefix.data"$/".prefix.data", "aw", \@progbits/ ; ' \ -e 's/".weak"$/".weak", "a", \@nobits/ ; ' \ `git grep -l '\.section'`
* [i386] Add data32 prefixes to all lgdt/lidt instructionsMichael Brown2008-11-071-5/+5
| | | | | | | | | | | | With a 16-bit operand, lgdt/lidt will load only a 24-bit base address, ignoring the high-order bits. This meant that we could fail to fully restore the GDT across a call into gPXE, if the GDT happened to be located above the 16MB mark. Not all of our lgdt/lidt instructions require a data32 prefix (for example, reloading the real-mode IDT can never require a 32-bit base address), but by adding them everywhere we will hopefully not forget the necessary ones in future.
* [uaccess] Formalise the uaccess APIMichael Brown2008-10-131-45/+56
| | | | | | The userptr_t is now the fundamental type that gets used for conversions. For example, virt_to_phys() is implemented in terms of virt_to_user() and user_to_phys().
* [librm] Add rm stack copying functionsDaniel Verkamp2008-08-291-0/+45
|
* [librm] Make rm_sp and rm_ss globals againDaniel Verkamp2008-08-281-0/+2
|
* [GDB] Add GDB stub for remote debuggingStefan Hajnoczi2008-06-051-11/+32
| | | | See http://etherboot.org/wiki/dev/gdbstub for documentation.
* Fix compiler warnings that appear only on OpenBSD.Michael Brown2007-12-061-1/+1
|
* Switch rm_ss and rm_sp back to being words; it'll make it lessMichael Brown2007-09-251-7/+7
| | | | confusing to read the code.
* Don't use the "rep ss movsb" trick to copy the RM stack to the PMMichael Brown2007-09-251-31/+34
| | | | stack; it breaks vmxassist.
* rm_ss, rm_sp, and pm_esp don't need to be accessed from anywhereMichael Brown2007-09-252-51/+0Star
| | | | outside of librm.S.
* Real-mode code might set the direction flag, which would cause carnage.Michael Brown2007-07-171-0/+3
|
* Leave protected-mode return address on PM stack when issuing aMichael Brown2007-01-091-11/+10Star
| | | | | | real_call(), rather than moving it to the RM stack and back again. This allows the real-mode function to completely destroy the stack contents, provided that it manages to return to real_call().
* Don't automatically call gateA20_set() when returning from a real-modeMichael Brown2007-01-041-5/+7
| | | | call.
* Towards making KEEP_IT_REAL work again.Michael Brown2006-08-241-15/+26
| | | | | Fix bug that caused over-allocation of .text16 and .data16 memory areas by a factor of 16.
* Tidy up commentMichael Brown2006-05-281-4/+5
|
* Fixed assembly on old versions of gasMichael Brown2006-05-281-3/+3
|
* Documented the fact that the prefix can prot_call(main) withoutMichael Brown2006-05-261-0/+9
| | | | worrying about its stack being destroyed during the Etherboot run.
* init_librm() and prot_call() are now real-mode far calls.Michael Brown2006-05-251-4/+4
| | | | | install() now calls relocate(), moves the protected-mode code to the new location, and calls hide_etherboot().
* Removed REAL_EXEC(); there is no longer any code using it.Michael Brown2006-05-241-1/+1
|
* Remove references to obsoleted REAL_CALL from documentation.Michael Brown2006-05-241-3/+2Star
|
* Provide access to rm_cs and rm_ds from protected-mode code.Michael Brown2006-05-131-0/+2
|