History log of /freebsd-10.1-release/sys/boot/i386/btx/btx/btx.S
Revision Date Author Comments
(<<< Hide modified files)
(Show modified files >>>)
# 272461 02-Oct-2014 gjb

Copy stable/10@r272459 to releng/10.1 as part of
the 10.1-RELEASE process.

Approved by: re (implicit)
Sponsored by: The FreeBSD Foundation

# 256562 15-Oct-2013 jhb

MFC 256293:
Sanitize the %eflags returned by BIOS routines. Some BIOS routines enter
protected mode and may leave protected-mode-specific flags like PSL_NT set
when they return to real mode. This can cause a fault when BTX re-enters
protected mode after the BIOS mode returns.

Approved by: re (gjb)


# 256281 10-Oct-2013 gjb

Copy head (r256279) to stable/10 as part of the 10.0-RELEASE cycle.

Approved by: re (implicit)
Sponsored by: The FreeBSD Foundation


# 249846 24-Apr-2013 dim

When rebooting (exiting) from the BTX loader, make sure to restore the
GDT from the correct segment, otherwise a triple fault would be caused.
In some virtual environments (VMware, VirtualBox, etc) this could lead
to a unhandled error or hang in the guest emulation software.

Thanks to avg and jhb for a few hints in the right direction.

Noticed by: Jeremy Chadwick <jdc@koitsu.org> (and many others)
MFC after: 1 week


# 241301 06-Oct-2012 avg

add detection of serial console presence to btx and boot2-like blocks

Note that this commit slightly increases size of boot blocks.

Reviewed by: jhb
Tested by: Olivier Cochard-Labbe <olivier@cochard.me>
MFC after: 26 days


# 235154 09-May-2012 avg

btxldr: future-proof argument passing from boot1/2-ish to loader

Place the arguments at a fixed offset of 0x800 withing the argument area
(of size 0x1000). Allow variable size extended arguments first of which
should be a size of the extended arguments (including the size
parameter).

Consolidate all related definitions in a new i386/common/bootargs.h header.

Many thanks to jhb and bde for their guidance and reviews.

Reviewed by: jhb, bde
Approved by: jhb
MFC after: 1 month


# 189017 24-Feb-2009 jhb

Fix some more issues with the real mode BTX.

The old BTX passed the general purpose registers from the 32-bit client to
the routines called via virtual 86 mode. The new BTX did the same thing.
However, it turns out that some instructions behave differently in virtual 86
mode and real mode (even though this is under-documented). For example, the
LEAVE instruction will cause an exception in real mode if any of the upper
16-bits of %ebp are non-zero after it executes. In virtual 8086 mode the
upper 16-bits are simply ignored. This could cause faults in hardware
interrupt handlers that inherited an %ebp larger than 0xffff from the 32-bit
client (loader, boot2, etc.) while running in real mode.

To fix, when executing hardware interrupt handlers provide an explicit clean
state where all the general purpose and segment registers are zero upon
entry to the interrupt handler. While here, I attempted to simplify the
control flow in the 'intusr' code that sets up the various stack frames
and exits protected mode to invoke the requested routine via real mode.

A huge thanks to Tor Egge (tegge@) for debugging this issue.

Submitted by: tegge
Reviewed by: tegge
Tested by: bz
MFC after: 1 week


# 181433 08-Aug-2008 jhb

Fix the hangs reported with the real mode BTX:
- I had errantly assumed that all user requests should run with interrupts
enabled. User requests for software interrupts, however, need to disable
interrupts (and tracing) just like hardware interrupts.
- Disable alignment checking when emulating a hardware interrupt as well
(based on the description of the real mode operation of the 'INT'
instruction in the IA-32 manuals).
- Use constants for fields in %eflags.

Tested by: bz
MFC after: 3 days


# 177039 10-Mar-2008 jhb

Change the BTX kernel to drop all the way out to real mode to invoke BIOS
routines (V86 requests from the client and hardware interrupt handlers):
- Install trampoline real mode interrupt handlers at IDT vectors 0x20-0x2f
to handle hardware interrupts by invoking the appropriate vector (0x8-0xf
or 0x70-0x78). This allows the 8259As to use vectors 0x20-0x2f in real
mode as well as protected mode will ensuring that the master 8259A
doesn't share IDT space with CPU exceptions in protected mode.
- Since we don't need to reserve space for page tables and a page directory
anymore since dropping paging support, move the TSS and protected mode
IDT up by 16k. Grow the ring 1 link stack by 16k as a result.
- Repurpose the ring 1 link stack to be used as a real mode stack when
invoking real mode routines either via a V86 request or a hardware
interrupts. This simplifies a few things as we avoid disturbing the
original user stack.
- Add some more block comments to explain how the code interacts with the
V86 structure as this wasn't immediately obvious from the prior comments
(e.g. that we explicitly copy the seg regs for real mode out of the V86
struct onto the stack to be popped off when going into real mode, etc.).
Also, document some of the stack frames we create going to real mode and
back.
- Remove all of the virtual 86 related code including having to simulate
various instructions and BIOS calls on a trap from virtual 86 mode.
- Explicitly panic if a user client attempts to perform a V86 CALL
request that isn't a far call.
- Bump version to 1.2.

Assuming this works ok this should fix some of the long standing issues
with USB booting as well as etherboot.

MFC after: 2 weeks
Submitted by: kib (some parts from his original real mode patch)


# 176631 27-Feb-2008 jhb

Retire the support for using paging in BTX. It hasn't been used since
before 4.0.

Submitted by: kib


# 164948 06-Dec-2006 jhb

Ignore any breakpoint instructions (int 3) we encounter in vm86 mode
rather than treating them as a fatal exception and halting. At least one
storage BIOS (some newer mpt(4) parts) have a breakpoint instruction in
their disk read routine.

MFC after: 3 days


# 163032 05-Oct-2006 jhb

- Fix a couple of improper uses of leal in the previous space saving
commits. For some reason I thought the scale factor was a shift count
rather than the multiplicand (that is, I thought leal (%eax,%edx,4) was
going to generate %eax + %edx << 4 rather than %eax + %edx * 4). What
I need is to multiply by 16 to convert a real-mode (seg, offset) tuple
into a flat address. However, the max multiplicand for scaled/index
addressing on i386 is 8, so go back to using a shl and an add.
- Convert two more inter-register mov instructions where we don't need to
preserve the source register to xchg instructions to keep our space
savings.

Tested by: Ian FREISLICH if at hetzner.co.za
MFC after: 1 week


# 162745 28-Sep-2006 jhb

Tweak the code to handle intercepting BIOS calls to int 0x15 to shave
another 16 bytes off of BTX (and thus boot2):
- Compare against the value of %eax that is saved on the stack instead of
loading it into %eax (which requires saving the current %eax on the
stack).
- Use %ch to examine the keyboard flag state in the BIOS to see if
Ctrl-Alt-Del is pressed instead of %al so we don't have to save %eax on
the stack anymore.

MFC after: 1 week


# 162744 28-Sep-2006 jhb

Optimize the int 15/87 handler for space to shave another 16 bytes off of
BTX (and thus boot2):
- Don't bother saving %eax, %ebx, or %ecx as it is not necessary.
- Use a more compact sequence to load the base value out of a GDT entry
by loading the contiguous low 24 bits into the upper 24 bits of %eax,
loading the high 8 bits into %al, and using a ror to rotate the bits
(2 mov's and a ror) rather than loading the pieces in smaller chunks
(3 mov's and a shl).
- Use movzwl + leal instead of movl + movw + shll + addl.
- Use 'xchgl %eax,%foo' rather than 'movl %eax,%foo' for cases where
it's ok to trash %eax. xchgl %eax, foo is a 1-byte opcode whereas the
mov is a 2-byte opcode.
- Use movzwl rather than xorl + movw.

MFC after: 1 week


# 162737 28-Sep-2006 jhb

A couple of simple tweaks that trim BTX by 6 bytes. Since BTX is
16-byte aligned within boot2 however, this actually trims boot2 by 16
bytes.


# 162710 27-Sep-2006 jhb

Emulate moving cr0, cr2, cr3, or cr4 into any i386 general register
rather than just emulating mov cr0, eax. This fixes some Compaq/HP BIOS
with DMA (as the BIOS tried to read cr3 so it could translate addresses
if paging was enabled).

MFC after: 1 week


# 138046 24-Nov-2004 jhb

Fix comments for serial I/O function prototypes that were broken in the
assembler to cpp(1) comment conversions. This allows btx to compile again
when BTX_SERIAL is defined.

Reported by: Danny Braniss danny at cs dot huji dot ac dot il
MFC after: 1 month


# 129240 14-May-2004 ru

Back out last revision that unnecessarily changed valid assembler
line comments and damaged the CVS history.

Prompted by: bde, jhb


# 128716 28-Apr-2004 ru

After talking to Bruce Evans and reading more standards specs,
switch to using C99-style comments everywhere in preprocessed
assembler. The reason is that lines starting with the regexp
'^[[:space:]]#' are treated as preprocessing directives, and
while it seems to work now with GCC, it's not necessarily has
to work. Use C99 comments `//' for the trailing comments to
save whitespace.


# 128709 28-Apr-2004 ru

Use C (and CPP) style comments for assembler-with-cpp sources,
for lines that start with a comment.


# 125693 11-Feb-2004 ru

Get rid of unnecessary use of m4(1) by using cpp(1) instead.
(John tells me there were problems when trying this before,
but it appears to be safe these day.)

OK'ed by: jhb
Repocopied by: joe


# 122806 16-Nov-2003 phk

When rebooting the machine jump to 0xf000:0xfff0 instead of 0xffff:0x0.

While we end up the same place, we end up with two different CS register
values after the jump and 0xf000 is compatible with the hardware reset
value.

This makes a difference if the BIOS does a near jump before a far jump.

Detective work and patch by: Adrian Steinmann <ast@marabu.ch>


# 104683 08-Oct-2002 jhb

Revert MEM_USR back to 0xa000 for BTX clients. Instead, adjust boot2
to run at 0xc000 by changing its virtual start address from 0x1000 to
0x2000.

Tested by: phk


# 104618 07-Oct-2002 phk

Move MEM_USR a page upwards to make space for larger UFS1 boot2.

Load 4 sectors more than we used to. This is harmless overhead for
the UFS1_ONLY case, but sufficient for boot2(UFS1+2).

Sponsored by: DARPA & NAI Labs


# 85995 03-Nov-2001 jhb

Whoops, missed these bits in the previous commit.


# 85994 03-Nov-2001 jhb

Add support for sending messages to the serial console which is helpful
when debugging boot problems. It is not on by default but is enabled via
the BTX_SERIAL variable. The port and speed can be set via the same
variables used by boot2 and the loader.


# 85993 03-Nov-2001 jhb

Add support for outputting multiple lines when dumping memory during the
register dump. Change the default to bump 2 lines of output (32 bytes)
instead of 1 line (16 byte).


# 85990 03-Nov-2001 jhb

Add support for trace traps by returning from them just as for breakpoint
traps rather than halting. Ideally, we should avoid printing the
'BTX halted' message for debug register dumps.


# 85989 03-Nov-2001 jhb

Output a newline at the end of a dump so that there are blank lines between
dumps when using breakpoints or tracing.


# 77273 27-May-2001 rnordier

Fix reboot buglet when BOOT_BTX_NOHANG is defined.

Submitted by: Umesh Krishnaswamy <umesh@juniper.net>


# 74592 21-Mar-2001 jhb

Always disable paging when exiting back to real mode after receiving a
fatal trap. Also, reload the GDT register to point to BTX's GDT before
playing around with the segment registers to return to real mode. This is
helpful if the kernel causes a fatal exception before it has setup its own
IDT and fault handlers. For example, if one happens to break mtx_init().
Without these changes BTX would recursively page fault (if paging was not
disabled) or triple fault and reset the CPU (without the GDT reload)
instead of providing a potentially useful register dump.

Reviewed by: rnordier


# 65063 24-Aug-2000 jhb

Add a new compile-time tweak to BTX. If you set the make(1) variable
BOOT_BTX_NOHANG, then BTX will be compiled with the appropriate flags so
that it reboots after a fault instead of hanging forever.

Requested by: ps
Approved by: rnordier


# 62657 05-Jul-2000 jhb

Emulate the WBINVD instruction when it is called by the BIOS.


# 62251 29-Jun-2000 jhb

Note that the cleaning up and reordering in revision 1.19 actually fixed a
nasty bug. The comparison to tset for an instruciton with the $0xf prefix
should have jumped down to the next non-prefix instruction test. Instead,
it jumped down to the next instruction test, which happened to be prefixed
instruction test. This test assumed that the earlier test had succeeded,
thus in some rare cases, this test would actually succeed, and we would
actually attempt to emulate a RDMSR instruction instead of the instruction
we were supposed to be emulating. Since %ecx usually did not contain a
valid MSR index at the time of the trap, this usually resulted in a #GP
due to an invalid MSR address and a lovely BTX fault when one tried to boot
the machine.

Noticed by: unfurl and others


# 62242 29-Jun-2000 jhb

Change the fault message to say 'BTX halted' isntead of 'System halted' to
avoid confusion.

Submitted by: George Scott <George.Scott@its.monash.edu.au>


# 62229 28-Jun-2000 jhb

Rework the detecting of the rdmsr and wrmsr instructions in the v86
monitor so that the codepath is cleaner and easier to maintain in the
future.


# 61743 17-Jun-2000 jhb

Add support for emulating the RDMSR and WRMSR instructions into BTX. In
theory, this should allow the K7V Athlon motherboard to boot ok with boot
virus protection enabled. However, I have no hardware to test this. It
shouldn't break anything though. :)

Prodded by: Kelly Yancey <kbyanc@posi.net>


# 60821 23-May-2000 jhb

Clean up all of the 16-bit assembly code in the x86 bootstrap to work
with the new binutils. Now that we have a decent assembler, all the old
m4 macros are no longer needed. Instead, straight assembly can be used
since as(1) now understands 16-bit addressing, branches, etc. Also,
several bugs have been fixed in as(1), allowing boot0.s to be further
cleaned up.


# 59634 26-Apr-2000 jhb

Don't disable interrupts when calling a vm86 mode interrupt or routine
from user mode. Don't disable interrupts when returning from vm86 mode
to user mode either. Now, we only disable interrupts before calling a
hardware interrupt handler, which is the only time we _should_ be
disabling interrupts.

Because of this, err, feature, any routine that one called in vm86 mode
had to re-enable interrupts by setting the interrupt flag or interrupts
would remain disabled even after the routine returned. For example, I
have a simple debugging routine that uses a vm86 mode function to dump
any arbitrary memory word that I use to read the BIOS timer or any other
memory location. This function does 1 load instruction from memory and
then returns. Since it didn't re-enable interrupts, the first time I
called it to read the BIOS timer, it disabled interrupts. This also
affected the PXE bootstrap as it needs interrupts enabled while it is
processing. This patch fixes both of those situations so that those
functions do not worry about having to enable interrupts. Hardware
interrupt handlers worked fine with the old code because they always
enable interrupts as part of their routine.

If you have any problems with the loader after this commit, please
let me know. I'd like to MFC it in a week or two since PXE support
needs it.

Noticed by: ps, Michael Johnston <michael.johnston@intel.com>


# 57254 16-Feb-2000 jhb

This patch to BTX fixes several small things:

1) Fix a bug in the int15 function 87 emulation where we only copied half
of what the BIOS asked for. This caused the Mylex RAID adapter to go
haywire and start trashing memory when you tried to boot from it.
2) Don't use interrupt 19 to reboot. Instead, set the reboot flag to a warm
boot and jump to the BIOS's reboot handler. int 19 doesn't clear memory
or restore the interrupt vector table, and thus really isn't safe. For
example, when booting off of PXE, the PXE BIOS eats up a chunk of memory
for its internal data and structures. Since we rebooted via int 19,
using the 'reboot' command in the loader resulted in that memory not
being reclaimed by the BIOS. Thus, after a few PXE boots, the system
was out of lower memory.
3) Catch any int 19 calls made by a BTX client or a user pressing
Ctrl-Alt-Delete and shutdown BTX and reboot the machine cleanly. This
fixes Ctrl-Alt-Delete in the loader and in boot2 instead of presenting
the user with a BTX fault.

Approved by: jkh
Found by: 1) by msmith


# 56691 27-Jan-2000 jhb

Fix brokenness introduced with the PAGING conditional variable. The value
of %cr0 wasn't reloaded into %eax before being modified to turn protected
mode off if PAGING was not defined. The result was that the processor did
not exit protected mode, so when it tried to jump to segment 0x0 in the
next instruction to clear the prefetch cache like one should when leaving
protected mode, it actually tried to jump to a null selector, causing a
GPF.


# 52545 27-Oct-1999 jhb

If PAGING is defined then actually turn it on when entering protected
mode.


# 52173 12-Oct-1999 jhb

aThis patch updates the BTX to emulate the BIOS function "Copy Extended
Memory" called as function 0x87 of interrupt 0x15. Since the Mylex RAID
adapter's BIOS used this function to access memory (actually PCI bus
space) beyond 16 MB, this patch also allows BTX to address all 4 Gig of
possible address space on i386+. Since the loader does not have room for
4 MB of page tables, this was done by turning off paging.

Paging was turned off via a compile time setting which defaults to off.
To enable paging, simply define the make variable PAGING.

rnordier might want to clean this up later.

Submitted by: W. Gerald Hicks <wghicks@bellsouth.net>,
Bosko Milekic <bmilekic@ares.dsuper.net>
Reviewed by: msmith
Required by: Mylex RAID adapter's BIOS


# 50477 27-Aug-1999 peter

$Id$ -> $FreeBSD$


# 44274 25-Feb-1999 rnordier

Emulate a V86 "movl %cr0,%eax" instruction.

Feedback and testing: Kurt Hopfensperger <kjhmdjd@ix.netcom.com>


# 43059 22-Jan-1999 rnordier

Push version numbers up to 1.00. This is just intended to reflect
that the BTX code can be regarded as stable: there are no associated
code changes.

Suggested by: obrien


# 40833 02-Nov-1998 rnordier

Revise a few comments.


# 40807 01-Nov-1998 rnordier

Ignore, rather than emulate, an i386 'hlt' instruction (though for
most practical purposes, this should be indistinguishable from a
more strictly correct approach).

Feedback and testing: msmith


# 39961 04-Oct-1998 rnordier

Allocate space for storing of arguments at the end of conventional
memory.


# 39930 03-Oct-1998 rnordier

For system calls, reboot without prompting; for exceptions, display
message and await reset.


# 39921 03-Oct-1998 rnordier

Map all BTX system pages readable at ring 3.
This resolves the firmware problem first raised in connection
with PR 8105, although unrelated.


# 39274 15-Sep-1998 rnordier

Add exec syscall.


# 39125 13-Sep-1998 rnordier

Enable client entry point support.


# 39088 12-Sep-1998 rnordier

BTX (aka the boot extender) is an i386 kernel that hosts 32-bit
bootstrap programs, and provides page-level protection, hardware
interrupt reflection, a virtual-8086 mode interface to BIOS, etc.