11 ** Callbacks are used for chaining interrupt handlers
12 ** off interrupt vectors
16 LIST_ENTRY(callback) chain;
22 LIST_HEAD(cbhead , callback) cbhead[127];
24 #define CBHASH(x) (((x) * 17) % 127)
27 ** Register (func) as a handler for (vec)
30 register_callback(u_long vec, callback_t func, char *name)
35 elm = malloc(sizeof(struct callback));
40 head = &cbhead[CBHASH(vec)];
41 LIST_INSERT_HEAD(head, elm, chain);
45 ** Find a handler for (vec)
48 find_callback(u_long vec)
53 head = &cbhead[CBHASH(vec)];
54 LIST_FOREACH(elm, head, chain)
58 debug(D_TRAPS2, "callback %s\n", elm->name);
61 return ((callback_t)0);
64 u_long trampoline_rover = 0xF1000000;
67 * Interrupts are disabled on an INTn call, so we must restore interrupts
68 * before via STI returning. IRET is not used here because 1) some DOS
69 * calls want to return status via the FLAGS register, and 2) external
70 * routines which hook INTn calls do not always put a FLAGS image on the
71 * stack which re-enables interrupts.
73 u_char softint_trampoline[] = {
80 u_char hardint_trampoline[] = {
84 u_char null_trampoline[] = {
89 insert_generic_trampoline(size_t len, u_char *p)
94 where = trampoline_rover;
95 q = (u_char *)VECPTR(where);
97 trampoline_rover += len;
102 insert_softint_trampoline(void)
104 return (insert_generic_trampoline(
105 sizeof(softint_trampoline), softint_trampoline));
109 insert_hardint_trampoline(void)
111 return (insert_generic_trampoline(
112 sizeof(hardint_trampoline), hardint_trampoline));
116 insert_null_trampoline(void)
118 return (insert_generic_trampoline(
119 sizeof(null_trampoline), null_trampoline));