svn commit: r276323 - head/sys/amd64/vmm/io
Neel Natu
neel at FreeBSD.org
Sun Dec 28 00:53:53 UTC 2014
Author: neel
Date: Sun Dec 28 00:53:52 2014
New Revision: 276323
URL: https://svnweb.freebsd.org/changeset/base/276323
Log:
Implement "special mask mode" in vatpic.
OpenBSD guests always enable "special mask mode" during boot. As a result of
r275952 this is flagged as an error and the guest cannot boot.
Reviewed by: grehan
Differential Revision: https://reviews.freebsd.org/D1384
MFC after: 1 week
Modified:
head/sys/amd64/vmm/io/vatpic.c
Modified: head/sys/amd64/vmm/io/vatpic.c
==============================================================================
--- head/sys/amd64/vmm/io/vatpic.c Sat Dec 27 23:19:08 2014 (r276322)
+++ head/sys/amd64/vmm/io/vatpic.c Sun Dec 28 00:53:52 2014 (r276323)
@@ -73,6 +73,7 @@ struct atpic {
uint8_t request; /* Interrupt Request Register (IIR) */
uint8_t service; /* Interrupt Service (ISR) */
uint8_t mask; /* Interrupt Mask Register (IMR) */
+ uint8_t smm; /* special mask mode */
int acnt[8]; /* sum of pin asserts and deasserts */
int lowprio; /* lowest priority irq */
@@ -131,8 +132,16 @@ vatpic_get_highest_isrpin(struct atpic *
ATPIC_PIN_FOREACH(pin, atpic, i) {
bit = (1 << pin);
- if (atpic->service & bit)
- return (pin);
+ if (atpic->service & bit) {
+ /*
+ * An IS bit that is masked by an IMR bit will not be
+ * cleared by a non-specific EOI in Special Mask Mode.
+ */
+ if (atpic->smm && (atpic->mask & bit) != 0)
+ continue;
+ else
+ return (pin);
+ }
}
return (-1);
@@ -153,6 +162,15 @@ vatpic_get_highest_irrpin(struct atpic *
if (atpic->sfn)
serviced &= ~(1 << 2);
+ /*
+ * In 'Special Mask Mode', when a mask bit is set in OCW1 it inhibits
+ * further interrupts at that level and enables interrupts from all
+ * other levels that are not masked. In other words the ISR has no
+ * bearing on the levels that can generate interrupts.
+ */
+ if (atpic->smm)
+ serviced = 0;
+
ATPIC_PIN_FOREACH(pin, atpic, tmp) {
bit = 1 << pin;
@@ -261,6 +279,7 @@ vatpic_icw1(struct vatpic *vatpic, struc
atpic->lowprio = 7;
atpic->rd_cmd_reg = 0;
atpic->poll = 0;
+ atpic->smm = 0;
if ((val & ICW1_SNGL) != 0) {
VATPIC_CTR0(vatpic, "vatpic cascade mode required");
@@ -375,8 +394,10 @@ vatpic_ocw3(struct vatpic *vatpic, struc
VATPIC_CTR1(vatpic, "atpic ocw3 0x%x", val);
if (val & OCW3_ESMM) {
- VATPIC_CTR0(vatpic, "atpic special mask mode not implemented");
- return (-1);
+ atpic->smm = val & OCW3_SMM ? 1 : 0;
+ VATPIC_CTR2(vatpic, "%s atpic special mask mode %s",
+ master_atpic(vatpic, atpic) ? "master" : "slave",
+ atpic->smm ? "enabled" : "disabled");
}
if (val & OCW3_RR) {
More information about the svn-src-all
mailing list