summaryrefslogtreecommitdiffstats
path: root/qemu/roms/ipxe/src/arch/i386/transitions
diff options
context:
space:
mode:
authorRajithaY <rajithax.yerrumsetty@intel.com>2017-04-25 03:31:15 -0700
committerRajitha Yerrumchetty <rajithax.yerrumsetty@intel.com>2017-05-22 06:48:08 +0000
commitbb756eebdac6fd24e8919e2c43f7d2c8c4091f59 (patch)
treeca11e03542edf2d8f631efeca5e1626d211107e3 /qemu/roms/ipxe/src/arch/i386/transitions
parenta14b48d18a9ed03ec191cf16b162206998a895ce (diff)
Adding qemu as a submodule of KVMFORNFV
This Patch includes the changes to add qemu as a submodule to kvmfornfv repo and make use of the updated latest qemu for the execution of all testcase Change-Id: I1280af507a857675c7f81d30c95255635667bdd7 Signed-off-by:RajithaY<rajithax.yerrumsetty@intel.com>
Diffstat (limited to 'qemu/roms/ipxe/src/arch/i386/transitions')
-rw-r--r--qemu/roms/ipxe/src/arch/i386/transitions/liba20.S313
-rw-r--r--qemu/roms/ipxe/src/arch/i386/transitions/libkir.S256
-rw-r--r--qemu/roms/ipxe/src/arch/i386/transitions/libpm.S0
-rw-r--r--qemu/roms/ipxe/src/arch/i386/transitions/librm.S671
-rw-r--r--qemu/roms/ipxe/src/arch/i386/transitions/librm_mgmt.c158
-rw-r--r--qemu/roms/ipxe/src/arch/i386/transitions/librm_test.c122
6 files changed, 0 insertions, 1520 deletions
diff --git a/qemu/roms/ipxe/src/arch/i386/transitions/liba20.S b/qemu/roms/ipxe/src/arch/i386/transitions/liba20.S
deleted file mode 100644
index 6c1e1f62f..000000000
--- a/qemu/roms/ipxe/src/arch/i386/transitions/liba20.S
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * Copyright (C) 2010 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
-
- .arch i386
-
-/****************************************************************************
- * test_a20_short, test_a20_long
- *
- * Check to see if A20 line is enabled
- *
- * Parameters:
- * none
- * Returns:
- * CF set if A20 line is not enabled
- * Corrupts:
- * none
- ****************************************************************************
- */
-#define TEST_A20_SHORT_MAX_RETRIES 0x20
-#define TEST_A20_LONG_MAX_RETRIES 0x200000
- .section ".text16.early", "awx", @progbits
- .code16
-test_a20_short:
- pushl %ecx
- movl $TEST_A20_SHORT_MAX_RETRIES, %ecx
- jmp 1f
- .size test_a20_short, . - test_a20_short
-test_a20_long:
- pushl %ecx
- movl $TEST_A20_LONG_MAX_RETRIES, %ecx
-1: pushw %ax
- pushw %ds
- pushw %es
-
- /* Set up segment registers for access across the 1MB boundary */
- xorw %ax, %ax
- movw %ax, %ds
- decw %ax
- movw %ax, %es
-
-2: /* Modify and check test pattern; succeed if we see a difference */
- pushfw
- cli
- xchgw %ds:0, %cx
- movw %es:0x10, %ax
- xchgw %ds:0, %cx
- popfw
- cmpw %ax, %cx
- clc
- jnz 99f
-
- /* Delay and retry */
- outb %al, $0x80
- addr32 loop 2b
- stc
-
-99: /* Restore registers and return */
- popw %es
- popw %ds
- popw %ax
- popl %ecx
- ret
- .size test_a20_long, . - test_a20_long
-
-/****************************************************************************
- * enable_a20_bios
- *
- * Try enabling A20 line via BIOS
- *
- * Parameters:
- * none
- * Returns:
- * CF set if A20 line is not enabled
- * Corrupts:
- * none
- ****************************************************************************
- */
- .section ".text16.early", "awx", @progbits
- .code16
-enable_a20_bios:
-
- /* Preserve registers. Be very paranoid, since some BIOSes
- * are reported to clobber %ebx
- */
- pushal
-
- /* Attempt INT 15,2401 */
- movw $0x2401, %ax
- int $0x15
- jc 99f
-
- /* Check that success was really successful */
- call test_a20_short
-
-99: /* Restore registers and return */
- popal
- ret
- .size enable_a20_bios, . - enable_a20_bios
-
-/****************************************************************************
- * enable_a20_kbc
- *
- * Try enabling A20 line via keyboard controller
- *
- * Parameters:
- * none
- * Returns:
- * CF set if A20 line is not enabled
- * Corrupts:
- * none
- ****************************************************************************
- */
-#define KC_RDWR 0x60
-#define KC_RDWR_SET_A20 0xdf
-#define KC_CMD 0x64
-#define KC_CMD_WOUT 0xd1
-#define KC_CMD_NULL 0xff
-#define KC_STATUS 0x64
-#define KC_STATUS_OBUF_FULL 0x01
-#define KC_STATUS_IBUF_FULL 0x02
-#define KC_MAX_RETRIES 100000
- .section ".text16.early", "awx", @progbits
- .code16
-enable_a20_kbc:
- /* Preserve registers */
- pushw %ax
-
- /* Try keyboard controller */
- call empty_kbc
- movb $KC_CMD_WOUT, %al
- outb %al, $KC_CMD
- call empty_kbc
- movb $KC_RDWR_SET_A20, %al
- outb %al, $KC_RDWR
- call empty_kbc
- movb $KC_CMD_NULL, %al
- outb %al, $KC_CMD
- call empty_kbc
-
- /* Check to see if it worked */
- call test_a20_long
-
- /* Restore registers and return */
- popw %ax
- ret
- .size enable_a20_kbc, . - enable_a20_kbc
-
- .section ".text16.early", "awx", @progbits
- .code16
-empty_kbc:
- /* Preserve registers */
- pushl %ecx
- pushw %ax
-
- /* Wait for KBC to become empty */
- movl $KC_MAX_RETRIES, %ecx
-1: outb %al, $0x80
- inb $KC_STATUS, %al
- testb $( KC_STATUS_OBUF_FULL | KC_STATUS_IBUF_FULL ), %al
- jz 99f
- testb $KC_STATUS_OBUF_FULL, %al
- jz 2f
- outb %al, $0x80
- inb $KC_RDWR, %al
-2: addr32 loop 1b
-
-99: /* Restore registers and return */
- popw %ax
- popl %ecx
- ret
- .size empty_kbc, . - empty_kbc
-
-/****************************************************************************
- * enable_a20_fast
- *
- * Try enabling A20 line via "Fast Gate A20"
- *
- * Parameters:
- * none
- * Returns:
- * CF set if A20 line is not enabled
- * Corrupts:
- * none
- ****************************************************************************
- */
-#define SCP_A 0x92
- .section ".text16.early", "awx", @progbits
- .code16
-enable_a20_fast:
- /* Preserve registers */
- pushw %ax
-
- /* Try "Fast Gate A20" */
- inb $SCP_A, %al
- orb $0x02, %al
- andb $~0x01, %al
- outb %al, $SCP_A
-
- /* Check to see if it worked */
- call test_a20_long
-
- /* Restore registers and return */
- popw %ax
- ret
- .size enable_a20_fast, . - enable_a20_fast
-
-/****************************************************************************
- * enable_a20
- *
- * Try enabling A20 line via any available method
- *
- * Parameters:
- * none
- * Returns:
- * CF set if A20 line is not enabled
- * Corrupts:
- * none
- ****************************************************************************
- */
-#define ENABLE_A20_RETRIES 255
- .section ".text16.early", "awx", @progbits
- .code16
- .globl enable_a20
-enable_a20:
- /* Preserve registers */
- pushl %ecx
- pushw %ax
-
- /* Check to see if A20 is already enabled */
- call test_a20_short
- jnc 99f
-
- /* Use known working method, if we have one */
- movw %cs:enable_a20_method, %ax
- testw %ax, %ax
- jz 1f
- call *%ax
- jmp 99f
-1:
- /* Try all methods in turn until one works */
- movl $ENABLE_A20_RETRIES, %ecx
-2: movw $enable_a20_bios, %ax
- movw %ax, %cs:enable_a20_method
- call *%ax
- jnc 99f
- movw $enable_a20_kbc, %ax
- movw %ax, %cs:enable_a20_method
- call *%ax
- jnc 99f
- movw $enable_a20_fast, %ax
- movw %ax, %cs:enable_a20_method
- call *%ax
- jnc 99f
- addr32 loop 2b
- /* Failure; exit with carry set */
- movw $0, %cs:enable_a20_method
- stc
-
-99: /* Restore registers and return */
- popw %ax
- popl %ecx
- ret
-
- .section ".text16.early.data", "aw", @progbits
- .align 2
-enable_a20_method:
- .word 0
- .size enable_a20_method, . - enable_a20_method
-
-/****************************************************************************
- * access_highmem (real mode far call)
- *
- * Open up access to high memory with A20 enabled
- *
- * Parameters:
- * none
- * Returns:
- * CF set if high memory could not be accessed
- * Corrupts:
- * none
- ****************************************************************************
- */
- .section ".text16.early", "awx", @progbits
- .code16
- .globl access_highmem
-access_highmem:
- /* Enable A20 line */
- call enable_a20
- lret
- .size access_highmem, . - access_highmem
diff --git a/qemu/roms/ipxe/src/arch/i386/transitions/libkir.S b/qemu/roms/ipxe/src/arch/i386/transitions/libkir.S
deleted file mode 100644
index fa9459d52..000000000
--- a/qemu/roms/ipxe/src/arch/i386/transitions/libkir.S
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * libkir: a transition library for -DKEEP_IT_REAL
- *
- * Michael Brown <mbrown@fensystems.co.uk>
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
-
-/****************************************************************************
- * This file defines libkir: an interface between external and
- * internal environments when -DKEEP_IT_REAL is used, so that both
- * internal and external environments are in real mode. It deals with
- * switching data segments and the stack. It provides the following
- * functions:
- *
- * ext_to_kir & switch between external and internal (kir)
- * kir_to_ext environments, preserving all non-segment
- * registers
- *
- * kir_call issue a call to an internal routine from external
- * code
- *
- * libkir is written to avoid assuming that segments are anything
- * other than opaque data types, and also avoids assuming that the
- * stack pointer is 16-bit. This should enable it to run just as well
- * in 16:16 or 16:32 protected mode as in real mode.
- ****************************************************************************
- */
-
-/* Breakpoint for when debugging under bochs */
-#define BOCHSBP xchgw %bx, %bx
-
- .text
- .arch i386
- .section ".text16", "awx", @progbits
- .code16
-
-/****************************************************************************
- * init_libkir (real-mode or 16:xx protected-mode far call)
- *
- * Initialise libkir ready for transitions to the kir environment
- *
- * Parameters:
- * %cs : .text16 segment
- * %ds : .data16 segment
- ****************************************************************************
- */
- .globl init_libkir
-init_libkir:
- /* Record segment registers */
- pushw %ds
- popw %cs:kir_ds
- lret
-
-/****************************************************************************
- * ext_to_kir (real-mode or 16:xx protected-mode near call)
- *
- * Switch from external stack and segment registers to internal stack
- * and segment registers. %ss:sp is restored from the saved kir_ds
- * and kir_sp. %ds, %es, %fs and %gs are all restored from the saved
- * kir_ds. All other registers are preserved.
- *
- * %cs:0000 must point to the start of the runtime image code segment
- * on entry.
- *
- * Parameters: none
- ****************************************************************************
- */
-
- .globl ext_to_kir
-ext_to_kir:
- /* Record external segment registers */
- movw %ds, %cs:ext_ds
- pushw %cs
- popw %ds /* Set %ds = %cs for easier access to variables */
- movw %es, %ds:ext_es
- movw %fs, %ds:ext_fs
- movw %gs, %ds:ext_fs
-
- /* Preserve registers */
- movw %ax, %ds:save_ax
-
- /* Extract near return address from stack */
- popw %ds:save_retaddr
-
- /* Record external %ss:esp */
- movw %ss, %ds:ext_ss
- movl %esp, %ds:ext_esp
-
- /* Load internal segment registers and stack pointer */
- movw %ds:kir_ds, %ax
- movw %ax, %ss
- movzwl %ds:kir_sp, %esp
- movw %ax, %ds
- movw %ax, %es
- movw %ax, %fs
- movw %ax, %gs
-1:
-
- /* Place return address on new stack */
- pushw %cs:save_retaddr
-
- /* Restore registers and return */
- movw %cs:save_ax, %ax
- ret
-
-/****************************************************************************
- * kir_to_ext (real-mode or 16:xx protected-mode near call)
- *
- * Switch from internal stack and segment registers to external stack
- * and segment registers. %ss:%esp is restored from the saved ext_ss
- * and ext_esp. Other segment registers are restored from the
- * corresponding locations. All other registers are preserved.
- *
- * Note that it is actually %ss that is recorded as kir_ds, on the
- * assumption that %ss == %ds when kir_to_ext is called.
- *
- * Parameters: none
- ****************************************************************************
- */
-
- .globl kir_to_ext
-kir_to_ext:
- /* Record near return address */
- pushw %cs
- popw %ds /* Set %ds = %cs for easier access to variables */
- popw %ds:save_retaddr
-
- /* Record internal segment registers and %sp */
- movw %ss, %ds:kir_ds
- movw %sp, %ds:kir_sp
-
- /* Load external segment registers and stack pointer */
- movw %ds:ext_ss, %ss
- movl %ds:ext_esp, %esp
- movw %ds:ext_gs, %gs
- movw %ds:ext_fs, %fs
- movw %ds:ext_es, %es
- movw %ds:ext_ds, %ds
-
- /* Return */
- pushw %cs:save_retaddr
- ret
-
-/****************************************************************************
- * kir_call (real-mode or 16:xx protected-mode far call)
- *
- * Call a specific C function in the internal code. The prototype of
- * the C function must be
- * void function ( struct i386_all_resg *ix86 );
- * ix86 will point to a struct containing the real-mode registers
- * at entry to kir_call.
- *
- * All registers will be preserved across kir_call(), unless the C
- * function explicitly overwrites values in ix86. Interrupt status
- * will also be preserved.
- *
- * Parameters:
- * function : (32-bit) virtual address of C function to call
- *
- * Example usage:
- * pushl $pxe_api_call
- * lcall $UNDI_CS, $kir_call
- * addw $4, %sp
- * to call in to the C function
- * void pxe_api_call ( struct i386_all_regs *ix86 );
- ****************************************************************************
- */
-
- .globl kir_call
-kir_call:
- /* Preserve flags. Must do this before any operation that may
- * affect flags.
- */
- pushfl
- popl %cs:save_flags
-
- /* Disable interrupts. We do funny things with the stack, and
- * we're not re-entrant.
- */
- cli
-
- /* Extract address of internal routine from stack. We must do
- * this without using (%bp), because we may be called with
- * either a 16-bit or a 32-bit stack segment.
- */
- popl %cs:save_retaddr /* Scratch location */
- popl %cs:save_function
- subl $8, %esp /* Restore %esp */
-
- /* Switch to internal stack. Note that the external stack is
- * inaccessible once we're running internally (since we have
- * no concept of 48-bit far pointers)
- */
- call ext_to_kir
-
- /* Store external registers on internal stack */
- pushl %cs:save_flags
- pushal
- pushl %cs:ext_fs_and_gs
- pushl %cs:ext_ds_and_es
- pushl %cs:ext_cs_and_ss
-
- /* Push &ix86 on stack and call function */
- sti
- pushl %esp
- data32 call *%cs:save_function
- popl %eax /* discard */
-
- /* Restore external registers from internal stack */
- popl %cs:ext_cs_and_ss
- popl %cs:ext_ds_and_es
- popl %cs:ext_fs_and_gs
- popal
- popl %cs:save_flags
-
- /* Switch to external stack */
- call kir_to_ext
-
- /* Restore flags */
- pushl %cs:save_flags
- popfl
-
- /* Return */
- lret
-
-/****************************************************************************
- * Stored internal and external stack and segment registers
- ****************************************************************************
- */
-
-ext_cs_and_ss:
-ext_cs: .word 0
-ext_ss: .word 0
-ext_ds_and_es:
-ext_ds: .word 0
-ext_es: .word 0
-ext_fs_and_gs:
-ext_fs: .word 0
-ext_gs: .word 0
-ext_esp: .long 0
-
- .globl kir_ds
-kir_ds: .word 0
- .globl kir_sp
-kir_sp: .word _estack
-
-/****************************************************************************
- * Temporary variables
- ****************************************************************************
- */
-save_ax: .word 0
-save_retaddr: .long 0
-save_flags: .long 0
-save_function: .long 0
diff --git a/qemu/roms/ipxe/src/arch/i386/transitions/libpm.S b/qemu/roms/ipxe/src/arch/i386/transitions/libpm.S
deleted file mode 100644
index e69de29bb..000000000
--- a/qemu/roms/ipxe/src/arch/i386/transitions/libpm.S
+++ /dev/null
diff --git a/qemu/roms/ipxe/src/arch/i386/transitions/librm.S b/qemu/roms/ipxe/src/arch/i386/transitions/librm.S
deleted file mode 100644
index 863e22415..000000000
--- a/qemu/roms/ipxe/src/arch/i386/transitions/librm.S
+++ /dev/null
@@ -1,671 +0,0 @@
-/*
- * librm: a library for interfacing to real-mode code
- *
- * Michael Brown <mbrown@fensystems.co.uk>
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
-
-/* Drag in local definitions */
-#include "librm.h"
-
-/* For switches to/from protected mode */
-#define CR0_PE 1
-
-/* Size of various C data structures */
-#define SIZEOF_I386_SEG_REGS 12
-#define SIZEOF_I386_REGS 32
-#define SIZEOF_REAL_MODE_REGS ( SIZEOF_I386_SEG_REGS + SIZEOF_I386_REGS )
-#define SIZEOF_I386_FLAGS 4
-#define SIZEOF_I386_ALL_REGS ( SIZEOF_REAL_MODE_REGS + SIZEOF_I386_FLAGS )
-
- .arch i386
-
-/****************************************************************************
- * Global descriptor table
- *
- * Call init_librm to set up the GDT before attempting to use any
- * protected-mode code.
- *
- * NOTE: This must be located before prot_to_real, otherwise gas
- * throws a "can't handle non absolute segment in `ljmp'" error due to
- * not knowing the value of REAL_CS when the ljmp is encountered.
- *
- * Note also that putting ".word gdt_end - gdt - 1" directly into
- * gdt_limit, rather than going via gdt_length, will also produce the
- * "non absolute segment" error. This is most probably a bug in gas.
- ****************************************************************************
- */
- .section ".data16", "aw", @progbits
- .align 16
-gdt:
-gdtr: /* The first GDT entry is unused, the GDTR can fit here. */
-gdt_limit: .word gdt_length - 1
-gdt_base: .long 0
- .word 0 /* padding */
-
- .org gdt + VIRTUAL_CS, 0
-virtual_cs: /* 32 bit protected mode code segment, virtual addresses */
- .word 0xffff, 0
- .byte 0, 0x9f, 0xcf, 0
-
- .org gdt + VIRTUAL_DS, 0
-virtual_ds: /* 32 bit protected mode data segment, virtual addresses */
- .word 0xffff, 0
- .byte 0, 0x93, 0xcf, 0
-
- .org gdt + PHYSICAL_CS, 0
-physical_cs: /* 32 bit protected mode code segment, physical addresses */
- .word 0xffff, 0
- .byte 0, 0x9f, 0xcf, 0
-
- .org gdt + PHYSICAL_DS, 0
-physical_ds: /* 32 bit protected mode data segment, physical addresses */
- .word 0xffff, 0
- .byte 0, 0x93, 0xcf, 0
-
- .org gdt + REAL_CS, 0
-real_cs: /* 16 bit real mode code segment */
- .word 0xffff, 0
- .byte 0, 0x9b, 0x00, 0
-
- .org gdt + REAL_DS
-real_ds: /* 16 bit real mode data segment */
- .word 0xffff, ( REAL_DS << 4 )
- .byte 0, 0x93, 0x00, 0
-
-gdt_end:
- .equ gdt_length, gdt_end - gdt
-
-/****************************************************************************
- * init_librm (real-mode far call, 16-bit real-mode far return address)
- *
- * Initialise the GDT ready for transitions to protected mode.
- *
- * Parameters:
- * %cs : .text16 segment
- * %ds : .data16 segment
- * %edi : Physical base of protected-mode code (virt_offset)
- ****************************************************************************
- */
- .section ".text16", "ax", @progbits
- .code16
- .globl init_librm
-init_librm:
- /* Preserve registers */
- pushl %eax
- pushl %ebx
-
- /* Store virt_offset and set up virtual_cs and virtual_ds segments */
- movl %edi, %eax
- movw $virtual_cs, %bx
- call set_seg_base
- movw $virtual_ds, %bx
- call set_seg_base
- movl %edi, rm_virt_offset
-
- /* Negate virt_offset */
- negl %edi
-
- /* Store rm_cs and text16, set up real_cs segment */
- xorl %eax, %eax
- movw %cs, %ax
- movw %ax, %cs:rm_cs
- shll $4, %eax
- movw $real_cs, %bx
- call set_seg_base
- addr32 leal (%eax, %edi), %ebx
- movl %ebx, rm_text16
-
- /* Store rm_ds and data16 */
- xorl %eax, %eax
- movw %ds, %ax
- movw %ax, %cs:rm_ds
- shll $4, %eax
- addr32 leal (%eax, %edi), %ebx
- movl %ebx, rm_data16
-
- /* Set GDT base */
- movl %eax, gdt_base
- addl $gdt, gdt_base
-
- /* Initialise IDT */
- pushl $init_idt
- pushw %cs
- call prot_call
- popl %eax /* discard */
-
- /* Restore registers */
- negl %edi
- popl %ebx
- popl %eax
- lret
-
- .section ".text16", "ax", @progbits
- .code16
-set_seg_base:
-1: movw %ax, 2(%bx)
- rorl $16, %eax
- movb %al, 4(%bx)
- movb %ah, 7(%bx)
- roll $16, %eax
- ret
-
-/****************************************************************************
- * real_to_prot (real-mode near call, 32-bit virtual return address)
- *
- * Switch from 16-bit real-mode to 32-bit protected mode with virtual
- * addresses. The real-mode %ss:sp is stored in rm_ss and rm_sp, and
- * the protected-mode %esp is restored from the saved pm_esp.
- * Interrupts are disabled. All other registers may be destroyed.
- *
- * The return address for this function should be a 32-bit virtual
- * address.
- *
- * Parameters:
- * %ecx : number of bytes to move from RM stack to PM stack
- *
- ****************************************************************************
- */
- .section ".text16", "ax", @progbits
- .code16
-real_to_prot:
- /* Enable A20 line */
- call enable_a20
- /* A failure at this point is fatal, and there's nothing we
- * can do about it other than lock the machine to make the
- * problem immediately visible.
- */
-1: jc 1b
-
- /* Make sure we have our data segment available */
- movw %cs:rm_ds, %ax
- movw %ax, %ds
-
- /* Add virt_offset, text16 and data16 to stack to be
- * copied, and also copy the return address.
- */
- pushl rm_virt_offset
- pushl rm_text16
- pushl rm_data16
- addw $16, %cx /* %ecx must be less than 64kB anyway */
-
- /* Real-mode %ss:%sp => %ebp:%edx and virtual address => %esi */
- xorl %ebp, %ebp
- movw %ss, %bp
- movzwl %sp, %edx
- movl %ebp, %eax
- shll $4, %eax
- addr32 leal (%eax,%edx), %esi
- subl rm_virt_offset, %esi
-
- /* Load protected-mode global descriptor table */
- data32 lgdt gdtr
-
- /* Zero segment registers. This wastes around 12 cycles on
- * real hardware, but saves a substantial number of emulated
- * instructions under KVM.
- */
- xorw %ax, %ax
- movw %ax, %ds
- movw %ax, %es
- movw %ax, %fs
- movw %ax, %gs
- movw %ax, %ss
-
- /* Switch to protected mode */
- cli
- movl %cr0, %eax
- orb $CR0_PE, %al
- movl %eax, %cr0
- data32 ljmp $VIRTUAL_CS, $r2p_pmode
- .section ".text", "ax", @progbits
- .code32
-r2p_pmode:
- /* Set up protected-mode data segments and stack pointer */
- movw $VIRTUAL_DS, %ax
- movw %ax, %ds
- movw %ax, %es
- movw %ax, %fs
- movw %ax, %gs
- movw %ax, %ss
- movl pm_esp, %esp
-
- /* Load protected-mode interrupt descriptor table */
- lidt idtr
-
- /* Record real-mode %ss:sp (after removal of data) */
- movw %bp, rm_ss
- addl %ecx, %edx
- movw %dx, rm_sp
-
- /* Move data from RM stack to PM stack */
- subl %ecx, %esp
- movl %esp, %edi
- rep movsb
-
- /* Publish virt_offset, text16 and data16 for PM code to use */
- popl data16
- popl text16
- popl virt_offset
-
- /* Return to virtual address */
- ret
-
-/****************************************************************************
- * prot_to_real (protected-mode near call, 32-bit real-mode return address)
- *
- * Switch from 32-bit protected mode with virtual addresses to 16-bit
- * real mode. The protected-mode %esp is stored in pm_esp and the
- * real-mode %ss:sp is restored from the saved rm_ss and rm_sp. The
- * high word of the real-mode %esp is set to zero. All real-mode data
- * segment registers are loaded from the saved rm_ds. Interrupts are
- * *not* enabled, since we want to be able to use prot_to_real in an
- * ISR. All other registers may be destroyed.
- *
- * The return address for this function should be a 32-bit (sic)
- * real-mode offset within .code16.
- *
- * Parameters:
- * %ecx : number of bytes to move from PM stack to RM stack
- * %esi : real-mode global and interrupt descriptor table registers
- *
- ****************************************************************************
- */
- .section ".text", "ax", @progbits
- .code32
-prot_to_real:
- /* Copy real-mode global descriptor table register to RM code segment */
- movl text16, %edi
- leal rm_gdtr(%edi), %edi
- movsw
- movsl
-
- /* Load real-mode interrupt descriptor table register */
- lidt (%esi)
-
- /* Add return address to data to be moved to RM stack */
- addl $4, %ecx
-
- /* Real-mode %ss:sp => %ebp:edx and virtual address => %edi */
- movzwl rm_ss, %ebp
- movzwl rm_sp, %edx
- subl %ecx, %edx
- movl %ebp, %eax
- shll $4, %eax
- leal (%eax,%edx), %edi
- subl virt_offset, %edi
-
- /* Move data from PM stack to RM stack */
- movl %esp, %esi
- rep movsb
-
- /* Record protected-mode %esp (after removal of data) */
- movl %esi, pm_esp
-
- /* Load real-mode segment limits */
- movw $REAL_DS, %ax
- movw %ax, %ds
- movw %ax, %es
- movw %ax, %fs
- movw %ax, %gs
- movw %ax, %ss
- ljmp $REAL_CS, $p2r_rmode
- .section ".text16", "ax", @progbits
- .code16
-p2r_rmode:
- /* Load real-mode GDT */
- data32 lgdt %cs:rm_gdtr
- /* Switch to real mode */
- movl %cr0, %eax
- andb $0!CR0_PE, %al
- movl %eax, %cr0
-p2r_ljmp_rm_cs:
- ljmp $0, $1f
-1:
- /* Set up real-mode data segments and stack pointer */
- movw %cs:rm_ds, %ax
- movw %ax, %ds
- movw %ax, %es
- movw %ax, %fs
- movw %ax, %gs
- movw %bp, %ss
- movl %edx, %esp
-
- /* Return to real-mode address */
- data32 ret
-
-
- /* Real-mode code and data segments. Assigned by the call to
- * init_librm. rm_cs doubles as the segment part of the jump
- * instruction used by prot_to_real. Both are located in
- * .text16 rather than .data16: rm_cs since it forms part of
- * the jump instruction within the code segment, and rm_ds
- * since real-mode code needs to be able to locate the data
- * segment with no other reference available.
- */
- .globl rm_cs
- .equ rm_cs, ( p2r_ljmp_rm_cs + 3 )
-
- .section ".text16.data", "aw", @progbits
- .globl rm_ds
-rm_ds: .word 0
-
- /* Real-mode global and interrupt descriptor table registers */
- .section ".text16.data", "aw", @progbits
-rm_gdtr:
- .word 0 /* Limit */
- .long 0 /* Base */
-
-/****************************************************************************
- * prot_call (real-mode far call, 16-bit real-mode far return address)
- *
- * Call a specific C function in the protected-mode code. The
- * prototype of the C function must be
- * void function ( struct i386_all_regs *ix86 );
- * ix86 will point to a struct containing the real-mode registers
- * at entry to prot_call.
- *
- * All registers will be preserved across prot_call(), unless the C
- * function explicitly overwrites values in ix86. Interrupt status
- * and GDT will also be preserved. Gate A20 will be enabled.
- *
- * Note that prot_call() does not rely on the real-mode stack
- * remaining intact in order to return, since everything relevant is
- * copied to the protected-mode stack for the duration of the call.
- * In particular, this means that a real-mode prefix can make a call
- * to main() which will return correctly even if the prefix's stack
- * gets vapourised during the Etherboot run. (The prefix cannot rely
- * on anything else on the stack being preserved, so should move any
- * critical data to registers before calling main()).
- *
- * Parameters:
- * function : virtual address of protected-mode function to call
- *
- * Example usage:
- * pushl $pxe_api_call
- * call prot_call
- * addw $4, %sp
- * to call in to the C function
- * void pxe_api_call ( struct i386_all_regs *ix86 );
- ****************************************************************************
- */
-
-#define PC_OFFSET_GDT ( 0 )
-#define PC_OFFSET_IDT ( PC_OFFSET_GDT + 6 )
-#define PC_OFFSET_IX86 ( PC_OFFSET_IDT + 6 )
-#define PC_OFFSET_RETADDR ( PC_OFFSET_IX86 + SIZEOF_I386_ALL_REGS )
-#define PC_OFFSET_FUNCTION ( PC_OFFSET_RETADDR + 4 )
-#define PC_OFFSET_END ( PC_OFFSET_FUNCTION + 4 )
-
- .section ".text16", "ax", @progbits
- .code16
- .globl prot_call
-prot_call:
- /* Preserve registers, flags and GDT on external RM stack */
- pushfl
- pushal
- pushw %gs
- pushw %fs
- pushw %es
- pushw %ds
- pushw %ss
- pushw %cs
- subw $PC_OFFSET_IX86, %sp
- movw %sp, %bp
- sidt PC_OFFSET_IDT(%bp)
- sgdt PC_OFFSET_GDT(%bp)
-
- /* For sanity's sake, clear the direction flag as soon as possible */
- cld
-
- /* Switch to protected mode and move register dump to PM stack */
- movl $PC_OFFSET_END, %ecx
- pushl $pc_pmode
- jmp real_to_prot
- .section ".text", "ax", @progbits
- .code32
-pc_pmode:
- /* Call function */
- leal PC_OFFSET_IX86(%esp), %eax
- pushl %eax
- call *(PC_OFFSET_FUNCTION+4)(%esp)
- popl %eax /* discard */
-
- /* Switch to real mode and move register dump back to RM stack */
- movl $PC_OFFSET_END, %ecx
- movl %esp, %esi
- pushl $pc_rmode
- jmp prot_to_real
- .section ".text16", "ax", @progbits
- .code16
-pc_rmode:
- /* Restore registers and flags and return */
- addw $( PC_OFFSET_IX86 + 4 /* also skip %cs and %ss */ ), %sp
- popw %ds
- popw %es
- popw %fs
- popw %gs
- popal
- /* popal skips %esp. We therefore want to do "movl -20(%sp),
- * %esp", but -20(%sp) is not a valid 80386 expression.
- * Fortunately, prot_to_real() zeroes the high word of %esp, so
- * we can just use -20(%esp) instead.
- */
- addr32 movl -20(%esp), %esp
- popfl
- lret
-
-/****************************************************************************
- * real_call (protected-mode near call, 32-bit virtual return address)
- *
- * Call a real-mode function from protected-mode code.
- *
- * The non-segment register values will be passed directly to the
- * real-mode code. The segment registers will be set as per
- * prot_to_real. The non-segment register values set by the real-mode
- * function will be passed back to the protected-mode caller. A
- * result of this is that this routine cannot be called directly from
- * C code, since it clobbers registers that the C ABI expects the
- * callee to preserve.
- *
- * librm.h defines a convenient macro REAL_CODE() for using real_call.
- * See librm.h and realmode.h for details and examples.
- *
- * Parameters:
- * (32-bit) near pointer to real-mode function to call
- *
- * Returns: none
- ****************************************************************************
- */
-
-#define RC_OFFSET_PRESERVE_REGS ( 0 )
-#define RC_OFFSET_RETADDR ( RC_OFFSET_PRESERVE_REGS + SIZEOF_I386_REGS )
-#define RC_OFFSET_FUNCTION ( RC_OFFSET_RETADDR + 4 )
-#define RC_OFFSET_END ( RC_OFFSET_FUNCTION + 4 )
-
- .section ".text", "ax", @progbits
- .code32
- .globl real_call
-real_call:
- /* Create register dump and function pointer copy on PM stack */
- pushal
- pushl RC_OFFSET_FUNCTION(%esp)
-
- /* Switch to real mode and move register dump to RM stack */
- movl $( RC_OFFSET_RETADDR + 4 /* function pointer copy */ ), %ecx
- pushl $rc_rmode
- movl $rm_default_gdtr_idtr, %esi
- jmp prot_to_real
- .section ".text16", "ax", @progbits
- .code16
-rc_rmode:
- /* Call real-mode function */
- popl rc_function
- popal
- call *rc_function
- pushal
-
- /* For sanity's sake, clear the direction flag as soon as possible */
- cld
-
- /* Switch to protected mode and move register dump back to PM stack */
- movl $RC_OFFSET_RETADDR, %ecx
- pushl $rc_pmode
- jmp real_to_prot
- .section ".text", "ax", @progbits
- .code32
-rc_pmode:
- /* Restore registers and return */
- popal
- ret
-
-
- /* Function vector, used because "call xx(%sp)" is not a valid
- * 16-bit expression.
- */
- .section ".data16", "aw", @progbits
-rc_function: .word 0, 0
-
- /* Default real-mode global and interrupt descriptor table registers */
- .section ".data", "aw", @progbits
-rm_default_gdtr_idtr:
- .word 0 /* Global descriptor table limit */
- .long 0 /* Global descriptor table base */
- .word 0x03ff /* Interrupt descriptor table limit */
- .long 0 /* Interrupt descriptor table base */
-
-/****************************************************************************
- * flatten_real_mode (real-mode near call)
- *
- * Switch to flat real mode
- *
- ****************************************************************************
- */
- .section ".text16", "ax", @progbits
- .code16
- .globl flatten_real_mode
-flatten_real_mode:
- /* Modify GDT to use flat real mode */
- movb $0x8f, real_cs + 6
- movb $0x8f, real_ds + 6
- /* Call dummy protected-mode function */
- pushl $flatten_dummy
- pushw %cs
- call prot_call
- addw $4, %sp
- /* Restore GDT */
- movb $0x00, real_cs + 6
- movb $0x00, real_ds + 6
- /* Return */
- ret
-
- .section ".text", "ax", @progbits
- .code32
-flatten_dummy:
- ret
-
-/****************************************************************************
- * Interrupt wrapper
- *
- * Used by the protected-mode interrupt vectors to call the
- * interrupt() function.
- *
- * May be entered with either physical or virtual stack segment.
- ****************************************************************************
- */
- .globl interrupt_wrapper
-interrupt_wrapper:
- /* Preserve segment registers and original %esp */
- pushl %ds
- pushl %es
- pushl %fs
- pushl %gs
- pushl %ss
- pushl %esp
-
- /* Switch to virtual addressing */
- call _intr_to_virt
-
- /* Expand IRQ number to whole %eax register */
- movzbl %al, %eax
-
- /* Call interrupt handler */
- call interrupt
-
- /* Restore original stack and segment registers */
- lss (%esp), %esp
- popl %ss
- popl %gs
- popl %fs
- popl %es
- popl %ds
-
- /* Restore registers and return */
- popal
- iret
-
-/****************************************************************************
- * Stored real-mode and protected-mode stack pointers
- *
- * The real-mode stack pointer is stored here whenever real_to_prot
- * is called and restored whenever prot_to_real is called. The
- * converse happens for the protected-mode stack pointer.
- *
- * Despite initial appearances this scheme is, in fact re-entrant,
- * because program flow dictates that we always return via the point
- * we left by. For example:
- * PXE API call entry
- * 1 real => prot
- * ...
- * Print a text string
- * ...
- * 2 prot => real
- * INT 10
- * 3 real => prot
- * ...
- * ...
- * 4 prot => real
- * PXE API call exit
- *
- * At point 1, the RM mode stack value, say RPXE, is stored in
- * rm_ss,sp. We want this value to still be present in rm_ss,sp when
- * we reach point 4.
- *
- * At point 2, the RM stack value is restored from RPXE. At point 3,
- * the RM stack value is again stored in rm_ss,sp. This *does*
- * overwrite the RPXE that we have stored there, but it's the same
- * value, since the code between points 2 and 3 has managed to return
- * to us.
- ****************************************************************************
- */
- .section ".data", "aw", @progbits
- .globl rm_sp
-rm_sp: .word 0
- .globl rm_ss
-rm_ss: .word 0
-pm_esp: .long _estack
-
-/****************************************************************************
- * Virtual address offsets
- *
- * These are used by the protected-mode code to map between virtual
- * and physical addresses, and to access variables in the .text16 or
- * .data16 segments.
- ****************************************************************************
- */
- /* Internal copies, created by init_librm (which runs in real mode) */
- .section ".data16", "aw", @progbits
-rm_virt_offset: .long 0
-rm_text16: .long 0
-rm_data16: .long 0
-
- /* Externally-visible copies, created by real_to_prot */
- .section ".data", "aw", @progbits
- .globl virt_offset
-virt_offset: .long 0
- .globl text16
-text16: .long 0
- .globl data16
-data16: .long 0
diff --git a/qemu/roms/ipxe/src/arch/i386/transitions/librm_mgmt.c b/qemu/roms/ipxe/src/arch/i386/transitions/librm_mgmt.c
deleted file mode 100644
index becb02677..000000000
--- a/qemu/roms/ipxe/src/arch/i386/transitions/librm_mgmt.c
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * librm: a library for interfacing to real-mode code
- *
- * Michael Brown <mbrown@fensystems.co.uk>
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdint.h>
-#include <ipxe/profile.h>
-#include <realmode.h>
-#include <pic8259.h>
-
-/*
- * This file provides functions for managing librm.
- *
- */
-
-/** The interrupt wrapper */
-extern char interrupt_wrapper[];
-
-/** The interrupt vectors */
-static struct interrupt_vector intr_vec[NUM_INT];
-
-/** The interrupt descriptor table */
-struct interrupt_descriptor idt[NUM_INT] __attribute__ (( aligned ( 16 ) ));
-
-/** The interrupt descriptor table register */
-struct idtr idtr = {
- .limit = ( sizeof ( idt ) - 1 ),
-};
-
-/** Timer interrupt profiler */
-static struct profiler timer_irq_profiler __profiler = { .name = "irq.timer" };
-
-/** Other interrupt profiler */
-static struct profiler other_irq_profiler __profiler = { .name = "irq.other" };
-
-/**
- * Allocate space on the real-mode stack and copy data there from a
- * user buffer
- *
- * @v data User buffer
- * @v size Size of stack data
- * @ret sp New value of real-mode stack pointer
- */
-uint16_t copy_user_to_rm_stack ( userptr_t data, size_t size ) {
- userptr_t rm_stack;
- rm_sp -= size;
- rm_stack = real_to_user ( rm_ss, rm_sp );
- memcpy_user ( rm_stack, 0, data, 0, size );
- return rm_sp;
-};
-
-/**
- * Deallocate space on the real-mode stack, optionally copying back
- * data to a user buffer.
- *
- * @v data User buffer
- * @v size Size of stack data
- */
-void remove_user_from_rm_stack ( userptr_t data, size_t size ) {
- if ( data ) {
- userptr_t rm_stack = real_to_user ( rm_ss, rm_sp );
- memcpy_user ( rm_stack, 0, data, 0, size );
- }
- rm_sp += size;
-};
-
-/**
- * Set interrupt vector
- *
- * @v intr Interrupt number
- * @v vector Interrupt vector, or NULL to disable
- */
-void set_interrupt_vector ( unsigned int intr, void *vector ) {
- struct interrupt_descriptor *idte;
-
- idte = &idt[intr];
- idte->segment = VIRTUAL_CS;
- idte->attr = ( vector ? ( IDTE_PRESENT | IDTE_TYPE_IRQ32 ) : 0 );
- idte->low = ( ( ( uint32_t ) vector ) & 0xffff );
- idte->high = ( ( ( uint32_t ) vector ) >> 16 );
-}
-
-/**
- * Initialise interrupt descriptor table
- *
- */
-void init_idt ( void ) {
- struct interrupt_vector *vec;
- unsigned int intr;
-
- /* Initialise the interrupt descriptor table and interrupt vectors */
- for ( intr = 0 ; intr < NUM_INT ; intr++ ) {
- vec = &intr_vec[intr];
- vec->pushal = PUSHAL_INSN;
- vec->movb = MOVB_INSN;
- vec->intr = intr;
- vec->jmp = JMP_INSN;
- vec->offset = ( ( uint32_t ) interrupt_wrapper -
- ( uint32_t ) vec->next );
- set_interrupt_vector ( intr, vec );
- }
- DBGC ( &intr_vec[0], "INTn vector at %p+%zxn (phys %#lx+%zxn)\n",
- intr_vec, sizeof ( intr_vec[0] ),
- virt_to_phys ( intr_vec ), sizeof ( intr_vec[0] ) );
-
- /* Initialise the interrupt descriptor table register */
- idtr.base = virt_to_phys ( idt );
-}
-
-/**
- * Determine interrupt profiler (for debugging)
- *
- * @v intr Interrupt number
- * @ret profiler Profiler
- */
-static struct profiler * interrupt_profiler ( int intr ) {
-
- switch ( intr ) {
- case IRQ_INT ( 0 ) :
- return &timer_irq_profiler;
- default:
- return &other_irq_profiler;
- }
-}
-
-/**
- * Interrupt handler
- *
- * @v intr Interrupt number
- */
-void __attribute__ (( cdecl, regparm ( 1 ) )) interrupt ( int intr ) {
- struct profiler *profiler = interrupt_profiler ( intr );
- uint32_t discard_eax;
-
- /* Reissue interrupt in real mode */
- profile_start ( profiler );
- __asm__ __volatile__ ( REAL_CODE ( "movb %%al, %%cs:(1f + 1)\n\t"
- "\n1:\n\t"
- "int $0x00\n\t" )
- : "=a" ( discard_eax ) : "0" ( intr ) );
- profile_stop ( profiler );
- profile_exclude ( profiler );
-}
-
-PROVIDE_UACCESS_INLINE ( librm, phys_to_user );
-PROVIDE_UACCESS_INLINE ( librm, user_to_phys );
-PROVIDE_UACCESS_INLINE ( librm, virt_to_user );
-PROVIDE_UACCESS_INLINE ( librm, user_to_virt );
-PROVIDE_UACCESS_INLINE ( librm, userptr_add );
-PROVIDE_UACCESS_INLINE ( librm, memcpy_user );
-PROVIDE_UACCESS_INLINE ( librm, memmove_user );
-PROVIDE_UACCESS_INLINE ( librm, memset_user );
-PROVIDE_UACCESS_INLINE ( librm, strlen_user );
-PROVIDE_UACCESS_INLINE ( librm, memchr_user );
diff --git a/qemu/roms/ipxe/src/arch/i386/transitions/librm_test.c b/qemu/roms/ipxe/src/arch/i386/transitions/librm_test.c
deleted file mode 100644
index f1a517eda..000000000
--- a/qemu/roms/ipxe/src/arch/i386/transitions/librm_test.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-/** @file
- *
- * Real mode transition self-tests
- *
- * This file allows for easy measurement of the time taken to perform
- * real mode transitions, which may have a substantial overhead when
- * running under a hypervisor.
- *
- */
-
-/* Forcibly enable assertions */
-#undef NDEBUG
-
-#include <ipxe/test.h>
-#include <ipxe/profile.h>
-#include <realmode.h>
-
-/** Number of sample iterations for profiling */
-#define PROFILE_COUNT 4096
-
-/** Protected-to-real mode transition profiler */
-static struct profiler p2r_profiler __profiler = { .name = "p2r" };
-
-/** Real-to-protected mode transition profiler */
-static struct profiler r2p_profiler __profiler = { .name = "r2p" };
-
-/** Real-mode call profiler */
-static struct profiler real_call_profiler __profiler = { .name = "real_call" };
-
-/** Protected-mode call profiler */
-static struct profiler prot_call_profiler __profiler = { .name = "prot_call" };
-
-/**
- * Dummy protected-mode function
- */
-static void librm_test_prot_call ( void ) {
- /* Do nothing */
-}
-
-/**
- * Perform real mode transition self-tests
- *
- */
-static void librm_test_exec ( void ) {
- unsigned int i;
- unsigned long timestamp;
- unsigned long started;
- unsigned long stopped;
- unsigned int discard_d;
-
- /* Profile mode transitions. We want to profile each
- * direction of the transition separately, so perform an RDTSC
- * while in real mode and tweak the profilers' start/stop
- * times appropriately.
- */
- for ( i = 0 ; i < PROFILE_COUNT ; i++ ) {
- profile_start ( &p2r_profiler );
- __asm__ __volatile__ ( REAL_CODE ( "rdtsc\n\t" )
- : "=a" ( timestamp ), "=d" ( discard_d )
- : );
- profile_start_at ( &r2p_profiler, timestamp );
- profile_stop ( &r2p_profiler );
- profile_stop_at ( &p2r_profiler, timestamp );
- }
-
- /* Profile complete real-mode call cycle */
- for ( i = 0 ; i < PROFILE_COUNT ; i++ ) {
- profile_start ( &real_call_profiler );
- __asm__ __volatile__ ( REAL_CODE ( "" ) : : );
- profile_stop ( &real_call_profiler );
- }
-
- /* Profile complete protected-mode call cycle */
- for ( i = 0 ; i < PROFILE_COUNT ; i++ ) {
- __asm__ __volatile__ ( REAL_CODE ( "rdtsc\n\t"
- "movl %0, %2\n\t"
- "pushl %3\n\t"
- "pushw %%cs\n\t"
- "call prot_call\n\t"
- "addw $4, %%sp\n\t"
- "rdtsc\n\t" )
- : "=a" ( stopped ), "=d" ( discard_d ),
- "=r" ( started )
- : "i" ( librm_test_prot_call ) );
- profile_start_at ( &prot_call_profiler, started );
- profile_stop_at ( &prot_call_profiler, stopped );
- }
-}
-
-/** Real mode transition self-test */
-struct self_test librm_test __self_test = {
- .name = "librm",
- .exec = librm_test_exec,
-};
-
-REQUIRING_SYMBOL ( librm_test );
-REQUIRE_OBJECT ( test );