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));