6 * @file BIOS interrupts
10 FILE_LICENCE ( GPL2_OR_LATER
);
15 * @v interrupt INT number
16 * @v handler Offset within .text16 to interrupt handler
17 * @v chain_vector Vector for chaining to previous handler
19 * Hooks in an i386 INT handler. The handler itself must reside
20 * within the .text16 segment. @c chain_vector will be filled in with
21 * the address of the previously-installed handler for this interrupt;
22 * the handler should probably exit by ljmping via this vector.
24 void hook_bios_interrupt ( unsigned int interrupt
, unsigned int handler
,
25 struct segoff
*chain_vector
) {
26 struct segoff vector
= {
31 DBG ( "Hooking INT %#02x to %04x:%04x\n",
32 interrupt
, rm_cs
, handler
);
34 if ( ( chain_vector
->segment
!= 0 ) ||
35 ( chain_vector
->offset
!= 0 ) ) {
36 /* Already hooked; do nothing */
37 DBG ( "...already hooked\n" );
41 copy_from_real ( chain_vector
, 0, ( interrupt
* 4 ),
42 sizeof ( *chain_vector
) );
43 DBG ( "...chaining to %04x:%04x\n",
44 chain_vector
->segment
, chain_vector
->offset
);
47 copy_from_real ( code
, chain_vector
->segment
,
48 chain_vector
->offset
, sizeof ( code
) );
49 DBG_HDA ( *chain_vector
, code
, sizeof ( code
) );
52 copy_to_real ( 0, ( interrupt
* 4 ), &vector
, sizeof ( vector
) );
53 hooked_bios_interrupts
++;
59 * @v interrupt INT number
60 * @v handler Offset within .text16 to interrupt handler
61 * @v chain_vector Vector containing address of previous handler
63 * Unhooks an i386 interrupt handler hooked by hook_i386_vector().
64 * Note that this operation may fail, if some external code has hooked
65 * the vector since we hooked in our handler. If it fails, it means
66 * that it is not possible to unhook our handler, and we must leave it
67 * (and its chaining vector) resident in memory.
69 int unhook_bios_interrupt ( unsigned int interrupt
, unsigned int handler
,
70 struct segoff
*chain_vector
) {
73 DBG ( "Unhooking INT %#02x from %04x:%04x\n",
74 interrupt
, rm_cs
, handler
);
76 copy_from_real ( &vector
, 0, ( interrupt
* 4 ), sizeof ( vector
) );
77 if ( ( vector
.segment
!= rm_cs
) || ( vector
.offset
!= handler
) ) {
78 DBG ( "...cannot unhook; vector points to %04x:%04x\n",
79 vector
.segment
, vector
.offset
);
83 DBG ( "...restoring to %04x:%04x\n",
84 chain_vector
->segment
, chain_vector
->offset
);
85 copy_to_real ( 0, ( interrupt
* 4 ), chain_vector
,
86 sizeof ( *chain_vector
) );
88 chain_vector
->segment
= 0;
89 chain_vector
->offset
= 0;
90 hooked_bios_interrupts
--;