MFC numerous features from HEAD.
[dragonfly.git] / usr.bin / doscmd / callback.c
blob3a9b99cd3de6d0470f350df70ad3ddda0fb43dfa
1 /*
2 * No copyright?!
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 $
6 */
8 #include <sys/queue.h>
9 #include "doscmd.h"
12 ** Callbacks are used for chaining interrupt handlers
13 ** off interrupt vectors
16 struct callback {
17 LIST_ENTRY(callback) chain;
18 u_long vec;
19 callback_t func;
20 const char *name;
23 LIST_HEAD(cbhead , callback) cbhead[127];
25 #define CBHASH(x) (((x) * 17) % 127)
28 ** Register (func) as a handler for (vec)
30 void
31 register_callback(u_long vec, callback_t func, const char *name)
33 struct cbhead *head;
34 struct callback *elm;
36 elm = malloc(sizeof(struct callback));
37 elm->vec = vec;
38 elm->func = func;
39 elm->name = name;
41 head = &cbhead[CBHASH(vec)];
42 LIST_INSERT_HEAD(head, elm, chain);
46 ** Find a handler for (vec)
48 callback_t
49 find_callback(u_long vec)
51 struct cbhead *head;
52 struct callback *elm;
54 head = &cbhead[CBHASH(vec)];
55 LIST_FOREACH(elm, head, chain)
56 if (elm->vec == vec)
57 break;
58 if (elm) {
59 debug(D_TRAPS2, "callback %s\n", elm->name);
60 return (elm->func);
61 } else
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[] = {
75 0xf4, /* HLT */
76 0xfb, /* STI */
77 0xca, /* RETF 2 */
81 u_char hardint_trampoline[] = {
82 0xf4, /* HLT */
83 0xcf, /* IRET */
85 u_char null_trampoline[] = {
86 0xcf, /* IRET */
89 u_long
90 insert_generic_trampoline(size_t len, u_char *p)
92 u_char *q;
93 u_long where;
95 where = trampoline_rover;
96 q = (u_char *)VECPTR(where);
97 memcpy(q, p, len);
98 trampoline_rover += len;
99 return (where);
102 u_long
103 insert_softint_trampoline(void)
105 return (insert_generic_trampoline(
106 sizeof(softint_trampoline), softint_trampoline));
109 u_long
110 insert_hardint_trampoline(void)
112 return (insert_generic_trampoline(
113 sizeof(hardint_trampoline), hardint_trampoline));
116 u_long
117 insert_null_trampoline(void)
119 return (insert_generic_trampoline(
120 sizeof(null_trampoline), null_trampoline));