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