kernel: Use hashdestroy() to free hash tables allocated with hashinit().
[dragonfly.git] / usr.bin / doscmd / callback.c
CommitLineData
1de703da
MD
1/*
2 * No copyright?!
3 *
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 */
984263bc
MD
7
8#include <sys/queue.h>
9#include "doscmd.h"
10
11/*
12** Callbacks are used for chaining interrupt handlers
13** off interrupt vectors
14*/
15
16struct callback {
17 LIST_ENTRY(callback) chain;
18 u_long vec;
19 callback_t func;
20 const char *name;
21};
22
23LIST_HEAD(cbhead , callback) cbhead[127];
24
25#define CBHASH(x) (((x) * 17) % 127)
26
27/*
28** Register (func) as a handler for (vec)
29*/
30void
31register_callback(u_long vec, callback_t func, const char *name)
32{
33 struct cbhead *head;
34 struct callback *elm;
35
36 elm = malloc(sizeof(struct callback));
37 elm->vec = vec;
38 elm->func = func;
39 elm->name = name;
40
41 head = &cbhead[CBHASH(vec)];
42 LIST_INSERT_HEAD(head, elm, chain);
43}
44
45/*
46** Find a handler for (vec)
47*/
48callback_t
49find_callback(u_long vec)
50{
51 struct cbhead *head;
52 struct callback *elm;
53
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);
63}
64
65u_long trampoline_rover = 0xF1000000;
66
67/*
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.
73 */
74u_char softint_trampoline[] = {
75 0xf4, /* HLT */
76 0xfb, /* STI */
77 0xca, /* RETF 2 */
78 2,
79 0,
80};
81u_char hardint_trampoline[] = {
82 0xf4, /* HLT */
83 0xcf, /* IRET */
84};
85u_char null_trampoline[] = {
86 0xcf, /* IRET */
87};
88
89u_long
90insert_generic_trampoline(size_t len, u_char *p)
91{
92 u_char *q;
93 u_long where;
94
95 where = trampoline_rover;
96 q = (u_char *)VECPTR(where);
97 memcpy(q, p, len);
98 trampoline_rover += len;
99 return (where);
100}
101
102u_long
103insert_softint_trampoline(void)
104{
105 return (insert_generic_trampoline(
106 sizeof(softint_trampoline), softint_trampoline));
107}
108
109u_long
110insert_hardint_trampoline(void)
111{
112 return (insert_generic_trampoline(
113 sizeof(hardint_trampoline), hardint_trampoline));
114}
115
116u_long
117insert_null_trampoline(void)
118{
119 return (insert_generic_trampoline(
120 sizeof(null_trampoline), null_trampoline));
121}