On 2025/6/27 上午11:01, Song Gao wrote:
LoongArchVirtMachinState adds avecintc features, and
it use to check whether virt machine support advance interrupt
controller
and default set avecintc = ON_OFF_AUTO_ON.
LoongArchVirtMachineState adds misc_feature and misc_status for
misc fetures and status. and set default avec feture bit.
Signed-off-by: Song Gao <gaos...@loongson.cn>
---
hw/loongarch/virt.c | 43
+++++++++++++++++++++++++++++++++----
include/hw/loongarch/virt.h | 15 +++++++++++++
2 files changed, 54 insertions(+), 4 deletions(-)
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 6a169d4824..426eaaef84 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -47,6 +47,28 @@
#include "hw/virtio/virtio-iommu.h"
#include "qemu/error-report.h"
+static void virt_get_avecintc(Object *obj, Visitor *v, const
char *name,
+ void *opaque, Error **errp)
+{
+ LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
+ OnOffAuto avecintc = lvms->avecintc;
+
+ visit_type_OnOffAuto(v, name, &avecintc, errp);
+
+}
+static void virt_set_avecintc(Object *obj, Visitor *v, const char
*name,
+ void *opaque, Error **errp)
+{
+ LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
+
+ if (lvms->avecintc == ON_OFF_AUTO_OFF) {
+ lvms->misc_feature &= ~BIT(IOCSRF_AVEC);
+ lvms->misc_status &= ~BIT(IOCSRM_AVEC_EN);
+ }
+
+ visit_type_OnOffAuto(v, name, &lvms->avecintc, errp);
It is a little strange that firstly check variable and then set it,
I think that visit_type_OnOffAuto() should be before
+ if (lvms->avecintc == ON_OFF_AUTO_OFF) {
+ lvms->misc_feature &= ~BIT(IOCSRF_AVEC);
+ lvms->misc_status &= ~BIT(IOCSRM_AVEC_EN);
+ }
+}
+
static void virt_get_veiointc(Object *obj, Visitor *v, const char
*name,
void *opaque, Error **errp)
{
@@ -539,6 +561,10 @@ static MemTxResult virt_iocsr_misc_write(void
*opaque, hwaddr addr,
return MEMTX_OK;
}
+ if (val & BIT(IOCSRM_AVEC_EN)) {
+ lvms->misc_status |= BIT(IOCSRM_AVEC_EN);
+ }
+
features = address_space_ldl(&lvms->as_iocsr,
EXTIOI_VIRT_BASE +
EXTIOI_VIRT_CONFIG,
attrs, NULL);
@@ -574,8 +600,9 @@ static MemTxResult virt_iocsr_misc_read(void
*opaque, hwaddr addr,
break;
case FEATURE_REG:
ret = BIT(IOCSRF_MSI) | BIT(IOCSRF_EXTIOI) |
BIT(IOCSRF_CSRIPI);
- /*TODO: check bit IOCSRF_AVEC with virt_is_avec_enabled */
- ret |= BIT(IOCSRF_AVEC);
+ if (virt_is_avecintc_enabled(lvms)) {
+ ret |= BIT(IOCSRF_AVEC);
+ }
if (kvm_enabled()) {
ret |= BIT(IOCSRF_VM);
}
@@ -605,8 +632,10 @@ static MemTxResult virt_iocsr_misc_read(void
*opaque, hwaddr addr,
if (features & BIT(EXTIOI_ENABLE_INT_ENCODE)) {
ret |= BIT_ULL(IOCSRM_EXTIOI_INT_ENCODE);
}
- /* enable avec default */
- ret |= BIT_ULL(IOCSRM_AVEC_EN);
+ if (virt_is_avecintc_enabled(lvms) &&
+ (lvms->misc_status & BIT(IOCSRM_AVEC_EN))) {
+ ret |= BIT_ULL(IOCSRM_AVEC_EN);
+ }
break;
default:
g_assert_not_reached();
@@ -850,6 +879,8 @@ static void virt_initfn(Object *obj)
if (tcg_enabled()) {
lvms->veiointc = ON_OFF_AUTO_OFF;
}
+ lvms->misc_feature = BIT(IOCSRF_AVEC);
+ lvms->avecintc = ON_OFF_AUTO_ON;
lvms->acpi = ON_OFF_AUTO_AUTO;
lvms->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6);
lvms->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8);
@@ -1242,6 +1273,10 @@ static void virt_class_init(ObjectClass *oc,
const void *data)
NULL, NULL);
object_class_property_set_description(oc, "v-eiointc",
"Enable Virt Extend I/O Interrupt
Controller.");
+ object_class_property_add(oc, "avecintc", "OnOffAuto",
+ virt_get_avecintc, virt_set_avecintc, NULL, NULL);
+ object_class_property_set_description(oc, "avecintc",
+ "Enable Advance Interrupt Controller.");
It is only can be added in TCG mode, in kvm mode avec should not be
supported now.
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
machine_class_allow_dynamic_sysbus_dev(mc,
TYPE_UEFI_VARS_SYSBUS);
#ifdef CONFIG_TPM
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
index cc6656619d..44504e5501 100644
--- a/include/hw/loongarch/virt.h
+++ b/include/hw/loongarch/virt.h
@@ -70,6 +70,7 @@ struct LoongArchVirtMachineState {
Notifier powerdown_notifier;
OnOffAuto acpi;
OnOffAuto veiointc;
+ OnOffAuto avecintc;
char *oem_id;
char *oem_table_id;
DeviceState *acpi_ged;
@@ -85,6 +86,8 @@ struct LoongArchVirtMachineState {
DeviceState *extioi;
struct memmap_entry *memmap_table;
unsigned int memmap_entries;
+ uint64_t misc_feature;
+ uint64_t misc_status;
};
#define TYPE_LOONGARCH_VIRT_MACHINE MACHINE_TYPE_NAME("virt")
@@ -92,6 +95,18 @@
OBJECT_DECLARE_SIMPLE_TYPE(LoongArchVirtMachineState,
LOONGARCH_VIRT_MACHINE)
void virt_acpi_setup(LoongArchVirtMachineState *lvms);
void virt_fdt_setup(LoongArchVirtMachineState *lvms);
+static inline bool
virt_is_avecintc_enabled(LoongArchVirtMachineState *lvms)
+{
+ if (!(lvms->misc_feature & BIT(IOCSRF_AVEC))) {
+ return false;
+ }
+
+ if (lvms->avecintc == ON_OFF_AUTO_OFF) {
+ return false;
+ }
Is it enough to only check variable misc_feature? checking avecintc
seems unnecessary duplicated.