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);
23 #include <sys/cdefs.h>
24 __FBSDID("$FreeBSD$");
32 void (*eoir)(void *arg);
36 static unsigned char IM;
38 static struct IRQ Irqs[8];
40 #define int_allowed(n) ((IM & 1 << (n)) == 0 && Irql > (n))
43 set_eoir(int irql, void (*eoir)(void *), void *arg)
45 Irqs [irql].eoir = eoir;
46 Irqs [irql].arg = arg;
52 return Irqs[irql].within;
58 regcontext_t *REGS = saved_regcontext;
61 if (R_EFLAGS & PSL_VIF) {
66 for (irql = 0; irql < 8; irql++)
67 if (int_allowed(irql) && (Irqs[irql].within || Irqs[irql].pending)) {
76 resume_interrupt(void)
78 regcontext_t *REGS = saved_regcontext;
81 if (R_EFLAGS & PSL_VIF) {
82 for (irql = 0; irql < 8; irql++)
83 if (Irqs[irql].within && int_allowed(irql)) {
84 Irqs[irql].within = 0;
86 Irqs[irql].eoir(Irqs[irql].arg);
89 for (irql = 0; irql < 8; irql++)
90 if (Irqs[irql].pending && int_allowed(irql)) {
91 Irqs[irql].pending = 0;
108 if (Irqs [Irql].busy)
115 ** Cause a hardware interrupt to happen immediately after
116 ** we return to vm86 mode
121 regcontext_t *REGS = saved_regcontext;
122 u_long vec = ivec[8 + irql];
125 ** if we're dead, or there's no vector, or the saved registers
128 if (dead || !saved_valid || vec == 0)
132 ** if the vector points into the BIOS, or the handler at the
133 ** other end is just an IRET, don't bother
135 if ((vec >> 16) == 0xf000 || *(u_char *)VECPTR(vec) == 0xcf)
138 if (!int_allowed(irql)) {
139 Irqs[irql].pending = 1;
143 if ((R_EFLAGS & PSL_VIF) == 0) {
144 Irqs[irql].pending = 1;
149 debug(D_TRAPS | (8 + irql), "Int%02x [%04lx:%04lx]\n",
150 8 + irql, vec >> 16, vec & 0xffff);
155 Irqs[Irql].within = 1;
157 PUSH((R_FLAGS & ~PSL_I) | (R_EFLAGS & PSL_VIF ? PSL_I : 0), REGS);
160 R_EFLAGS &= ~PSL_VIF; /* XXX disable interrupts */
161 PUTVEC(R_CS, R_IP, vec);
167 if (!Irqs[irql].pending)
169 Irqs[irql].pending = 0;
174 irqc_in(int port __unused)
176 return 0x60; /* What should be here? */
180 irqc_out(int port __unused, unsigned char val)
187 imr_in(int port __unused)
193 imr_out(int port __unused, unsigned char val)
200 ** Cause a software interrupt to happen immediately after we
201 ** return to vm86 mode
206 regcontext_t *REGS = saved_regcontext;
207 u_long vec = ivec[intnum];
210 ** if we're dead, or there's no vector or the saved registers are
213 if (dead || !saved_valid || vec == 0)
217 ** if the vector points into the BIOS, or the handler at the other
218 ** end is just an IRET, don't bother.
220 if ((vec >> 16) == 0xf000 || *(u_char *)VECPTR(vec) == 0xcf)
223 debug(D_TRAPS | intnum, "INT %02x [%04lx:%04lx]\n",
224 intnum, vec >> 16, vec & 0xffff);
226 PUSH((R_FLAGS & ~PSL_I) | (R_EFLAGS & PSL_VIF ? PSL_I : 0), REGS);
229 R_EFLAGS &= ~PSL_VIF; /* XXX disable interrupts? */
230 PUTVEC(R_CS, R_IP, vec);
238 for (i = 0; i < 8; i++) {
247 define_input_port_handler(0x20, irqc_in);
248 define_output_port_handler(0x20, irqc_out);
249 define_input_port_handler(0x21, imr_in);
250 define_output_port_handler(0x21, imr_out);