xref: /freebsd/sys/amd64/vmm/io/vatpic.c (revision 5ae59dec60e3815b621ae87f74a377cf3449ca55)
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 void
450 vatpic_pending_intr(struct vm *vm, int *vecptr)
451 {
452 	struct vatpic *vatpic;
453 	struct atpic *atpic;
454 	int pin;
455 
456 	vatpic = vm_atpic(vm);
457 
458 	atpic = &vatpic->atpic[0];
459 
460 	VATPIC_LOCK(vatpic);
461 
462 	pin = vatpic_get_highest_irrpin(atpic);
463 	if (pin == -1)
464 		pin = 7;
465 	if (pin == 2) {
466 		atpic = &vatpic->atpic[1];
467 		pin = vatpic_get_highest_irrpin(atpic);
468 	}
469 
470 	*vecptr = atpic->irq_base + pin;
471 
472 	VATPIC_UNLOCK(vatpic);
473 }
474 
475 static void
476 vatpic_pin_accepted(struct atpic *atpic, int pin)
477 {
478 	atpic->intr_raised = false;
479 
480 	if (atpic->acnt[pin] == 0)
481 		atpic->request &= ~(1 << pin);
482 
483 	if (atpic->aeoi == true) {
484 		if (atpic->rotate == true)
485 			atpic->priority = pin;
486 	} else {
487 		atpic->service |= (1 << pin);
488 	}
489 }
490 
491 void
492 vatpic_intr_accepted(struct vm *vm, int vector)
493 {
494 	struct vatpic *vatpic;
495 	int pin;
496 
497 	vatpic = vm_atpic(vm);
498 
499 	VATPIC_LOCK(vatpic);
500 
501 	pin = vector & 0x7;
502 
503 	if ((vector & ~0x7) == vatpic->atpic[1].irq_base) {
504 		vatpic_pin_accepted(&vatpic->atpic[1], pin);
505 		/*
506 		 * If this vector originated from the slave,
507 		 * accept the cascaded interrupt too.
508 		 */
509 		vatpic_pin_accepted(&vatpic->atpic[0], 2);
510 	} else {
511 		vatpic_pin_accepted(&vatpic->atpic[0], pin);
512 	}
513 
514 	vatpic_notify_intr(vatpic);
515 
516 	VATPIC_UNLOCK(vatpic);
517 }
518 
519 static int
520 vatpic_read(struct vatpic *vatpic, struct atpic *atpic, bool in, int port,
521 	    int bytes, uint32_t *eax)
522 {
523 	VATPIC_LOCK(vatpic);
524 
525 	if (atpic->poll) {
526 		VATPIC_CTR0(vatpic, "vatpic polled mode not supported");
527 		VATPIC_UNLOCK(vatpic);
528 		return (-1);
529 	} else {
530 		if (port & ICU_IMR_OFFSET) {
531 			/* read interrrupt mask register */
532 			*eax = atpic->mask;
533 		} else {
534 			if (atpic->rd_cmd_reg == OCW3_RIS) {
535 				/* read interrupt service register */
536 				*eax = atpic->service;
537 			} else {
538 				/* read interrupt request register */
539 				*eax = atpic->request;
540 			}
541 		}
542 	}
543 
544 	VATPIC_UNLOCK(vatpic);
545 
546 	return (0);
547 
548 }
549 
550 static int
551 vatpic_write(struct vatpic *vatpic, struct atpic *atpic, bool in, int port,
552     int bytes, uint32_t *eax)
553 {
554 	int error;
555 	uint8_t val;
556 
557 	val = *eax;
558 
559 	VATPIC_LOCK(vatpic);
560 
561 	if (port & ICU_IMR_OFFSET) {
562 		if (atpic->ready) {
563 			error = vatpic_ocw1(vatpic, atpic, val);
564 		} else {
565 			switch (atpic->icw_num) {
566 			case 2:
567 				error = vatpic_icw2(vatpic, atpic, val);
568 				break;
569 			case 3:
570 				error = vatpic_icw3(vatpic, atpic, val);
571 				break;
572 			case 4:
573 				error = vatpic_icw4(vatpic, atpic, val);
574 				break;
575 			}
576 		}
577 	} else {
578 		if (val & (1 << 4))
579 			error = vatpic_icw1(vatpic, atpic, val);
580 
581 		if (atpic->ready) {
582 			if (val & (1 << 3))
583 				error = vatpic_ocw3(vatpic, atpic, val);
584 			else
585 				error = vatpic_ocw2(vatpic, atpic, val);
586 		}
587 	}
588 
589 	if (atpic->ready)
590 		vatpic_notify_intr(vatpic);
591 
592 	VATPIC_UNLOCK(vatpic);
593 
594 	return (error);
595 }
596 
597 int
598 vatpic_master_handler(void *vm, int vcpuid, bool in, int port, int bytes,
599     uint32_t *eax)
600 {
601 	struct vatpic *vatpic;
602 	struct atpic *atpic;
603 
604 	vatpic = vm_atpic(vm);
605 	atpic = &vatpic->atpic[0];
606 
607 	if (bytes != 1)
608 		return (-1);
609 
610 	if (in) {
611 		return (vatpic_read(vatpic, atpic, in, port, bytes, eax));
612 	}
613 
614 	return (vatpic_write(vatpic, atpic, in, port, bytes, eax));
615 }
616 
617 int
618 vatpic_slave_handler(void *vm, int vcpuid, bool in, int port, int bytes,
619     uint32_t *eax)
620 {
621 	struct vatpic *vatpic;
622 	struct atpic *atpic;
623 
624 	vatpic = vm_atpic(vm);
625 	atpic = &vatpic->atpic[1];
626 
627 	if (bytes != 1)
628 		return (-1);
629 
630 	if (in) {
631 		return (vatpic_read(vatpic, atpic, in, port, bytes, eax));
632 	}
633 
634 	return (vatpic_write(vatpic, atpic, in, port, bytes, eax));
635 }
636 
637 int
638 vatpic_elc_handler(void *vm, int vcpuid, bool in, int port, int bytes,
639     uint32_t *eax)
640 {
641 	struct vatpic *vatpic;
642 	bool is_master;
643 
644 	vatpic = vm_atpic(vm);
645 	is_master = (port == IO_ELCR1);
646 
647 	if (bytes != 1)
648 		return (-1);
649 
650 	VATPIC_LOCK(vatpic);
651 
652 	if (in) {
653 		if (is_master)
654 			*eax = vatpic->elc[0];
655 		else
656 			*eax = vatpic->elc[1];
657 	} else {
658 		/*
659 		 * For the master PIC the cascade channel (IRQ2), the
660 		 * heart beat timer (IRQ0), and the keyboard
661 		 * controller (IRQ1) cannot be programmed for level
662 		 * mode.
663 		 *
664 		 * For the slave PIC the real time clock (IRQ8) and
665 		 * the floating point error interrupt (IRQ13) cannot
666 		 * be programmed for level mode.
667 		 */
668 		if (is_master)
669 			vatpic->elc[0] = (*eax & 0xf8);
670 		else
671 			vatpic->elc[1] = (*eax & 0xde);
672 	}
673 
674 	VATPIC_UNLOCK(vatpic);
675 
676 	return (0);
677 }
678 
679 struct vatpic *
680 vatpic_init(struct vm *vm)
681 {
682 	struct vatpic *vatpic;
683 
684 	vatpic = malloc(sizeof(struct vatpic), M_VATPIC, M_WAITOK | M_ZERO);
685 	vatpic->vm = vm;
686 
687 	mtx_init(&vatpic->mtx, "vatpic lock", NULL, MTX_SPIN);
688 
689 	return (vatpic);
690 }
691 
692 void
693 vatpic_cleanup(struct vatpic *vatpic)
694 {
695 	free(vatpic, M_VATPIC);
696 }
697