4 * $FreeBSD: src/usr.bin/doscmd/callback.c,v 1.2.2.2 2002/04/25 11:04:50 tg Exp $
5 * $DragonFly: src/usr.bin/doscmd/callback.c,v 1.2 2003/06/17 04:29:25 dillon Exp $
12 ** Callbacks are used for chaining interrupt handlers
13 ** off interrupt vectors
17 LIST_ENTRY(callback
) chain
;
23 LIST_HEAD(cbhead
, callback
) cbhead
[127];
25 #define CBHASH(x) (((x) * 17) % 127)
28 ** Register (func) as a handler for (vec)
31 register_callback(u_long vec
, callback_t func
, const char *name
)
36 elm
= malloc(sizeof(struct callback
));
41 head
= &cbhead
[CBHASH(vec
)];
42 LIST_INSERT_HEAD(head
, elm
, chain
);
46 ** Find a handler for (vec)
49 find_callback(u_long vec
)
54 head
= &cbhead
[CBHASH(vec
)];
55 LIST_FOREACH(elm
, head
, chain
)
59 debug(D_TRAPS2
, "callback %s\n", elm
->name
);
62 return ((callback_t
)0);
65 u_long trampoline_rover
= 0xF1000000;
68 * Interrupts are disabled on an INTn call, so we must restore interrupts
69 * before via STI returning. IRET is not used here because 1) some DOS
70 * calls want to return status via the FLAGS register, and 2) external
71 * routines which hook INTn calls do not always put a FLAGS image on the
72 * stack which re-enables interrupts.
74 u_char softint_trampoline
[] = {
81 u_char hardint_trampoline
[] = {
85 u_char null_trampoline
[] = {
90 insert_generic_trampoline(size_t len
, u_char
*p
)
95 where
= trampoline_rover
;
96 q
= (u_char
*)VECPTR(where
);
98 trampoline_rover
+= len
;
103 insert_softint_trampoline(void)
105 return (insert_generic_trampoline(
106 sizeof(softint_trampoline
), softint_trampoline
));
110 insert_hardint_trampoline(void)
112 return (insert_generic_trampoline(
113 sizeof(hardint_trampoline
), hardint_trampoline
));
117 insert_null_trampoline(void)
119 return (insert_generic_trampoline(
120 sizeof(null_trampoline
), null_trampoline
));