mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-08-03 17:31:42 +00:00
hv: vioapic: minor refine about vioapic_init
Most code in the if ... else is duplicated. We could put it out of the conditional statement. Tracked-On: #4550 Signed-off-by: Li Fei1 <fei1.li@intel.com>
This commit is contained in:
parent
2c9c681e6d
commit
907a0f7c04
@ -43,7 +43,6 @@
|
|||||||
#define DBG_LEVEL_VIOAPIC 6U
|
#define DBG_LEVEL_VIOAPIC 6U
|
||||||
#define ACRN_IOAPIC_VERSION 0x11U
|
#define ACRN_IOAPIC_VERSION 0x11U
|
||||||
|
|
||||||
#define IOAPIC_ID_MASK 0x0f000000U
|
|
||||||
#define MASK_ALL_INTERRUPTS 0x0001000000010000UL
|
#define MASK_ALL_INTERRUPTS 0x0001000000010000UL
|
||||||
|
|
||||||
static inline struct acrn_vioapics *vm_ioapics(const struct acrn_vm *vm)
|
static inline struct acrn_vioapics *vm_ioapics(const struct acrn_vm *vm)
|
||||||
@ -52,7 +51,7 @@ static inline struct acrn_vioapics *vm_ioapics(const struct acrn_vm *vm)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @pre pin < vioapic->nr_pins
|
* @pre pin < vioapic->chipinfo.nr_pins
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
vioapic_generate_intr(struct acrn_single_vioapic *vioapic, uint32_t pin)
|
vioapic_generate_intr(struct acrn_single_vioapic *vioapic, uint32_t pin)
|
||||||
@ -85,7 +84,7 @@ vioapic_generate_intr(struct acrn_single_vioapic *vioapic, uint32_t pin)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @pre pin < vioapic->nr_pins
|
* @pre pin < vioapic->chipinfo.nr_pins
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
vioapic_set_pinstate(struct acrn_single_vioapic *vioapic, uint32_t pin, uint32_t level)
|
vioapic_set_pinstate(struct acrn_single_vioapic *vioapic, uint32_t pin, uint32_t level)
|
||||||
@ -93,7 +92,7 @@ vioapic_set_pinstate(struct acrn_single_vioapic *vioapic, uint32_t pin, uint32_t
|
|||||||
uint32_t old_lvl;
|
uint32_t old_lvl;
|
||||||
union ioapic_rte rte;
|
union ioapic_rte rte;
|
||||||
|
|
||||||
if (pin < vioapic->nr_pins) {
|
if (pin < vioapic->chipinfo.nr_pins) {
|
||||||
rte = vioapic->rtbl[pin];
|
rte = vioapic->rtbl[pin];
|
||||||
old_lvl = (uint32_t)bitmap_test((uint16_t)(pin & 0x3FU), &vioapic->pin_state[pin >> 6U]);
|
old_lvl = (uint32_t)bitmap_test((uint16_t)(pin & 0x3FU), &vioapic->pin_state[pin >> 6U]);
|
||||||
if (level == 0U) {
|
if (level == 0U) {
|
||||||
@ -216,18 +215,18 @@ static uint32_t
|
|||||||
vioapic_indirect_read(const struct acrn_single_vioapic *vioapic, uint32_t addr)
|
vioapic_indirect_read(const struct acrn_single_vioapic *vioapic, uint32_t addr)
|
||||||
{
|
{
|
||||||
uint32_t regnum, ret = 0U;
|
uint32_t regnum, ret = 0U;
|
||||||
uint32_t pin, pincount = vioapic->nr_pins;
|
uint32_t pin, pincount = vioapic->chipinfo.nr_pins;
|
||||||
|
|
||||||
regnum = addr & 0xffU;
|
regnum = addr & 0xffU;
|
||||||
switch (regnum) {
|
switch (regnum) {
|
||||||
case IOAPIC_ID:
|
case IOAPIC_ID:
|
||||||
ret = vioapic->id;
|
ret = (uint32_t)vioapic->chipinfo.id << IOAPIC_ID_SHIFT;
|
||||||
break;
|
break;
|
||||||
case IOAPIC_VER:
|
case IOAPIC_VER:
|
||||||
ret = ((pincount - 1U) << MAX_RTE_SHIFT) | ACRN_IOAPIC_VERSION;
|
ret = ((pincount - 1U) << MAX_RTE_SHIFT) | ACRN_IOAPIC_VERSION;
|
||||||
break;
|
break;
|
||||||
case IOAPIC_ARB:
|
case IOAPIC_ARB:
|
||||||
ret = vioapic->id;
|
ret = (uint32_t)vioapic->chipinfo.id << IOAPIC_ID_SHIFT;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/*
|
/*
|
||||||
@ -261,7 +260,7 @@ static inline bool vioapic_need_intr(const struct acrn_single_vioapic *vioapic,
|
|||||||
union ioapic_rte rte;
|
union ioapic_rte rte;
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
if (pin < vioapic->nr_pins) {
|
if (pin < vioapic->chipinfo.nr_pins) {
|
||||||
rte = vioapic->rtbl[pin];
|
rte = vioapic->rtbl[pin];
|
||||||
lvl = (uint32_t)bitmap_test(pin & 0x3FU, &vioapic->pin_state[pin >> 6U]);
|
lvl = (uint32_t)bitmap_test(pin & 0x3FU, &vioapic->pin_state[pin >> 6U]);
|
||||||
ret = !!(((rte.bits.intr_polarity == IOAPIC_RTE_INTPOL_ALO) && lvl == 0U) ||
|
ret = !!(((rte.bits.intr_polarity == IOAPIC_RTE_INTPOL_ALO) && lvl == 0U) ||
|
||||||
@ -280,12 +279,12 @@ static void vioapic_indirect_write(struct acrn_single_vioapic *vioapic, uint32_t
|
|||||||
{
|
{
|
||||||
union ioapic_rte last, new, changed;
|
union ioapic_rte last, new, changed;
|
||||||
uint32_t regnum;
|
uint32_t regnum;
|
||||||
uint32_t pin, pincount = vioapic->nr_pins;
|
uint32_t pin, pincount = vioapic->chipinfo.nr_pins;
|
||||||
|
|
||||||
regnum = addr & 0xffUL;
|
regnum = addr & 0xffUL;
|
||||||
switch (regnum) {
|
switch (regnum) {
|
||||||
case IOAPIC_ID:
|
case IOAPIC_ID:
|
||||||
vioapic->id = data & IOAPIC_ID_MASK;
|
vioapic->chipinfo.id = (uint8_t)((data & IOAPIC_ID_MASK) >> IOAPIC_ID_SHIFT);
|
||||||
break;
|
break;
|
||||||
case IOAPIC_VER:
|
case IOAPIC_VER:
|
||||||
case IOAPIC_ARB:
|
case IOAPIC_ARB:
|
||||||
@ -359,7 +358,7 @@ static void vioapic_indirect_write(struct acrn_single_vioapic *vioapic, uint32_t
|
|||||||
/* VM enable intr */
|
/* VM enable intr */
|
||||||
/* NOTE: only support max 256 pin */
|
/* NOTE: only support max 256 pin */
|
||||||
|
|
||||||
(void)ptirq_intx_pin_remap(vioapic->vm, vioapic->gsi_base + pin, INTX_CTLR_IOAPIC);
|
(void)ptirq_intx_pin_remap(vioapic->vm, vioapic->chipinfo.gsi_base + pin, INTX_CTLR_IOAPIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -385,7 +384,7 @@ vioapic_mmio_rw(struct acrn_single_vioapic *vioapic, uint64_t gpa,
|
|||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
uint64_t rflags;
|
uint64_t rflags;
|
||||||
|
|
||||||
offset = (uint32_t)(gpa - vioapic->base_addr);
|
offset = (uint32_t)(gpa - vioapic->chipinfo.addr);
|
||||||
|
|
||||||
spinlock_irqsave_obtain(&(vioapic->mtx), &rflags);
|
spinlock_irqsave_obtain(&(vioapic->mtx), &rflags);
|
||||||
|
|
||||||
@ -426,7 +425,7 @@ vioapic_mmio_rw(struct acrn_single_vioapic *vioapic, uint64_t gpa,
|
|||||||
static void
|
static void
|
||||||
vioapic_process_eoi(struct acrn_single_vioapic *vioapic, uint32_t vector)
|
vioapic_process_eoi(struct acrn_single_vioapic *vioapic, uint32_t vector)
|
||||||
{
|
{
|
||||||
uint32_t pin, pincount = vioapic->nr_pins;
|
uint32_t pin, pincount = vioapic->chipinfo.nr_pins;
|
||||||
union ioapic_rte rte;
|
union ioapic_rte rte;
|
||||||
uint64_t rflags;
|
uint64_t rflags;
|
||||||
|
|
||||||
@ -444,7 +443,7 @@ vioapic_process_eoi(struct acrn_single_vioapic *vioapic, uint32_t vector)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptirq_intx_ack(vioapic->vm, vioapic->gsi_base + pin, INTX_CTLR_IOAPIC);
|
ptirq_intx_ack(vioapic->vm, vioapic->chipinfo.gsi_base + pin, INTX_CTLR_IOAPIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -490,11 +489,11 @@ static void reset_one_vioapic(struct acrn_single_vioapic *vioapic)
|
|||||||
uint32_t pin, pincount;
|
uint32_t pin, pincount;
|
||||||
|
|
||||||
/* Initialize all redirection entries to mask all interrupts */
|
/* Initialize all redirection entries to mask all interrupts */
|
||||||
pincount = vioapic->nr_pins;
|
pincount = vioapic->chipinfo.nr_pins;
|
||||||
for (pin = 0U; pin < pincount; pin++) {
|
for (pin = 0U; pin < pincount; pin++) {
|
||||||
vioapic->rtbl[pin].full = MASK_ALL_INTERRUPTS;
|
vioapic->rtbl[pin].full = MASK_ALL_INTERRUPTS;
|
||||||
}
|
}
|
||||||
vioapic->id = 0U;
|
vioapic->chipinfo.id = 0U;
|
||||||
vioapic->ioregsel = 0U;
|
vioapic->ioregsel = 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -511,60 +510,42 @@ void reset_vioapics(const struct acrn_vm *vm)
|
|||||||
void
|
void
|
||||||
vioapic_init(struct acrn_vm *vm)
|
vioapic_init(struct acrn_vm *vm)
|
||||||
{
|
{
|
||||||
struct ioapic_info *platform_ioapic_info;
|
static struct ioapic_info virt_ioapic_info = {
|
||||||
uint8_t platform_ioapic_num;
|
.nr_pins = VIOAPIC_RTE_NUM,
|
||||||
|
.addr = VIOAPIC_BASE
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ioapic_info *vioapic_info;
|
||||||
uint8_t vioapic_index;
|
uint8_t vioapic_index;
|
||||||
struct acrn_single_vioapic *vioapic;
|
struct acrn_single_vioapic *vioapic = NULL;
|
||||||
|
|
||||||
if (is_sos_vm(vm)) {
|
if (is_sos_vm(vm)) {
|
||||||
platform_ioapic_num = get_platform_ioapic_info(&platform_ioapic_info);
|
vm->arch_vm.vioapics.ioapic_num = get_platform_ioapic_info(&vioapic_info);
|
||||||
vm->arch_vm.vioapics.ioapic_num = platform_ioapic_num;
|
|
||||||
for (vioapic_index = 0U; vioapic_index < platform_ioapic_num; vioapic_index++) {
|
|
||||||
vioapic = &vm->arch_vm.vioapics.vioapic_array[vioapic_index];
|
|
||||||
spinlock_init(&(vioapic->mtx));
|
|
||||||
vioapic->nr_pins = platform_ioapic_info[vioapic_index].nr_pins;
|
|
||||||
vioapic->base_addr = platform_ioapic_info[vioapic_index].addr;
|
|
||||||
vioapic->gsi_base = platform_ioapic_info[vioapic_index].gsi_base;
|
|
||||||
|
|
||||||
vioapic->vm = vm;
|
|
||||||
reset_one_vioapic(vioapic);
|
|
||||||
|
|
||||||
register_mmio_emulation_handler(vm,
|
|
||||||
vioapic_mmio_access_handler,
|
|
||||||
(uint64_t)vioapic->base_addr,
|
|
||||||
(uint64_t)vioapic->base_addr + VIOAPIC_SIZE,
|
|
||||||
(void *)vioapic, false);
|
|
||||||
ept_del_mr(vm, (uint64_t *)vm->arch_vm.nworld_eptp,
|
|
||||||
(uint64_t)vioapic->base_addr, VIOAPIC_SIZE);
|
|
||||||
vioapic->ready = true;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Maximum number of GSI is computed as GSI base of the IOAPIC i.e. enumerated last in ACPI MADT
|
|
||||||
* plus the number of interrupt pins of that IOAPIC.
|
|
||||||
*/
|
|
||||||
vm->arch_vm.vioapics.nr_gsi = platform_ioapic_info[platform_ioapic_num - 1U].gsi_base +
|
|
||||||
platform_ioapic_info[platform_ioapic_num - 1U].nr_pins;
|
|
||||||
} else {
|
} else {
|
||||||
vm->arch_vm.vioapics.ioapic_num = 1U;
|
vm->arch_vm.vioapics.ioapic_num = 1U;
|
||||||
vioapic = &vm->arch_vm.vioapics.vioapic_array[0U];
|
vioapic_info = &virt_ioapic_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (vioapic_index = 0U; vioapic_index < vm->arch_vm.vioapics.ioapic_num; vioapic_index++) {
|
||||||
|
vioapic = &vm->arch_vm.vioapics.vioapic_array[vioapic_index];
|
||||||
spinlock_init(&(vioapic->mtx));
|
spinlock_init(&(vioapic->mtx));
|
||||||
vioapic->nr_pins = VIOAPIC_RTE_NUM;
|
vioapic->chipinfo = vioapic_info[vioapic_index];
|
||||||
vioapic->base_addr = VIOAPIC_BASE;
|
|
||||||
vioapic->gsi_base = 0U;
|
|
||||||
vioapic->vm = vm;
|
vioapic->vm = vm;
|
||||||
reset_one_vioapic(&vm->arch_vm.vioapics.vioapic_array[0U]);
|
reset_one_vioapic(vioapic);
|
||||||
|
|
||||||
|
register_mmio_emulation_handler(vm, vioapic_mmio_access_handler, (uint64_t)vioapic->chipinfo.addr,
|
||||||
register_mmio_emulation_handler(vm,
|
(uint64_t)vioapic->chipinfo.addr + VIOAPIC_SIZE, (void *)vioapic, false);
|
||||||
vioapic_mmio_access_handler,
|
ept_del_mr(vm, (uint64_t *)vm->arch_vm.nworld_eptp, (uint64_t)vioapic->chipinfo.addr, VIOAPIC_SIZE);
|
||||||
(uint64_t)vioapic->base_addr,
|
|
||||||
(uint64_t)vioapic->base_addr + VIOAPIC_SIZE,
|
|
||||||
(void *)vioapic, false);
|
|
||||||
ept_del_mr(vm, (uint64_t *)vm->arch_vm.nworld_eptp,
|
|
||||||
(uint64_t)vioapic->base_addr, VIOAPIC_SIZE);
|
|
||||||
vioapic->ready = true;
|
vioapic->ready = true;
|
||||||
|
}
|
||||||
|
|
||||||
vm->arch_vm.vioapics.nr_gsi = VIOAPIC_RTE_NUM;
|
/*
|
||||||
|
* Maximum number of GSI is computed as GSI base of the IOAPIC i.e. enumerated last in ACPI MADT
|
||||||
|
* plus the number of interrupt pins of that IOAPIC.
|
||||||
|
*/
|
||||||
|
if (vioapic != NULL) {
|
||||||
|
vm->arch_vm.vioapics.nr_gsi = vioapic->chipinfo.gsi_base + vioapic->chipinfo.nr_pins;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,6 +435,9 @@ union ioapic_rte {
|
|||||||
#define IOAPIC_REDTBL22 (IOAPIC_REDTBL+0x2cU)
|
#define IOAPIC_REDTBL22 (IOAPIC_REDTBL+0x2cU)
|
||||||
#define IOAPIC_REDTBL23 (IOAPIC_REDTBL+0x2eU)
|
#define IOAPIC_REDTBL23 (IOAPIC_REDTBL+0x2eU)
|
||||||
|
|
||||||
|
#define IOAPIC_ID_MASK 0x0f000000U
|
||||||
|
#define IOAPIC_ID_SHIFT 24U
|
||||||
|
|
||||||
/* fields in VER, for redirection entry */
|
/* fields in VER, for redirection entry */
|
||||||
#define IOAPIC_MAX_RTE_MASK 0x00ff0000U
|
#define IOAPIC_MAX_RTE_MASK 0x00ff0000U
|
||||||
#define MAX_RTE_SHIFT 16U
|
#define MAX_RTE_SHIFT 16U
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <apicreg.h>
|
#include <apicreg.h>
|
||||||
|
#include <ioapic.h>
|
||||||
#include <util.h>
|
#include <util.h>
|
||||||
|
|
||||||
#define VIOAPIC_BASE 0xFEC00000UL
|
#define VIOAPIC_BASE 0xFEC00000UL
|
||||||
@ -55,10 +56,7 @@
|
|||||||
struct acrn_single_vioapic {
|
struct acrn_single_vioapic {
|
||||||
spinlock_t mtx;
|
spinlock_t mtx;
|
||||||
struct acrn_vm *vm;
|
struct acrn_vm *vm;
|
||||||
uint32_t base_addr;
|
struct ioapic_info chipinfo;
|
||||||
uint32_t nr_pins;
|
|
||||||
uint32_t gsi_base;
|
|
||||||
uint32_t id;
|
|
||||||
bool ready;
|
bool ready;
|
||||||
uint32_t ioregsel;
|
uint32_t ioregsel;
|
||||||
union ioapic_rte rtbl[REDIR_ENTRIES_HW];
|
union ioapic_rte rtbl[REDIR_ENTRIES_HW];
|
||||||
|
Loading…
Reference in New Issue
Block a user