6 * 1) Second PIC is not implemented.
7 * 2) Interrupt priority management is not implemented.
8 * 3) What should be read from port 0x20?
10 * "within interrupt processing" means the following is true:
11 * 1) Hardware interrupt <irql> is delivered by hardint().
12 * 2) Next interrupt <irql> is not possible yet by either:
18 * int isinhardint(int irql)
19 * void set_eoir(int irql, void (*eoir)(void *), void *arg);
21 * $FreeBSD: src/usr.bin/doscmd/int.c,v 1.3.2.2 2002/04/25 11:04:51 tg Exp $
22 * $DragonFly: src/usr.bin/doscmd/int.c,v 1.2 2003/06/17 04:29:26 dillon Exp $
31 void (*eoir
)(void *arg
);
35 static unsigned char IM
;
37 static struct IRQ Irqs
[8];
39 #define int_allowed(n) ((IM & 1 << (n)) == 0 && Irql > (n))
42 set_eoir(int irql
, void (*eoir
)(void *), void *arg
)
44 Irqs
[irql
].eoir
= eoir
;
45 Irqs
[irql
].arg
= arg
;
51 return Irqs
[irql
].within
;
57 regcontext_t
*REGS
= saved_regcontext
;
60 if (R_EFLAGS
& PSL_VIF
) {
65 for (irql
= 0; irql
< 8; irql
++)
66 if (int_allowed(irql
) && (Irqs
[irql
].within
|| Irqs
[irql
].pending
)) {
75 resume_interrupt(void)
77 regcontext_t
*REGS
= saved_regcontext
;
80 if (R_EFLAGS
& PSL_VIF
) {
81 for (irql
= 0; irql
< 8; irql
++)
82 if (Irqs
[irql
].within
&& int_allowed(irql
)) {
83 Irqs
[irql
].within
= 0;
85 Irqs
[irql
].eoir(Irqs
[irql
].arg
);
88 for (irql
= 0; irql
< 8; irql
++)
89 if (Irqs
[irql
].pending
&& int_allowed(irql
)) {
90 Irqs
[irql
].pending
= 0;
107 if (Irqs
[Irql
].busy
)
114 ** Cause a hardware interrupt to happen immediately after
115 ** we return to vm86 mode
120 regcontext_t
*REGS
= saved_regcontext
;
121 u_long vec
= ivec
[8 + irql
];
124 ** if we're dead, or there's no vector, or the saved registers
127 if (dead
|| !saved_valid
|| vec
== 0)
131 ** if the vector points into the BIOS, or the handler at the
132 ** other end is just an IRET, don't bother
134 if ((vec
>> 16) == 0xf000 || *(u_char
*)VECPTR(vec
) == 0xcf)
137 if (!int_allowed(irql
)) {
138 Irqs
[irql
].pending
= 1;
142 if ((R_EFLAGS
& PSL_VIF
) == 0) {
143 Irqs
[irql
].pending
= 1;
148 debug(D_TRAPS
| (8 + irql
), "Int%02x [%04lx:%04lx]\n",
149 8 + irql
, vec
>> 16, vec
& 0xffff);
154 Irqs
[Irql
].within
= 1;
156 PUSH((R_FLAGS
& ~PSL_I
) | (R_EFLAGS
& PSL_VIF
? PSL_I
: 0), REGS
);
159 R_EFLAGS
&= ~PSL_VIF
; /* XXX disable interrupts */
160 PUTVEC(R_CS
, R_IP
, vec
);
166 if (!Irqs
[irql
].pending
)
168 Irqs
[irql
].pending
= 0;
175 return 0x60; /* What should be here? */
179 irqc_out(int port
, unsigned char val
)
192 imr_out(int port
, unsigned char val
)
199 ** Cause a software interrupt to happen immediately after we
200 ** return to vm86 mode
205 regcontext_t
*REGS
= saved_regcontext
;
206 u_long vec
= ivec
[intnum
];
209 ** if we're dead, or there's no vector or the saved registers are
212 if (dead
|| !saved_valid
|| vec
== 0)
216 ** if the vector points into the BIOS, or the handler at the other
217 ** end is just an IRET, don't bother.
219 if ((vec
>> 16) == 0xf000 || *(u_char
*)VECPTR(vec
) == 0xcf)
222 debug(D_TRAPS
| intnum
, "INT %02x [%04lx:%04lx]\n",
223 intnum
, vec
>> 16, vec
& 0xffff);
225 PUSH((R_FLAGS
& ~PSL_I
) | (R_EFLAGS
& PSL_VIF
? PSL_I
: 0), REGS
);
228 R_EFLAGS
&= ~PSL_VIF
; /* XXX disable interrupts? */
229 PUTVEC(R_CS
, R_IP
, vec
);
237 for (i
= 0; i
< 8; i
++) {
246 define_input_port_handler(0x20, irqc_in
);
247 define_output_port_handler(0x20, irqc_out
);
248 define_input_port_handler(0x21, imr_in
);
249 define_output_port_handler(0x21, imr_out
);