[comboot] Run com32 programs with a valid IDT
authorGeoff Lywood <glywood@vmware.com>
Wed, 7 Jul 2010 22:35:01 +0000 (15:35 -0700)
committerStefan Hajnoczi <stefanha@gmail.com>
Sun, 1 Aug 2010 11:56:51 +0000 (12:56 +0100)
commitb764464f04c5316e0f8188ef6bf3a74e8ebc1f00
treedcbea41ad2d597fe8c4d19b9edaeebfedc02a604
parentc542da3f3d167a79903c6d4cfdbd97891513b954
[comboot] Run com32 programs with a valid IDT

COM32 binaries generally expect to run with interrupts enabled. Syslinux does
so, and COM32 programs will execute cli/sti pairs when running a critical
section, to provide mutual exclusion against BIOS interrupt handlers.
Previously, under gPXE, the IDT was not valid, so any interrupt (e.g. a timer
tick) would generally cause the machine to triple fault.

This change introduces code to:
- Create a valid IDT at the same location that syslinux uses
- Create an "interrupt jump buffer", which contains small pieces of code that
  simply record the vector number and jump to a common handler
- Thunk down to real mode and execute the BIOS's interrupt handler whenever
  an interrupt is received in a COM32 program
- Switch IDTs and enable/disable interrupts when context switching to and from
  COM32 binaries

Testing done:
- Booted VMware ESX using a COM32 multiboot loader (mboot.c32)
- Built with GDBSERIAL enabled, and tested breakpoints on int22 and com32_irq
- Put the following code in a COM32 program:
    asm volatile ( "sti" );
    while ( 1 );
  Before this change, the machine would triple fault immediately. After this
  change, it hangs as expected. Under Bochs, it is possible to see the
  interrupt handler run, and the current time in the BIOS data area gets
  incremented.

Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com>
src/arch/i386/image/com32.c
src/arch/i386/include/comboot.h
src/arch/i386/interface/syslinux/com32_call.c
src/arch/i386/interface/syslinux/com32_wrapper.S