mirror of
https://github.com/ipxe/ipxe
synced 2025-12-26 17:42:47 +03:00
[bios] Add bin-x86_64-pcbios build platform
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>
This commit is contained in:
119
src/arch/x86/interface/pcbios/biosint.c
Normal file
119
src/arch/x86/interface/pcbios/biosint.c
Normal file
@@ -0,0 +1,119 @@
|
||||
#include <errno.h>
|
||||
#include <realmode.h>
|
||||
#include <biosint.h>
|
||||
|
||||
/**
|
||||
* @file BIOS interrupts
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
/**
|
||||
* Hook INT vector
|
||||
*
|
||||
* @v interrupt INT number
|
||||
* @v handler Offset within .text16 to interrupt handler
|
||||
* @v chain_vector Vector for chaining to previous handler
|
||||
*
|
||||
* Hooks in an i386 INT handler. The handler itself must reside
|
||||
* within the .text16 segment. @c chain_vector will be filled in with
|
||||
* the address of the previously-installed handler for this interrupt;
|
||||
* the handler should probably exit by ljmping via this vector.
|
||||
*/
|
||||
void hook_bios_interrupt ( unsigned int interrupt, unsigned int handler,
|
||||
struct segoff *chain_vector ) {
|
||||
struct segoff vector = {
|
||||
.segment = rm_cs,
|
||||
.offset = handler,
|
||||
};
|
||||
|
||||
DBG ( "Hooking INT %#02x to %04x:%04x\n",
|
||||
interrupt, rm_cs, handler );
|
||||
|
||||
if ( ( chain_vector->segment != 0 ) ||
|
||||
( chain_vector->offset != 0 ) ) {
|
||||
/* Already hooked; do nothing */
|
||||
DBG ( "...already hooked\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
copy_from_real ( chain_vector, 0, ( interrupt * 4 ),
|
||||
sizeof ( *chain_vector ) );
|
||||
DBG ( "...chaining to %04x:%04x\n",
|
||||
chain_vector->segment, chain_vector->offset );
|
||||
if ( DBG_LOG ) {
|
||||
char code[64];
|
||||
copy_from_real ( code, chain_vector->segment,
|
||||
chain_vector->offset, sizeof ( code ) );
|
||||
DBG_HDA ( *chain_vector, code, sizeof ( code ) );
|
||||
}
|
||||
|
||||
copy_to_real ( 0, ( interrupt * 4 ), &vector, sizeof ( vector ) );
|
||||
hooked_bios_interrupts++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unhook INT vector
|
||||
*
|
||||
* @v interrupt INT number
|
||||
* @v handler Offset within .text16 to interrupt handler
|
||||
* @v chain_vector Vector containing address of previous handler
|
||||
*
|
||||
* Unhooks an i386 interrupt handler hooked by hook_i386_vector().
|
||||
* Note that this operation may fail, if some external code has hooked
|
||||
* the vector since we hooked in our handler. If it fails, it means
|
||||
* that it is not possible to unhook our handler, and we must leave it
|
||||
* (and its chaining vector) resident in memory.
|
||||
*/
|
||||
int unhook_bios_interrupt ( unsigned int interrupt, unsigned int handler,
|
||||
struct segoff *chain_vector ) {
|
||||
struct segoff vector;
|
||||
|
||||
DBG ( "Unhooking INT %#02x from %04x:%04x\n",
|
||||
interrupt, rm_cs, handler );
|
||||
|
||||
copy_from_real ( &vector, 0, ( interrupt * 4 ), sizeof ( vector ) );
|
||||
if ( ( vector.segment != rm_cs ) || ( vector.offset != handler ) ) {
|
||||
DBG ( "...cannot unhook; vector points to %04x:%04x\n",
|
||||
vector.segment, vector.offset );
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
DBG ( "...restoring to %04x:%04x\n",
|
||||
chain_vector->segment, chain_vector->offset );
|
||||
copy_to_real ( 0, ( interrupt * 4 ), chain_vector,
|
||||
sizeof ( *chain_vector ) );
|
||||
|
||||
chain_vector->segment = 0;
|
||||
chain_vector->offset = 0;
|
||||
hooked_bios_interrupts--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump changes to interrupt vector table (for debugging)
|
||||
*
|
||||
*/
|
||||
void check_bios_interrupts ( void ) {
|
||||
static struct segoff vectors[256];
|
||||
static uint8_t initialised;
|
||||
struct segoff vector;
|
||||
unsigned int i;
|
||||
|
||||
/* Print any changed interrupt vectors */
|
||||
for ( i = 0; i < ( sizeof ( vectors ) / sizeof ( vectors[0] ) ); i++ ) {
|
||||
copy_from_real ( &vector, 0, ( i * sizeof ( vector ) ),
|
||||
sizeof ( vector ) );
|
||||
if ( memcmp ( &vector, &vectors[i], sizeof ( vector ) ) == 0 )
|
||||
continue;
|
||||
if ( initialised ) {
|
||||
dbg_printf ( "INT %02x changed %04x:%04x => "
|
||||
"%04x:%04x\n", i, vectors[i].segment,
|
||||
vectors[i].offset, vector.segment,
|
||||
vector.offset );
|
||||
}
|
||||
memcpy ( &vectors[i], &vector, sizeof ( vectors[i] ) );
|
||||
}
|
||||
initialised = 1;
|
||||
}
|
||||
Reference in New Issue
Block a user