diff --git a/hypervisor/arch/x86/assign.c b/hypervisor/arch/x86/assign.c index 4f885b4cb..107d66839 100644 --- a/hypervisor/arch/x86/assign.c +++ b/hypervisor/arch/x86/assign.c @@ -54,9 +54,9 @@ ptirq_lookup_entry_by_vpin(const struct acrn_vm *vm, uint32_t virt_pin, bool pic return entry; } -static uint64_t calculate_logical_dest_mask(uint64_t pdmask) +static uint32_t calculate_logical_dest_mask(uint64_t pdmask) { - uint64_t dest_mask = 0UL; + uint32_t dest_mask = 0UL; uint64_t pcpu_mask = pdmask; uint16_t pcpu_id; @@ -72,8 +72,8 @@ static uint64_t calculate_logical_dest_mask(uint64_t pdmask) static void ptirq_build_physical_msi(struct acrn_vm *vm, struct ptirq_msi_info *info, uint32_t vector) { - uint64_t vdmask, pdmask, dest_mask; - uint32_t dest, delmode; + uint64_t vdmask, pdmask; + uint32_t dest, delmode, dest_mask; bool phys; /* get physical destination cpu mask */ @@ -114,8 +114,8 @@ ptirq_build_physical_rte(struct acrn_vm *vm, struct ptirq_remapping_info *entry) union source_id *virt_sid = &entry->virt_sid; if (virt_sid->intx_id.src == PTDEV_VPIN_IOAPIC) { - uint64_t vdmask, pdmask, delmode, dest_mask, vector; - uint32_t dest; + uint64_t vdmask, pdmask; + uint32_t dest, delmode, dest_mask, vector; union ioapic_rte virt_rte; bool phys; @@ -123,7 +123,7 @@ ptirq_build_physical_rte(struct acrn_vm *vm, struct ptirq_remapping_info *entry) rte = virt_rte; /* init polarity & pin state */ - if ((rte.full & IOAPIC_RTE_INTPOL) != 0UL) { + if (rte.bits.intr_polarity == IOAPIC_RTE_INTPOL_ALO) { if (entry->polarity == 0U) { vioapic_set_irqline_nolock(vm, virt_sid->intx_id.pin, GSI_SET_HIGH); } @@ -136,27 +136,27 @@ ptirq_build_physical_rte(struct acrn_vm *vm, struct ptirq_remapping_info *entry) } /* physical destination cpu mask */ - phys = ((virt_rte.full & IOAPIC_RTE_DESTMOD) == IOAPIC_RTE_DESTPHY); - dest = (uint32_t)(virt_rte.full >> IOAPIC_RTE_DEST_SHIFT); + phys = (virt_rte.bits.dest_mode == IOAPIC_RTE_DESTMODE_PHY); + dest = (uint32_t)virt_rte.bits.dest_field; vlapic_calcdest(vm, &vdmask, dest, phys, false); pdmask = vcpumask2pcpumask(vm, vdmask); /* physical delivery mode */ - delmode = virt_rte.full & IOAPIC_RTE_DELMOD; - if ((delmode != IOAPIC_RTE_DELFIXED) && - (delmode != IOAPIC_RTE_DELLOPRI)) { - delmode = IOAPIC_RTE_DELLOPRI; + delmode = virt_rte.bits.delivery_mode; + if ((delmode != IOAPIC_RTE_DELMODE_FIXED) && + (delmode != IOAPIC_RTE_DELMODE_LOPRI)) { + delmode = IOAPIC_RTE_DELMODE_LOPRI; } /* update physical delivery mode, dest mode(logical) & vector */ - vector = (uint64_t)irq_to_vector(phys_irq); - rte.full &= ~(IOAPIC_RTE_DESTMOD | IOAPIC_RTE_DELMOD | IOAPIC_RTE_INTVEC); - rte.full |= IOAPIC_RTE_DESTLOG | delmode | vector; + vector = irq_to_vector(phys_irq); + rte.bits.dest_mode = IOAPIC_RTE_DESTMODE_LOGICAL; + rte.bits.delivery_mode = delmode; + rte.bits.vector = vector; dest_mask = calculate_logical_dest_mask(pdmask); /* update physical dest field */ - rte.full &= ~IOAPIC_RTE_DEST_MASK; - rte.full |= dest_mask << IOAPIC_RTE_DEST_SHIFT; + rte.bits.dest_field = dest_mask; dev_dbg(ACRN_DBG_IRQ, "IOAPIC RTE = 0x%x:%x(V) -> 0x%x:%x(P)", virt_rte.u.hi_32, virt_rte.u.lo_32, @@ -167,10 +167,11 @@ ptirq_build_physical_rte(struct acrn_vm *vm, struct ptirq_remapping_info *entry) /* just update trigger mode */ ioapic_get_rte(phys_irq, &phys_rte); - rte.full = phys_rte.full & (~IOAPIC_RTE_TRGRMOD); - vpic_get_irqline_trigger_mode(vm, virt_sid->intx_id.pin, &trigger); + rte = phys_rte; + rte.bits.trigger_mode = IOAPIC_RTE_TRGRMODE_EDGE; + vpic_get_irqline_trigger_mode(vm, (uint32_t)virt_sid->intx_id.pin, &trigger); if (trigger == LEVEL_TRIGGER) { - rte.full |= IOAPIC_RTE_TRGRLVL; + rte.bits.trigger_mode = IOAPIC_RTE_TRGRMODE_LEVEL; } dev_dbg(ACRN_DBG_IRQ, "IOAPIC RTE = 0x%x:%x(P) -> 0x%x:%x(P)", @@ -367,8 +368,8 @@ static void ptirq_handle_intx(struct acrn_vm *vm, bool trigger_lvl = false; /* VPIN_IOAPIC src means we have vioapic enabled */ - vioapic_get_rte(vm, virt_sid->intx_id.pin, &rte); - if ((rte.full & IOAPIC_RTE_TRGRMOD) == IOAPIC_RTE_TRGRLVL) { + vioapic_get_rte(vm, (uint32_t)virt_sid->intx_id.pin, &rte); + if (rte.bits.trigger_mode == IOAPIC_RTE_TRGRMODE_LEVEL) { trigger_lvl = true; } @@ -557,7 +558,7 @@ static void activate_physical_ioapic(struct acrn_vm *vm, { union ioapic_rte rte; uint32_t phys_irq = entry->allocated_pirq; - uint32_t intr_mask; + uint64_t intr_mask; bool is_lvl_trigger = false; /* disable interrupt */ @@ -565,19 +566,19 @@ static void activate_physical_ioapic(struct acrn_vm *vm, /* build physical IOAPIC RTE */ rte = ptirq_build_physical_rte(vm, entry); - intr_mask = (uint32_t)(rte.full & IOAPIC_RTE_INTMASK); + intr_mask = rte.bits.intr_mask; /* update irq trigger mode according to info in guest */ - if ((rte.full & IOAPIC_RTE_TRGRMOD) == IOAPIC_RTE_TRGRLVL) { + if (rte.bits.trigger_mode == IOAPIC_RTE_TRGRMODE_LEVEL) { is_lvl_trigger = true; } set_irq_trigger_mode(phys_irq, is_lvl_trigger); /* set rte entry when masked */ - rte.full |= IOAPIC_RTE_INTMSET; + rte.bits.intr_mask = IOAPIC_RTE_MASK_SET; ioapic_set_rte(phys_irq, rte); - if (intr_mask == IOAPIC_RTE_INTMCLR) { + if (intr_mask == IOAPIC_RTE_MASK_CLR) { ioapic_gsi_unmask_irq(phys_irq); } } diff --git a/hypervisor/arch/x86/guest/vlapic.c b/hypervisor/arch/x86/guest/vlapic.c index 3deef4925..8f2c25c1b 100644 --- a/hypervisor/arch/x86/guest/vlapic.c +++ b/hypervisor/arch/x86/guest/vlapic.c @@ -1806,13 +1806,13 @@ vlapic_deliver_intr(struct acrn_vm *vm, bool level, uint32_t dest, bool phys, uint64_t dmask; struct acrn_vcpu *target_vcpu; - if ((delmode != IOAPIC_RTE_DELFIXED) && - (delmode != IOAPIC_RTE_DELLOPRI) && - (delmode != IOAPIC_RTE_DELEXINT)) { + if ((delmode != IOAPIC_RTE_DELMODE_FIXED) && + (delmode != IOAPIC_RTE_DELMODE_LOPRI) && + (delmode != IOAPIC_RTE_DELMODE_EXINT)) { dev_dbg(ACRN_DBG_LAPIC, "vlapic intr invalid delmode %#x", delmode); } else { - lowprio = (delmode == IOAPIC_RTE_DELLOPRI) || rh; + lowprio = (delmode == IOAPIC_RTE_DELMODE_LOPRI) || rh; /* * We don't provide any virtual interrupt redirection hardware so @@ -1829,7 +1829,7 @@ vlapic_deliver_intr(struct acrn_vm *vm, bool level, uint32_t dest, bool phys, /* only make request when vlapic enabled */ vlapic = vcpu_vlapic(target_vcpu); if (vlapic_enabled(vlapic)) { - if (delmode == IOAPIC_RTE_DELEXINT) { + if (delmode == IOAPIC_RTE_DELMODE_EXINT) { vcpu_inject_extint(target_vcpu); } else { vlapic_set_intr(target_vcpu, vec, level); diff --git a/hypervisor/arch/x86/ioapic.c b/hypervisor/arch/x86/ioapic.c index dafeef2d1..4840b69f6 100644 --- a/hypervisor/arch/x86/ioapic.c +++ b/hypervisor/arch/x86/ioapic.c @@ -45,23 +45,23 @@ static const uint32_t legacy_irq_to_pin[NR_LEGACY_IRQ] = { 15U, /* IRQ15*/ }; -static const uint64_t legacy_irq_trigger_mode[NR_LEGACY_IRQ] = { - IOAPIC_RTE_TRGREDG, /* IRQ0*/ - IOAPIC_RTE_TRGREDG, /* IRQ1*/ - IOAPIC_RTE_TRGREDG, /* IRQ2*/ - IOAPIC_RTE_TRGREDG, /* IRQ3*/ - IOAPIC_RTE_TRGREDG, /* IRQ4*/ - IOAPIC_RTE_TRGREDG, /* IRQ5*/ - IOAPIC_RTE_TRGREDG, /* IRQ6*/ - IOAPIC_RTE_TRGREDG, /* IRQ7*/ - IOAPIC_RTE_TRGREDG, /* IRQ8*/ - IOAPIC_RTE_TRGRLVL, /* IRQ9*/ - IOAPIC_RTE_TRGREDG, /* IRQ10*/ - IOAPIC_RTE_TRGREDG, /* IRQ11*/ - IOAPIC_RTE_TRGREDG, /* IRQ12*/ - IOAPIC_RTE_TRGREDG, /* IRQ13*/ - IOAPIC_RTE_TRGREDG, /* IRQ14*/ - IOAPIC_RTE_TRGREDG, /* IRQ15*/ +static const uint32_t legacy_irq_trigger_mode[NR_LEGACY_IRQ] = { + IOAPIC_RTE_TRGRMODE_EDGE, /* IRQ0*/ + IOAPIC_RTE_TRGRMODE_EDGE, /* IRQ1*/ + IOAPIC_RTE_TRGRMODE_EDGE, /* IRQ2*/ + IOAPIC_RTE_TRGRMODE_EDGE, /* IRQ3*/ + IOAPIC_RTE_TRGRMODE_EDGE, /* IRQ4*/ + IOAPIC_RTE_TRGRMODE_EDGE, /* IRQ5*/ + IOAPIC_RTE_TRGRMODE_EDGE, /* IRQ6*/ + IOAPIC_RTE_TRGRMODE_EDGE, /* IRQ7*/ + IOAPIC_RTE_TRGRMODE_EDGE, /* IRQ8*/ + IOAPIC_RTE_TRGRMODE_LEVEL, /* IRQ9*/ + IOAPIC_RTE_TRGRMODE_EDGE, /* IRQ10*/ + IOAPIC_RTE_TRGRMODE_EDGE, /* IRQ11*/ + IOAPIC_RTE_TRGRMODE_EDGE, /* IRQ12*/ + IOAPIC_RTE_TRGRMODE_EDGE, /* IRQ13*/ + IOAPIC_RTE_TRGRMODE_EDGE, /* IRQ14*/ + IOAPIC_RTE_TRGRMODE_EDGE, /* IRQ15*/ }; static const uint32_t pic_ioapic_pin_map[NR_LEGACY_PIN] = { @@ -184,17 +184,18 @@ create_rte_for_legacy_irq(uint32_t irq, uint32_t vr) * before we have ACPI table parsing in HV we use common hardcode */ - rte.full = IOAPIC_RTE_INTMSET; - rte.full |= legacy_irq_trigger_mode[irq]; - rte.full |= DEFAULT_DEST_MODE; - rte.full |= DEFAULT_DELIVERY_MODE; - rte.full |= (IOAPIC_RTE_INTVEC & (uint64_t)vr); + rte.full = 0UL; + rte.bits.intr_mask = IOAPIC_RTE_MASK_SET; + rte.bits.trigger_mode = legacy_irq_trigger_mode[irq]; + rte.bits.dest_mode = DEFAULT_DEST_MODE; + rte.bits.delivery_mode = DEFAULT_DELIVERY_MODE; + rte.bits.vector = vr; /* Fixed to active high */ - rte.full |= IOAPIC_RTE_INTAHI; + rte.bits.intr_polarity = IOAPIC_RTE_INTPOL_AHI; /* Dest field: legacy irq fixed to CPU0 */ - rte.full |= (1UL << IOAPIC_RTE_DEST_SHIFT); + rte.bits.dest_field = 1U; return rte; } @@ -204,21 +205,23 @@ create_rte_for_gsi_irq(uint32_t irq, uint32_t vr) { union ioapic_rte rte; + rte.full = 0UL; + if (irq < NR_LEGACY_IRQ) { rte = create_rte_for_legacy_irq(irq, vr); } else { /* irq default masked, level trig */ - rte.full = IOAPIC_RTE_INTMSET; - rte.full |= IOAPIC_RTE_TRGRLVL; - rte.full |= DEFAULT_DEST_MODE; - rte.full |= DEFAULT_DELIVERY_MODE; - rte.full |= (IOAPIC_RTE_INTVEC & (uint64_t)vr); + rte.bits.intr_mask = IOAPIC_RTE_MASK_SET; + rte.bits.trigger_mode = IOAPIC_RTE_TRGRMODE_LEVEL; + rte.bits.dest_mode = DEFAULT_DEST_MODE; + rte.bits.delivery_mode = DEFAULT_DELIVERY_MODE; + rte.bits.vector = vr; /* Fixed to active high */ - rte.full |= IOAPIC_RTE_INTAHI; + rte.bits.intr_polarity = IOAPIC_RTE_INTPOL_AHI; /* Dest field */ - rte.full |= (ALL_CPUS_MASK << IOAPIC_RTE_DEST_SHIFT); + rte.bits.dest_field = ALL_CPUS_MASK; } return rte; @@ -233,7 +236,7 @@ static void ioapic_set_routing(uint32_t gsi, uint32_t vr) rte = create_rte_for_gsi_irq(gsi, vr); ioapic_set_rte_entry(addr, gsi_table_data[gsi].pin, rte); - if ((rte.full & IOAPIC_RTE_TRGRMOD) != 0UL) { + if (rte.bits.trigger_mode == IOAPIC_RTE_TRGRMODE_LEVEL) { set_irq_trigger_mode(gsi, true); } else { set_irq_trigger_mode(gsi, false); @@ -322,9 +325,9 @@ ioapic_irq_gsi_mask_unmask(uint32_t irq, bool mask) if (addr != NULL) { ioapic_get_rte_entry(addr, pin, &rte); if (mask) { - rte.full |= IOAPIC_RTE_INTMSET; + rte.bits.intr_mask = IOAPIC_RTE_MASK_SET; } else { - rte.full &= ~IOAPIC_RTE_INTMASK; + rte.bits.intr_mask = IOAPIC_RTE_MASK_CLR; } ioapic_set_rte_entry(addr, pin, rte); dev_dbg(ACRN_DBG_PTIRQ, "update: irq:%d pin:%hhu rte:%lx", diff --git a/hypervisor/debug/shell.c b/hypervisor/debug/shell.c index 86ca79066..82fe9d295 100644 --- a/hypervisor/debug/shell.c +++ b/hypervisor/debug/shell.c @@ -927,8 +927,8 @@ static void get_entry_info(const struct ptirq_remapping_info *entry, char *type, (void)strncpy_s(type, 16U, "PIC", 16U); } ioapic_get_rte(phys_irq, &rte); - *dest = rte.full >> IOAPIC_RTE_DEST_SHIFT; - if ((rte.full & IOAPIC_RTE_TRGRLVL) != 0UL) { + *dest = rte.bits.dest_field; + if (rte.bits.trigger_mode == IOAPIC_RTE_TRGRMODE_LEVEL) { *lvl_tm = true; } else { *lvl_tm = false; @@ -1047,13 +1047,13 @@ static void get_vioapic_info(char *str_arg, size_t str_max, uint16_t vmid) rte.full = 0UL; for (pin = 0U; pin < pincount; pin++) { vioapic_get_rte(vm, pin, &rte); - mask = ((rte.full & IOAPIC_RTE_INTMASK) == IOAPIC_RTE_INTMSET); - remote_irr = ((rte.full & IOAPIC_RTE_REM_IRR) == IOAPIC_RTE_REM_IRR); - phys = ((rte.full & IOAPIC_RTE_DESTMOD) == IOAPIC_RTE_DESTPHY); - delmode = (uint32_t)(rte.full & IOAPIC_RTE_DELMOD); - level = ((rte.full & IOAPIC_RTE_TRGRLVL) != 0UL); - vector = rte.u.lo_32 & IOAPIC_RTE_LOW_INTVEC; - dest = (uint32_t)(rte.full >> IOAPIC_RTE_DEST_SHIFT); + mask = (rte.bits.intr_mask == IOAPIC_RTE_MASK_SET); + remote_irr = (rte.bits.remote_irr == IOAPIC_RTE_REM_IRR); + phys = (rte.bits.dest_mode == IOAPIC_RTE_DESTMODE_PHY); + delmode = rte.bits.delivery_mode; + level = (rte.bits.trigger_mode == IOAPIC_RTE_TRGRMODE_LEVEL); + vector = rte.bits.vector; + dest = rte.bits.dest_field; len = snprintf(str, size, "\r\n%hhu\t0x%X\t%s\t0x%X\t%s\t%u\t%d\t%d", pin, vector, phys ? "phys" : "logic", dest, level ? "level" : "edge", @@ -1092,18 +1092,6 @@ static int32_t shell_show_vioapic_info(int32_t argc, char **argv) return -EINVAL; } -static void get_rte_info(union ioapic_rte rte, bool *mask, bool *irr, - bool *phys, uint32_t *delmode, bool *level, uint32_t *vector, uint32_t *dest) -{ - *mask = ((rte.full & IOAPIC_RTE_INTMASK) == IOAPIC_RTE_INTMSET); - *irr = ((rte.full & IOAPIC_RTE_REM_IRR) == IOAPIC_RTE_REM_IRR); - *phys = ((rte.full & IOAPIC_RTE_DESTMOD) == IOAPIC_RTE_DESTPHY); - *delmode = (uint32_t)(rte.full & IOAPIC_RTE_DELMOD); - *level = ((rte.full & IOAPIC_RTE_TRGRLVL) != 0UL); - *vector = (uint32_t)(rte.full & IOAPIC_RTE_INTVEC); - *dest = (uint32_t)(rte.full >> APIC_ID_SHIFT); -} - /** * @brief Get information of ioapic * @@ -1133,9 +1121,6 @@ static int32_t get_ioapic_info(char *str_arg, size_t str_max_len) uint32_t pin = ioapic_irq_to_pin(irq); union ioapic_rte rte; - bool irr, phys, level, mask; - uint32_t delmode, vector, dest; - /* Add NULL check for addr, INVALID_PIN check for pin */ if ((addr == NULL) || (!ioapic_is_pin_valid(pin))) { goto overflow; @@ -1143,8 +1128,6 @@ static int32_t get_ioapic_info(char *str_arg, size_t str_max_len) ioapic_get_rte_entry(addr, pin, &rte); - get_rte_info(rte, &mask, &irr, &phys, &delmode, &level, &vector, &dest); - len = snprintf(str, size, "\r\n%03d\t%03hhu\t0x%08X\t0x%08X\t", irq, pin, rte.u.hi_32, rte.u.lo_32); if (len >= size) { goto overflow; @@ -1153,7 +1136,9 @@ static int32_t get_ioapic_info(char *str_arg, size_t str_max_len) str += len; len = snprintf(str, size, "0x%02X\t0x%02X\t%s\t%s\t%u\t%d\t%d", - vector, dest, phys ? "phys" : "logic", level ? "level" : "edge", delmode >> 8, irr, mask); + rte.bits.vector, rte.bits.dest_field, rte.bits.dest_mode ? "logic" : "phys", + rte.bits.trigger_mode ? "level" : "edge", rte.bits.delivery_mode, rte.bits.remote_irr, + rte.bits.intr_mask); if (len >= size) { goto overflow; } diff --git a/hypervisor/debug/vuart.c b/hypervisor/debug/vuart.c index 4d17563d2..6db8dfbd8 100644 --- a/hypervisor/debug/vuart.c +++ b/hypervisor/debug/vuart.c @@ -143,7 +143,7 @@ static void vuart_toggle_intr(const struct acrn_vuart *vu) * modify the vioapic setting, as it's only for debug uart, * we want to make it as an known issue. */ - if ((rte.full & IOAPIC_RTE_INTPOL) != 0UL) { + if (rte.bits.intr_polarity == IOAPIC_RTE_INTPOL_ALO) { operation = (intr_reason != IIR_NOPEND) ? GSI_SET_LOW : GSI_SET_HIGH; } else { operation = (intr_reason != IIR_NOPEND) ? GSI_SET_HIGH : GSI_SET_LOW; diff --git a/hypervisor/dm/vioapic.c b/hypervisor/dm/vioapic.c index dbf4d28a3..e8251f21c 100644 --- a/hypervisor/dm/vioapic.c +++ b/hypervisor/dm/vioapic.c @@ -32,8 +32,7 @@ #include -#define RTBL_RO_BITS (uint32_t)(IOAPIC_RTE_REM_IRR | IOAPIC_RTE_DELIVS) -#define NEED_EOI_EXIT_UPDATE (IOAPIC_RTE_TRGRMOD | IOAPIC_RTE_DELMOD | IOAPIC_RTE_DEST_MASK | IOAPIC_RTE_INTVEC) +#define RTBL_RO_BITS ((uint32_t)0x00004000U | (uint32_t)0x00001000U) /*Remote IRR and Delivery Status bits*/ #define ACRN_DBG_IOAPIC 6U #define ACRN_IOAPIC_VERSION 0x11U @@ -53,22 +52,22 @@ vioapic_generate_intr(struct acrn_vioapic *vioapic, uint32_t pin) rte = vioapic->rtbl[pin]; - if ((rte.full & IOAPIC_RTE_INTMASK) == IOAPIC_RTE_INTMSET) { + if (rte.bits.intr_mask == IOAPIC_RTE_MASK_SET) { dev_dbg(ACRN_DBG_IOAPIC, "ioapic pin%hhu: masked", pin); } else { - phys = ((rte.full & IOAPIC_RTE_DESTMOD) == IOAPIC_RTE_DESTPHY); - delmode = (uint32_t)(rte.full & IOAPIC_RTE_DELMOD); - level = ((rte.full & IOAPIC_RTE_TRGRLVL) != 0UL); + phys = (rte.bits.dest_mode == IOAPIC_RTE_DESTMODE_PHY); + delmode = rte.bits.delivery_mode; + level = (rte.bits.trigger_mode == IOAPIC_RTE_TRGRMODE_LEVEL); /* For level trigger irq, avoid send intr if * previous one hasn't received EOI */ - if (!level || ((vioapic->rtbl[pin].full & IOAPIC_RTE_REM_IRR) == 0UL)) { + if (!level || (vioapic->rtbl[pin].bits.remote_irr == 0UL)) { if (level) { - vioapic->rtbl[pin].full |= IOAPIC_RTE_REM_IRR; + vioapic->rtbl[pin].bits.remote_irr = IOAPIC_RTE_REM_IRR; } - vector = rte.u.lo_32 & IOAPIC_RTE_LOW_INTVEC; - dest = (uint32_t)(rte.full >> IOAPIC_RTE_DEST_SHIFT); + vector = rte.bits.vector; + dest = rte.bits.dest_field; vlapic_deliver_intr(vioapic->vm, level, dest, phys, delmode, vector, false); } } @@ -89,14 +88,14 @@ vioapic_set_pinstate(struct acrn_vioapic *vioapic, uint32_t pin, uint32_t level) if (level == 0U) { /* clear pin_state and deliver interrupt according to polarity */ bitmap_clear_nolock((uint16_t)(pin & 0x3FU), &vioapic->pin_state[pin >> 6U]); - if (((rte.full & IOAPIC_RTE_INTPOL) != 0UL) + if ((rte.bits.intr_polarity == IOAPIC_RTE_INTPOL_ALO) && old_lvl != level) { vioapic_generate_intr(vioapic, pin); } } else { /* set pin_state and deliver intrrupt according to polarity */ bitmap_set_nolock((uint16_t)(pin & 0x3FU), &vioapic->pin_state[pin >> 6U]); - if (((rte.full & IOAPIC_RTE_INTPOL) == 0UL) + if ((rte.bits.intr_polarity == IOAPIC_RTE_INTPOL_AHI) && old_lvl != level) { vioapic_generate_intr(vioapic, pin); } @@ -200,19 +199,19 @@ vioapic_update_eoi_exit(const struct acrn_vioapic *vioapic) for (pin = 0U; pin < pincount; pin++) { rte = vioapic->rtbl[pin]; - level = ((rte.full & IOAPIC_RTE_TRGRLVL) != 0UL); - vector = rte.u.lo_32 & IOAPIC_RTE_LOW_INTVEC; + level = (rte.bits.trigger_mode == IOAPIC_RTE_TRGRMODE_LEVEL); + vector = rte.bits.vector; if (level && ((vector >= 0x20U) && (vector < NR_MAX_VECTOR))) { /* if level-trigger and vector is valid */ - delmode = (uint32_t)(rte.full & IOAPIC_RTE_DELMOD); + delmode = (uint32_t)rte.bits.delivery_mode; - if ((delmode != APIC_DELMODE_FIXED) && (delmode != APIC_DELMODE_LOWPRIO)) { + if ((delmode != IOAPIC_RTE_DELMODE_FIXED) && (delmode != IOAPIC_RTE_DELMODE_LOPRI)) { dev_dbg(ACRN_DBG_IOAPIC, "Ignoring level trigger-mode for delivery-mode 0x%x", delmode); } else { - dest = (uint32_t)((rte.full) >> IOAPIC_RTE_DEST_SHIFT); - phys = ((rte.full & IOAPIC_RTE_DESTLOG) == 0UL); + dest = (uint32_t)rte.bits.dest_field; + phys = (rte.bits.dest_mode == IOAPIC_RTE_DESTMODE_PHY); vlapic_calcdest(vioapic->vm, &mask, dest, phys, false); for (vcpu_id = ffs64(mask); vcpu_id != INVALID_BIT_INDEX; vcpu_id = ffs64(mask)) { @@ -285,8 +284,8 @@ static inline bool vioapic_need_intr(const struct acrn_vioapic *vioapic, uint16_ } else { rte = vioapic->rtbl[pin]; lvl = (uint32_t)bitmap_test(pin & 0x3FU, &vioapic->pin_state[pin >> 6U]); - ret = !!((((rte.full & IOAPIC_RTE_INTPOL) != 0UL) && lvl == 0U) || - (((rte.full & IOAPIC_RTE_INTPOL) == 0UL) && lvl != 0U)); + ret = !!(((rte.bits.intr_polarity == IOAPIC_RTE_INTPOL_ALO) && lvl == 0U) || + ((rte.bits.intr_polarity == IOAPIC_RTE_INTPOL_AHI) && lvl != 0U)); } return ret; @@ -298,8 +297,7 @@ static inline bool vioapic_need_intr(const struct acrn_vioapic *vioapic, uint16_ */ static void vioapic_indirect_write(struct acrn_vioapic *vioapic, uint32_t addr, uint32_t data) { - union ioapic_rte last, new; - uint64_t changed; + union ioapic_rte last, new, changed; uint32_t regnum; uint32_t pin, pincount = vioapic_pincount(vioapic->vm); @@ -344,15 +342,15 @@ static void vioapic_indirect_write(struct acrn_vioapic *vioapic, uint32_t addr, * 0x20 version IOAPIC, otherwise use switch Trigger Mode to * Edge Sensitive to clear it. */ - if ((new.full & IOAPIC_RTE_TRGRLVL) == 0U) { - new.full &= ~IOAPIC_RTE_REM_IRR; + if (new.bits.trigger_mode == IOAPIC_RTE_TRGRMODE_EDGE) { + new.bits.remote_irr = 0U; } - changed = last.full ^ new.full; + changed.full = last.full ^ new.full; /* pin0 from vpic mask/unmask */ - if ((pin == 0U) && ((changed & IOAPIC_RTE_INTMASK) != 0UL)) { + if ((pin == 0U) && (changed.bits.intr_mask != 0UL)) { /* mask -> umask */ - if ((last.full & IOAPIC_RTE_INTMASK) != 0UL) { + if (last.bits.intr_mask == IOAPIC_RTE_MASK_SET) { if ((vioapic->vm->wire_mode == VPIC_WIRE_NULL) || (vioapic->vm->wire_mode == VPIC_WIRE_INTR)) { vioapic->vm->wire_mode = VPIC_WIRE_IOAPIC; @@ -380,7 +378,8 @@ static void vioapic_indirect_write(struct acrn_vioapic *vioapic, uint32_t addr, * rendezvous all the vcpus to update their vlapic * trigger-mode registers. */ - if ((changed & NEED_EOI_EXIT_UPDATE) != 0UL) { + if ((changed.bits.vector != 0UL) || (changed.bits.delivery_mode != 0UL) + || (changed.bits.trigger_mode != 0UL) || (changed.bits.dest_field != 0UL)) { dev_dbg(ACRN_DBG_IOAPIC, "ioapic pin%hhu: recalculate vlapic trigger-mode reg", pin); vioapic_update_eoi_exit(vioapic); } @@ -391,15 +390,15 @@ static void vioapic_indirect_write(struct acrn_vioapic *vioapic, uint32_t addr, * - previous interrupt has been EOIed * - pin level is asserted */ - if (((vioapic->rtbl[pin].full & IOAPIC_RTE_INTMASK) == IOAPIC_RTE_INTMCLR) && - ((vioapic->rtbl[pin].full & IOAPIC_RTE_REM_IRR) == 0UL) && + if ((vioapic->rtbl[pin].bits.intr_mask == IOAPIC_RTE_MASK_CLR) && + (vioapic->rtbl[pin].bits.remote_irr == 0UL) && vioapic_need_intr(vioapic, (uint16_t)pin)) { dev_dbg(ACRN_DBG_IOAPIC, "ioapic pin%hhu: asserted at rtbl write", pin); vioapic_generate_intr(vioapic, pin); } /* remap for ptdev */ - if (((new.full & IOAPIC_RTE_INTMASK) == 0UL) || ((last.full & IOAPIC_RTE_INTMASK) == 0UL)) { + if ((new.bits.intr_mask == IOAPIC_RTE_MASK_CLR) || (last.bits.intr_mask == IOAPIC_RTE_MASK_CLR)) { /* VM enable intr */ /* NOTE: only support max 256 pin */ (void)ptirq_intx_pin_remap(vioapic->vm, pin, PTDEV_VPIN_IOAPIC); @@ -465,8 +464,8 @@ vioapic_process_eoi(struct acrn_vm *vm, uint32_t vector) /* notify device to ack if assigned pin */ for (pin = 0U; pin < pincount; pin++) { rte = vioapic->rtbl[pin]; - if (((rte.u.lo_32 & IOAPIC_RTE_LOW_INTVEC) != vector) || - ((rte.full & IOAPIC_RTE_REM_IRR) == 0UL)) { + if ((rte.bits.vector != vector) || + (rte.bits.remote_irr == 0U)) { continue; } @@ -480,12 +479,12 @@ vioapic_process_eoi(struct acrn_vm *vm, uint32_t vector) spinlock_obtain(&(vioapic->mtx)); for (pin = 0U; pin < pincount; pin++) { rte = vioapic->rtbl[pin]; - if (((rte.u.lo_32 & IOAPIC_RTE_LOW_INTVEC) != vector) || - ((rte.full & IOAPIC_RTE_REM_IRR) == 0UL)) { + if ((rte.bits.vector != vector) || + (rte.bits.remote_irr == 0U)) { continue; } - vioapic->rtbl[pin].full &= (~IOAPIC_RTE_REM_IRR); + vioapic->rtbl[pin].bits.remote_irr = 0U; if (vioapic_need_intr(vioapic, (uint16_t)pin)) { dev_dbg(ACRN_DBG_IOAPIC, "ioapic pin%hhu: asserted at eoi", pin); diff --git a/hypervisor/include/arch/x86/apicreg.h b/hypervisor/include/arch/x86/apicreg.h index f2d65445d..27e5e57e7 100644 --- a/hypervisor/include/arch/x86/apicreg.h +++ b/hypervisor/include/arch/x86/apicreg.h @@ -166,6 +166,30 @@ struct ioapic { uint32_t rsv1[3]; }; +/* + * Macros for bits in union ioapic_rte + */ +#define IOAPIC_RTE_MASK_CLR 0x0U /* Interrupt Mask: Clear */ +#define IOAPIC_RTE_MASK_SET 0x1U /* Interrupt Mask: Set */ + +#define IOAPIC_RTE_TRGRMODE_EDGE 0x0U /* Trigger Mode: Edge */ +#define IOAPIC_RTE_TRGRMODE_LEVEL 0x1U /* Trigger Mode: Level */ + +#define IOAPIC_RTE_REM_IRR 0x1U /* Remote IRR: Read-Only */ + +#define IOAPIC_RTE_INTPOL_AHI 0x0U /* Interrupt Polarity: active high */ +#define IOAPIC_RTE_INTPOL_ALO 0x1U /* Interrupt Polarity: active low */ + +#define IOAPIC_RTE_DELIVS 0x1U /* Delivery Status: Read-Only */ + +#define IOAPIC_RTE_DESTMODE_PHY 0x0U /* Destination Mode: Physical */ +#define IOAPIC_RTE_DESTMODE_LOGICAL 0x1U /* Destination Mode: Logical */ + +#define IOAPIC_RTE_DELMODE_FIXED 0x0U /* Delivery Mode: Fixed */ +#define IOAPIC_RTE_DELMODE_LOPRI 0x1U /* Delivery Mode: Lowest priority */ +#define IOAPIC_RTE_DELMODE_INIT 0x5U /* Delivery Mode: INIT signal */ +#define IOAPIC_RTE_DELMODE_EXINT 0x7U /* Delivery Mode: External INTerrupt */ + /* IOAPIC Redirection Table (RTE) Entry structure */ union ioapic_rte { uint64_t full; @@ -173,6 +197,18 @@ union ioapic_rte { uint32_t lo_32; uint32_t hi_32; } u; + struct { + uint64_t vector:8; + uint64_t delivery_mode:3; + uint64_t dest_mode:1; + uint64_t delivery_status:1; + uint64_t intr_polarity:1; + uint64_t remote_irr:1; + uint64_t trigger_mode:1; + uint64_t intr_mask:1; + uint64_t rsvd_1:39; + uint64_t dest_field:8; + } bits __packed; }; /****************************************************************************** @@ -390,45 +426,4 @@ union ioapic_rte { #define IOAPIC_MAX_RTE_MASK 0x00ff0000U #define MAX_RTE_SHIFT 16U -/* - * fields in the IO APIC's redirection table entries - */ -#define IOAPIC_RTE_DEST_SHIFT 56U -/* broadcast addr: all APICs */ -#define IOAPIC_RTE_DEST_MASK 0xff00000000000000UL - -#define IOAPIC_RTE_RESV 0x00fe0000UL /* reserved */ - -#define IOAPIC_RTE_INTMASK 0x00010000UL /* R/W: INTerrupt mask */ -#define IOAPIC_RTE_INTMCLR 0x00000000UL /* clear, allow INTs */ -#define IOAPIC_RTE_INTMSET 0x00010000UL /* set, inhibit INTs */ - -#define IOAPIC_RTE_TRGRMOD 0x00008000UL /* R/W: trigger mode */ -#define IOAPIC_RTE_TRGREDG 0x00000000UL /* edge */ -#define IOAPIC_RTE_TRGRLVL 0x00008000UL /* level */ - -#define IOAPIC_RTE_REM_IRR 0x00004000UL /* RO: remote IRR */ - -#define IOAPIC_RTE_INTPOL 0x00002000UL /*R/W:INT input pin polarity*/ -#define IOAPIC_RTE_INTAHI 0x00000000UL /* active high */ -#define IOAPIC_RTE_INTALO 0x00002000UL /* active low */ - -#define IOAPIC_RTE_DELIVS 0x00001000UL /* RO: delivery status */ - -#define IOAPIC_RTE_DESTMOD 0x00000800UL /*R/W:destination mode*/ -#define IOAPIC_RTE_DESTPHY 0x00000000UL /* physical */ -#define IOAPIC_RTE_DESTLOG 0x00000800UL /* logical */ - -#define IOAPIC_RTE_DELMOD 0x00000700UL /* R/W: delivery mode */ -#define IOAPIC_RTE_DELFIXED 0x00000000UL /* fixed */ -#define IOAPIC_RTE_DELLOPRI 0x00000100UL /* lowest priority */ -#define IOAPIC_RTE_DELSMI 0x00000200UL /*System Management INT*/ -#define IOAPIC_RTE_DELRSV1 0x00000300UL /* reserved */ -#define IOAPIC_RTE_DELNMI 0x00000400UL /* NMI signal */ -#define IOAPIC_RTE_DELINIT 0x00000500UL /* INIT signal */ -#define IOAPIC_RTE_DELRSV2 0x00000600UL /* reserved */ -#define IOAPIC_RTE_DELEXINT 0x00000700UL /* External INTerrupt */ - -#define IOAPIC_RTE_INTVEC 0x000000ffUL /*R/W: INT vector field*/ - #endif /* APICREG_H */ diff --git a/hypervisor/include/arch/x86/irq.h b/hypervisor/include/arch/x86/irq.h index d56032a7d..7385c3643 100644 --- a/hypervisor/include/arch/x86/irq.h +++ b/hypervisor/include/arch/x86/irq.h @@ -48,9 +48,9 @@ #define POSTED_INTR_NOTIFY_IRQ (NR_IRQS - 3U) #define PMI_IRQ (NR_IRQS - 4U) -#define DEFAULT_DEST_MODE IOAPIC_RTE_DESTLOG -#define DEFAULT_DELIVERY_MODE IOAPIC_RTE_DELLOPRI -#define ALL_CPUS_MASK ((1UL << (uint64_t)get_pcpu_nums()) - 1UL) +#define DEFAULT_DEST_MODE IOAPIC_RTE_DESTMODE_LOGICAL +#define DEFAULT_DELIVERY_MODE IOAPIC_RTE_DELMODE_LOPRI +#define ALL_CPUS_MASK (uint32_t) (((uint32_t)1U << (uint32_t) get_pcpu_nums()) - (uint32_t)1U) #define IRQ_ALLOC_BITMAP_SIZE INT_DIV_ROUNDUP(NR_IRQS, 64U)