vatpic.c revision 276349
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: stable/10/sys/amd64/vmm/io/vatpic.c 276349 2014-12-28 21:27:13Z neel $");
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
50static 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
56enum irqstate {
57	IRQSTATE_ASSERT,
58	IRQSTATE_DEASSERT,
59	IRQSTATE_PULSE
60};
61
62struct 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
83struct 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
105static void vatpic_set_pinstate(struct vatpic *vatpic, int pin, bool newstate);
106
107static __inline int
108vatpic_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
124static __inline int
125vatpic_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
157static void
158vatpic_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		 * From Section 3.6.2, "Interrupt Modes", in the
199		 * MPtable Specification, Version 1.4
200		 *
201		 * PIC interrupts are routed to both the Local APIC
202		 * and the I/O APIC to support operation in 1 of 3
203		 * modes.
204		 *
205		 * 1. Legacy PIC Mode: the PIC effectively bypasses
206		 * all APIC components.  In this mode the local APIC is
207		 * disabled and LINT0 is reconfigured as INTR to
208		 * deliver the PIC interrupt directly to the CPU.
209		 *
210		 * 2. Virtual Wire Mode: the APIC is treated as a
211		 * virtual wire which delivers interrupts from the PIC
212		 * to the CPU.  In this mode LINT0 is programmed as
213		 * ExtINT to indicate that the PIC is the source of
214		 * the interrupt.
215		 *
216		 * 3. Virtual Wire Mode via I/O APIC: PIC interrupts are
217		 * fielded by the I/O APIC and delivered to the appropriate
218		 * CPU.  In this mode the I/O APIC input 0 is programmed
219		 * as ExtINT to indicate that the PIC is the source of the
220		 * interrupt.
221		 */
222		atpic->intr_raised = true;
223		lapic_set_local_intr(vatpic->vm, -1, APIC_LVT_LINT0);
224		vioapic_pulse_irq(vatpic->vm, 0);
225	} else {
226		VATPIC_CTR3(vatpic, "atpic master no eligible interrupts "
227		    "(imr 0x%x irr 0x%x isr 0x%x)",
228		    atpic->mask, atpic->request, atpic->service);
229	}
230}
231
232static int
233vatpic_icw1(struct vatpic *vatpic, struct atpic *atpic, uint8_t val)
234{
235	VATPIC_CTR1(vatpic, "atpic icw1 0x%x", val);
236
237	atpic->ready = false;
238
239	atpic->icw_num = 1;
240	atpic->mask = 0;
241	atpic->priority = 0;
242	atpic->rd_cmd_reg = 0;
243
244	if ((val & ICW1_SNGL) != 0) {
245		VATPIC_CTR0(vatpic, "vatpic cascade mode required");
246		return (-1);
247	}
248
249	if ((val & ICW1_IC4) == 0) {
250		VATPIC_CTR0(vatpic, "vatpic icw4 required");
251		return (-1);
252	}
253
254	atpic->icw_num++;
255
256	return (0);
257}
258
259static int
260vatpic_icw2(struct vatpic *vatpic, struct atpic *atpic, uint8_t val)
261{
262	VATPIC_CTR1(vatpic, "atpic icw2 0x%x", val);
263
264	atpic->irq_base = val & 0xf8;
265
266	atpic->icw_num++;
267
268	return (0);
269}
270
271static int
272vatpic_icw3(struct vatpic *vatpic, struct atpic *atpic, uint8_t val)
273{
274	VATPIC_CTR1(vatpic, "atpic icw3 0x%x", val);
275
276	atpic->icw_num++;
277
278	return (0);
279}
280
281static int
282vatpic_icw4(struct vatpic *vatpic, struct atpic *atpic, uint8_t val)
283{
284	VATPIC_CTR1(vatpic, "atpic icw4 0x%x", val);
285
286	if ((val & ICW4_8086) == 0) {
287		VATPIC_CTR0(vatpic, "vatpic microprocessor mode required");
288		return (-1);
289	}
290
291	if ((val & ICW4_AEOI) != 0)
292		atpic->aeoi = true;
293
294	atpic->icw_num = 0;
295	atpic->ready = true;
296
297	return (0);
298}
299
300static int
301vatpic_ocw1(struct vatpic *vatpic, struct atpic *atpic, uint8_t val)
302{
303	VATPIC_CTR1(vatpic, "atpic ocw1 0x%x", val);
304
305	atpic->mask = val & 0xff;
306
307	return (0);
308}
309
310static int
311vatpic_ocw2(struct vatpic *vatpic, struct atpic *atpic, uint8_t val)
312{
313	VATPIC_CTR1(vatpic, "atpic ocw2 0x%x", val);
314
315	atpic->rotate = ((val & OCW2_R) != 0);
316
317	if ((val & OCW2_EOI) != 0) {
318		int isr_bit;
319
320		if ((val & OCW2_SL) != 0) {
321			/* specific EOI */
322			isr_bit = val & 0x7;
323		} else {
324			/* non-specific EOI */
325			isr_bit = vatpic_get_highest_isrpin(atpic);
326		}
327
328		if (isr_bit != -1) {
329			atpic->service &= ~(1 << isr_bit);
330
331			if (atpic->rotate)
332				atpic->priority = isr_bit;
333		}
334	} else if ((val & OCW2_SL) != 0 && atpic->rotate == true) {
335		/* specific priority */
336		atpic->priority = val & 0x7;
337	}
338
339	return (0);
340}
341
342static int
343vatpic_ocw3(struct vatpic *vatpic, struct atpic *atpic, uint8_t val)
344{
345	VATPIC_CTR1(vatpic, "atpic ocw3 0x%x", val);
346
347	atpic->poll = ((val & OCW3_P) != 0);
348
349	if (val & OCW3_RR) {
350		/* read register command */
351		atpic->rd_cmd_reg = val & OCW3_RIS;
352	}
353
354	return (0);
355}
356
357static void
358vatpic_set_pinstate(struct vatpic *vatpic, int pin, bool newstate)
359{
360	struct atpic *atpic;
361	int oldcnt, newcnt;
362	bool level;
363
364	KASSERT(pin >= 0 && pin < 16,
365	    ("vatpic_set_pinstate: invalid pin number %d", pin));
366	KASSERT(VATPIC_LOCKED(vatpic),
367	    ("vatpic_set_pinstate: vatpic is not locked"));
368
369	atpic = &vatpic->atpic[pin >> 3];
370
371	oldcnt = atpic->acnt[pin & 0x7];
372	if (newstate)
373		atpic->acnt[pin & 0x7]++;
374	else
375		atpic->acnt[pin & 0x7]--;
376	newcnt = atpic->acnt[pin & 0x7];
377
378	if (newcnt < 0) {
379		VATPIC_CTR2(vatpic, "atpic pin%d: bad acnt %d", pin, newcnt);
380	}
381
382	level = ((vatpic->elc[pin >> 3] & (1 << (pin & 0x7))) != 0);
383
384	if ((oldcnt == 0 && newcnt == 1) || (newcnt > 0 && level == true)) {
385		/* rising edge or level */
386		VATPIC_CTR1(vatpic, "atpic pin%d: asserted", pin);
387		atpic->request |= (1 << (pin & 0x7));
388	} else if (oldcnt == 1 && newcnt == 0) {
389		/* falling edge */
390		VATPIC_CTR1(vatpic, "atpic pin%d: deasserted", pin);
391	} else {
392		VATPIC_CTR3(vatpic, "atpic pin%d: %s, ignored, acnt %d",
393		    pin, newstate ? "asserted" : "deasserted", newcnt);
394	}
395
396	vatpic_notify_intr(vatpic);
397}
398
399static int
400vatpic_set_irqstate(struct vm *vm, int irq, enum irqstate irqstate)
401{
402	struct vatpic *vatpic;
403	struct atpic *atpic;
404
405	if (irq < 0 || irq > 15)
406		return (EINVAL);
407
408	vatpic = vm_atpic(vm);
409	atpic = &vatpic->atpic[irq >> 3];
410
411	if (atpic->ready == false)
412		return (0);
413
414	VATPIC_LOCK(vatpic);
415	switch (irqstate) {
416	case IRQSTATE_ASSERT:
417		vatpic_set_pinstate(vatpic, irq, true);
418		break;
419	case IRQSTATE_DEASSERT:
420		vatpic_set_pinstate(vatpic, irq, false);
421		break;
422	case IRQSTATE_PULSE:
423		vatpic_set_pinstate(vatpic, irq, true);
424		vatpic_set_pinstate(vatpic, irq, false);
425		break;
426	default:
427		panic("vatpic_set_irqstate: invalid irqstate %d", irqstate);
428	}
429	VATPIC_UNLOCK(vatpic);
430
431	return (0);
432}
433
434int
435vatpic_assert_irq(struct vm *vm, int irq)
436{
437	return (vatpic_set_irqstate(vm, irq, IRQSTATE_ASSERT));
438}
439
440int
441vatpic_deassert_irq(struct vm *vm, int irq)
442{
443	return (vatpic_set_irqstate(vm, irq, IRQSTATE_DEASSERT));
444}
445
446int
447vatpic_pulse_irq(struct vm *vm, int irq)
448{
449	return (vatpic_set_irqstate(vm, irq, IRQSTATE_PULSE));
450}
451
452int
453vatpic_set_irq_trigger(struct vm *vm, int irq, enum vm_intr_trigger trigger)
454{
455	struct vatpic *vatpic;
456
457	if (irq < 0 || irq > 15)
458		return (EINVAL);
459
460	/*
461	 * See comment in vatpic_elc_handler.  These IRQs must be
462	 * edge triggered.
463	 */
464	if (trigger == LEVEL_TRIGGER) {
465		switch (irq) {
466		case 0:
467		case 1:
468		case 2:
469		case 8:
470		case 13:
471			return (EINVAL);
472		}
473	}
474
475	vatpic = vm_atpic(vm);
476
477	VATPIC_LOCK(vatpic);
478
479	if (trigger == LEVEL_TRIGGER)
480		vatpic->elc[irq >> 3] |=  1 << (irq & 0x7);
481	else
482		vatpic->elc[irq >> 3] &=  ~(1 << (irq & 0x7));
483
484	VATPIC_UNLOCK(vatpic);
485
486	return (0);
487}
488
489void
490vatpic_pending_intr(struct vm *vm, int *vecptr)
491{
492	struct vatpic *vatpic;
493	struct atpic *atpic;
494	int pin;
495
496	vatpic = vm_atpic(vm);
497
498	atpic = &vatpic->atpic[0];
499
500	VATPIC_LOCK(vatpic);
501
502	pin = vatpic_get_highest_irrpin(atpic);
503	if (pin == 2) {
504		atpic = &vatpic->atpic[1];
505		pin = vatpic_get_highest_irrpin(atpic);
506	}
507
508	/*
509	 * If there are no pins active at this moment then return the spurious
510	 * interrupt vector instead.
511	 */
512	if (pin == -1)
513		pin = 7;
514
515	KASSERT(pin >= 0 && pin <= 7, ("%s: invalid pin %d", __func__, pin));
516	*vecptr = atpic->irq_base + pin;
517
518	VATPIC_UNLOCK(vatpic);
519}
520
521static void
522vatpic_pin_accepted(struct atpic *atpic, int pin)
523{
524	atpic->intr_raised = false;
525
526	if (atpic->acnt[pin] == 0)
527		atpic->request &= ~(1 << pin);
528
529	if (atpic->aeoi == true) {
530		if (atpic->rotate == true)
531			atpic->priority = pin;
532	} else {
533		atpic->service |= (1 << pin);
534	}
535}
536
537void
538vatpic_intr_accepted(struct vm *vm, int vector)
539{
540	struct vatpic *vatpic;
541	int pin;
542
543	vatpic = vm_atpic(vm);
544
545	VATPIC_LOCK(vatpic);
546
547	pin = vector & 0x7;
548
549	if ((vector & ~0x7) == vatpic->atpic[1].irq_base) {
550		vatpic_pin_accepted(&vatpic->atpic[1], pin);
551		/*
552		 * If this vector originated from the slave,
553		 * accept the cascaded interrupt too.
554		 */
555		vatpic_pin_accepted(&vatpic->atpic[0], 2);
556	} else {
557		vatpic_pin_accepted(&vatpic->atpic[0], pin);
558	}
559
560	vatpic_notify_intr(vatpic);
561
562	VATPIC_UNLOCK(vatpic);
563}
564
565static int
566vatpic_read(struct vatpic *vatpic, struct atpic *atpic, bool in, int port,
567	    int bytes, uint32_t *eax)
568{
569	VATPIC_LOCK(vatpic);
570
571	if (atpic->poll) {
572		VATPIC_CTR0(vatpic, "vatpic polled mode not supported");
573		VATPIC_UNLOCK(vatpic);
574		return (-1);
575	} else {
576		if (port & ICU_IMR_OFFSET) {
577			/* read interrrupt mask register */
578			*eax = atpic->mask;
579		} else {
580			if (atpic->rd_cmd_reg == OCW3_RIS) {
581				/* read interrupt service register */
582				*eax = atpic->service;
583			} else {
584				/* read interrupt request register */
585				*eax = atpic->request;
586			}
587		}
588	}
589
590	VATPIC_UNLOCK(vatpic);
591
592	return (0);
593
594}
595
596static int
597vatpic_write(struct vatpic *vatpic, struct atpic *atpic, bool in, int port,
598    int bytes, uint32_t *eax)
599{
600	int error;
601	uint8_t val;
602
603	error = 0;
604	val = *eax;
605
606	VATPIC_LOCK(vatpic);
607
608	if (port & ICU_IMR_OFFSET) {
609		switch (atpic->icw_num) {
610		case 2:
611			error = vatpic_icw2(vatpic, atpic, val);
612			break;
613		case 3:
614			error = vatpic_icw3(vatpic, atpic, val);
615			break;
616		case 4:
617			error = vatpic_icw4(vatpic, atpic, val);
618			break;
619		default:
620			error = vatpic_ocw1(vatpic, atpic, val);
621			break;
622		}
623	} else {
624		if (val & (1 << 4))
625			error = vatpic_icw1(vatpic, atpic, val);
626
627		if (atpic->ready) {
628			if (val & (1 << 3))
629				error = vatpic_ocw3(vatpic, atpic, val);
630			else
631				error = vatpic_ocw2(vatpic, atpic, val);
632		}
633	}
634
635	if (atpic->ready)
636		vatpic_notify_intr(vatpic);
637
638	VATPIC_UNLOCK(vatpic);
639
640	return (error);
641}
642
643int
644vatpic_master_handler(void *vm, int vcpuid, bool in, int port, int bytes,
645    uint32_t *eax)
646{
647	struct vatpic *vatpic;
648	struct atpic *atpic;
649
650	vatpic = vm_atpic(vm);
651	atpic = &vatpic->atpic[0];
652
653	if (bytes != 1)
654		return (-1);
655
656	if (in) {
657		return (vatpic_read(vatpic, atpic, in, port, bytes, eax));
658	}
659
660	return (vatpic_write(vatpic, atpic, in, port, bytes, eax));
661}
662
663int
664vatpic_slave_handler(void *vm, int vcpuid, bool in, int port, int bytes,
665    uint32_t *eax)
666{
667	struct vatpic *vatpic;
668	struct atpic *atpic;
669
670	vatpic = vm_atpic(vm);
671	atpic = &vatpic->atpic[1];
672
673	if (bytes != 1)
674		return (-1);
675
676	if (in) {
677		return (vatpic_read(vatpic, atpic, in, port, bytes, eax));
678	}
679
680	return (vatpic_write(vatpic, atpic, in, port, bytes, eax));
681}
682
683int
684vatpic_elc_handler(void *vm, int vcpuid, bool in, int port, int bytes,
685    uint32_t *eax)
686{
687	struct vatpic *vatpic;
688	bool is_master;
689
690	vatpic = vm_atpic(vm);
691	is_master = (port == IO_ELCR1);
692
693	if (bytes != 1)
694		return (-1);
695
696	VATPIC_LOCK(vatpic);
697
698	if (in) {
699		if (is_master)
700			*eax = vatpic->elc[0];
701		else
702			*eax = vatpic->elc[1];
703	} else {
704		/*
705		 * For the master PIC the cascade channel (IRQ2), the
706		 * heart beat timer (IRQ0), and the keyboard
707		 * controller (IRQ1) cannot be programmed for level
708		 * mode.
709		 *
710		 * For the slave PIC the real time clock (IRQ8) and
711		 * the floating point error interrupt (IRQ13) cannot
712		 * be programmed for level mode.
713		 */
714		if (is_master)
715			vatpic->elc[0] = (*eax & 0xf8);
716		else
717			vatpic->elc[1] = (*eax & 0xde);
718	}
719
720	VATPIC_UNLOCK(vatpic);
721
722	return (0);
723}
724
725struct vatpic *
726vatpic_init(struct vm *vm)
727{
728	struct vatpic *vatpic;
729
730	vatpic = malloc(sizeof(struct vatpic), M_VATPIC, M_WAITOK | M_ZERO);
731	vatpic->vm = vm;
732
733	mtx_init(&vatpic->mtx, "vatpic lock", NULL, MTX_SPIN);
734
735	return (vatpic);
736}
737
738void
739vatpic_cleanup(struct vatpic *vatpic)
740{
741	free(vatpic, M_VATPIC);
742}
743