vpic: change assert/deassert method

use pin_state[pin] to record vpic pin signal, and change the interface name
accordingly.

Tracked-On: #1269
Signed-off-by: Jason Chen CJ <jason.cj.chen@intel.com>
This commit is contained in:
Jason Chen CJ 2018-10-15 12:12:25 +08:00 committed by wenlingz
parent f9a163954d
commit a028567b9c
2 changed files with 26 additions and 35 deletions

View File

@ -35,7 +35,7 @@
#define NR_VPIC_PINS_TOTAL 16U #define NR_VPIC_PINS_TOTAL 16U
#define VPIC_INVALID_PIN 0xffU #define VPIC_INVALID_PIN 0xffU
static void vpic_set_pinstate(struct acrn_vpic *vpic, uint8_t pin, bool newstate); static void vpic_set_pinstate(struct acrn_vpic *vpic, uint8_t pin, uint8_t level);
static inline bool master_pic(struct acrn_vpic *vpic, struct i8259_reg_state *i8259) static inline bool master_pic(struct acrn_vpic *vpic, struct i8259_reg_state *i8259)
{ {
@ -144,8 +144,8 @@ static void vpic_notify_intr(struct acrn_vpic *vpic)
* Cascade the request from the slave to the master. * Cascade the request from the slave to the master.
*/ */
i8259->intr_raised = true; i8259->intr_raised = true;
vpic_set_pinstate(vpic, (uint8_t)2U, true); vpic_set_pinstate(vpic, (uint8_t)2U, 1U);
vpic_set_pinstate(vpic, (uint8_t)2U, false); vpic_set_pinstate(vpic, (uint8_t)2U, 0U);
} else { } else {
dev_dbg(ACRN_DBG_PIC, dev_dbg(ACRN_DBG_PIC,
"pic slave no eligible interrupt (imr 0x%x irr 0x%x isr 0x%x)", "pic slave no eligible interrupt (imr 0x%x irr 0x%x isr 0x%x)",
@ -398,46 +398,37 @@ static int vpic_ocw3(struct acrn_vpic *vpic, struct i8259_reg_state *i8259, uint
/** /**
* @pre pin < NR_VPIC_PINS_TOTAL * @pre pin < NR_VPIC_PINS_TOTAL
*/ */
static void vpic_set_pinstate(struct acrn_vpic *vpic, uint8_t pin, bool newstate) static void vpic_set_pinstate(struct acrn_vpic *vpic, uint8_t pin,
uint8_t level)
{ {
struct i8259_reg_state *i8259; struct i8259_reg_state *i8259;
int oldcnt, newcnt; uint8_t old_lvl;
bool level; bool lvl_trigger;
if (pin >= NR_VPIC_PINS_TOTAL) {
return;
}
i8259 = &vpic->i8259[pin >> 3U]; i8259 = &vpic->i8259[pin >> 3U];
old_lvl = i8259->pin_state[pin & 0x7U];
oldcnt = i8259->acnt[pin & 0x7U]; if (level) {
if (newstate) { i8259->pin_state[pin & 0x7U] = 1U;
i8259->acnt[pin & 0x7U]++;
} else { } else {
i8259->acnt[pin & 0x7U]--; i8259->pin_state[pin & 0x7U] = 0U;
}
newcnt = i8259->acnt[pin & 0x7U];
if (newcnt < 0) {
pr_warn("pic pin%hhu: bad acnt %d\n", pin, newcnt);
} }
level = ((vpic->i8259[pin >> 3U].elc & (1U << (pin & 0x7U))) != 0); lvl_trigger = ((vpic->i8259[pin >> 3U].elc & (1U << (pin & 0x7U))) != 0);
if (((oldcnt == 0) && (newcnt == 1)) || ((newcnt > 0) && (level == true))) { if (((old_lvl == 0U) && (level == 1U)) ||
/* rising edge or level */ ((level == 1U) && (lvl_trigger == true))) {
/* raising edge or level */
dev_dbg(ACRN_DBG_PIC, "pic pin%hhu: asserted\n", pin); dev_dbg(ACRN_DBG_PIC, "pic pin%hhu: asserted\n", pin);
i8259->request |= (uint8_t)(1U << (pin & 0x7U)); i8259->request |= (uint8_t)(1U << (pin & 0x7U));
} else if ((oldcnt == 1) && (newcnt == 0)) { } else if ((old_lvl == 1U) && (level == 0U)) {
/* falling edge */ /* falling edge */
dev_dbg(ACRN_DBG_PIC, "pic pin%hhu: deasserted\n", pin); dev_dbg(ACRN_DBG_PIC, "pic pin%hhu: deasserted\n", pin);
if (level) { if (lvl_trigger) {
i8259->request &= ~(uint8_t)(1U << (pin & 0x7U)); i8259->request &= ~(uint8_t)(1U << (pin & 0x7U));
} }
} else { } else {
dev_dbg(ACRN_DBG_PIC, dev_dbg(ACRN_DBG_PIC, "pic pin%hhu: %s, ignored\n",
"pic pin%hhu: %s, ignored, acnt %d\n", pin, level ? "asserted" : "deasserted");
pin, newstate ? "asserted" : "deasserted", newcnt);
} }
vpic_notify_intr(vpic); vpic_notify_intr(vpic);
@ -472,18 +463,18 @@ void vpic_set_irq(struct vm *vm, uint32_t irq, uint32_t operation)
spinlock_obtain(&(vpic->lock)); spinlock_obtain(&(vpic->lock));
switch (operation) { switch (operation) {
case GSI_SET_HIGH: case GSI_SET_HIGH:
vpic_set_pinstate(vpic, pin, true); vpic_set_pinstate(vpic, pin, 1U);
break; break;
case GSI_SET_LOW: case GSI_SET_LOW:
vpic_set_pinstate(vpic, pin, false); vpic_set_pinstate(vpic, pin, 0U);
break; break;
case GSI_RAISING_PULSE: case GSI_RAISING_PULSE:
vpic_set_pinstate(vpic, pin, true); vpic_set_pinstate(vpic, pin, 1U);
vpic_set_pinstate(vpic, pin, false); vpic_set_pinstate(vpic, pin, 0U);
break; break;
case GSI_FALLING_PULSE: case GSI_FALLING_PULSE:
vpic_set_pinstate(vpic, pin, false); vpic_set_pinstate(vpic, pin, 0U);
vpic_set_pinstate(vpic, pin, true); vpic_set_pinstate(vpic, pin, 1U);
break; break;
default: default:
/* /*

View File

@ -106,7 +106,7 @@ struct i8259_reg_state {
uint8_t mask; /* Interrupt Mask Register (IMR) */ uint8_t mask; /* Interrupt Mask Register (IMR) */
uint8_t smm; /* special mask mode */ uint8_t smm; /* special mask mode */
int acnt[8]; /* sum of pin asserts and deasserts */ uint8_t pin_state[8]; /* pin state for level */
uint8_t lowprio; /* lowest priority irq */ uint8_t lowprio; /* lowest priority irq */
bool intr_raised; bool intr_raised;