david/ipxe
Archived
1
0

[comboot] Implement INT 22h AX=001Bh (Cleanup, shuffle, and boot to real mode)

This commit is contained in:
Daniel Verkamp 2008-09-29 10:45:57 -05:00 committed by Michael Brown
parent 5026a35fef
commit dbbd81c140
2 changed files with 95 additions and 1 deletions

View File

@ -57,6 +57,40 @@ typedef struct {
com32_reg32_t eflags; /* Offset 40 */
} com32sys_t;
typedef struct {
uint32_t eax; /* Offset 0 */
uint32_t ecx; /* Offset 4 */
uint32_t edx; /* Offset 8 */
uint32_t ebx; /* Offset 12 */
uint32_t esp; /* Offset 16 */
uint32_t ebp; /* Offset 20 */
uint32_t esi; /* Offset 24 */
uint32_t edi; /* Offset 28 */
uint32_t eip; /* Offset 32 */
} syslinux_pm_regs;
typedef struct {
uint16_t es; /* Offset 0 */
uint16_t _unused_cs; /* Offset 2 */
uint16_t ds; /* Offset 4 */
uint16_t ss; /* Offset 6 */
uint16_t fs; /* Offset 8 */
uint16_t gs; /* Offset 10 */
uint32_t eax; /* Offset 12 */
uint32_t ecx; /* Offset 16 */
uint32_t edx; /* Offset 20 */
uint32_t ebx; /* Offset 24 */
uint32_t esp; /* Offset 28 */
uint32_t ebp; /* Offset 32 */
uint32_t esi; /* Offset 36 */
uint32_t edi; /* Offset 40 */
uint16_t ip; /* Offset 44 */
uint16_t cs; /* Offset 46 */
} syslinux_rm_regs;
typedef struct {
uint32_t dest;
uint32_t src;

View File

@ -53,6 +53,14 @@ static char __data16_array ( syslinux_configuration_file, [] ) = "";
static uint8_t __data16 ( comboot_feature_flags ) = COMBOOT_FEATURE_IDLE_LOOP;
#define comboot_feature_flags __use_data16 ( comboot_feature_flags )
typedef union {
syslinux_pm_regs pm; syslinux_rm_regs rm;
} syslinux_regs;
/** Initial register values for INT 22h AX=1Ah and 1Bh */
static syslinux_regs __text16 ( comboot_initial_regs );
#define comboot_initial_regs __use_text16 ( comboot_initial_regs )
static struct segoff __text16 ( int20_vector );
#define int20_vector __use_text16 ( int20_vector )
@ -316,7 +324,7 @@ static __asmcall void int22 ( struct i386_all_regs *ix86 ) {
case 0x0001: /* Get Version */
/* Number of INT 22h API functions available */
ix86->regs.ax = 0x0018;
ix86->regs.ax = 0x001B;
/* SYSLINUX version number */
ix86->regs.ch = 0; /* major */
@ -569,6 +577,58 @@ static __asmcall void int22 ( struct i386_all_regs *ix86 ) {
ix86->flags &= ~CF;
break;
case 0x001B: /* Cleanup, shuffle and boot to real mode */
if ( ix86->regs.cx > COMBOOT_MAX_SHUFFLE_DESCRIPTORS )
break;
/* Perform final cleanup */
shutdown ( SHUTDOWN_BOOT );
/* Perform sequence of copies */
shuffle ( ix86->segs.es, ix86->regs.di, ix86->regs.cx );
/* Copy initial register values to .text16 */
memcpy_user ( real_to_user ( rm_cs, (unsigned) __from_text16 ( &comboot_initial_regs ) ), 0,
real_to_user ( ix86->segs.ds, ix86->regs.si ), 0,
sizeof(syslinux_rm_regs) );
/* Load initial register values */
__asm__ __volatile__ (
REAL_CODE (
/* Point SS:SP at the register value structure */
"pushw %%cs\n\t"
"popw %%ss\n\t"
"movw $comboot_initial_regs, %%sp\n\t"
/* Segment registers */
"popw %%es\n\t"
"popw %%ax\n\t" /* Skip CS */
"popw %%ds\n\t"
"popw %%ax\n\t" /* Skip SS for now */
"popw %%fs\n\t"
"popw %%gs\n\t"
/* GP registers */
"popl %%eax\n\t"
"popl %%ecx\n\t"
"popl %%edx\n\t"
"popl %%ebx\n\t"
"popl %%ebp\n\t" /* Skip ESP for now */
"popl %%ebp\n\t"
"popl %%esi\n\t"
"popl %%edi\n\t"
/* Load correct SS:ESP */
"movw $(comboot_initial_regs + 6), %%sp\n\t"
"popw %%ss\n\t"
"movl %%cs:(comboot_initial_regs + 28), %%esp\n\t"
"ljmp *%%cs:(comboot_initial_regs + 44)\n\t"
)
: : );
break;
default:
DBG ( "COMBOOT unknown int22 function %04x\n", ix86->regs.ax );
break;