xref: /freebsd/sys/amd64/vmm/io/vatpic.c (revision 0572ccaa4543b0abef8ef81e384c1d04de9f3da1)
1 /*-
2  * Copyright (c) 2014 Tycho Nightingale <tycho.nightingale@pluribusnetworks.com>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26 
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29 
30 #include <sys/param.h>
31 #include <sys/types.h>
32 #include <sys/queue.h>
33 #include <sys/cpuset.h>
34 #include <sys/kernel.h>
35 #include <sys/lock.h>
36 #include <sys/malloc.h>
37 #include <sys/mutex.h>
38 #include <sys/systm.h>
39 
40 #include <x86/apicreg.h>
41 #include <dev/ic/i8259.h>
42 
43 #include <machine/vmm.h>
44 
45 #include "vmm_ktr.h"
46 #include "vmm_lapic.h"
47 #include "vioapic.h"
48 #include "vatpic.h"
49 
50 static MALLOC_DEFINE(M_VATPIC, "atpic", "bhyve virtual atpic (8259)");
51 
52 #define	VATPIC_LOCK(vatpic)		mtx_lock_spin(&((vatpic)->mtx))
53 #define	VATPIC_UNLOCK(vatpic)		mtx_unlock_spin(&((vatpic)->mtx))
54 #define	VATPIC_LOCKED(vatpic)		mtx_owned(&((vatpic)->mtx))
55 
56 enum irqstate {
57 	IRQSTATE_ASSERT,
58 	IRQSTATE_DEASSERT,
59 	IRQSTATE_PULSE
60 };
61 
62 struct atpic {
63 	bool		ready;
64 	int		icw_num;
65 	int		rd_cmd_reg;
66 
67 	bool		aeoi;
68 	bool		poll;
69 	bool		rotate;
70 	bool		sfn;		/* special fully-nested mode */
71 
72 	int		irq_base;
73 	uint8_t		request;	/* Interrupt Request Register (IIR) */
74 	uint8_t		service;	/* Interrupt Service (ISR) */
75 	uint8_t		mask;		/* Interrupt Mask Register (IMR) */
76 
77 	int		acnt[8];	/* sum of pin asserts and deasserts */
78 	int		priority;	/* current pin priority */
79 
80 	bool		intr_raised;
81 };
82 
83 struct vatpic {
84 	struct vm	*vm;
85 	struct mtx	mtx;
86 	struct atpic	atpic[2];
87 	uint8_t		elc[2];
88 };
89 
90 #define	VATPIC_CTR0(vatpic, fmt)					\
91 	VM_CTR0((vatpic)->vm, fmt)
92 
93 #define	VATPIC_CTR1(vatpic, fmt, a1)					\
94 	VM_CTR1((vatpic)->vm, fmt, a1)
95 
96 #define	VATPIC_CTR2(vatpic, fmt, a1, a2)				\
97 	VM_CTR2((vatpic)->vm, fmt, a1, a2)
98 
99 #define	VATPIC_CTR3(vatpic, fmt, a1, a2, a3)				\
100 	VM_CTR3((vatpic)->vm, fmt, a1, a2, a3)
101 
102 #define	VATPIC_CTR4(vatpic, fmt, a1, a2, a3, a4)			\
103 	VM_CTR4((vatpic)->vm, fmt, a1, a2, a3, a4)
104 
105 static void vatpic_set_pinstate(struct vatpic *vatpic, int pin, bool newstate);
106 
107 static __inline int
108 vatpic_get_highest_isrpin(struct atpic *atpic)
109 {
110 	int bit, pin;
111 	int i;
112 
113 	for (i = 0; i <= 7; i++) {
114 		pin = ((i + 7 - atpic->priority) & 0x7);
115                 bit = (1 << pin);
116 
117 		if (atpic->service & bit)
118 			return (pin);
119 	}
120 
121 	return (-1);
122 }
123 
124 static __inline int
125 vatpic_get_highest_irrpin(struct atpic *atpic)
126 {
127 	int serviced;
128 	int bit, pin;
129 	int i, j;
130 
131 	/*
132 	 * In 'Special Fully-Nested Mode' when an interrupt request from
133 	 * a slave is in service, the slave is not locked out from the
134 	 * master's priority logic.
135 	 */
136 	serviced = atpic->service;
137 	if (atpic->sfn)
138 		serviced &= ~(1 << 2);
139 
140 	for (i = 0; i <= 7; i++) {
141 		pin = ((i + 7 - atpic->priority) & 0x7);
142 		bit = (1 << pin);
143 		if (serviced & bit)
144 			break;
145 	}
146 
147 	for (j = 0; j < i; j++) {
148 		pin = ((j + 7 - atpic->priority) & 0x7);
149 		bit = (1 << pin);
150 		if (atpic->request & bit && (~atpic->mask & bit))
151 			return (pin);
152 	}
153 
154 	return (-1);
155 }
156 
157 static void
158 vatpic_notify_intr(struct vatpic *vatpic)
159 {
160 	struct atpic *atpic;
161 	int pin;
162 
163 	KASSERT(VATPIC_LOCKED(vatpic), ("vatpic_notify_intr not locked"));
164 
165 	/*
166 	 * First check the slave.
167 	 */
168 	atpic = &vatpic->atpic[1];
169 	if (!atpic->intr_raised &&
170 	    (pin = vatpic_get_highest_irrpin(atpic)) != -1) {
171 		VATPIC_CTR4(vatpic, "atpic slave notify pin = %d "
172 		    "(imr 0x%x irr 0x%x isr 0x%x)", pin,
173 		    atpic->mask, atpic->request, atpic->service);
174 
175 		/*
176 		 * Cascade the request from the slave to the master.
177 		 */
178 		atpic->intr_raised = true;
179 		vatpic_set_pinstate(vatpic, 2, true);
180 		vatpic_set_pinstate(vatpic, 2, false);
181 	} else {
182 		VATPIC_CTR3(vatpic, "atpic slave no eligible interrupts "
183 		    "(imr 0x%x irr 0x%x isr 0x%x)",
184 		    atpic->mask, atpic->request, atpic->service);
185 	}
186 
187 	/*
188 	 * Then check the master.
189 	 */
190 	atpic = &vatpic->atpic[0];
191 	if (!atpic->intr_raised &&
192 	    (pin = vatpic_get_highest_irrpin(atpic)) != -1) {
193 		VATPIC_CTR4(vatpic, "atpic master notify pin = %d "
194 		    "(imr 0x%x irr 0x%x isr 0x%x)", pin,
195 		    atpic->mask, atpic->request, atpic->service);
196 
197 		/*
198 		 * PIC interrupts are routed to both the Local APIC
199 		 * and the I/O APIC to support operation in 1 of 3
200 		 * modes.
201 		 *
202 		 * 1. Legacy PIC Mode: the PIC effectively bypasses
203 		 * all APIC components.  In mode '1' the local APIC is
204 		 * disabled and LINT0 is reconfigured as INTR to
205 		 * deliver the PIC interrupt directly to the CPU.
206 		 *
207 		 * 2. Virtual Wire Mode: the APIC is treated as a
208 		 * virtual wire which delivers interrupts from the PIC
209 		 * to the CPU.  In mode '2' LINT0 is programmed as
210 		 * ExtINT to indicate that the PIC is the source of
211 		 * the interrupt.
212 		 *
213 		 * 3. Symmetric I/O Mode: PIC interrupts are fielded
214 		 * by the I/O APIC and delivered to the appropriate
215 		 * CPU.  In mode '3' the I/O APIC input 0 is
216 		 * programmed as ExtINT to indicate that the PIC is
217 		 * the source of the interrupt.
218 		 */
219 		atpic->intr_raised = true;
220 		lapic_set_local_intr(vatpic->vm, -1, APIC_LVT_LINT0);
221 		vioapic_pulse_irq(vatpic->vm, 0);
222 	} else {
223 		VATPIC_CTR3(vatpic, "atpic master no eligible interrupts "
224 		    "(imr 0x%x irr 0x%x isr 0x%x)",
225 		    atpic->mask, atpic->request, atpic->service);
226 	}
227 }
228 
229 static int
230 vatpic_icw1(struct vatpic *vatpic, struct atpic *atpic, uint8_t val)
231 {
232 	VATPIC_CTR1(vatpic, "atpic icw1 0x%x", val);
233 
234 	atpic->ready = false;
235 
236 	atpic->icw_num = 1;
237 	atpic->mask = 0;
238 	atpic->priority = 0;
239 	atpic->rd_cmd_reg = 0;
240 
241 	if ((val & ICW1_SNGL) != 0) {
242 		VATPIC_CTR0(vatpic, "vatpic cascade mode required");
243 		return (-1);
244 	}
245 
246 	if ((val & ICW1_IC4) == 0) {
247 		VATPIC_CTR0(vatpic, "vatpic icw4 required");
248 		return (-1);
249 	}
250 
251 	atpic->icw_num++;
252 
253 	return (0);
254 }
255 
256 static int
257 vatpic_icw2(struct vatpic *vatpic, struct atpic *atpic, uint8_t val)
258 {
259 	VATPIC_CTR1(vatpic, "atpic icw2 0x%x", val);
260 
261 	atpic->irq_base = val & 0xf8;
262 
263 	atpic->icw_num++;
264 
265 	return (0);
266 }
267 
268 static int
269 vatpic_icw3(struct vatpic *vatpic, struct atpic *atpic, uint8_t val)
270 {
271 	VATPIC_CTR1(vatpic, "atpic icw3 0x%x", val);
272 
273 	atpic->icw_num++;
274 
275 	return (0);
276 }
277 
278 static int
279 vatpic_icw4(struct vatpic *vatpic, struct atpic *atpic, uint8_t val)
280 {
281 	VATPIC_CTR1(vatpic, "atpic icw4 0x%x", val);
282 
283 	if ((val & ICW4_8086) == 0) {
284 		VATPIC_CTR0(vatpic, "vatpic microprocessor mode required");
285 		return (-1);
286 	}
287 
288 	if ((val & ICW4_AEOI) != 0)
289 		atpic->aeoi = true;
290 
291 	atpic->icw_num = 0;
292 	atpic->ready = true;
293 
294 	return (0);
295 }
296 
297 static int
298 vatpic_ocw1(struct vatpic *vatpic, struct atpic *atpic, uint8_t val)
299 {
300 	VATPIC_CTR1(vatpic, "atpic ocw1 0x%x", val);
301 
302 	atpic->mask = val & 0xff;
303 
304 	return (0);
305 }
306 
307 static int
308 vatpic_ocw2(struct vatpic *vatpic, struct atpic *atpic, uint8_t val)
309 {
310 	VATPIC_CTR1(vatpic, "atpic ocw2 0x%x", val);
311 
312 	atpic->rotate = ((val & OCW2_R) != 0);
313 
314 	if ((val & OCW2_EOI) != 0) {
315 		int isr_bit;
316 
317 		if ((val & OCW2_SL) != 0) {
318 			/* specific EOI */
319 			isr_bit = val & 0x7;
320 		} else {
321 			/* non-specific EOI */
322 			isr_bit = vatpic_get_highest_isrpin(atpic);
323 		}
324 
325 		if (isr_bit != -1) {
326 			atpic->service &= ~(1 << isr_bit);
327 
328 			if (atpic->rotate)
329 				atpic->priority = isr_bit;
330 		}
331 	} else if ((val & OCW2_SL) != 0 && atpic->rotate == true) {
332 		/* specific priority */
333 		atpic->priority = val & 0x7;
334 	}
335 
336 	return (0);
337 }
338 
339 static int
340 vatpic_ocw3(struct vatpic *vatpic, struct atpic *atpic, uint8_t val)
341 {
342 	VATPIC_CTR1(vatpic, "atpic ocw3 0x%x", val);
343 
344 	atpic->poll = ((val & OCW3_P) != 0);
345 
346 	if (val & OCW3_RR) {
347 		/* read register command */
348 		atpic->rd_cmd_reg = val & OCW3_RIS;
349 	}
350 
351 	return (0);
352 }
353 
354 static void
355 vatpic_set_pinstate(struct vatpic *vatpic, int pin, bool newstate)
356 {
357 	struct atpic *atpic;
358 	int oldcnt, newcnt;
359 	bool level;
360 
361 	KASSERT(pin >= 0 && pin < 16,
362 	    ("vatpic_set_pinstate: invalid pin number %d", pin));
363 	KASSERT(VATPIC_LOCKED(vatpic),
364 	    ("vatpic_set_pinstate: vatpic is not locked"));
365 
366 	atpic = &vatpic->atpic[pin >> 3];
367 
368 	oldcnt = atpic->acnt[pin & 0x7];
369 	if (newstate)
370 		atpic->acnt[pin & 0x7]++;
371 	else
372 		atpic->acnt[pin & 0x7]--;
373 	newcnt = atpic->acnt[pin & 0x7];
374 
375 	if (newcnt < 0) {
376 		VATPIC_CTR2(vatpic, "atpic pin%d: bad acnt %d", pin, newcnt);
377 	}
378 
379 	level = ((vatpic->elc[pin >> 3] & (1 << (pin & 0x7))) != 0);
380 
381 	if ((oldcnt == 0 && newcnt == 1) || (newcnt > 0 && level == true)) {
382 		/* rising edge or level */
383 		VATPIC_CTR1(vatpic, "atpic pin%d: asserted", pin);
384 		atpic->request |= (1 << (pin & 0x7));
385 	} else if (oldcnt == 1 && newcnt == 0) {
386 		/* falling edge */
387 		VATPIC_CTR1(vatpic, "atpic pin%d: deasserted", pin);
388 	} else {
389 		VATPIC_CTR3(vatpic, "atpic pin%d: %s, ignored, acnt %d",
390 		    pin, newstate ? "asserted" : "deasserted", newcnt);
391 	}
392 
393 	vatpic_notify_intr(vatpic);
394 }
395 
396 static int
397 vatpic_set_irqstate(struct vm *vm, int irq, enum irqstate irqstate)
398 {
399 	struct vatpic *vatpic;
400 	struct atpic *atpic;
401 
402 	if (irq < 0 || irq > 15)
403 		return (EINVAL);
404 
405 	vatpic = vm_atpic(vm);
406 	atpic = &vatpic->atpic[irq >> 3];
407 
408 	if (atpic->ready == false)
409 		return (0);
410 
411 	VATPIC_LOCK(vatpic);
412 	switch (irqstate) {
413 	case IRQSTATE_ASSERT:
414 		vatpic_set_pinstate(vatpic, irq, true);
415 		break;
416 	case IRQSTATE_DEASSERT:
417 		vatpic_set_pinstate(vatpic, irq, false);
418 		break;
419 	case IRQSTATE_PULSE:
420 		vatpic_set_pinstate(vatpic, irq, true);
421 		vatpic_set_pinstate(vatpic, irq, false);
422 		break;
423 	default:
424 		panic("vatpic_set_irqstate: invalid irqstate %d", irqstate);
425 	}
426 	VATPIC_UNLOCK(vatpic);
427 
428 	return (0);
429 }
430 
431 int
432 vatpic_assert_irq(struct vm *vm, int irq)
433 {
434 	return (vatpic_set_irqstate(vm, irq, IRQSTATE_ASSERT));
435 }
436 
437 int
438 vatpic_deassert_irq(struct vm *vm, int irq)
439 {
440 	return (vatpic_set_irqstate(vm, irq, IRQSTATE_DEASSERT));
441 }
442 
443 int
444 vatpic_pulse_irq(struct vm *vm, int irq)
445 {
446 	return (vatpic_set_irqstate(vm, irq, IRQSTATE_PULSE));
447 }
448 
449 int
450 vatpic_set_irq_trigger(struct vm *vm, int irq, enum vm_intr_trigger trigger)
451 {
452 	struct vatpic *vatpic;
453 
454 	if (irq < 0 || irq > 15)
455 		return (EINVAL);
456 
457 	/*
458 	 * See comment in vatpic_elc_handler.  These IRQs must be
459 	 * edge triggered.
460 	 */
461 	if (trigger == LEVEL_TRIGGER) {
462 		switch (irq) {
463 		case 0:
464 		case 1:
465 		case 2:
466 		case 8:
467 		case 13:
468 			return (EINVAL);
469 		}
470 	}
471 
472 	vatpic = vm_atpic(vm);
473 
474 	VATPIC_LOCK(vatpic);
475 
476 	if (trigger == LEVEL_TRIGGER)
477 		vatpic->elc[irq >> 3] |=  1 << (irq & 0x7);
478 	else
479 		vatpic->elc[irq >> 3] &=  ~(1 << (irq & 0x7));
480 
481 	VATPIC_UNLOCK(vatpic);
482 
483 	return (0);
484 }
485 
486 void
487 vatpic_pending_intr(struct vm *vm, int *vecptr)
488 {
489 	struct vatpic *vatpic;
490 	struct atpic *atpic;
491 	int pin;
492 
493 	vatpic = vm_atpic(vm);
494 
495 	atpic = &vatpic->atpic[0];
496 
497 	VATPIC_LOCK(vatpic);
498 
499 	pin = vatpic_get_highest_irrpin(atpic);
500 	if (pin == -1)
501 		pin = 7;
502 	if (pin == 2) {
503 		atpic = &vatpic->atpic[1];
504 		pin = vatpic_get_highest_irrpin(atpic);
505 	}
506 
507 	*vecptr = atpic->irq_base + pin;
508 
509 	VATPIC_UNLOCK(vatpic);
510 }
511 
512 static void
513 vatpic_pin_accepted(struct atpic *atpic, int pin)
514 {
515 	atpic->intr_raised = false;
516 
517 	if (atpic->acnt[pin] == 0)
518 		atpic->request &= ~(1 << pin);
519 
520 	if (atpic->aeoi == true) {
521 		if (atpic->rotate == true)
522 			atpic->priority = pin;
523 	} else {
524 		atpic->service |= (1 << pin);
525 	}
526 }
527 
528 void
529 vatpic_intr_accepted(struct vm *vm, int vector)
530 {
531 	struct vatpic *vatpic;
532 	int pin;
533 
534 	vatpic = vm_atpic(vm);
535 
536 	VATPIC_LOCK(vatpic);
537 
538 	pin = vector & 0x7;
539 
540 	if ((vector & ~0x7) == vatpic->atpic[1].irq_base) {
541 		vatpic_pin_accepted(&vatpic->atpic[1], pin);
542 		/*
543 		 * If this vector originated from the slave,
544 		 * accept the cascaded interrupt too.
545 		 */
546 		vatpic_pin_accepted(&vatpic->atpic[0], 2);
547 	} else {
548 		vatpic_pin_accepted(&vatpic->atpic[0], pin);
549 	}
550 
551 	vatpic_notify_intr(vatpic);
552 
553 	VATPIC_UNLOCK(vatpic);
554 }
555 
556 static int
557 vatpic_read(struct vatpic *vatpic, struct atpic *atpic, bool in, int port,
558 	    int bytes, uint32_t *eax)
559 {
560 	VATPIC_LOCK(vatpic);
561 
562 	if (atpic->poll) {
563 		VATPIC_CTR0(vatpic, "vatpic polled mode not supported");
564 		VATPIC_UNLOCK(vatpic);
565 		return (-1);
566 	} else {
567 		if (port & ICU_IMR_OFFSET) {
568 			/* read interrrupt mask register */
569 			*eax = atpic->mask;
570 		} else {
571 			if (atpic->rd_cmd_reg == OCW3_RIS) {
572 				/* read interrupt service register */
573 				*eax = atpic->service;
574 			} else {
575 				/* read interrupt request register */
576 				*eax = atpic->request;
577 			}
578 		}
579 	}
580 
581 	VATPIC_UNLOCK(vatpic);
582 
583 	return (0);
584 
585 }
586 
587 static int
588 vatpic_write(struct vatpic *vatpic, struct atpic *atpic, bool in, int port,
589     int bytes, uint32_t *eax)
590 {
591 	int error;
592 	uint8_t val;
593 
594 	val = *eax;
595 
596 	VATPIC_LOCK(vatpic);
597 
598 	if (port & ICU_IMR_OFFSET) {
599 		if (atpic->ready) {
600 			error = vatpic_ocw1(vatpic, atpic, val);
601 		} else {
602 			switch (atpic->icw_num) {
603 			case 2:
604 				error = vatpic_icw2(vatpic, atpic, val);
605 				break;
606 			case 3:
607 				error = vatpic_icw3(vatpic, atpic, val);
608 				break;
609 			case 4:
610 				error = vatpic_icw4(vatpic, atpic, val);
611 				break;
612 			}
613 		}
614 	} else {
615 		if (val & (1 << 4))
616 			error = vatpic_icw1(vatpic, atpic, val);
617 
618 		if (atpic->ready) {
619 			if (val & (1 << 3))
620 				error = vatpic_ocw3(vatpic, atpic, val);
621 			else
622 				error = vatpic_ocw2(vatpic, atpic, val);
623 		}
624 	}
625 
626 	if (atpic->ready)
627 		vatpic_notify_intr(vatpic);
628 
629 	VATPIC_UNLOCK(vatpic);
630 
631 	return (error);
632 }
633 
634 int
635 vatpic_master_handler(void *vm, int vcpuid, bool in, int port, int bytes,
636     uint32_t *eax)
637 {
638 	struct vatpic *vatpic;
639 	struct atpic *atpic;
640 
641 	vatpic = vm_atpic(vm);
642 	atpic = &vatpic->atpic[0];
643 
644 	if (bytes != 1)
645 		return (-1);
646 
647 	if (in) {
648 		return (vatpic_read(vatpic, atpic, in, port, bytes, eax));
649 	}
650 
651 	return (vatpic_write(vatpic, atpic, in, port, bytes, eax));
652 }
653 
654 int
655 vatpic_slave_handler(void *vm, int vcpuid, bool in, int port, int bytes,
656     uint32_t *eax)
657 {
658 	struct vatpic *vatpic;
659 	struct atpic *atpic;
660 
661 	vatpic = vm_atpic(vm);
662 	atpic = &vatpic->atpic[1];
663 
664 	if (bytes != 1)
665 		return (-1);
666 
667 	if (in) {
668 		return (vatpic_read(vatpic, atpic, in, port, bytes, eax));
669 	}
670 
671 	return (vatpic_write(vatpic, atpic, in, port, bytes, eax));
672 }
673 
674 int
675 vatpic_elc_handler(void *vm, int vcpuid, bool in, int port, int bytes,
676     uint32_t *eax)
677 {
678 	struct vatpic *vatpic;
679 	bool is_master;
680 
681 	vatpic = vm_atpic(vm);
682 	is_master = (port == IO_ELCR1);
683 
684 	if (bytes != 1)
685 		return (-1);
686 
687 	VATPIC_LOCK(vatpic);
688 
689 	if (in) {
690 		if (is_master)
691 			*eax = vatpic->elc[0];
692 		else
693 			*eax = vatpic->elc[1];
694 	} else {
695 		/*
696 		 * For the master PIC the cascade channel (IRQ2), the
697 		 * heart beat timer (IRQ0), and the keyboard
698 		 * controller (IRQ1) cannot be programmed for level
699 		 * mode.
700 		 *
701 		 * For the slave PIC the real time clock (IRQ8) and
702 		 * the floating point error interrupt (IRQ13) cannot
703 		 * be programmed for level mode.
704 		 */
705 		if (is_master)
706 			vatpic->elc[0] = (*eax & 0xf8);
707 		else
708 			vatpic->elc[1] = (*eax & 0xde);
709 	}
710 
711 	VATPIC_UNLOCK(vatpic);
712 
713 	return (0);
714 }
715 
716 struct vatpic *
717 vatpic_init(struct vm *vm)
718 {
719 	struct vatpic *vatpic;
720 
721 	vatpic = malloc(sizeof(struct vatpic), M_VATPIC, M_WAITOK | M_ZERO);
722 	vatpic->vm = vm;
723 
724 	mtx_init(&vatpic->mtx, "vatpic lock", NULL, MTX_SPIN);
725 
726 	return (vatpic);
727 }
728 
729 void
730 vatpic_cleanup(struct vatpic *vatpic)
731 {
732 	free(vatpic, M_VATPIC);
733 }
734