:p
atchew
Login
The following changes since commit b254e486242466dad881fc2bbfa215f1b67cd30f: Merge tag 'pull-riscv-to-apply-20260109' of https://github.com/alistair23/qemu into staging (2026-01-10 10:31:57 +1100) are available in the Git repository at: https://github.com/bibo-mao/qemu.git tags/pull-loongarch-20260112 for you to fetch changes up to 1a8d5e95d70ab1bdbc2a39065e9864f4201e519f: hw/loongarch/virt: Add property highmem-mmio-size with virt machine (2026-01-12 14:58:01 +0800) ---------------------------------------------------------------- pull-loongarch-20260112 queue ---------------------------------------------------------------- Bibo Mao (10): target/loongarch: Add PMU migration support in KVM mode target/loongarch: Call function loongarch_la464_init_csr() after realized target/loongarch: Add PMU register dump support in KVM hw/loongarch/virt: Add field ram_end in LoongArchVirtMachineState hw/loongarch/virt: Add field gpex in LoongArchVirtMachineState hw/loongarch/virt: Get irq number from gpex config info hw/loongarch/virt: Get PCI info from gpex config info hw/loongarch/virt: Add property highmem_mmio with virt machine hw/loongarch/virt: Add high MMIO support with GPEX host hw/loongarch/virt: Add property highmem-mmio-size with virt machine hw/loongarch/virt-acpi-build.c | 17 +--- hw/loongarch/virt-fdt-build.c | 43 +++++++--- hw/loongarch/virt.c | 175 ++++++++++++++++++++++++++++++++++++++--- include/hw/loongarch/virt.h | 5 +- target/loongarch/cpu-csr.h | 4 + target/loongarch/cpu.c | 11 ++- target/loongarch/cpu.h | 4 + target/loongarch/csr.c | 32 ++++++++ target/loongarch/kvm/kvm.c | 54 ++++++++++++- target/loongarch/machine.c | 21 +++++ 10 files changed, 322 insertions(+), 44 deletions(-)
PMU is supported in KVM mode. When VM is migrated, PMU register should be migrated also, otherwise PMU will be disabled after migration. Here add PMU register save and restore interface and PMU register state migration is added also. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Song Gao <gaosong@loongson.cn> --- target/loongarch/cpu-csr.h | 4 +++ target/loongarch/cpu.h | 4 +++ target/loongarch/kvm/kvm.c | 54 +++++++++++++++++++++++++++++++++++++- target/loongarch/machine.c | 21 +++++++++++++++ 4 files changed, 82 insertions(+), 1 deletion(-) diff --git a/target/loongarch/cpu-csr.h b/target/loongarch/cpu-csr.h index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/cpu-csr.h +++ b/target/loongarch/cpu-csr.h @@ -XXX,XX +XXX,XX @@ FIELD(CSR_DMW_32, PSEG, 25, 3) FIELD(CSR_DMW_32, VSEG, 29, 3) FIELD(CSR_DMW_64, VSEG, 60, 4) +/* Performance Counter registers */ +#define LOONGARCH_CSR_PERFCTRL(N) (0x200 + 2 * N) +#define LOONGARCH_CSR_PERFCNTR(N) (0x201 + 2 * N) + /* Debug CSRs */ #define LOONGARCH_CSR_DBG 0x500 /* debug config */ FIELD(CSR_DBG, DST, 0, 1) diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -XXX,XX +XXX,XX @@ extern const char * const fregnames[32]; #define IRQ_IPI 12 #define INT_DMSI 14 +#define MAX_PERF_EVENTS 16 #define LOONGARCH_STLB 2048 /* 2048 STLB */ #define LOONGARCH_MTLB 64 /* 64 MTLB */ #define LOONGARCH_TLB_MAX (LOONGARCH_STLB + LOONGARCH_MTLB) @@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState { uint64_t CSR_MERRSAVE; uint64_t CSR_CTAG; uint64_t CSR_DMW[4]; + uint64_t CSR_PERFCTRL[MAX_PERF_EVENTS]; + uint64_t CSR_PERFCNTR[MAX_PERF_EVENTS]; uint64_t CSR_DBG; uint64_t CSR_DERA; uint64_t CSR_DSAVE; @@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState { struct { uint64_t guest_addr; } stealtime; + uint32_t perf_event_num; #ifdef CONFIG_TCG float_status fp_status; diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/kvm/kvm.c +++ b/target/loongarch/kvm/kvm.c @@ -XXX,XX +XXX,XX @@ static int kvm_loongarch_put_regs_core(CPUState *cs) return ret; } +static int kvm_loongarch_put_pmu(CPUState *cs) +{ + int i, ret = 0; + CPULoongArchState *env = cpu_env(cs); + LoongArchCPU *cpu = LOONGARCH_CPU(cs); + + if (cpu->pmu != ON_OFF_AUTO_ON) { + return 0; + } + + for (i = 0; i < env->perf_event_num; i++) { + ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PERFCTRL(i)), + &env->CSR_PERFCTRL[i]); + ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PERFCNTR(i)), + &env->CSR_PERFCNTR[i]); + } + + return ret; +} + +static int kvm_loongarch_get_pmu(CPUState *cs) +{ + int i, ret = 0; + CPULoongArchState *env = cpu_env(cs); + LoongArchCPU *cpu = LOONGARCH_CPU(cs); + + if (cpu->pmu != ON_OFF_AUTO_ON) { + return 0; + } + + for (i = 0; i < env->perf_event_num; i++) { + ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PERFCTRL(i)), + &env->CSR_PERFCTRL[i]); + ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PERFCNTR(i)), + &env->CSR_PERFCNTR[i]); + } + + return ret; +} + static int kvm_loongarch_get_csr(CPUState *cs) { int ret = 0; @@ -XXX,XX +XXX,XX @@ static int kvm_loongarch_get_csr(CPUState *cs) ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(3)), &env->CSR_DMW[3]); + ret |= kvm_loongarch_get_pmu(cs); + ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TVAL), &env->CSR_TVAL); @@ -XXX,XX +XXX,XX @@ static int kvm_loongarch_put_csr(CPUState *cs, KvmPutState level) ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(3)), &env->CSR_DMW[3]); + + ret |= kvm_loongarch_put_pmu(cs); + /* * timer cfg must be put at last since it is used to enable * guest timer @@ -XXX,XX +XXX,XX @@ static int kvm_cpu_check_pmu(CPUState *cs, Error **errp) } if (kvm_supported) { + /* + * TODO: Will add supported perf event number query interface + * from host, set perf event number with 4 by default + */ + cpu->pmu = ON_OFF_AUTO_ON; + env->perf_event_num = 4; env->cpucfg[6] = FIELD_DP32(env->cpucfg[6], CPUCFG6, PMP, 1); - env->cpucfg[6] = FIELD_DP32(env->cpucfg[6], CPUCFG6, PMNUM, 3); + env->cpucfg[6] = FIELD_DP32(env->cpucfg[6], CPUCFG6, PMNUM, + env->perf_event_num - 1); env->cpucfg[6] = FIELD_DP32(env->cpucfg[6], CPUCFG6, PMBITS, 63); env->cpucfg[6] = FIELD_DP32(env->cpucfg[6], CPUCFG6, UPM, 1); } diff --git a/target/loongarch/machine.c b/target/loongarch/machine.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/machine.c +++ b/target/loongarch/machine.c @@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_lbt = { }, }; +static bool pmu_needed(void *opaque) +{ + LoongArchCPU *cpu = opaque; + + return cpu->pmu == ON_OFF_AUTO_ON; +} + +static const VMStateDescription vmstate_pmu = { + .name = "cpu/pmu", + .version_id = 0, + .minimum_version_id = 0, + .needed = pmu_needed, + .fields = (const VMStateField[]) { + VMSTATE_UINT32(env.perf_event_num, LoongArchCPU), + VMSTATE_UINT64_ARRAY(env.CSR_PERFCTRL, LoongArchCPU, MAX_PERF_EVENTS), + VMSTATE_UINT64_ARRAY(env.CSR_PERFCNTR, LoongArchCPU, MAX_PERF_EVENTS), + VMSTATE_END_OF_LIST() + }, +}; + #if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY) static bool tlb_needed(void *opaque) { @@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_loongarch_cpu = { #endif &vmstate_lbt, &vmstate_msgint, + &vmstate_pmu, NULL } }; -- 2.52.0
When CPU is realized, it will check capability of host and set guest features, such as PMU CSR register number used by VM etc. Here move function call with loongarch_la464_init_csr() after CPU is realized. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Song Gao <gaosong@loongson.cn> --- target/loongarch/cpu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -XXX,XX +XXX,XX @@ bool loongarch_cpu_has_work(CPUState *cs) } #endif /* !CONFIG_USER_ONLY */ -static void loongarch_la464_init_csr(Object *obj) +static void loongarch_la464_init_csr(DeviceState *dev) { #ifndef CONFIG_USER_ONLY static bool initialized; - LoongArchCPU *cpu = LOONGARCH_CPU(obj); + LoongArchCPU *cpu = LOONGARCH_CPU(dev); CPULoongArchState *env = &cpu->env; int i, num; @@ -XXX,XX +XXX,XX @@ static void loongarch_la464_initfn(Object *obj) cpu->msgint = ON_OFF_AUTO_OFF; cpu->ptw = ON_OFF_AUTO_OFF; - loongarch_la464_init_csr(obj); loongarch_cpu_post_init(obj); } @@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_realizefn(DeviceState *dev, Error **errp) qemu_init_vcpu(cs); cpu_reset(cs); + loongarch_la464_init_csr(dev); lacc->parent_realize(dev, errp); } -- 2.52.0
PMU is supported in KVM mode. With info registers command, PMU CSR registers should be dumped also. And it is not necessary in TCG mode. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Song Gao <gaosong@loongson.cn> --- target/loongarch/cpu.c | 5 +++++ target/loongarch/csr.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -XXX,XX +XXX,XX @@ static void loongarch_la464_init_csr(DeviceState *dev) set_csr_flag(LOONGARCH_CSR_MERRERA, CSRFL_UNUSED); set_csr_flag(LOONGARCH_CSR_MERRSAVE, CSRFL_UNUSED); set_csr_flag(LOONGARCH_CSR_CTAG, CSRFL_UNUSED); + + for (i = env->perf_event_num; i < MAX_PERF_EVENTS; i++) { + set_csr_flag(LOONGARCH_CSR_PERFCTRL(i), CSRFL_UNUSED); + set_csr_flag(LOONGARCH_CSR_PERFCNTR(i), CSRFL_UNUSED); + } } #endif } diff --git a/target/loongarch/csr.c b/target/loongarch/csr.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/csr.c +++ b/target/loongarch/csr.c @@ -XXX,XX +XXX,XX @@ static CSRInfo csr_info[] = { CSR_OFF_ARRAY(DMW, 1), CSR_OFF_ARRAY(DMW, 2), CSR_OFF_ARRAY(DMW, 3), + CSR_OFF_ARRAY(PERFCTRL, 0), + CSR_OFF_ARRAY(PERFCNTR, 0), + CSR_OFF_ARRAY(PERFCTRL, 1), + CSR_OFF_ARRAY(PERFCNTR, 1), + CSR_OFF_ARRAY(PERFCTRL, 2), + CSR_OFF_ARRAY(PERFCNTR, 2), + CSR_OFF_ARRAY(PERFCTRL, 3), + CSR_OFF_ARRAY(PERFCNTR, 3), + CSR_OFF_ARRAY(PERFCTRL, 4), + CSR_OFF_ARRAY(PERFCNTR, 4), + CSR_OFF_ARRAY(PERFCTRL, 5), + CSR_OFF_ARRAY(PERFCNTR, 5), + CSR_OFF_ARRAY(PERFCTRL, 6), + CSR_OFF_ARRAY(PERFCNTR, 6), + CSR_OFF_ARRAY(PERFCTRL, 7), + CSR_OFF_ARRAY(PERFCNTR, 7), + CSR_OFF_ARRAY(PERFCTRL, 8), + CSR_OFF_ARRAY(PERFCNTR, 8), + CSR_OFF_ARRAY(PERFCTRL, 9), + CSR_OFF_ARRAY(PERFCNTR, 9), + CSR_OFF_ARRAY(PERFCTRL, 10), + CSR_OFF_ARRAY(PERFCNTR, 10), + CSR_OFF_ARRAY(PERFCTRL, 11), + CSR_OFF_ARRAY(PERFCNTR, 11), + CSR_OFF_ARRAY(PERFCTRL, 12), + CSR_OFF_ARRAY(PERFCNTR, 12), + CSR_OFF_ARRAY(PERFCTRL, 13), + CSR_OFF_ARRAY(PERFCNTR, 13), + CSR_OFF_ARRAY(PERFCTRL, 14), + CSR_OFF_ARRAY(PERFCNTR, 14), + CSR_OFF_ARRAY(PERFCTRL, 15), + CSR_OFF_ARRAY(PERFCNTR, 15), CSR_OFF(DBG), CSR_OFF(DERA), CSR_OFF(DSAVE), -- 2.52.0
DRAM region is dynamically set and the last valid physical address region with LoongArch Virt Machine. To record the last valid physical address, field ram_end is added in structure LoongArchVirtMachineState. In future end address of DRAM cannot exceed base addres of PCIE 64-bit MMIO region. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Song Gao <gaosong@loongson.cn> --- hw/loongarch/virt.c | 2 ++ include/hw/loongarch/virt.h | 1 + 2 files changed, 3 insertions(+) diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index XXXXXXX..XXXXXXX 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -XXX,XX +XXX,XX @@ static void virt_init(MachineState *machine) exit(EXIT_FAILURE); } machine_memory_devices_init(machine, base, device_mem_size); + base += device_mem_size; } + lvms->ram_end = base; /* load the BIOS image. */ virt_firmware_init(lvms); diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h index XXXXXXX..XXXXXXX 100644 --- a/include/hw/loongarch/virt.h +++ b/include/hw/loongarch/virt.h @@ -XXX,XX +XXX,XX @@ struct LoongArchVirtMachineState { uint64_t misc_feature; uint64_t misc_status; DeviceState *dintc; + hwaddr ram_end; }; #define TYPE_LOONGARCH_VIRT_MACHINE MACHINE_TYPE_NAME("virt") -- 2.52.0
Add field gpex in structure LoongArchVirtMachineState, type of field gpex is structure GPEXConfig and it is to record configuration information about GPEX host bridge. And remove field pci_bus in structure LoongArchVirtMachineState since the information is in field gpex already. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Song Gao <gaosong@loongson.cn> --- hw/loongarch/virt-acpi-build.c | 13 +------------ hw/loongarch/virt.c | 9 ++++++++- include/hw/loongarch/virt.h | 3 ++- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/hw/loongarch/virt-acpi-build.c b/hw/loongarch/virt-acpi-build.c index XXXXXXX..XXXXXXX 100644 --- a/hw/loongarch/virt-acpi-build.c +++ b/hw/loongarch/virt-acpi-build.c @@ -XXX,XX +XXX,XX @@ build_la_ged_aml(Aml *dsdt, MachineState *machine) static void build_pci_device_aml(Aml *scope, LoongArchVirtMachineState *lvms) { - struct GPEXConfig cfg = { - .mmio64.base = VIRT_PCI_MEM_BASE, - .mmio64.size = VIRT_PCI_MEM_SIZE, - .pio.base = VIRT_PCI_IO_BASE, - .pio.size = VIRT_PCI_IO_SIZE, - .ecam.base = VIRT_PCI_CFG_BASE, - .ecam.size = VIRT_PCI_CFG_SIZE, - .irq = VIRT_GSI_BASE + VIRT_DEVICE_IRQS, - .bus = lvms->pci_bus, - }; - - acpi_dsdt_add_gpex(scope, &cfg); + acpi_dsdt_add_gpex(scope, &lvms->gpex); } static void build_flash_aml(Aml *scope, LoongArchVirtMachineState *lvms) diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index XXXXXXX..XXXXXXX 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -XXX,XX +XXX,XX @@ static void virt_devices_init(DeviceState *pch_pic, d = SYS_BUS_DEVICE(gpex_dev); sysbus_realize_and_unref(d, &error_fatal); pci_bus = PCI_HOST_BRIDGE(gpex_dev)->bus; - lvms->pci_bus = pci_bus; + lvms->gpex.mmio64.base = VIRT_PCI_MEM_BASE; + lvms->gpex.mmio64.size = VIRT_PCI_MEM_SIZE; + lvms->gpex.pio.base = VIRT_PCI_IO_BASE; + lvms->gpex.pio.size = VIRT_PCI_IO_SIZE; + lvms->gpex.ecam.base = VIRT_PCI_CFG_BASE; + lvms->gpex.ecam.size = VIRT_PCI_CFG_SIZE; + lvms->gpex.irq = VIRT_GSI_BASE + VIRT_DEVICE_IRQS; + lvms->gpex.bus = pci_bus; /* Map only part size_ecam bytes of ECAM space */ ecam_alias = g_new0(MemoryRegion, 1); diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h index XXXXXXX..XXXXXXX 100644 --- a/include/hw/loongarch/virt.h +++ b/include/hw/loongarch/virt.h @@ -XXX,XX +XXX,XX @@ #include "qemu/queue.h" #include "hw/block/flash.h" #include "hw/loongarch/boot.h" +#include "hw/pci-host/gpex.h" /* IOCSR region */ #define VERSION_REG 0x0 @@ -XXX,XX +XXX,XX @@ struct LoongArchVirtMachineState { DeviceState *acpi_ged; int fdt_size; DeviceState *platform_bus_dev; - PCIBus *pci_bus; PFlashCFI01 *flash[2]; MemoryRegion system_iocsr; MemoryRegion iocsr_mem; @@ -XXX,XX +XXX,XX @@ struct LoongArchVirtMachineState { uint64_t misc_status; DeviceState *dintc; hwaddr ram_end; + struct GPEXConfig gpex; }; #define TYPE_LOONGARCH_VIRT_MACHINE MACHINE_TYPE_NAME("virt") -- 2.52.0
The base irq number of GPEX PCIE host bridge can comes from gpex::irq. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Song Gao <gaosong@loongson.cn> --- hw/loongarch/virt.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index XXXXXXX..XXXXXXX 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -XXX,XX +XXX,XX @@ static void virt_devices_init(DeviceState *pch_pic, PCIBus *pci_bus; MemoryRegion *ecam_alias, *ecam_reg, *pio_alias, *pio_reg; MemoryRegion *mmio_alias, *mmio_reg; - int i; + int i, irq; gpex_dev = qdev_new(TYPE_GPEX_HOST); d = SYS_BUS_DEVICE(gpex_dev); @@ -XXX,XX +XXX,XX @@ static void virt_devices_init(DeviceState *pch_pic, pio_alias); for (i = 0; i < PCI_NUM_PINS; i++) { - sysbus_connect_irq(d, i, - qdev_get_gpio_in(pch_pic, 16 + i)); - gpex_set_irq_num(GPEX_HOST(gpex_dev), i, 16 + i); + irq = lvms->gpex.irq + i - VIRT_GSI_BASE; + sysbus_connect_irq(d, i, qdev_get_gpio_in(pch_pic, irq)); + gpex_set_irq_num(GPEX_HOST(gpex_dev), i, irq); } /* @@ -XXX,XX +XXX,XX @@ static void virt_devices_init(DeviceState *pch_pic, */ for (i = VIRT_UART_COUNT; i-- > 0;) { hwaddr base = VIRT_UART_BASE + i * VIRT_UART_SIZE; - int irq = VIRT_UART_IRQ + i - VIRT_GSI_BASE; + irq = VIRT_UART_IRQ + i - VIRT_GSI_BASE; serial_mm_init(get_system_memory(), base, 0, qdev_get_gpio_in(pch_pic, irq), 115200, serial_hd(i), DEVICE_LITTLE_ENDIAN); -- 2.52.0
PCIE host bridge configuration information such as MMIO/Conf/IO base and size can come from gpex config info. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Song Gao <gaosong@loongson.cn> --- hw/loongarch/virt-acpi-build.c | 4 ++-- hw/loongarch/virt-fdt-build.c | 14 +++++++------- hw/loongarch/virt.c | 16 +++++++++------- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/hw/loongarch/virt-acpi-build.c b/hw/loongarch/virt-acpi-build.c index XXXXXXX..XXXXXXX 100644 --- a/hw/loongarch/virt-acpi-build.c +++ b/hw/loongarch/virt-acpi-build.c @@ -XXX,XX +XXX,XX @@ static void acpi_build(AcpiBuildTables *tables, MachineState *machine) acpi_add_table(table_offsets, tables_blob); { AcpiMcfgInfo mcfg = { - .base = VIRT_PCI_CFG_BASE, - .size = VIRT_PCI_CFG_SIZE, + .base = lvms->gpex.ecam.base, + .size = lvms->gpex.ecam.size, }; build_mcfg(tables_blob, tables->linker, &mcfg, lvms->oem_id, lvms->oem_table_id); diff --git a/hw/loongarch/virt-fdt-build.c b/hw/loongarch/virt-fdt-build.c index XXXXXXX..XXXXXXX 100644 --- a/hw/loongarch/virt-fdt-build.c +++ b/hw/loongarch/virt-fdt-build.c @@ -XXX,XX +XXX,XX @@ static void fdt_add_pcie_node(const LoongArchVirtMachineState *lvms, uint32_t *pch_msi_phandle) { char *nodename; - hwaddr base_mmio = VIRT_PCI_MEM_BASE; - hwaddr size_mmio = VIRT_PCI_MEM_SIZE; - hwaddr base_pio = VIRT_PCI_IO_BASE; - hwaddr size_pio = VIRT_PCI_IO_SIZE; - hwaddr base_pcie = VIRT_PCI_CFG_BASE; - hwaddr size_pcie = VIRT_PCI_CFG_SIZE; + hwaddr base_mmio = lvms->gpex.mmio64.base; + hwaddr size_mmio = lvms->gpex.mmio64.size; + hwaddr base_pio = lvms->gpex.pio.base; + hwaddr size_pio = lvms->gpex.pio.size; + hwaddr base_pcie = lvms->gpex.ecam.base; + hwaddr size_pcie = lvms->gpex.ecam.size; hwaddr base = base_pcie; const MachineState *ms = MACHINE(lvms); @@ -XXX,XX +XXX,XX @@ static void fdt_add_pcie_node(const LoongArchVirtMachineState *lvms, qemu_fdt_setprop_cell(ms->fdt, nodename, "#size-cells", 2); qemu_fdt_setprop_cell(ms->fdt, nodename, "linux,pci-domain", 0); qemu_fdt_setprop_cells(ms->fdt, nodename, "bus-range", 0, - PCIE_MMCFG_BUS(VIRT_PCI_CFG_SIZE - 1)); + PCIE_MMCFG_BUS(size_pcie - 1)); qemu_fdt_setprop(ms->fdt, nodename, "dma-coherent", NULL, 0); qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, base_pcie, 2, size_pcie); diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index XXXXXXX..XXXXXXX 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -XXX,XX +XXX,XX @@ static void virt_devices_init(DeviceState *pch_pic, PCIBus *pci_bus; MemoryRegion *ecam_alias, *ecam_reg, *pio_alias, *pio_reg; MemoryRegion *mmio_alias, *mmio_reg; + hwaddr mmio_base, mmio_size; int i, irq; gpex_dev = qdev_new(TYPE_GPEX_HOST); @@ -XXX,XX +XXX,XX @@ static void virt_devices_init(DeviceState *pch_pic, lvms->gpex.ecam.size = VIRT_PCI_CFG_SIZE; lvms->gpex.irq = VIRT_GSI_BASE + VIRT_DEVICE_IRQS; lvms->gpex.bus = pci_bus; + mmio_base = lvms->gpex.mmio64.base; + mmio_size = lvms->gpex.mmio64.size; /* Map only part size_ecam bytes of ECAM space */ ecam_alias = g_new0(MemoryRegion, 1); ecam_reg = sysbus_mmio_get_region(d, 0); memory_region_init_alias(ecam_alias, OBJECT(gpex_dev), "pcie-ecam", - ecam_reg, 0, VIRT_PCI_CFG_SIZE); - memory_region_add_subregion(get_system_memory(), VIRT_PCI_CFG_BASE, + ecam_reg, 0, lvms->gpex.ecam.size); + memory_region_add_subregion(get_system_memory(), lvms->gpex.ecam.base, ecam_alias); /* Map PCI mem space */ mmio_alias = g_new0(MemoryRegion, 1); mmio_reg = sysbus_mmio_get_region(d, 1); memory_region_init_alias(mmio_alias, OBJECT(gpex_dev), "pcie-mmio", - mmio_reg, VIRT_PCI_MEM_BASE, VIRT_PCI_MEM_SIZE); - memory_region_add_subregion(get_system_memory(), VIRT_PCI_MEM_BASE, - mmio_alias); + mmio_reg, mmio_base, mmio_size); + memory_region_add_subregion(get_system_memory(), mmio_base, mmio_alias); /* Map PCI IO port space. */ pio_alias = g_new0(MemoryRegion, 1); pio_reg = sysbus_mmio_get_region(d, 2); memory_region_init_alias(pio_alias, OBJECT(gpex_dev), "pcie-io", pio_reg, - VIRT_PCI_IO_OFFSET, VIRT_PCI_IO_SIZE); - memory_region_add_subregion(get_system_memory(), VIRT_PCI_IO_BASE, + VIRT_PCI_IO_OFFSET, lvms->gpex.pio.size); + memory_region_add_subregion(get_system_memory(), lvms->gpex.pio.base, pio_alias); for (i = 0; i < PCI_NUM_PINS; i++) { -- 2.52.0
On LoongArch Virt Machine, MMIO region with GPEX host bridge is 0x40000000 -- 0x7FFFFFFF. The total size is 1G bytes and it is enough for emulated virtio devices basically. However on some conditions such as hostmem is added with virtio-gpu device, the command line is -device virtio-gpu-gl,hostmem=4G. The PCIE MMIO region is not enough, 64-bit high MMIO region is required. Here add property highmem_mmio with virt machine, however it brings out incompatible issue. Here the default value is false. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Song Gao <gaosong@loongson.cn> --- hw/loongarch/virt.c | 21 +++++++++++++++++++++ include/hw/loongarch/virt.h | 1 + 2 files changed, 22 insertions(+) diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index XXXXXXX..XXXXXXX 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -XXX,XX +XXX,XX @@ static void virt_set_veiointc(Object *obj, Visitor *v, const char *name, visit_type_OnOffAuto(v, name, &lvms->veiointc, errp); } +static bool virt_get_highmem_mmio(Object *obj, Error **errp) +{ + LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj); + + return lvms->highmem_mmio; +} + +static void virt_set_highmem_mmio(Object *obj, bool value, Error **errp) +{ + LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj); + + lvms->highmem_mmio = value; +} + static PFlashCFI01 *virt_flash_create1(LoongArchVirtMachineState *lvms, const char *name, const char *alias_prop_name) @@ -XXX,XX +XXX,XX @@ static void virt_class_init(ObjectClass *oc, const void *data) "Override the default value of field OEM Table ID " "in ACPI table header." "The string may be up to 8 bytes in size"); + + object_class_property_add_bool(oc, "highmem-mmio", + virt_get_highmem_mmio, + virt_set_highmem_mmio); + object_class_property_set_description(oc, "highmem-mmio", + "Set on/off to enable/disable high " + "memory region for PCI MMIO"); } static const TypeInfo virt_machine_types[] = { diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h index XXXXXXX..XXXXXXX 100644 --- a/include/hw/loongarch/virt.h +++ b/include/hw/loongarch/virt.h @@ -XXX,XX +XXX,XX @@ struct LoongArchVirtMachineState { DeviceState *dintc; hwaddr ram_end; struct GPEXConfig gpex; + bool highmem_mmio; }; #define TYPE_LOONGARCH_VIRT_MACHINE MACHINE_TYPE_NAME("virt") -- 2.52.0
With high MMIO supported, its base address comes from high end of physical address space. Also add high MMIO support with GPEX host bridge. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Song Gao <gaosong@loongson.cn> --- hw/loongarch/virt-fdt-build.c | 33 +++++++++++---- hw/loongarch/virt.c | 76 ++++++++++++++++++++++++++++++++++- 2 files changed, 100 insertions(+), 9 deletions(-) diff --git a/hw/loongarch/virt-fdt-build.c b/hw/loongarch/virt-fdt-build.c index XXXXXXX..XXXXXXX 100644 --- a/hw/loongarch/virt-fdt-build.c +++ b/hw/loongarch/virt-fdt-build.c @@ -XXX,XX +XXX,XX @@ static void fdt_add_pcie_node(const LoongArchVirtMachineState *lvms, uint32_t *pch_msi_phandle) { char *nodename; - hwaddr base_mmio = lvms->gpex.mmio64.base; - hwaddr size_mmio = lvms->gpex.mmio64.size; + hwaddr base_mmio, base_mmio_high; + hwaddr size_mmio, size_mmio_high; hwaddr base_pio = lvms->gpex.pio.base; hwaddr size_pio = lvms->gpex.pio.size; hwaddr base_pcie = lvms->gpex.ecam.base; @@ -XXX,XX +XXX,XX @@ static void fdt_add_pcie_node(const LoongArchVirtMachineState *lvms, qemu_fdt_setprop(ms->fdt, nodename, "dma-coherent", NULL, 0); qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, base_pcie, 2, size_pcie); - qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "ranges", - 1, FDT_PCI_RANGE_IOPORT, 2, VIRT_PCI_IO_OFFSET, - 2, base_pio, 2, size_pio, - 1, FDT_PCI_RANGE_MMIO, 2, base_mmio, - 2, base_mmio, 2, size_mmio); + if (lvms->highmem_mmio) { + base_mmio_high = lvms->gpex.mmio64.base; + size_mmio_high = lvms->gpex.mmio64.size; + base_mmio = lvms->gpex.mmio32.base; + size_mmio = lvms->gpex.mmio32.size; + qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "ranges", + 1, FDT_PCI_RANGE_IOPORT, + 2, VIRT_PCI_IO_OFFSET, + 2, base_pio, 2, size_pio, + 1, FDT_PCI_RANGE_MMIO, 2, base_mmio, + 2, base_mmio, 2, size_mmio, + 1, FDT_PCI_RANGE_MMIO_64BIT, + 2, base_mmio_high, + 2, base_mmio_high, 2, size_mmio_high); + } else { + base_mmio = lvms->gpex.mmio64.base; + size_mmio = lvms->gpex.mmio64.size; + qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "ranges", + 1, FDT_PCI_RANGE_IOPORT, + 2, VIRT_PCI_IO_OFFSET, + 2, base_pio, 2, size_pio, + 1, FDT_PCI_RANGE_MMIO, 2, base_mmio, + 2, base_mmio, 2, size_mmio); + } qemu_fdt_setprop_cells(ms->fdt, nodename, "msi-map", 0, *pch_msi_phandle, 0, 0x10000); fdt_add_pcie_irq_map_node(lvms, nodename, pch_pic_phandle); diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index XXXXXXX..XXXXXXX 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -XXX,XX +XXX,XX @@ static void virt_set_dmsi(Object *obj, Visitor *v, const char *name, } } +#define DEFAULT_HIGH_PCIE_MMIO_SIZE_GB 64 +#define DEFAULT_HIGH_PCIE_MMIO_SIZE (DEFAULT_HIGH_PCIE_MMIO_SIZE_GB * GiB) + static void virt_get_veiointc(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) { @@ -XXX,XX +XXX,XX @@ static DeviceState *create_platform_bus(DeviceState *pch_pic) return dev; } +static void virt_set_highmmio(LoongArchVirtMachineState *lvms) +{ + LoongArchCPU *cpu = LOONGARCH_CPU(first_cpu); + CPULoongArchState *env = &cpu->env; + struct GPEXConfig *gpex; + int vaddr_bits, phys_bits; + + vaddr_bits = FIELD_EX32(env->cpucfg[1], CPUCFG1, VALEN) + 1; + phys_bits = FIELD_EX32(env->cpucfg[1], CPUCFG1, PALEN) + 1; + if (phys_bits <= 32) { + return; + } + + gpex = &lvms->gpex; + if (gpex->mmio64.size == 0) { + gpex->mmio64.size = DEFAULT_HIGH_PCIE_MMIO_SIZE; + } + + /* + * UEFI BIOS uses 1:1 identified mapping PCI high mmio space, and + * virtual address space is low end through PGDL page table. + * + * Max physical address bit cannot exceed vaddr_bits - 1 + */ + if (phys_bits > (vaddr_bits - 1)) { + phys_bits = vaddr_bits - 1; + } + + /* + * GPEX base address starts from end of physical address + */ + gpex->mmio64.base = BIT_ULL(phys_bits) - BIT_ULL(phys_bits - 3); + if (gpex->mmio64.base + gpex->mmio64.size > BIT_ULL(phys_bits)) { + error_report("GPEX region base %" PRIu64 " size %" PRIu64 + " exceeds %d physical bits", + gpex->mmio64.base, gpex->mmio64.size, + phys_bits); + exit(EXIT_FAILURE); + } + + if (lvms->ram_end > gpex->mmio64.base) { + error_report("DRAM end address %" PRIu64 + " exceeds GPEX region base %" PRIu64, + lvms->ram_end, gpex->mmio64.base); + exit(EXIT_FAILURE); + } +} + static void virt_devices_init(DeviceState *pch_pic, LoongArchVirtMachineState *lvms) { @@ -XXX,XX +XXX,XX @@ static void virt_devices_init(DeviceState *pch_pic, d = SYS_BUS_DEVICE(gpex_dev); sysbus_realize_and_unref(d, &error_fatal); pci_bus = PCI_HOST_BRIDGE(gpex_dev)->bus; - lvms->gpex.mmio64.base = VIRT_PCI_MEM_BASE; - lvms->gpex.mmio64.size = VIRT_PCI_MEM_SIZE; lvms->gpex.pio.base = VIRT_PCI_IO_BASE; lvms->gpex.pio.size = VIRT_PCI_IO_SIZE; lvms->gpex.ecam.base = VIRT_PCI_CFG_BASE; @@ -XXX,XX +XXX,XX @@ static void virt_devices_init(DeviceState *pch_pic, lvms->gpex.bus = pci_bus; mmio_base = lvms->gpex.mmio64.base; mmio_size = lvms->gpex.mmio64.size; + if (lvms->highmem_mmio) { + virt_set_highmmio(lvms); + lvms->gpex.mmio32.base = VIRT_PCI_MEM_BASE; + lvms->gpex.mmio32.size = VIRT_PCI_MEM_SIZE; + mmio_base = lvms->gpex.mmio32.base; + mmio_size = lvms->gpex.mmio32.size; + } else { + lvms->gpex.mmio64.base = VIRT_PCI_MEM_BASE; + lvms->gpex.mmio64.size = VIRT_PCI_MEM_SIZE; + mmio_base = lvms->gpex.mmio64.base; + mmio_size = lvms->gpex.mmio64.size; + } /* Map only part size_ecam bytes of ECAM space */ ecam_alias = g_new0(MemoryRegion, 1); @@ -XXX,XX +XXX,XX @@ static void virt_devices_init(DeviceState *pch_pic, memory_region_init_alias(mmio_alias, OBJECT(gpex_dev), "pcie-mmio", mmio_reg, mmio_base, mmio_size); memory_region_add_subregion(get_system_memory(), mmio_base, mmio_alias); + if (lvms->highmem_mmio) { + /* Map high MMIO space */ + mmio_alias = g_new0(MemoryRegion, 1); + mmio_base = lvms->gpex.mmio64.base; + mmio_size = lvms->gpex.mmio64.size; + memory_region_init_alias(mmio_alias, OBJECT(gpex_dev), + "pcie-mmio-high", mmio_reg, + mmio_base, mmio_size); + memory_region_add_subregion(get_system_memory(), mmio_base, + mmio_alias); + } /* Map PCI IO port space. */ pio_alias = g_new0(MemoryRegion, 1); -- 2.52.0
The default high mmio size of GPEX PCIE host controller is 64G bytes on virt machine. If it does not meet requirements with some pass-throught HW devices in future, it can be adjust dynamically, here adds property highmem-mmio-size to set high mmio size. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Song Gao <gaosong@loongson.cn> --- hw/loongarch/virt.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index XXXXXXX..XXXXXXX 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -XXX,XX +XXX,XX @@ #include "qemu/osdep.h" #include "qemu/units.h" #include "qemu/datadir.h" +#include "qemu/cutils.h" #include "qapi/error.h" #include "exec/target_page.h" #include "hw/core/boards.h" @@ -XXX,XX +XXX,XX @@ static void virt_set_highmem_mmio(Object *obj, bool value, Error **errp) lvms->highmem_mmio = value; } +static void virt_get_highmem_mmio_size(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj); + uint64_t size = lvms->gpex.mmio64.size; + + visit_type_size(v, name, &size, errp); +} + +static void virt_set_highmem_mmio_size(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj); + uint64_t size; + + if (!visit_type_size(v, name, &size, errp)) { + return; + } + + if (!is_power_of_2(size)) { + error_setg(errp, "highmem-mmio-size is not a power of 2"); + return; + } + + if (size < DEFAULT_HIGH_PCIE_MMIO_SIZE) { + char *sz = size_to_str(DEFAULT_HIGH_PCIE_MMIO_SIZE); + error_setg(errp, "highmem-mmio-size cannot be set to a lower value " + "than the default (%s)", sz); + g_free(sz); + return; + } + + lvms->gpex.mmio64.size = size; +} + static PFlashCFI01 *virt_flash_create1(LoongArchVirtMachineState *lvms, const char *name, const char *alias_prop_name) @@ -XXX,XX +XXX,XX @@ static void virt_class_init(ObjectClass *oc, const void *data) object_class_property_set_description(oc, "highmem-mmio", "Set on/off to enable/disable high " "memory region for PCI MMIO"); + object_class_property_add(oc, "highmem-mmio-size", "size", + virt_get_highmem_mmio_size, + virt_set_highmem_mmio_size, + NULL, NULL); + object_class_property_set_description(oc, "highmem-mmio-size", + "Set the high memory region size " + "for PCI MMIO"); } static const TypeInfo virt_machine_types[] = { -- 2.52.0
The following changes since commit cc329c491768b2d91eb0b0984f3baa0bf805776d: Merge tag 'block-pull-request' of https://gitlab.com/stefanha/qemu into staging (2026-06-08 09:30:30 -0400) are available in the Git repository at: https://github.com/gaosong715/qemu.git tags/pull-loongarch-20260609 for you to fetch changes up to b653a954d427561fc563238af6b2feb8da209e41: target/loongarch: Add new structure CPUSysState (2026-06-09 08:37:18 -0400) ---------------------------------------------------------------- pull-loongarch-20260609 ---------------------------------------------------------------- Bibo Mao (14): target/loongarch: Add new field curState in CPULoongArchState target/loongarch: Use sys_state in cpu.c when accessing CSR registers target/loongarch: Use sys_state in cpu_helper.c when accessing CSR registers target/loongarch: Use sys_state in file arch_dump.c when accessing CSR registers target/loongarch: Use sys_state in kvm.c when accessing CSR registers target/loongarch: Use sys_state in tlb_helper.c when accessing CSR registers target/loongarch: Use sys_state in tcg_cpu.c when accessing CSR registers target/loongarch: Use sys_state in csr_helper.c when accessing CSR registers target/loongarch: Use sys_state in op_helper.c when accessing CSR registers linux-user/loongarch64: Use sys_state when accessing CSR registers target/loongarch: Add default CSRFL_BASIC info with flags field target/loongarch: Add wrapper function get_csr_offset() target/loongarch: Add macro CSR_OFFSET and CPU_CSR_OFFSET target/loongarch: Add new structure CPUSysState hw/intc/loongarch_dintc.c | 4 +- linux-user/loongarch64/cpu_loop.c | 5 +- linux-user/loongarch64/elfload.c | 4 +- linux-user/loongarch64/signal.c | 16 +- target/loongarch/arch_dump.c | 5 +- target/loongarch/cpu-mmu.h | 4 +- target/loongarch/cpu.c | 120 ++++++----- target/loongarch/cpu.h | 49 +++-- target/loongarch/cpu_helper.c | 41 ++-- target/loongarch/csr.c | 10 +- target/loongarch/csr.h | 10 + target/loongarch/gdbstub.c | 3 +- target/loongarch/kvm/kvm.c | 228 +++++++++++---------- target/loongarch/machine.c | 118 +++++------ target/loongarch/tcg/constant_timer.c | 10 +- target/loongarch/tcg/csr_helper.c | 55 ++--- target/loongarch/tcg/insn_trans/trans_extra.c.inc | 6 +- .../tcg/insn_trans/trans_privileged.c.inc | 16 +- target/loongarch/tcg/op_helper.c | 45 ++-- target/loongarch/tcg/tcg_cpu.c | 107 +++++----- target/loongarch/tcg/tlb_helper.c | 137 +++++++------ 21 files changed, 549 insertions(+), 444 deletions(-)
From: Bibo Mao <maobibo@loongson.cn> New field sys_state is added in structure CPULoongArchState, it points to CPULoongArchState itself now. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Philippe Mathieu-Daudé <philmd@mailo.com> Tested-by: Song Gao <gaosong@loongson.cn> Message-ID: <20260605082552.175336-2-maobibo@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn> --- target/loongarch/cpu.c | 2 ++ target/loongarch/cpu.h | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -XXX,XX +XXX,XX @@ static void loongarch_la464_initfn(Object *obj) uint32_t data = 0, field; int i; + set_sys_state(env, env); for (i = 0; i < 21; i++) { env->cpucfg[i] = 0x0; } @@ -XXX,XX +XXX,XX @@ static void loongarch_la132_initfn(Object *obj) uint32_t data = 0; int i; + set_sys_state(env, env); for (i = 0; i < 21; i++) { env->cpucfg[i] = 0x0; } diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -XXX,XX +XXX,XX @@ typedef struct LoongArchBT { #define CPU_VENDOR_LOONGSON "Loongson" #define CPU_MODEL_3A5000 "3A5000" #define CPU_MODEL_1C101 "1C101" +struct CPUArchState; +typedef struct CPUArchState CPUSysState; typedef struct CPUArchState { uint64_t gpr[32]; @@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState { AddressSpace *address_space_iocsr; uint32_t mp_state; #endif + CPUSysState *sys_state; } CPULoongArchState; typedef struct LoongArchCPUTopo { @@ -XXX,XX +XXX,XX @@ struct LoongArchCPUClass { #define MMU_USER_IDX MMU_PLV_USER #define MMU_DA_IDX 4 +static inline CPUSysState *env_sys(CPULoongArchState *env) +{ + return env->sys_state; +} + +static inline void set_sys_state(CPULoongArchState *env, CPUSysState *sys) +{ + env->sys_state = sys; +} + static inline bool is_la64(CPULoongArchState *env) { return FIELD_EX32(env->cpucfg[1], CPUCFG1, ARCH) == CPUCFG1_ARCH_LA64; -- 2.54.0
From: Bibo Mao <maobibo@loongson.cn> When accessing CSR register in file cpu.c, use sys_state rather than env. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Philippe Mathieu-Daudé <philmd@mailo.com> Tested-by: Song Gao <gaosong@loongson.cn> Message-ID: <20260605082552.175336-3-maobibo@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn> --- target/loongarch/cpu.c | 114 ++++++++++++++++++++++------------------- target/loongarch/cpu.h | 5 +- 2 files changed, 63 insertions(+), 56 deletions(-) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -XXX,XX +XXX,XX @@ void loongarch_cpu_set_irq(void *opaque, int irq, int level) LoongArchCPU *cpu = opaque; CPULoongArchState *env = &cpu->env; CPUState *cs = CPU(cpu); + CPUSysState *sys = env_sys(env); if (irq < 0 || irq >= N_IRQS) { return; @@ -XXX,XX +XXX,XX @@ void loongarch_cpu_set_irq(void *opaque, int irq, int level) if (kvm_enabled()) { kvm_loongarch_set_interrupt(cpu, irq, level); } else if (tcg_enabled()) { - env->CSR_ESTAT = deposit64(env->CSR_ESTAT, irq, 1, level != 0); - if (FIELD_EX64(env->CSR_ESTAT, CSR_ESTAT, IS)) { + sys->CSR_ESTAT = deposit64(sys->CSR_ESTAT, irq, 1, level != 0); + if (FIELD_EX64(sys->CSR_ESTAT, CSR_ESTAT, IS)) { cpu_interrupt(cs, CPU_INTERRUPT_HARD); } else { cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); @@ -XXX,XX +XXX,XX @@ bool cpu_loongarch_hw_interrupts_pending(CPULoongArchState *env) { uint32_t pending; uint32_t status; + CPUSysState *sys = env_sys(env); - pending = FIELD_EX64(env->CSR_ESTAT, CSR_ESTAT, IS); - status = FIELD_EX64(env->CSR_ECFG, CSR_ECFG, LIE); + pending = FIELD_EX64(sys->CSR_ESTAT, CSR_ESTAT, IS); + status = FIELD_EX64(sys->CSR_ECFG, CSR_ECFG, LIE); return (pending & status) != 0; } @@ -XXX,XX +XXX,XX @@ static void loongarch_la464_init_csr(DeviceState *dev) static bool initialized; LoongArchCPU *cpu = LOONGARCH_CPU(dev); CPULoongArchState *env = &cpu->env; + CPUSysState *sys = env_sys(env); int i, num; if (!initialized) { initialized = true; - num = FIELD_EX64(env->CSR_PRCFG1, CSR_PRCFG1, SAVE_NUM); + num = FIELD_EX64(sys->CSR_PRCFG1, CSR_PRCFG1, SAVE_NUM); for (i = num; i < 16; i++) { set_csr_flag(LOONGARCH_CSR_SAVE(i), CSRFL_UNUSED); } @@ -XXX,XX +XXX,XX @@ static void loongarch_la464_initfn(Object *obj) { LoongArchCPU *cpu = LOONGARCH_CPU(obj); CPULoongArchState *env = &cpu->env; + CPUSysState *sys; uint32_t data = 0, field; int i; @@ -XXX,XX +XXX,XX @@ static void loongarch_la464_initfn(Object *obj) data = FIELD_DP32(data, CPUCFG20, L3IU_SIZE, 6); env->cpucfg[20] = data; - env->CSR_ASID = FIELD_DP64(0, CSR_ASID, ASIDBITS, 0xa); + sys = env_sys(env); + sys->CSR_ASID = FIELD_DP64(0, CSR_ASID, ASIDBITS, 0xa); - env->CSR_PRCFG1 = FIELD_DP64(env->CSR_PRCFG1, CSR_PRCFG1, SAVE_NUM, 8); - env->CSR_PRCFG1 = FIELD_DP64(env->CSR_PRCFG1, CSR_PRCFG1, TIMER_BITS, 0x2f); - env->CSR_PRCFG1 = FIELD_DP64(env->CSR_PRCFG1, CSR_PRCFG1, VSMAX, 7); + sys->CSR_PRCFG1 = FIELD_DP64(sys->CSR_PRCFG1, CSR_PRCFG1, SAVE_NUM, 8); + sys->CSR_PRCFG1 = FIELD_DP64(sys->CSR_PRCFG1, CSR_PRCFG1, TIMER_BITS, 0x2f); + sys->CSR_PRCFG1 = FIELD_DP64(sys->CSR_PRCFG1, CSR_PRCFG1, VSMAX, 7); - env->CSR_PRCFG2 = 0x3ffff000; + sys->CSR_PRCFG2 = 0x3ffff000; - env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, TLB_TYPE, 2); - env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, MTLB_ENTRY, 63); - env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, STLB_WAYS, 7); - env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, STLB_SETS, 8); + sys->CSR_PRCFG3 = FIELD_DP64(sys->CSR_PRCFG3, CSR_PRCFG3, TLB_TYPE, 2); + sys->CSR_PRCFG3 = FIELD_DP64(sys->CSR_PRCFG3, CSR_PRCFG3, MTLB_ENTRY, 63); + sys->CSR_PRCFG3 = FIELD_DP64(sys->CSR_PRCFG3, CSR_PRCFG3, STLB_WAYS, 7); + sys->CSR_PRCFG3 = FIELD_DP64(sys->CSR_PRCFG3, CSR_PRCFG3, STLB_SETS, 8); cpu->msgint = ON_OFF_AUTO_OFF; cpu->ptw = ON_OFF_AUTO_OFF; @@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_reset_hold(Object *obj, ResetType type) CPUState *cs = CPU(obj); LoongArchCPUClass *lacc = LOONGARCH_CPU_GET_CLASS(obj); CPULoongArchState *env = cpu_env(cs); + CPUSysState *sys = env_sys(env); if (lacc->parent_phases.hold) { lacc->parent_phases.hold(obj, type); @@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_reset_hold(Object *obj, ResetType type) int n; /* Set csr registers value after reset, see the manual 6.4. */ - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, PLV, 0); - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, IE, 0); - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DA, 1); - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, PG, 0); - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DATF, 0); - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DATM, 0); - - env->CSR_EUEN = FIELD_DP64(env->CSR_EUEN, CSR_EUEN, FPE, 0); - env->CSR_EUEN = FIELD_DP64(env->CSR_EUEN, CSR_EUEN, SXE, 0); - env->CSR_EUEN = FIELD_DP64(env->CSR_EUEN, CSR_EUEN, ASXE, 0); - env->CSR_EUEN = FIELD_DP64(env->CSR_EUEN, CSR_EUEN, BTE, 0); - - env->CSR_MISC = 0; - - env->CSR_ECFG = FIELD_DP64(env->CSR_ECFG, CSR_ECFG, VS, 0); - env->CSR_ECFG = FIELD_DP64(env->CSR_ECFG, CSR_ECFG, LIE, 0); - - env->CSR_ESTAT = env->CSR_ESTAT & (~MAKE_64BIT_MASK(0, 2)); - env->CSR_RVACFG = FIELD_DP64(env->CSR_RVACFG, CSR_RVACFG, RBITS, 0); - env->CSR_CPUID = cs->cpu_index; - env->CSR_TCFG = FIELD_DP64(env->CSR_TCFG, CSR_TCFG, EN, 0); - env->CSR_LLBCTL = FIELD_DP64(env->CSR_LLBCTL, CSR_LLBCTL, KLO, 0); - env->CSR_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR, 0); - env->CSR_MERRCTL = FIELD_DP64(env->CSR_MERRCTL, CSR_MERRCTL, ISMERR, 0); - env->CSR_TID = cs->cpu_index; + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, PLV, 0); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, IE, 0); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, DA, 1); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, PG, 0); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, DATF, 0); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, DATM, 0); + + sys->CSR_EUEN = FIELD_DP64(sys->CSR_EUEN, CSR_EUEN, FPE, 0); + sys->CSR_EUEN = FIELD_DP64(sys->CSR_EUEN, CSR_EUEN, SXE, 0); + sys->CSR_EUEN = FIELD_DP64(sys->CSR_EUEN, CSR_EUEN, ASXE, 0); + sys->CSR_EUEN = FIELD_DP64(sys->CSR_EUEN, CSR_EUEN, BTE, 0); + + sys->CSR_MISC = 0; + + sys->CSR_ECFG = FIELD_DP64(sys->CSR_ECFG, CSR_ECFG, VS, 0); + sys->CSR_ECFG = FIELD_DP64(sys->CSR_ECFG, CSR_ECFG, LIE, 0); + + sys->CSR_ESTAT = sys->CSR_ESTAT & (~MAKE_64BIT_MASK(0, 2)); + sys->CSR_RVACFG = FIELD_DP64(sys->CSR_RVACFG, CSR_RVACFG, RBITS, 0); + sys->CSR_CPUID = cs->cpu_index; + sys->CSR_TCFG = FIELD_DP64(sys->CSR_TCFG, CSR_TCFG, EN, 0); + sys->CSR_LLBCTL = FIELD_DP64(sys->CSR_LLBCTL, CSR_LLBCTL, KLO, 0); + sys->CSR_TLBRERA = FIELD_DP64(sys->CSR_TLBRERA, CSR_TLBRERA, ISTLBR, 0); + sys->CSR_MERRCTL = FIELD_DP64(sys->CSR_MERRCTL, CSR_MERRCTL, ISMERR, 0); + sys->CSR_TID = cs->cpu_index; /* * Workaround for edk2-stable202408, CSR PGD register is set only if * its value is equal to zero for boot cpu, it causes reboot issue. * * Here clear CSR registers relative with TLB. */ - env->CSR_PGDH = 0; - env->CSR_PGDL = 0; - env->CSR_PWCH = 0; - env->CSR_EENTRY = 0; - env->CSR_TLBRENTRY = 0; - env->CSR_MERRENTRY = 0; + sys->CSR_PGDH = 0; + sys->CSR_PGDL = 0; + sys->CSR_PWCH = 0; + sys->CSR_EENTRY = 0; + sys->CSR_TLBRENTRY = 0; + sys->CSR_MERRENTRY = 0; /* set CSR_PWCL.PTBASE and CSR_STLBPS.PS bits from CSR_PRCFG2 */ - if (env->CSR_PRCFG2 == 0) { - env->CSR_PRCFG2 = 0x3fffff000; + if (sys->CSR_PRCFG2 == 0) { + sys->CSR_PRCFG2 = 0x3fffff000; } - tlb_ps = ctz32(env->CSR_PRCFG2); - env->CSR_STLBPS = FIELD_DP64(env->CSR_STLBPS, CSR_STLBPS, PS, tlb_ps); - env->CSR_PWCL = FIELD_DP64(env->CSR_PWCL, CSR_PWCL, PTBASE, tlb_ps); + tlb_ps = ctz32(sys->CSR_PRCFG2); + sys->CSR_STLBPS = FIELD_DP64(sys->CSR_STLBPS, CSR_STLBPS, PS, tlb_ps); + sys->CSR_PWCL = FIELD_DP64(sys->CSR_PWCL, CSR_PWCL, PTBASE, tlb_ps); for (n = 0; n < 4; n++) { - env->CSR_DMW[n] = FIELD_DP64(env->CSR_DMW[n], CSR_DMW, PLV0, 0); - env->CSR_DMW[n] = FIELD_DP64(env->CSR_DMW[n], CSR_DMW, PLV1, 0); - env->CSR_DMW[n] = FIELD_DP64(env->CSR_DMW[n], CSR_DMW, PLV2, 0); - env->CSR_DMW[n] = FIELD_DP64(env->CSR_DMW[n], CSR_DMW, PLV3, 0); + sys->CSR_DMW[n] = FIELD_DP64(sys->CSR_DMW[n], CSR_DMW, PLV0, 0); + sys->CSR_DMW[n] = FIELD_DP64(sys->CSR_DMW[n], CSR_DMW, PLV1, 0); + sys->CSR_DMW[n] = FIELD_DP64(sys->CSR_DMW[n], CSR_DMW, PLV2, 0); + sys->CSR_DMW[n] = FIELD_DP64(sys->CSR_DMW[n], CSR_DMW, PLV3, 0); } #ifndef CONFIG_USER_ONLY diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -XXX,XX +XXX,XX @@ static inline bool is_va32(CPULoongArchState *env) { /* VA32 if !LA64 or VA32L[1-3] */ bool va32 = !is_la64(env); - uint64_t plv = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV); - if (plv >= 1 && (FIELD_EX64(env->CSR_MISC, CSR_MISC, VA32) & (1 << plv))) { + CPUSysState *sys = env_sys(env); + uint64_t plv = FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, PLV); + if (plv >= 1 && (FIELD_EX64(sys->CSR_MISC, CSR_MISC, VA32) & (1 << plv))) { va32 = true; } return va32; -- 2.54.0
From: Bibo Mao <maobibo@loongson.cn> When accessing CSR register in file cpu_helper.c, use sys_state rather than env. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Philippe Mathieu-Daudé <philmd@mailo.com> Tested-by: Song Gao <gaosong@loongson.cn> Message-ID: <20260605082552.175336-4-maobibo@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn> --- target/loongarch/cpu_helper.c | 41 +++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/target/loongarch/cpu_helper.c b/target/loongarch/cpu_helper.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/cpu_helper.c +++ b/target/loongarch/cpu_helper.c @@ -XXX,XX +XXX,XX @@ void get_dir_base_width(CPULoongArchState *env, uint64_t *dir_base, uint64_t *dir_width, unsigned int level) { + CPUSysState *sys = env_sys(env); + switch (level) { case 1: - *dir_base = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR1_BASE); - *dir_width = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR1_WIDTH); + *dir_base = FIELD_EX64(sys->CSR_PWCL, CSR_PWCL, DIR1_BASE); + *dir_width = FIELD_EX64(sys->CSR_PWCL, CSR_PWCL, DIR1_WIDTH); break; case 2: - *dir_base = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR2_BASE); - *dir_width = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR2_WIDTH); + *dir_base = FIELD_EX64(sys->CSR_PWCL, CSR_PWCL, DIR2_BASE); + *dir_width = FIELD_EX64(sys->CSR_PWCL, CSR_PWCL, DIR2_WIDTH); break; case 3: - *dir_base = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR3_BASE); - *dir_width = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR3_WIDTH); + *dir_base = FIELD_EX64(sys->CSR_PWCH, CSR_PWCH, DIR3_BASE); + *dir_width = FIELD_EX64(sys->CSR_PWCH, CSR_PWCH, DIR3_WIDTH); break; case 4: - *dir_base = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR4_BASE); - *dir_width = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR4_WIDTH); + *dir_base = FIELD_EX64(sys->CSR_PWCH, CSR_PWCH, DIR4_BASE); + *dir_width = FIELD_EX64(sys->CSR_PWCH, CSR_PWCH, DIR4_WIDTH); break; default: /* level may be zero for ldpte */ - *dir_base = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTBASE); - *dir_width = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTWIDTH); + *dir_base = FIELD_EX64(sys->CSR_PWCL, CSR_PWCL, PTBASE); + *dir_width = FIELD_EX64(sys->CSR_PWCL, CSR_PWCL, PTWIDTH); break; } } @@ -XXX,XX +XXX,XX @@ TLBRet loongarch_ptw(CPULoongArchState *env, MMUContext *context, vaddr address; TLBRet ret; MemTxResult ret1; - + CPUSysState *sys = env_sys(env); address = context->addr; if ((address >> 63) & 0x1) { - base = env->CSR_PGDH; + base = sys->CSR_PGDH; } else { - base = env->CSR_PGDL; + base = sys->CSR_PGDL; } base &= palen_mask; @@ -XXX,XX +XXX,XX @@ TLBRet get_physical_address(CPULoongArchState *env, MMUContext *context, int kernel_mode = mmu_idx == MMU_KERNEL_IDX; uint32_t plv, base_c, base_v; int64_t addr_high; - uint8_t da = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, DA); - uint8_t pg = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG); + CPUSysState *sys = env_sys(env); + uint8_t da = FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, DA); + uint8_t pg = FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, PG); vaddr address; /* Check PG and DA */ @@ -XXX,XX +XXX,XX @@ TLBRet get_physical_address(CPULoongArchState *env, MMUContext *context, /* Check direct map window */ for (int i = 0; i < 4; i++) { if (is_la64(env)) { - base_c = FIELD_EX64(env->CSR_DMW[i], CSR_DMW_64, VSEG); + base_c = FIELD_EX64(sys->CSR_DMW[i], CSR_DMW_64, VSEG); } else { - base_c = FIELD_EX64(env->CSR_DMW[i], CSR_DMW_32, VSEG); + base_c = FIELD_EX64(sys->CSR_DMW[i], CSR_DMW_32, VSEG); } - if ((plv & env->CSR_DMW[i]) && (base_c == base_v)) { - context->physical = dmw_va2pa(env, address, env->CSR_DMW[i]); + if ((plv & sys->CSR_DMW[i]) && (base_c == base_v)) { + context->physical = dmw_va2pa(env, address, sys->CSR_DMW[i]); context->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; context->mmu_index = MMU_DA_IDX; return TLBRET_MATCH; -- 2.54.0
From: Bibo Mao <maobibo@loongson.cn> When accessing CSR registers in file arch_dump.c, use sys_state rather than env. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Philippe Mathieu-Daudé <philmd@mailo.com> Tested-by: Song Gao <gaosong@loongson.cn> Message-ID: <20260605082552.175336-5-maobibo@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn> --- hw/intc/loongarch_dintc.c | 4 +++- target/loongarch/arch_dump.c | 5 +++-- target/loongarch/cpu-mmu.h | 4 +++- target/loongarch/gdbstub.c | 3 ++- target/loongarch/tcg/constant_timer.c | 10 ++++++---- 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/hw/intc/loongarch_dintc.c b/hw/intc/loongarch_dintc.c index XXXXXXX..XXXXXXX 100644 --- a/hw/intc/loongarch_dintc.c +++ b/hw/intc/loongarch_dintc.c @@ -XXX,XX +XXX,XX @@ static void do_set_vcpu_dintc_irq(CPUState *cs, run_on_cpu_data data) { int irq = data.host_int; CPULoongArchState *env; + CPUSysState *sys; env = &LOONGARCH_CPU(cs)->env; + sys = env_sys(env); cpu_synchronize_state(cs); - set_bit(irq, (unsigned long *)&env->CSR_MSGIS); + set_bit(irq, (unsigned long *)&sys->CSR_MSGIS); } static void loongarch_dintc_mem_write(void *opaque, hwaddr addr, diff --git a/target/loongarch/arch_dump.c b/target/loongarch/arch_dump.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/arch_dump.c +++ b/target/loongarch/arch_dump.c @@ -XXX,XX +XXX,XX @@ int loongarch_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs, { struct loongarch_note note; CPULoongArchState *env = &LOONGARCH_CPU(cs)->env; + CPUSysState *sys = env_sys(env); int ret, i; loongarch_note_init(¬e, s, "CORE", 5, NT_PRSTATUS, @@ -XXX,XX +XXX,XX @@ int loongarch_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs, for (i = 0; i < 32; ++i) { note.prstatus.pr_reg.gpr[i] = cpu_to_dump64(s, env->gpr[i]); } - note.prstatus.pr_reg.csr_era = cpu_to_dump64(s, env->CSR_ERA); - note.prstatus.pr_reg.csr_badv = cpu_to_dump64(s, env->CSR_BADV); + note.prstatus.pr_reg.csr_era = cpu_to_dump64(s, sys->CSR_ERA); + note.prstatus.pr_reg.csr_badv = cpu_to_dump64(s, sys->CSR_BADV); ret = f(¬e, LOONGARCH_PRSTATUS_NOTE_SIZE, s); if (ret < 0) { return -1; diff --git a/target/loongarch/cpu-mmu.h b/target/loongarch/cpu-mmu.h index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/cpu-mmu.h +++ b/target/loongarch/cpu-mmu.h @@ -XXX,XX +XXX,XX @@ typedef struct MMUContext { static inline bool cpu_has_ptw(CPULoongArchState *env) { - return !!FIELD_EX64(env->CSR_PWCH, CSR_PWCH, HPTW_EN); + CPUSysState *sys = env_sys(env); + + return !!FIELD_EX64(sys->CSR_PWCH, CSR_PWCH, HPTW_EN); } static inline bool pte_present(CPULoongArchState *env, uint64_t entry) diff --git a/target/loongarch/gdbstub.c b/target/loongarch/gdbstub.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/gdbstub.c +++ b/target/loongarch/gdbstub.c @@ -XXX,XX +XXX,XX @@ void write_fcc(CPULoongArchState *env, uint64_t val) int loongarch_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) { CPULoongArchState *env = cpu_env(cs); + CPUSysState *sys = env_sys(env); if (0 <= n && n <= 34) { uint64_t val; @@ -XXX,XX +XXX,XX @@ int loongarch_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) } else if (n == 33) { val = env->pc; } else /* if (n == 34) */ { - val = env->CSR_BADV; + val = sys->CSR_BADV; } if (is_la64(env)) { diff --git a/target/loongarch/tcg/constant_timer.c b/target/loongarch/tcg/constant_timer.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/tcg/constant_timer.c +++ b/target/loongarch/tcg/constant_timer.c @@ -XXX,XX +XXX,XX @@ void cpu_loongarch_store_constant_timer_config(LoongArchCPU *cpu, uint64_t value) { CPULoongArchState *env = &cpu->env; + CPUSysState *sys = env_sys(env); uint64_t now, next; - env->CSR_TCFG = value; + sys->CSR_TCFG = value; if (value & CONSTANT_TIMER_ENABLE) { now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); next = now + (value & CONSTANT_TIMER_TICK_MASK) * TIMER_PERIOD; @@ -XXX,XX +XXX,XX @@ void loongarch_constant_timer_cb(void *opaque) { LoongArchCPU *cpu = opaque; CPULoongArchState *env = &cpu->env; + CPUSysState *sys = env_sys(env); uint64_t now, next; - if (FIELD_EX64(env->CSR_TCFG, CSR_TCFG, PERIODIC)) { + if (FIELD_EX64(sys->CSR_TCFG, CSR_TCFG, PERIODIC)) { now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - next = now + (env->CSR_TCFG & CONSTANT_TIMER_TICK_MASK) * TIMER_PERIOD; + next = now + (sys->CSR_TCFG & CONSTANT_TIMER_TICK_MASK) * TIMER_PERIOD; timer_mod(&cpu->timer, next); } else { - env->CSR_TCFG = FIELD_DP64(env->CSR_TCFG, CSR_TCFG, EN, 0); + sys->CSR_TCFG = FIELD_DP64(sys->CSR_TCFG, CSR_TCFG, EN, 0); } loongarch_cpu_set_irq(opaque, IRQ_TIMER, 1); -- 2.54.0
From: Bibo Mao <maobibo@loongson.cn> When accessing CSR registers in file kvm.c, use sys_state rather than env. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Philippe Mathieu-Daudé <philmd@mailo.com> Tested-by: Song Gao <gaosong@loongson.cn> Message-ID: <20260605082552.175336-6-maobibo@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn> --- target/loongarch/kvm/kvm.c | 228 +++++++++++++++++++------------------ 1 file changed, 116 insertions(+), 112 deletions(-) diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/kvm/kvm.c +++ b/target/loongarch/kvm/kvm.c @@ -XXX,XX +XXX,XX @@ static int kvm_loongarch_put_pmu(CPUState *cs) int i, ret = 0; CPULoongArchState *env = cpu_env(cs); LoongArchCPU *cpu = LOONGARCH_CPU(cs); + CPUSysState *sys = env_sys(env); if (cpu->pmu != ON_OFF_AUTO_ON) { return 0; @@ -XXX,XX +XXX,XX @@ static int kvm_loongarch_put_pmu(CPUState *cs) for (i = 0; i < env->perf_event_num; i++) { ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PERFCTRL(i)), - &env->CSR_PERFCTRL[i]); + &sys->CSR_PERFCTRL[i]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PERFCNTR(i)), - &env->CSR_PERFCNTR[i]); + &sys->CSR_PERFCNTR[i]); } return ret; @@ -XXX,XX +XXX,XX @@ static int kvm_loongarch_get_pmu(CPUState *cs) int i, ret = 0; CPULoongArchState *env = cpu_env(cs); LoongArchCPU *cpu = LOONGARCH_CPU(cs); + CPUSysState *sys = env_sys(env); if (cpu->pmu != ON_OFF_AUTO_ON) { return 0; @@ -XXX,XX +XXX,XX @@ static int kvm_loongarch_get_pmu(CPUState *cs) for (i = 0; i < env->perf_event_num; i++) { ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PERFCTRL(i)), - &env->CSR_PERFCTRL[i]); + &sys->CSR_PERFCTRL[i]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PERFCNTR(i)), - &env->CSR_PERFCNTR[i]); + &sys->CSR_PERFCNTR[i]); } return ret; @@ -XXX,XX +XXX,XX @@ static int kvm_loongarch_get_csr(CPUState *cs) { int ret = 0; CPULoongArchState *env = cpu_env(cs); + CPUSysState *sys = env_sys(env); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CRMD), - &env->CSR_CRMD); + &sys->CSR_CRMD); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRMD), - &env->CSR_PRMD); + &sys->CSR_PRMD); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EUEN), - &env->CSR_EUEN); + &sys->CSR_EUEN); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_MISC), - &env->CSR_MISC); + &sys->CSR_MISC); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ECFG), - &env->CSR_ECFG); + &sys->CSR_ECFG); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ESTAT), - &env->CSR_ESTAT); + &sys->CSR_ESTAT); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ERA), - &env->CSR_ERA); + &sys->CSR_ERA); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADV), - &env->CSR_BADV); + &sys->CSR_BADV); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADI), - &env->CSR_BADI); + &sys->CSR_BADI); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EENTRY), - &env->CSR_EENTRY); + &sys->CSR_EENTRY); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBIDX), - &env->CSR_TLBIDX); + &sys->CSR_TLBIDX); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBEHI), - &env->CSR_TLBEHI); + &sys->CSR_TLBEHI); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO0), - &env->CSR_TLBELO0); + &sys->CSR_TLBELO0); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO1), - &env->CSR_TLBELO1); + &sys->CSR_TLBELO1); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ASID), - &env->CSR_ASID); + &sys->CSR_ASID); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDL), - &env->CSR_PGDL); + &sys->CSR_PGDL); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDH), - &env->CSR_PGDH); + &sys->CSR_PGDH); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGD), - &env->CSR_PGD); + &sys->CSR_PGD); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCL), - &env->CSR_PWCL); + &sys->CSR_PWCL); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCH), - &env->CSR_PWCH); + &sys->CSR_PWCH); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_STLBPS), - &env->CSR_STLBPS); + &sys->CSR_STLBPS); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_RVACFG), - &env->CSR_RVACFG); + &sys->CSR_RVACFG); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CPUID), - &env->CSR_CPUID); + &sys->CSR_CPUID); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG1), - &env->CSR_PRCFG1); + &sys->CSR_PRCFG1); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG2), - &env->CSR_PRCFG2); + &sys->CSR_PRCFG2); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG3), - &env->CSR_PRCFG3); + &sys->CSR_PRCFG3); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(0)), - &env->CSR_SAVE[0]); + &sys->CSR_SAVE[0]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(1)), - &env->CSR_SAVE[1]); + &sys->CSR_SAVE[1]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(2)), - &env->CSR_SAVE[2]); + &sys->CSR_SAVE[2]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(3)), - &env->CSR_SAVE[3]); + &sys->CSR_SAVE[3]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(4)), - &env->CSR_SAVE[4]); + &sys->CSR_SAVE[4]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(5)), - &env->CSR_SAVE[5]); + &sys->CSR_SAVE[5]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(6)), - &env->CSR_SAVE[6]); + &sys->CSR_SAVE[6]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(7)), - &env->CSR_SAVE[7]); + &sys->CSR_SAVE[7]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TID), - &env->CSR_TID); + &sys->CSR_TID); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CNTC), - &env->CSR_CNTC); + &sys->CSR_CNTC); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TICLR), - &env->CSR_TICLR); + &sys->CSR_TICLR); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_LLBCTL), - &env->CSR_LLBCTL); + &sys->CSR_LLBCTL); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL1), - &env->CSR_IMPCTL1); + &sys->CSR_IMPCTL1); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL2), - &env->CSR_IMPCTL2); + &sys->CSR_IMPCTL2); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRENTRY), - &env->CSR_TLBRENTRY); + &sys->CSR_TLBRENTRY); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRBADV), - &env->CSR_TLBRBADV); + &sys->CSR_TLBRBADV); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRERA), - &env->CSR_TLBRERA); + &sys->CSR_TLBRERA); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRSAVE), - &env->CSR_TLBRSAVE); + &sys->CSR_TLBRSAVE); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO0), - &env->CSR_TLBRELO0); + &sys->CSR_TLBRELO0); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO1), - &env->CSR_TLBRELO1); + &sys->CSR_TLBRELO1); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBREHI), - &env->CSR_TLBREHI); + &sys->CSR_TLBREHI); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRPRMD), - &env->CSR_TLBRPRMD); + &sys->CSR_TLBRPRMD); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(0)), - &env->CSR_DMW[0]); + &sys->CSR_DMW[0]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(1)), - &env->CSR_DMW[1]); + &sys->CSR_DMW[1]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(2)), - &env->CSR_DMW[2]); + &sys->CSR_DMW[2]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(3)), - &env->CSR_DMW[3]); + &sys->CSR_DMW[3]); ret |= kvm_loongarch_get_pmu(cs); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TVAL), - &env->CSR_TVAL); + &sys->CSR_TVAL); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TCFG), - &env->CSR_TCFG); + &sys->CSR_TCFG); return ret; } @@ -XXX,XX +XXX,XX @@ static int kvm_loongarch_put_csr(CPUState *cs, KvmPutState level) { int ret = 0; CPULoongArchState *env = cpu_env(cs); + CPUSysState *sys = env_sys(env); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CRMD), - &env->CSR_CRMD); + &sys->CSR_CRMD); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRMD), - &env->CSR_PRMD); + &sys->CSR_PRMD); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EUEN), - &env->CSR_EUEN); + &sys->CSR_EUEN); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_MISC), - &env->CSR_MISC); + &sys->CSR_MISC); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ECFG), - &env->CSR_ECFG); + &sys->CSR_ECFG); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ESTAT), - &env->CSR_ESTAT); + &sys->CSR_ESTAT); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ERA), - &env->CSR_ERA); + &sys->CSR_ERA); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADV), - &env->CSR_BADV); + &sys->CSR_BADV); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADI), - &env->CSR_BADI); + &sys->CSR_BADI); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EENTRY), - &env->CSR_EENTRY); + &sys->CSR_EENTRY); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBIDX), - &env->CSR_TLBIDX); + &sys->CSR_TLBIDX); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBEHI), - &env->CSR_TLBEHI); + &sys->CSR_TLBEHI); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO0), - &env->CSR_TLBELO0); + &sys->CSR_TLBELO0); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO1), - &env->CSR_TLBELO1); + &sys->CSR_TLBELO1); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ASID), - &env->CSR_ASID); + &sys->CSR_ASID); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDL), - &env->CSR_PGDL); + &sys->CSR_PGDL); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDH), - &env->CSR_PGDH); + &sys->CSR_PGDH); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGD), - &env->CSR_PGD); + &sys->CSR_PGD); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCL), - &env->CSR_PWCL); + &sys->CSR_PWCL); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCH), - &env->CSR_PWCH); + &sys->CSR_PWCH); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_STLBPS), - &env->CSR_STLBPS); + &sys->CSR_STLBPS); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_RVACFG), - &env->CSR_RVACFG); + &sys->CSR_RVACFG); /* CPUID is constant after poweron, it should be set only once */ if (level >= KVM_PUT_FULL_STATE) { ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CPUID), - &env->CSR_CPUID); + &sys->CSR_CPUID); } ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG1), - &env->CSR_PRCFG1); + &sys->CSR_PRCFG1); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG2), - &env->CSR_PRCFG2); + &sys->CSR_PRCFG2); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG3), - &env->CSR_PRCFG3); + &sys->CSR_PRCFG3); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(0)), - &env->CSR_SAVE[0]); + &sys->CSR_SAVE[0]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(1)), - &env->CSR_SAVE[1]); + &sys->CSR_SAVE[1]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(2)), - &env->CSR_SAVE[2]); + &sys->CSR_SAVE[2]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(3)), - &env->CSR_SAVE[3]); + &sys->CSR_SAVE[3]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(4)), - &env->CSR_SAVE[4]); + &sys->CSR_SAVE[4]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(5)), - &env->CSR_SAVE[5]); + &sys->CSR_SAVE[5]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(6)), - &env->CSR_SAVE[6]); + &sys->CSR_SAVE[6]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(7)), - &env->CSR_SAVE[7]); + &sys->CSR_SAVE[7]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TID), - &env->CSR_TID); + &sys->CSR_TID); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CNTC), - &env->CSR_CNTC); + &sys->CSR_CNTC); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TICLR), - &env->CSR_TICLR); + &sys->CSR_TICLR); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_LLBCTL), - &env->CSR_LLBCTL); + &sys->CSR_LLBCTL); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL1), - &env->CSR_IMPCTL1); + &sys->CSR_IMPCTL1); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL2), - &env->CSR_IMPCTL2); + &sys->CSR_IMPCTL2); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRENTRY), - &env->CSR_TLBRENTRY); + &sys->CSR_TLBRENTRY); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRBADV), - &env->CSR_TLBRBADV); + &sys->CSR_TLBRBADV); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRERA), - &env->CSR_TLBRERA); + &sys->CSR_TLBRERA); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRSAVE), - &env->CSR_TLBRSAVE); + &sys->CSR_TLBRSAVE); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO0), - &env->CSR_TLBRELO0); + &sys->CSR_TLBRELO0); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO1), - &env->CSR_TLBRELO1); + &sys->CSR_TLBRELO1); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBREHI), - &env->CSR_TLBREHI); + &sys->CSR_TLBREHI); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRPRMD), - &env->CSR_TLBRPRMD); + &sys->CSR_TLBRPRMD); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(0)), - &env->CSR_DMW[0]); + &sys->CSR_DMW[0]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(1)), - &env->CSR_DMW[1]); + &sys->CSR_DMW[1]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(2)), - &env->CSR_DMW[2]); + &sys->CSR_DMW[2]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(3)), - &env->CSR_DMW[3]); + &sys->CSR_DMW[3]); ret |= kvm_loongarch_put_pmu(cs); @@ -XXX,XX +XXX,XX @@ static int kvm_loongarch_put_csr(CPUState *cs, KvmPutState level) * guest timer */ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TVAL), - &env->CSR_TVAL); + &sys->CSR_TVAL); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TCFG), - &env->CSR_TCFG); + &sys->CSR_TCFG); return ret; } -- 2.54.0
From: Bibo Mao <maobibo@loongson.cn> When accessing CSR registers in file tlb_helper.c, use sys_state rather than env. There is no function change. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Philippe Mathieu-Daudé <philmd@mailo.com> Tested-by: Song Gao <gaosong@loongson.cn> Message-ID: <20260605082552.175336-7-maobibo@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn> --- target/loongarch/tcg/tlb_helper.c | 137 +++++++++++++++++------------- 1 file changed, 77 insertions(+), 60 deletions(-) diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/tcg/tlb_helper.c +++ b/target/loongarch/tcg/tlb_helper.c @@ -XXX,XX +XXX,XX @@ static bool tlb_match_asid(bool global, int asid, int tlb_asid) bool check_ps(CPULoongArchState *env, uint8_t tlb_ps) { + CPUSysState *sys = env_sys(env); + if (tlb_ps >= 64) { return false; } - return BIT_ULL(tlb_ps) & (env->CSR_PRCFG2); + return BIT_ULL(tlb_ps) & (sys->CSR_PRCFG2); } static void raise_mmu_exception(CPULoongArchState *env, vaddr address, MMUAccessType access_type, TLBRet tlb_error) { CPUState *cs = env_cpu(env); + CPUSysState *sys = env_sys(env); switch (tlb_error) { default: @@ -XXX,XX +XXX,XX @@ static void raise_mmu_exception(CPULoongArchState *env, vaddr address, } else if (access_type == MMU_INST_FETCH) { cs->exception_index = EXCCODE_PIF; } - env->CSR_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR, 1); + sys->CSR_TLBRERA = FIELD_DP64(sys->CSR_TLBRERA, CSR_TLBRERA, ISTLBR, 1); break; case TLBRET_INVALID: /* TLB match with no valid bit */ @@ -XXX,XX +XXX,XX @@ static void raise_mmu_exception(CPULoongArchState *env, vaddr address, } if (tlb_error == TLBRET_NOMATCH) { - env->CSR_TLBRBADV = address; + sys->CSR_TLBRBADV = address; if (is_la64(env)) { - env->CSR_TLBREHI = FIELD_DP64(env->CSR_TLBREHI, CSR_TLBREHI_64, + sys->CSR_TLBREHI = FIELD_DP64(sys->CSR_TLBREHI, CSR_TLBREHI_64, VPPN, extract64(address, 13, 35)); } else { - env->CSR_TLBREHI = FIELD_DP64(env->CSR_TLBREHI, CSR_TLBREHI_32, + sys->CSR_TLBREHI = FIELD_DP64(sys->CSR_TLBREHI, CSR_TLBREHI_32, VPPN, extract64(address, 13, 19)); } } else { - if (!FIELD_EX64(env->CSR_DBG, CSR_DBG, DST)) { - env->CSR_BADV = address; + if (!FIELD_EX64(sys->CSR_DBG, CSR_DBG, DST)) { + sys->CSR_BADV = address; } - env->CSR_TLBEHI = address & (TARGET_PAGE_MASK << 1); + sys->CSR_TLBEHI = address & (TARGET_PAGE_MASK << 1); } } @@ -XXX,XX +XXX,XX @@ static void invalidate_tlb(CPULoongArchState *env, int index) LoongArchTLB *tlb; uint16_t csr_asid, tlb_asid, tlb_g; uint8_t tlb_e; + CPUSysState *sys = env_sys(env); - csr_asid = FIELD_EX64(env->CSR_ASID, CSR_ASID, ASID); + csr_asid = FIELD_EX64(sys->CSR_ASID, CSR_ASID, ASID); tlb = &env->tlb[index]; tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E); if (!tlb_e) { @@ -XXX,XX +XXX,XX @@ static void sptw_prepare_context(CPULoongArchState *env, MMUContext *context) { uint64_t lo0, lo1, csr_vppn; uint8_t csr_ps; + CPUSysState *sys = env_sys(env); - if (FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) { - csr_ps = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI, PS); + if (FIELD_EX64(sys->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) { + csr_ps = FIELD_EX64(sys->CSR_TLBREHI, CSR_TLBREHI, PS); if (is_la64(env)) { - csr_vppn = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI_64, VPPN); + csr_vppn = FIELD_EX64(sys->CSR_TLBREHI, CSR_TLBREHI_64, VPPN); } else { - csr_vppn = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI_32, VPPN); + csr_vppn = FIELD_EX64(sys->CSR_TLBREHI, CSR_TLBREHI_32, VPPN); } - lo0 = env->CSR_TLBRELO0; - lo1 = env->CSR_TLBRELO1; + lo0 = sys->CSR_TLBRELO0; + lo1 = sys->CSR_TLBRELO1; } else { - csr_ps = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, PS); + csr_ps = FIELD_EX64(sys->CSR_TLBIDX, CSR_TLBIDX, PS); if (is_la64(env)) { - csr_vppn = FIELD_EX64(env->CSR_TLBEHI, CSR_TLBEHI_64, VPPN); + csr_vppn = FIELD_EX64(sys->CSR_TLBEHI, CSR_TLBEHI_64, VPPN); } else { - csr_vppn = FIELD_EX64(env->CSR_TLBEHI, CSR_TLBEHI_32, VPPN); + csr_vppn = FIELD_EX64(sys->CSR_TLBEHI, CSR_TLBEHI_32, VPPN); } - lo0 = env->CSR_TLBELO0; - lo1 = env->CSR_TLBELO1; + lo0 = sys->CSR_TLBELO0; + lo1 = sys->CSR_TLBELO1; } context->ps = csr_ps; @@ -XXX,XX +XXX,XX @@ static void fill_tlb_entry(CPULoongArchState *env, LoongArchTLB *tlb, uint64_t lo0, lo1, csr_vppn; uint16_t csr_asid; uint8_t csr_ps; + CPUSysState *sys = env_sys(env); csr_vppn = context->addr >> R_TLB_MISC_VPPN_SHIFT; csr_ps = context->ps; @@ -XXX,XX +XXX,XX @@ static void fill_tlb_entry(CPULoongArchState *env, LoongArchTLB *tlb, tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, PS, csr_ps); tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, VPPN, csr_vppn); tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, E, 1); - csr_asid = FIELD_EX64(env->CSR_ASID, CSR_ASID, ASID); + csr_asid = FIELD_EX64(sys->CSR_ASID, CSR_ASID, ASID); tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, ASID, csr_asid); tlb->tlb_entry0 = lo0; @@ -XXX,XX +XXX,XX @@ static LoongArchTLB *loongarch_tlb_search_cb(CPULoongArchState *env, bool tlb_g; int i, compare_shift; uint64_t vpn, tlb_vppn; + CPUSysState *sys = env_sys(env); - stlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS); + stlb_ps = FIELD_EX64(sys->CSR_STLBPS, CSR_STLBPS, PS); vpn = (vaddr & TARGET_VIRT_MASK) >> (stlb_ps + 1); stlb_idx = vpn & 0xff; /* VA[25:15] <==> TLBIDX.index for 16KiB Page */ compare_shift = stlb_ps + 1 - R_TLB_MISC_VPPN_SHIFT; @@ -XXX,XX +XXX,XX @@ static bool loongarch_tlb_search(CPULoongArchState *env, vaddr vaddr, int csr_asid; tlb_match func; LoongArchTLB *tlb; + CPUSysState *sys = env_sys(env); func = tlb_match_any; - csr_asid = FIELD_EX64(env->CSR_ASID, CSR_ASID, ASID); + csr_asid = FIELD_EX64(sys->CSR_ASID, CSR_ASID, ASID); tlb = loongarch_tlb_search_cb(env, vaddr, csr_asid, func); if (tlb) { *index = tlb - env->tlb; @@ -XXX,XX +XXX,XX @@ static bool loongarch_tlb_search(CPULoongArchState *env, vaddr vaddr, void helper_tlbsrch(CPULoongArchState *env) { int index, match; + CPUSysState *sys = env_sys(env); - if (FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) { - match = loongarch_tlb_search(env, env->CSR_TLBREHI, &index); + if (FIELD_EX64(sys->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) { + match = loongarch_tlb_search(env, sys->CSR_TLBREHI, &index); } else { - match = loongarch_tlb_search(env, env->CSR_TLBEHI, &index); + match = loongarch_tlb_search(env, sys->CSR_TLBEHI, &index); } if (match) { - env->CSR_TLBIDX = FIELD_DP64(env->CSR_TLBIDX, CSR_TLBIDX, INDEX, index); - env->CSR_TLBIDX = FIELD_DP64(env->CSR_TLBIDX, CSR_TLBIDX, NE, 0); + sys->CSR_TLBIDX = FIELD_DP64(sys->CSR_TLBIDX, CSR_TLBIDX, INDEX, index); + sys->CSR_TLBIDX = FIELD_DP64(sys->CSR_TLBIDX, CSR_TLBIDX, NE, 0); return; } - env->CSR_TLBIDX = FIELD_DP64(env->CSR_TLBIDX, CSR_TLBIDX, NE, 1); + sys->CSR_TLBIDX = FIELD_DP64(sys->CSR_TLBIDX, CSR_TLBIDX, NE, 1); } void helper_tlbrd(CPULoongArchState *env) @@ -XXX,XX +XXX,XX @@ void helper_tlbrd(CPULoongArchState *env) LoongArchTLB *tlb; int index; uint8_t tlb_ps, tlb_e; + CPUSysState *sys = env_sys(env); - index = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, INDEX); + index = FIELD_EX64(sys->CSR_TLBIDX, CSR_TLBIDX, INDEX); tlb = &env->tlb[index]; tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS); tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E); if (!tlb_e) { /* Invalid TLB entry */ - env->CSR_TLBIDX = FIELD_DP64(env->CSR_TLBIDX, CSR_TLBIDX, NE, 1); - env->CSR_ASID = FIELD_DP64(env->CSR_ASID, CSR_ASID, ASID, 0); - env->CSR_TLBEHI = 0; - env->CSR_TLBELO0 = 0; - env->CSR_TLBELO1 = 0; - env->CSR_TLBIDX = FIELD_DP64(env->CSR_TLBIDX, CSR_TLBIDX, PS, 0); + sys->CSR_TLBIDX = FIELD_DP64(sys->CSR_TLBIDX, CSR_TLBIDX, NE, 1); + sys->CSR_ASID = FIELD_DP64(sys->CSR_ASID, CSR_ASID, ASID, 0); + sys->CSR_TLBEHI = 0; + sys->CSR_TLBELO0 = 0; + sys->CSR_TLBELO1 = 0; + sys->CSR_TLBIDX = FIELD_DP64(sys->CSR_TLBIDX, CSR_TLBIDX, PS, 0); } else { /* Valid TLB entry */ - env->CSR_TLBIDX = FIELD_DP64(env->CSR_TLBIDX, CSR_TLBIDX, NE, 0); - env->CSR_TLBIDX = FIELD_DP64(env->CSR_TLBIDX, CSR_TLBIDX, + sys->CSR_TLBIDX = FIELD_DP64(sys->CSR_TLBIDX, CSR_TLBIDX, NE, 0); + sys->CSR_TLBIDX = FIELD_DP64(sys->CSR_TLBIDX, CSR_TLBIDX, PS, (tlb_ps & 0x3f)); - env->CSR_TLBEHI = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN) << + sys->CSR_TLBEHI = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN) << R_TLB_MISC_VPPN_SHIFT; - env->CSR_TLBELO0 = tlb->tlb_entry0; - env->CSR_TLBELO1 = tlb->tlb_entry1; + sys->CSR_TLBELO0 = tlb->tlb_entry0; + sys->CSR_TLBELO1 = tlb->tlb_entry1; } } @@ -XXX,XX +XXX,XX @@ static void update_tlb_index(CPULoongArchState *env, MMUContext *context, void helper_tlbwr(CPULoongArchState *env) { - int index = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, INDEX); + CPUSysState *sys = env_sys(env); + int index = FIELD_EX64(sys->CSR_TLBIDX, CSR_TLBIDX, INDEX); MMUContext context; - if (FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, NE)) { + if (FIELD_EX64(sys->CSR_TLBIDX, CSR_TLBIDX, NE)) { invalidate_tlb(env, index); return; } @@ -XXX,XX +XXX,XX @@ static int get_tlb_random_index(CPULoongArchState *env, vaddr addr, uint16_t asid, tlb_asid, stlb_ps; LoongArchTLB *tlb; uint8_t tlb_e, tlb_g; + CPUSysState *sys = env_sys(env); /* Validity of stlb_ps is checked in helper_csrwr_stlbps() */ - stlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS); - asid = FIELD_EX64(env->CSR_ASID, CSR_ASID, ASID); + stlb_ps = FIELD_EX64(sys->CSR_STLBPS, CSR_STLBPS, PS); + asid = FIELD_EX64(sys->CSR_ASID, CSR_ASID, ASID); if (pagesize == stlb_ps) { /* Only write into STLB bits [47:13] */ address = addr & ~MAKE_64BIT_MASK(0, R_CSR_TLBEHI_64_VPPN_SHIFT); @@ -XXX,XX +XXX,XX @@ void helper_tlbfill(CPULoongArchState *env) vaddr entryhi; int index, pagesize; MMUContext context; + CPUSysState *sys = env_sys(env); - if (FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) { - entryhi = env->CSR_TLBREHI; + if (FIELD_EX64(sys->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) { + entryhi = sys->CSR_TLBREHI; /* Validity of pagesize is checked in helper_ldpte() */ - pagesize = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI, PS); + pagesize = FIELD_EX64(sys->CSR_TLBREHI, CSR_TLBREHI, PS); } else { - entryhi = env->CSR_TLBEHI; + entryhi = sys->CSR_TLBEHI; /* Validity of pagesize is checked in helper_tlbrd() */ - pagesize = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, PS); + pagesize = FIELD_EX64(sys->CSR_TLBIDX, CSR_TLBIDX, PS); } sptw_prepare_context(env, &context); @@ -XXX,XX +XXX,XX @@ void helper_tlbclr(CPULoongArchState *env) LoongArchTLB *tlb; int i, index; uint16_t csr_asid, tlb_asid, tlb_g; + CPUSysState *sys = env_sys(env); - csr_asid = FIELD_EX64(env->CSR_ASID, CSR_ASID, ASID); - index = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, INDEX); + csr_asid = FIELD_EX64(sys->CSR_ASID, CSR_ASID, ASID); + index = FIELD_EX64(sys->CSR_TLBIDX, CSR_TLBIDX, INDEX); if (index < LOONGARCH_STLB) { /* STLB. One line per operation */ @@ -XXX,XX +XXX,XX @@ void helper_tlbclr(CPULoongArchState *env) void helper_tlbflush(CPULoongArchState *env) { int i, index; + CPUSysState *sys = env_sys(env); - index = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, INDEX); + index = FIELD_EX64(sys->CSR_TLBIDX, CSR_TLBIDX, INDEX); if (index < LOONGARCH_STLB) { /* STLB. One line per operation */ @@ -XXX,XX +XXX,XX @@ target_ulong helper_lddir(CPULoongArchState *env, target_ulong base, uint64_t palen_mask = loongarch_palen_mask(env); uint64_t dir_base, dir_width; uint64_t val; + CPUSysState *sys = env_sys(env); if (unlikely((level == 0) || (level > 4))) { qemu_log_mask(LOG_GUEST_ERROR, @@ -XXX,XX +XXX,XX @@ target_ulong helper_lddir(CPULoongArchState *env, target_ulong base, } } - badvaddr = env->CSR_TLBRBADV; + badvaddr = sys->CSR_TLBRBADV; base = base & palen_mask; get_dir_base_width(env, &dir_base, &dir_width, level); index = (badvaddr >> dir_base) & ((1 << dir_width) - 1); @@ -XXX,XX +XXX,XX @@ void helper_ldpte(CPULoongArchState *env, target_ulong base, target_ulong odd, { CPUState *cs = env_cpu(env); hwaddr phys, tmp0, ptindex, ptoffset0, ptoffset1; + CPUSysState *sys = env_sys(env); uint64_t pte_raw; uint64_t badv; - uint64_t ptbase = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTBASE); - uint64_t ptwidth = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTWIDTH); + uint64_t ptbase = FIELD_EX64(sys->CSR_PWCL, CSR_PWCL, PTBASE); + uint64_t ptwidth = FIELD_EX64(sys->CSR_PWCL, CSR_PWCL, PTWIDTH); uint64_t palen_mask = loongarch_palen_mask(env); uint64_t dir_base, dir_width; uint8_t ps; @@ -XXX,XX +XXX,XX @@ void helper_ldpte(CPULoongArchState *env, target_ulong base, target_ulong odd, return; } } else { - badv = env->CSR_TLBRBADV; + badv = sys->CSR_TLBRBADV; base = base & palen_mask; @@ -XXX,XX +XXX,XX @@ void helper_ldpte(CPULoongArchState *env, target_ulong base, target_ulong odd, } if (odd) { - env->CSR_TLBRELO1 = tmp0; + sys->CSR_TLBRELO1 = tmp0; } else { - env->CSR_TLBRELO0 = tmp0; + sys->CSR_TLBRELO0 = tmp0; } - env->CSR_TLBREHI = FIELD_DP64(env->CSR_TLBREHI, CSR_TLBREHI, PS, ps); + sys->CSR_TLBREHI = FIELD_DP64(sys->CSR_TLBREHI, CSR_TLBREHI, PS, ps); } static TLBRet loongarch_map_tlb_entry(CPULoongArchState *env, -- 2.54.0
From: Bibo Mao <maobibo@loongson.cn> When accessing CSR registers in file tcg_cpu.c, use sys_state rather than env. There is no function change. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Philippe Mathieu-Daudé <philmd@mailo.com> Tested-by: Song Gao <gaosong@loongson.cn> Message-ID: <20260605082552.175336-8-maobibo@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn> --- target/loongarch/tcg/tcg_cpu.c | 107 +++++++++++++++++---------------- 1 file changed, 56 insertions(+), 51 deletions(-) diff --git a/target/loongarch/tcg/tcg_cpu.c b/target/loongarch/tcg/tcg_cpu.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/tcg/tcg_cpu.c +++ b/target/loongarch/tcg/tcg_cpu.c @@ -XXX,XX +XXX,XX @@ void G_NORETURN do_raise_exception(CPULoongArchState *env, static void loongarch_cpu_do_interrupt(CPUState *cs) { CPULoongArchState *env = cpu_env(cs); + CPUSysState *sys = env_sys(env); bool update_badinstr = 1; int cause = -1; - bool tlbfill = FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR); - uint32_t vec_size = FIELD_EX64(env->CSR_ECFG, CSR_ECFG, VS); + bool tlbfill = FIELD_EX64(sys->CSR_TLBRERA, CSR_TLBRERA, ISTLBR); + uint32_t vec_size = FIELD_EX64(sys->CSR_ECFG, CSR_ECFG, VS); uint64_t last_pc = env->pc; if (cs->exception_index != EXCCODE_INT) { qemu_log_mask(CPU_LOG_INT, "%s enter: pc " TARGET_FMT_lx " ERA " TARGET_FMT_lx " TLBRERA " TARGET_FMT_lx " exception: %d (%s)\n", - __func__, env->pc, env->CSR_ERA, env->CSR_TLBRERA, + __func__, env->pc, sys->CSR_ERA, sys->CSR_TLBRERA, cs->exception_index, loongarch_exception_name(cs->exception_index)); } switch (cs->exception_index) { case EXCCODE_DBP: - env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, DCL, 1); - env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, ECODE, 0xC); + sys->CSR_DBG = FIELD_DP64(sys->CSR_DBG, CSR_DBG, DCL, 1); + sys->CSR_DBG = FIELD_DP64(sys->CSR_DBG, CSR_DBG, ECODE, 0xC); goto set_DERA; set_DERA: - env->CSR_DERA = env->pc; - env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, DST, 1); - set_pc(env, env->CSR_EENTRY + 0x480); + sys->CSR_DERA = env->pc; + sys->CSR_DBG = FIELD_DP64(sys->CSR_DBG, CSR_DBG, DST, 1); + set_pc(env, sys->CSR_EENTRY + 0x480); break; case EXCCODE_INT: - if (FIELD_EX64(env->CSR_DBG, CSR_DBG, DST)) { - env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, DEI, 1); + if (FIELD_EX64(sys->CSR_DBG, CSR_DBG, DST)) { + sys->CSR_DBG = FIELD_DP64(sys->CSR_DBG, CSR_DBG, DEI, 1); goto set_DERA; } QEMU_FALLTHROUGH; @@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_do_interrupt(CPUState *cs) update_badinstr = 0; break; case EXCCODE_BCE: - env->CSR_BADV = env->pc; + sys->CSR_BADV = env->pc; QEMU_FALLTHROUGH; case EXCCODE_SYS: case EXCCODE_BRK: @@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_do_interrupt(CPUState *cs) if (update_badinstr) { MemOpIdx oi = make_memop_idx(MO_LEUL, cpu_mmu_index(cs, true)); - env->CSR_BADI = cpu_ldl_code_mmu(env, env->pc, oi, 0); + sys->CSR_BADI = cpu_ldl_code_mmu(env, env->pc, oi, 0); } /* Save PLV and IE */ if (tlbfill) { - env->CSR_TLBRPRMD = FIELD_DP64(env->CSR_TLBRPRMD, CSR_TLBRPRMD, PPLV, - FIELD_EX64(env->CSR_CRMD, + sys->CSR_TLBRPRMD = FIELD_DP64(sys->CSR_TLBRPRMD, CSR_TLBRPRMD, PPLV, + FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, PLV)); - env->CSR_TLBRPRMD = FIELD_DP64(env->CSR_TLBRPRMD, CSR_TLBRPRMD, PIE, - FIELD_EX64(env->CSR_CRMD, CSR_CRMD, IE)); + sys->CSR_TLBRPRMD = FIELD_DP64(sys->CSR_TLBRPRMD, CSR_TLBRPRMD, PIE, + FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, IE)); /* set the DA mode */ - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DA, 1); - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, PG, 0); - env->CSR_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, CSR_TLBRERA, + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, DA, 1); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, PG, 0); + sys->CSR_TLBRERA = FIELD_DP64(sys->CSR_TLBRERA, CSR_TLBRERA, PC, (env->pc >> 2)); } else { - env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, ECODE, + sys->CSR_ESTAT = FIELD_DP64(sys->CSR_ESTAT, CSR_ESTAT, ECODE, EXCODE_MCODE(cause)); - env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, ESUBCODE, + sys->CSR_ESTAT = FIELD_DP64(sys->CSR_ESTAT, CSR_ESTAT, ESUBCODE, EXCODE_SUBCODE(cause)); - env->CSR_PRMD = FIELD_DP64(env->CSR_PRMD, CSR_PRMD, PPLV, - FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV)); - env->CSR_PRMD = FIELD_DP64(env->CSR_PRMD, CSR_PRMD, PIE, - FIELD_EX64(env->CSR_CRMD, CSR_CRMD, IE)); - env->CSR_ERA = env->pc; + sys->CSR_PRMD = FIELD_DP64(sys->CSR_PRMD, CSR_PRMD, PPLV, + FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, PLV)); + sys->CSR_PRMD = FIELD_DP64(sys->CSR_PRMD, CSR_PRMD, PIE, + FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, IE)); + sys->CSR_ERA = env->pc; } - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, PLV, 0); - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, IE, 0); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, PLV, 0); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, IE, 0); if (vec_size) { vec_size = (1 << vec_size) * 4; @@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_do_interrupt(CPUState *cs) if (cs->exception_index == EXCCODE_INT) { /* Interrupt */ uint32_t vector = 0; - uint32_t pending = FIELD_EX64(env->CSR_ESTAT, CSR_ESTAT, IS); - pending &= FIELD_EX64(env->CSR_ECFG, CSR_ECFG, LIE); + uint32_t pending = FIELD_EX64(sys->CSR_ESTAT, CSR_ESTAT, IS); + pending &= FIELD_EX64(sys->CSR_ECFG, CSR_ECFG, LIE); /* Find the highest-priority interrupt. */ vector = 31 - clz32(pending); - set_pc(env, env->CSR_EENTRY + \ + set_pc(env, sys->CSR_EENTRY + \ (EXCCODE_EXTERNAL_INT + vector) * vec_size); qemu_log_mask(CPU_LOG_INT, "%s: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx " cause %d\n" " A " TARGET_FMT_lx " D " TARGET_FMT_lx " vector = %d ExC " TARGET_FMT_lx "ExS" TARGET_FMT_lx "\n", - __func__, env->pc, env->CSR_ERA, - cause, env->CSR_BADV, env->CSR_DERA, vector, - env->CSR_ECFG, env->CSR_ESTAT); + __func__, env->pc, sys->CSR_ERA, + cause, sys->CSR_BADV, sys->CSR_DERA, vector, + sys->CSR_ECFG, sys->CSR_ESTAT); qemu_plugin_vcpu_interrupt_cb(cs, last_pc); } else { if (tlbfill) { - set_pc(env, env->CSR_TLBRENTRY); + set_pc(env, sys->CSR_TLBRENTRY); } else { - set_pc(env, env->CSR_EENTRY + EXCODE_MCODE(cause) * vec_size); + set_pc(env, sys->CSR_EENTRY + EXCODE_MCODE(cause) * vec_size); } qemu_log_mask(CPU_LOG_INT, "%s: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx @@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_do_interrupt(CPUState *cs) " EXCFG " TARGET_FMT_lx " BADVA " TARGET_FMT_lx "BADI " TARGET_FMT_lx " SYS_NUM " TARGET_FMT_lu " cpu %d asid " TARGET_FMT_lx "\n", __func__, env->pc, - tlbfill ? env->CSR_TLBRERA : env->CSR_ERA, - cause, tlbfill ? "(refill)" : "", env->CSR_ESTAT, - env->CSR_ECFG, - tlbfill ? env->CSR_TLBRBADV : env->CSR_BADV, - env->CSR_BADI, env->gpr[11], cs->cpu_index, - env->CSR_ASID); + tlbfill ? sys->CSR_TLBRERA : sys->CSR_ERA, + cause, tlbfill ? "(refill)" : "", sys->CSR_ESTAT, + sys->CSR_ECFG, + tlbfill ? sys->CSR_TLBRBADV : sys->CSR_BADV, + sys->CSR_BADI, env->gpr[11], cs->cpu_index, + sys->CSR_ASID); qemu_plugin_vcpu_exception_cb(cs, last_pc); } cs->exception_index = -1; @@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, uintptr_t retaddr) { CPULoongArchState *env = cpu_env(cs); + CPUSysState *sys = env_sys(env); - env->CSR_BADV = addr; + sys->CSR_BADV = addr; if (access_type == MMU_INST_FETCH) { do_raise_exception(env, EXCCODE_ADEF, retaddr); } else { @@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, static inline bool cpu_loongarch_hw_interrupts_enabled(CPULoongArchState *env) { bool ret = 0; + CPUSysState *sys = env_sys(env); - ret = (FIELD_EX64(env->CSR_CRMD, CSR_CRMD, IE) && - !(FIELD_EX64(env->CSR_DBG, CSR_DBG, DST))); + ret = (FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, IE) && + !(FIELD_EX64(sys->CSR_DBG, CSR_DBG, DST))); return ret; } @@ -XXX,XX +XXX,XX @@ static vaddr loongarch_pointer_wrap(CPUState *cs, int mmu_idx, static TCGTBCPUState loongarch_get_tb_cpu_state(CPUState *cs) { CPULoongArchState *env = cpu_env(cs); + CPUSysState *sys = env_sys(env); uint32_t flags; - flags = env->CSR_CRMD & (R_CSR_CRMD_PLV_MASK | R_CSR_CRMD_PG_MASK); - flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, FPE) * HW_FLAGS_EUEN_FPE; - flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE) * HW_FLAGS_EUEN_SXE; - flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, ASXE) * HW_FLAGS_EUEN_ASXE; + flags = sys->CSR_CRMD & (R_CSR_CRMD_PLV_MASK | R_CSR_CRMD_PG_MASK); + flags |= FIELD_EX64(sys->CSR_EUEN, CSR_EUEN, FPE) * HW_FLAGS_EUEN_FPE; + flags |= FIELD_EX64(sys->CSR_EUEN, CSR_EUEN, SXE) * HW_FLAGS_EUEN_SXE; + flags |= FIELD_EX64(sys->CSR_EUEN, CSR_EUEN, ASXE) * HW_FLAGS_EUEN_ASXE; flags |= is_va32(env) * HW_FLAGS_VA32; return (TCGTBCPUState){ .pc = env->pc, .flags = flags }; @@ -XXX,XX +XXX,XX @@ static void loongarch_restore_state_to_opc(CPUState *cs, static int loongarch_cpu_mmu_index(CPUState *cs, bool ifetch) { CPULoongArchState *env = cpu_env(cs); + CPUSysState *sys = env_sys(env); - if (FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG)) { - return FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV); + if (FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, PG)) { + return FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, PLV); } return MMU_DA_IDX; } -- 2.54.0
From: Bibo Mao <maobibo@loongson.cn> When accessing CSR registers in file csr_helper.c, use sys_state rather than env. There is no function change. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Philippe Mathieu-Daudé <philmd@mailo.com> Tested-by: Song Gao <gaosong@loongson.cn> Message-ID: <20260605082552.175336-9-maobibo@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn> --- target/loongarch/tcg/csr_helper.c | 55 ++++++++++++++++++------------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/target/loongarch/tcg/csr_helper.c b/target/loongarch/tcg/csr_helper.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/tcg/csr_helper.c +++ b/target/loongarch/tcg/csr_helper.c @@ -XXX,XX +XXX,XX @@ target_ulong helper_csrwr_stlbps(CPULoongArchState *env, target_ulong val) { - int64_t old_v = env->CSR_STLBPS; + CPUSysState *sys = env_sys(env); + int64_t old_v = sys->CSR_STLBPS; /* * The real hardware only supports the min tlb_ps is 12 @@ -XXX,XX +XXX,XX @@ target_ulong helper_csrwr_stlbps(CPULoongArchState *env, target_ulong val) } else { /* Only update PS field, reserved bit keeps zero */ val = FIELD_DP64(val, CSR_STLBPS, RESERVE, 0); - env->CSR_STLBPS = val; + sys->CSR_STLBPS = val; } return old_v; @@ -XXX,XX +XXX,XX @@ target_ulong helper_csrwr_stlbps(CPULoongArchState *env, target_ulong val) target_ulong helper_csrrd_pgd(CPULoongArchState *env) { int64_t v; + CPUSysState *sys = env_sys(env); - if (env->CSR_TLBRERA & 0x1) { - v = env->CSR_TLBRBADV; + if (sys->CSR_TLBRERA & 0x1) { + v = sys->CSR_TLBRBADV; } else { - v = env->CSR_BADV; + v = sys->CSR_BADV; } if ((v >> 63) & 0x1) { - v = env->CSR_PGDH; + v = sys->CSR_PGDH; } else { - v = env->CSR_PGDL; + v = sys->CSR_PGDL; } return v; @@ -XXX,XX +XXX,XX @@ target_ulong helper_csrrd_pgd(CPULoongArchState *env) target_ulong helper_csrrd_cpuid(CPULoongArchState *env) { LoongArchCPU *lac = env_archcpu(env); + CPUSysState *sys = env_sys(env); - env->CSR_CPUID = CPU(lac)->cpu_index; + sys->CSR_CPUID = CPU(lac)->cpu_index; - return env->CSR_CPUID; + return sys->CSR_CPUID; } target_ulong helper_csrrd_tval(CPULoongArchState *env) @@ -XXX,XX +XXX,XX @@ target_ulong helper_csrrd_tval(CPULoongArchState *env) target_ulong helper_csrrd_msgir(CPULoongArchState *env) { int irq, new; + CPUSysState *sys = env_sys(env); - irq = find_first_bit((unsigned long *)env->CSR_MSGIS, 256); + irq = find_first_bit((unsigned long *)sys->CSR_MSGIS, 256); if (irq < 256) { - clear_bit(irq, (unsigned long *)env->CSR_MSGIS); - new = find_first_bit((unsigned long *)env->CSR_MSGIS, 256); + clear_bit(irq, (unsigned long *)sys->CSR_MSGIS); + new = find_first_bit((unsigned long *)sys->CSR_MSGIS, 256); if (new < 256) { return irq; } - env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, MSGINT, 0); + sys->CSR_ESTAT = FIELD_DP64(sys->CSR_ESTAT, CSR_ESTAT, MSGINT, 0); } else { /* bit 31 set 1 for no invalid irq */ irq = BIT(31); @@ -XXX,XX +XXX,XX @@ target_ulong helper_csrrd_msgir(CPULoongArchState *env) target_ulong helper_csrwr_estat(CPULoongArchState *env, target_ulong val) { - int64_t old_v = env->CSR_ESTAT; + CPUSysState *sys = env_sys(env); + int64_t old_v = sys->CSR_ESTAT; /* Only IS[1:0] can be written */ - env->CSR_ESTAT = deposit64(env->CSR_ESTAT, 0, 2, val); + sys->CSR_ESTAT = deposit64(sys->CSR_ESTAT, 0, 2, val); return old_v; } target_ulong helper_csrwr_asid(CPULoongArchState *env, target_ulong val) { - int64_t old_v = env->CSR_ASID; + CPUSysState *sys = env_sys(env); + int64_t old_v = sys->CSR_ASID; /* Only ASID filed of CSR_ASID can be written */ - env->CSR_ASID = deposit64(env->CSR_ASID, 0, 10, val); - if (old_v != env->CSR_ASID) { + sys->CSR_ASID = deposit64(sys->CSR_ASID, 0, 10, val); + if (old_v != sys->CSR_ASID) { tlb_flush(env_cpu(env)); } return old_v; @@ -XXX,XX +XXX,XX @@ target_ulong helper_csrwr_asid(CPULoongArchState *env, target_ulong val) target_ulong helper_csrwr_tcfg(CPULoongArchState *env, target_ulong val) { LoongArchCPU *cpu = env_archcpu(env); - int64_t old_v = env->CSR_TCFG; + CPUSysState *sys = env_sys(env); + int64_t old_v = sys->CSR_TCFG; cpu_loongarch_store_constant_timer_config(cpu, val); @@ -XXX,XX +XXX,XX @@ target_ulong helper_csrwr_ticlr(CPULoongArchState *env, target_ulong val) target_ulong helper_csrwr_pwcl(CPULoongArchState *env, target_ulong val) { uint8_t shift, ptbase; - int64_t old_v = env->CSR_PWCL; + CPUSysState *sys = env_sys(env); + int64_t old_v = sys->CSR_PWCL; /* * The real hardware only supports 64bit PTE width now, 128bit or others @@ -XXX,XX +XXX,XX @@ target_ulong helper_csrwr_pwcl(CPULoongArchState *env, target_ulong val) qemu_log_mask(LOG_GUEST_ERROR, "Attempted set ptbase 2^%d\n", ptbase); } - env->CSR_PWCL = val; + sys->CSR_PWCL = val; return old_v; } target_ulong helper_csrwr_pwch(CPULoongArchState *env, target_ulong val) { uint8_t has_ptw; - int64_t old_v = env->CSR_PWCH; + CPUSysState *sys = env_sys(env); + int64_t old_v = sys->CSR_PWCH; val = FIELD_DP64(val, CSR_PWCH, RESERVE, 0); has_ptw = FIELD_EX32(env->cpucfg[2], CPUCFG2, HPTW); @@ -XXX,XX +XXX,XX @@ target_ulong helper_csrwr_pwch(CPULoongArchState *env, target_ulong val) val = FIELD_DP64(val, CSR_PWCH, HPTW_EN, 0); } - env->CSR_PWCH = val; + sys->CSR_PWCH = val; return old_v; } -- 2.54.0
From: Bibo Mao <maobibo@loongson.cn> When accessing CSR registers in file op_helper.c, use sys_state rather than env. There is no function change. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Philippe Mathieu-Daudé <philmd@mailo.com> Tested-by: Song Gao <gaosong@loongson.cn> Message-ID: <20260605083756.175598-1-maobibo@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn> --- target/loongarch/tcg/op_helper.c | 45 ++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/target/loongarch/tcg/op_helper.c b/target/loongarch/tcg/op_helper.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/tcg/op_helper.c +++ b/target/loongarch/tcg/op_helper.c @@ -XXX,XX +XXX,XX @@ target_ulong helper_bitswap(target_ulong v) /* loongarch assert op */ void helper_asrtle_d(CPULoongArchState *env, target_ulong rj, target_ulong rk) { + CPUSysState *sys = env_sys(env); + if (rj > rk) { - env->CSR_BADV = rj; + sys->CSR_BADV = rj; do_raise_exception(env, EXCCODE_BCE, GETPC()); } } void helper_asrtgt_d(CPULoongArchState *env, target_ulong rj, target_ulong rk) { + CPUSysState *sys = env_sys(env); + if (rj <= rk) { - env->CSR_BADV = rj; + sys->CSR_BADV = rj; do_raise_exception(env, EXCCODE_BCE, GETPC()); } } @@ -XXX,XX +XXX,XX @@ uint64_t helper_rdtime_d(CPULoongArchState *env) #else uint64_t plv; LoongArchCPU *cpu = env_archcpu(env); + CPUSysState *sys = env_sys(env); - plv = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV); - if (extract64(env->CSR_MISC, R_CSR_MISC_DRDTL_SHIFT + plv, 1)) { + plv = FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, PLV); + if (extract64(sys->CSR_MISC, R_CSR_MISC_DRDTL_SHIFT + plv, 1)) { do_raise_exception(env, EXCCODE_IPE, GETPC()); } @@ -XXX,XX +XXX,XX @@ uint64_t helper_rdtime_d(CPULoongArchState *env) void helper_ertn(CPULoongArchState *env) { uint64_t csr_pplv, csr_pie; - if (FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) { - csr_pplv = FIELD_EX64(env->CSR_TLBRPRMD, CSR_TLBRPRMD, PPLV); - csr_pie = FIELD_EX64(env->CSR_TLBRPRMD, CSR_TLBRPRMD, PIE); - - env->CSR_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR, 0); - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DA, 0); - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, PG, 1); - set_pc(env, env->CSR_TLBRERA); + CPUSysState *sys = env_sys(env); + + if (FIELD_EX64(sys->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) { + csr_pplv = FIELD_EX64(sys->CSR_TLBRPRMD, CSR_TLBRPRMD, PPLV); + csr_pie = FIELD_EX64(sys->CSR_TLBRPRMD, CSR_TLBRPRMD, PIE); + + sys->CSR_TLBRERA = FIELD_DP64(sys->CSR_TLBRERA, CSR_TLBRERA, ISTLBR, 0); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, DA, 0); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, PG, 1); + set_pc(env, sys->CSR_TLBRERA); qemu_log_mask(CPU_LOG_INT, "%s: TLBRERA " TARGET_FMT_lx "\n", - __func__, env->CSR_TLBRERA); + __func__, sys->CSR_TLBRERA); } else { - csr_pplv = FIELD_EX64(env->CSR_PRMD, CSR_PRMD, PPLV); - csr_pie = FIELD_EX64(env->CSR_PRMD, CSR_PRMD, PIE); + csr_pplv = FIELD_EX64(sys->CSR_PRMD, CSR_PRMD, PPLV); + csr_pie = FIELD_EX64(sys->CSR_PRMD, CSR_PRMD, PIE); - set_pc(env, env->CSR_ERA); + set_pc(env, sys->CSR_ERA); qemu_log_mask(CPU_LOG_INT, "%s: ERA " TARGET_FMT_lx "\n", - __func__, env->CSR_ERA); + __func__, sys->CSR_ERA); } - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, PLV, csr_pplv); - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, IE, csr_pie); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, PLV, csr_pplv); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, IE, csr_pie); env->lladdr = 1; } -- 2.54.0
From: Bibo Mao <maobibo@loongson.cn> When accessing CSR registers in directory linux-user/loongarch64/, use sys_state rather than env. There is no function change. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Philippe Mathieu-Daudé <philmd@mailo.com> Tested-by: Song Gao <gaosong@loongson.cn> Message-ID: <20260605083844.175612-1-maobibo@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn> --- linux-user/loongarch64/cpu_loop.c | 5 +++-- linux-user/loongarch64/elfload.c | 4 +++- linux-user/loongarch64/signal.c | 16 ++++++++++------ 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/linux-user/loongarch64/cpu_loop.c b/linux-user/loongarch64/cpu_loop.c index XXXXXXX..XXXXXXX 100644 --- a/linux-user/loongarch64/cpu_loop.c +++ b/linux-user/loongarch64/cpu_loop.c @@ -XXX,XX +XXX,XX @@ enum { void cpu_loop(CPULoongArchState *env) { + CPUSysState *sys = env_sys(env); CPUState *cs = env_cpu(env); int trapnr, si_code; abi_long ret; @@ -XXX,XX +XXX,XX @@ void cpu_loop(CPULoongArchState *env) * choose the layout of any signal frame. */ case EXCCODE_SXD: - env->CSR_EUEN |= R_CSR_EUEN_SXE_MASK; + sys->CSR_EUEN |= R_CSR_EUEN_SXE_MASK; break; case EXCCODE_ASXD: - env->CSR_EUEN |= R_CSR_EUEN_ASXE_MASK; + sys->CSR_EUEN |= R_CSR_EUEN_ASXE_MASK; break; case EXCP_ATOMIC: diff --git a/linux-user/loongarch64/elfload.c b/linux-user/loongarch64/elfload.c index XXXXXXX..XXXXXXX 100644 --- a/linux-user/loongarch64/elfload.c +++ b/linux-user/loongarch64/elfload.c @@ -XXX,XX +XXX,XX @@ const char *get_elf_platform(CPUState *cs) void elf_core_copy_regs(target_elf_gregset_t *r, const CPULoongArchState *env) { + CPUSysState *sys = env_sys((CPULoongArchState *)env); + r->pt.regs[0] = 0; for (int i = 1; i < ARRAY_SIZE(env->gpr); i++) { @@ -XXX,XX +XXX,XX @@ void elf_core_copy_regs(target_elf_gregset_t *r, const CPULoongArchState *env) } r->pt.csr_era = tswapreg(env->pc); - r->pt.csr_badv = tswapreg(env->CSR_BADV); + r->pt.csr_badv = tswapreg(sys->CSR_BADV); } diff --git a/linux-user/loongarch64/signal.c b/linux-user/loongarch64/signal.c index XXXXXXX..XXXXXXX 100644 --- a/linux-user/loongarch64/signal.c +++ b/linux-user/loongarch64/signal.c @@ -XXX,XX +XXX,XX @@ static abi_ptr extframe_alloc(struct extctx_layout *extctx, static abi_ptr setup_extcontext(CPULoongArchState *env, struct extctx_layout *extctx, abi_ptr sp) { + CPUSysState *sys = env_sys(env); + memset(extctx, 0, sizeof(struct extctx_layout)); /* Grow down, alloc "end" context info first. */ @@ -XXX,XX +XXX,XX @@ static abi_ptr setup_extcontext(CPULoongArchState *env, /* For qemu, there is no lazy fp context switch, so fp always present. */ extctx->flags = SC_USED_FP; - if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, ASXE)) { + if (FIELD_EX64(sys->CSR_EUEN, CSR_EUEN, ASXE)) { sp = extframe_alloc(extctx, &extctx->lasx, sizeof(struct target_lasx_context), LASX_CTX_ALIGN, sp); - } else if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE)) { + } else if (FIELD_EX64(sys->CSR_EUEN, CSR_EUEN, SXE)) { sp = extframe_alloc(extctx, &extctx->lsx, sizeof(struct target_lsx_context), LSX_CTX_ALIGN, sp); } else { @@ -XXX,XX +XXX,XX @@ static void setup_sigframe(CPULoongArchState *env, struct target_sigcontext *sc, struct extctx_layout *extctx) { + CPUSysState *sys = env_sys(env); struct target_sctx_info *info; int i; @@ -XXX,XX +XXX,XX @@ static void setup_sigframe(CPULoongArchState *env, * Set extension context */ - if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, ASXE)) { + if (FIELD_EX64(sys->CSR_EUEN, CSR_EUEN, ASXE)) { struct target_lasx_context *lasx_ctx; info = extctx->lasx.haddr; @@ -XXX,XX +XXX,XX @@ static void setup_sigframe(CPULoongArchState *env, } __put_user(read_fcc(env), &lasx_ctx->fcc); __put_user(env->fcsr0, &lasx_ctx->fcsr); - } else if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE)) { + } else if (FIELD_EX64(sys->CSR_EUEN, CSR_EUEN, SXE)) { struct target_lsx_context *lsx_ctx; info = extctx->lsx.haddr; @@ -XXX,XX +XXX,XX @@ void setup_rt_frame(int sig, struct target_sigaction *ka, target_siginfo_t *info, target_sigset_t *set, CPULoongArchState *env) { + CPUSysState *sys = env_sys(env); struct target_rt_sigframe *frame; struct extctx_layout extctx; abi_ptr frame_addr; @@ -XXX,XX +XXX,XX @@ void setup_rt_frame(int sig, struct target_sigaction *ka, return; } - if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, ASXE)) { + if (FIELD_EX64(sys->CSR_EUEN, CSR_EUEN, ASXE)) { extctx.lasx.haddr = (void *)frame + (extctx.lasx.gaddr - frame_addr); extctx.end.haddr = (void *)frame + (extctx.end.gaddr - frame_addr); - } else if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE)) { + } else if (FIELD_EX64(sys->CSR_EUEN, CSR_EUEN, SXE)) { extctx.lsx.haddr = (void *)frame + (extctx.lsx.gaddr - frame_addr); extctx.end.haddr = (void *)frame + (extctx.end.gaddr - frame_addr); } else { -- 2.54.0
From: Bibo Mao <maobibo@loongson.cn> With CSR array structure, its validity is checked from offset field. Now default CSRFL_BASIC information is added with flags field and its validility can be checked with flags field. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Tested-by: Song Gao <gaosong@loongson.cn> Message-ID: <20260605083854.175625-1-maobibo@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn> --- target/loongarch/csr.c | 6 +++--- target/loongarch/csr.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/target/loongarch/csr.c b/target/loongarch/csr.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/csr.c +++ b/target/loongarch/csr.c @@ -XXX,XX +XXX,XX @@ [LOONGARCH_CSR_##NAME(N)] = { \ .name = (stringify(NAME##N)), \ .offset = offsetof(CPULoongArchState, CSR_##NAME[N]), \ - .flags = 0, .readfn = NULL, .writefn = NULL \ + .flags = CSRFL_BASIC, .readfn = NULL, .writefn = NULL \ } #define CSR_OFF_FLAGS(NAME, FL) CSR_OFF_FUNCS(NAME, FL, NULL, NULL) -#define CSR_OFF(NAME) CSR_OFF_FLAGS(NAME, 0) +#define CSR_OFF(NAME) CSR_OFF_FLAGS(NAME, CSRFL_BASIC) static CSRInfo csr_info[] = { CSR_OFF_FLAGS(CRMD, CSRFL_EXITTB), @@ -XXX,XX +XXX,XX @@ CSRInfo *get_csr(unsigned int csr_num) } csr = &csr_info[csr_num]; - if (csr->offset == 0) { + if (csr->flags == 0) { return NULL; } diff --git a/target/loongarch/csr.h b/target/loongarch/csr.h index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/csr.h +++ b/target/loongarch/csr.h @@ -XXX,XX +XXX,XX @@ enum { CSRFL_EXITTB = (1 << 1), CSRFL_IO = (1 << 2), CSRFL_UNUSED = (1 << 3), + CSRFL_BASIC = (1 << 4), }; typedef struct { -- 2.54.0
From: Bibo Mao <maobibo@loongson.cn> Add wrapper function get_csr_offset(), it is to get offset from structure CPULoongArchState. There is no function change, and it is used for future LVZ feature. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Philippe Mathieu-Daudé <philmd@mailo.com> Tested-by: Song Gao <gaosong@loongson.cn> Message-ID: <20260605083904.175636-1-maobibo@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn> --- target/loongarch/cpu.c | 4 ++-- target/loongarch/csr.h | 4 ++++ .../tcg/insn_trans/trans_privileged.c.inc | 16 +++++++++++----- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_dump_csr(CPUState *cs, FILE *f) { #ifndef CONFIG_USER_ONLY CPULoongArchState *env = cpu_env(cs); - CSRInfo *csr_info; + const CSRInfo *csr_info; int64_t *addr; int i, j, len, col = 0; @@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_dump_csr(CPUState *cs, FILE *f) qemu_fprintf(f, " CSR%03d:", col); } - addr = (void *)env + csr_info->offset; + addr = (void *)env + get_csr_offset(csr_info, 0); qemu_fprintf(f, " %s ", csr_info->name); len = strlen(csr_info->name); for (; len < 6; len++) { diff --git a/target/loongarch/csr.h b/target/loongarch/csr.h index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/csr.h +++ b/target/loongarch/csr.h @@ -XXX,XX +XXX,XX @@ typedef struct { CSRInfo *get_csr(unsigned int csr_num); bool set_csr_flag(unsigned int csr_num, int flag); +static inline unsigned int get_csr_offset(const CSRInfo *csr, int vm_level) +{ + return csr->offset; +} #endif /* TARGET_LOONGARCH_CSR_H */ diff --git a/target/loongarch/tcg/insn_trans/trans_privileged.c.inc b/target/loongarch/tcg/insn_trans/trans_privileged.c.inc index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/tcg/insn_trans/trans_privileged.c.inc +++ b/target/loongarch/tcg/insn_trans/trans_privileged.c.inc @@ -XXX,XX +XXX,XX @@ static bool trans_csrrd(DisasContext *ctx, arg_csrrd *a) TCGv dest; const CSRInfo *csr; GenCSRRead readfn; + tcg_target_long offset; if (check_plv(ctx)) { return false; @@ -XXX,XX +XXX,XX @@ static bool trans_csrrd(DisasContext *ctx, arg_csrrd *a) if (readfn) { readfn(dest, tcg_env); } else { - tcg_gen_ld_tl(dest, tcg_env, csr->offset); + offset = get_csr_offset(csr, 0); + tcg_gen_ld_tl(dest, tcg_env, offset); } } gen_set_gpr(a->rd, dest, EXT_NONE); @@ -XXX,XX +XXX,XX @@ static bool trans_csrwr(DisasContext *ctx, arg_csrwr *a) TCGv dest, src1; const CSRInfo *csr; GenCSRWrite writefn; + tcg_target_long offset; if (check_plv(ctx)) { return false; @@ -XXX,XX +XXX,XX @@ static bool trans_csrwr(DisasContext *ctx, arg_csrwr *a) writefn(dest, tcg_env, src1); } else { dest = tcg_temp_new(); - tcg_gen_ld_tl(dest, tcg_env, csr->offset); - tcg_gen_st_tl(src1, tcg_env, csr->offset); + offset = get_csr_offset(csr, 0); + tcg_gen_ld_tl(dest, tcg_env, offset); + tcg_gen_st_tl(src1, tcg_env, offset); } gen_set_gpr(a->rd, dest, EXT_NONE); return true; @@ -XXX,XX +XXX,XX @@ static bool trans_csrxchg(DisasContext *ctx, arg_csrxchg *a) TCGv src1, mask, oldv, newv, temp; const CSRInfo *csr; GenCSRWrite writefn; + tcg_target_long offset; if (check_plv(ctx)) { return false; @@ -XXX,XX +XXX,XX @@ static bool trans_csrxchg(DisasContext *ctx, arg_csrxchg *a) newv = tcg_temp_new(); temp = tcg_temp_new(); - tcg_gen_ld_tl(oldv, tcg_env, csr->offset); + offset = get_csr_offset(csr, 0); + tcg_gen_ld_tl(oldv, tcg_env, offset); tcg_gen_and_tl(newv, src1, mask); tcg_gen_andc_tl(temp, oldv, mask); tcg_gen_or_tl(newv, newv, temp); @@ -XXX,XX +XXX,XX @@ static bool trans_csrxchg(DisasContext *ctx, arg_csrxchg *a) if (writefn) { writefn(oldv, tcg_env, newv); } else { - tcg_gen_st_tl(newv, tcg_env, csr->offset); + tcg_gen_st_tl(newv, tcg_env, offset); } gen_set_gpr(a->rd, oldv, EXT_NONE); return true; -- 2.54.0
From: Bibo Mao <maobibo@loongson.cn> Instruction rdtime is to read TSC timestamp and logic vCPU id, it is also used by Linux user mode emulation. However function get_csr_offset() cannot be called in user mode emulation, here macro CSR_OFFSET and CPU_CSR_OFFSET are added. The added macro can be called in both user emulation and system emulation. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Philippe Mathieu-Daudé <philmd@mailo.com> Tested-by: Song Gao <gaosong@loongson.cn> Message-ID: <20260605083910.175647-1-maobibo@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn> --- target/loongarch/csr.c | 4 ++-- target/loongarch/csr.h | 3 +++ target/loongarch/tcg/insn_trans/trans_extra.c.inc | 6 +++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/target/loongarch/csr.c b/target/loongarch/csr.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/csr.c +++ b/target/loongarch/csr.c @@ -XXX,XX +XXX,XX @@ #define CSR_OFF_FUNCS(NAME, FL, RD, WR) \ [LOONGARCH_CSR_##NAME] = { \ .name = (stringify(NAME)), \ - .offset = offsetof(CPULoongArchState, CSR_##NAME), \ + .offset = CSR_OFFSET(CSR_##NAME), \ .flags = FL, .readfn = RD, .writefn = WR \ } #define CSR_OFF_ARRAY(NAME, N) \ [LOONGARCH_CSR_##NAME(N)] = { \ .name = (stringify(NAME##N)), \ - .offset = offsetof(CPULoongArchState, CSR_##NAME[N]), \ + .offset = CSR_OFFSET(CSR_##NAME[N]), \ .flags = CSRFL_BASIC, .readfn = NULL, .writefn = NULL \ } diff --git a/target/loongarch/csr.h b/target/loongarch/csr.h index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/csr.h +++ b/target/loongarch/csr.h @@ -XXX,XX +XXX,XX @@ #include "cpu-csr.h" +#define CSR_OFFSET(id) offsetof(CPULoongArchState, id) +#define CPU_CSR_OFFSET(id, vm_level) CSR_OFFSET(id) + typedef void (*GenCSRFunc)(void); enum { CSRFL_READONLY = (1 << 0), diff --git a/target/loongarch/tcg/insn_trans/trans_extra.c.inc b/target/loongarch/tcg/insn_trans/trans_extra.c.inc index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/tcg/insn_trans/trans_extra.c.inc +++ b/target/loongarch/tcg/insn_trans/trans_extra.c.inc @@ -XXX,XX +XXX,XX @@ * Copyright (c) 2021 Loongson Technology Corporation Limited */ +#include "csr.h" static bool trans_break(DisasContext *ctx, arg_break *a) { generate_exception(ctx, EXCCODE_BRK); @@ -XXX,XX +XXX,XX @@ static bool gen_rdtime(DisasContext *ctx, arg_rr *a, { TCGv dst1 = gpr_dst(ctx, a->rd, EXT_NONE); TCGv dst2 = gpr_dst(ctx, a->rj, EXT_NONE); + tcg_target_long offset; translator_io_start(&ctx->base); gen_helper_rdtime_d(dst1, tcg_env); if (word) { tcg_gen_sextract_tl(dst1, dst1, high ? 32 : 0, 32); } - tcg_gen_ld_i64(dst2, tcg_env, offsetof(CPULoongArchState, CSR_TID)); + + offset = CPU_CSR_OFFSET(CSR_TID, 0); + tcg_gen_ld_i64(dst2, tcg_env, offset); return true; } -- 2.54.0
From: Bibo Mao <maobibo@loongson.cn> New structure CPUSysState is added here, now it only contains CSR registers, in future TLB and timer can be moved to this structure also. It is only code movement, no function change. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Tested-by: Song Gao <gaosong@loongson.cn> Message-ID: <20260605083938.175658-1-maobibo@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn> --- target/loongarch/cpu.c | 4 +- target/loongarch/cpu.h | 35 +++++------ target/loongarch/csr.h | 8 ++- target/loongarch/machine.c | 118 +++++++++++++++++++------------------ 4 files changed, 85 insertions(+), 80 deletions(-) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -XXX,XX +XXX,XX @@ static void loongarch_la464_initfn(Object *obj) uint32_t data = 0, field; int i; - set_sys_state(env, env); + set_sys_state(env, &env->sys_states[0]); for (i = 0; i < 21; i++) { env->cpucfg[i] = 0x0; } @@ -XXX,XX +XXX,XX @@ static void loongarch_la132_initfn(Object *obj) uint32_t data = 0; int i; - set_sys_state(env, env); + set_sys_state(env, &env->sys_states[0]); for (i = 0; i < 21; i++) { env->cpucfg[i] = 0x0; } diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -XXX,XX +XXX,XX @@ typedef struct LoongArchBT { #define CPU_VENDOR_LOONGSON "Loongson" #define CPU_MODEL_3A5000 "3A5000" #define CPU_MODEL_1C101 "1C101" -struct CPUArchState; -typedef struct CPUArchState CPUSysState; - -typedef struct CPUArchState { - uint64_t gpr[32]; - uint64_t pc; - - fpr_t fpr[32]; - bool cf[8]; - uint32_t fcsr0; - lbt_t lbt; - - uint32_t cpucfg[21]; - uint32_t pv_features; - uint64_t vendor_id; - uint64_t cpu_id; - +typedef struct CPUSysState { /* LoongArch CSRs */ uint64_t CSR_CRMD; uint64_t CSR_PRMD; @@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState { uint64_t CSR_MSGIS[N_MSGIS]; uint64_t CSR_MSGIR; uint64_t CSR_MSGIE; +} CPUSysState; + +typedef struct CPUArchState { + uint64_t gpr[32]; + uint64_t pc; + + fpr_t fpr[32]; + bool cf[8]; + uint32_t fcsr0; + lbt_t lbt; + + uint32_t cpucfg[21]; + uint32_t pv_features; + uint64_t vendor_id; + uint64_t cpu_id; + CPUSysState sys_states[1]; + struct { uint64_t guest_addr; } stealtime; diff --git a/target/loongarch/csr.h b/target/loongarch/csr.h index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/csr.h +++ b/target/loongarch/csr.h @@ -XXX,XX +XXX,XX @@ #include "cpu-csr.h" -#define CSR_OFFSET(id) offsetof(CPULoongArchState, id) -#define CPU_CSR_OFFSET(id, vm_level) CSR_OFFSET(id) +#define CSR_OFFSET(id) offsetof(CPUSysState, id) +#define CPU_CSR_OFFSET(id, vm_level) \ + (offsetof(CPULoongArchState, sys_states[vm_level]) \ + + CSR_OFFSET(id)) typedef void (*GenCSRFunc)(void); enum { @@ -XXX,XX +XXX,XX @@ CSRInfo *get_csr(unsigned int csr_num); bool set_csr_flag(unsigned int csr_num, int flag); static inline unsigned int get_csr_offset(const CSRInfo *csr, int vm_level) { - return csr->offset; + return csr->offset + offsetof(CPULoongArchState, sys_states[vm_level]); } #endif /* TARGET_LOONGARCH_CSR_H */ diff --git a/target/loongarch/machine.c b/target/loongarch/machine.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/machine.c +++ b/target/loongarch/machine.c @@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_msgint = { .minimum_version_id = 1, .needed = msgint_needed, .fields = (const VMStateField[]) { - VMSTATE_UINT64_ARRAY(env.CSR_MSGIS, LoongArchCPU, N_MSGIS), - VMSTATE_UINT64(env.CSR_MSGIR, LoongArchCPU), - VMSTATE_UINT64(env.CSR_MSGIE, LoongArchCPU), + VMSTATE_UINT64_ARRAY(env.sys_states[0].CSR_MSGIS, LoongArchCPU, N_MSGIS), + VMSTATE_UINT64(env.sys_states[0].CSR_MSGIR, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_MSGIE, LoongArchCPU), VMSTATE_END_OF_LIST() }, }; @@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pmu = { .needed = pmu_needed, .fields = (const VMStateField[]) { VMSTATE_UINT32(env.perf_event_num, LoongArchCPU), - VMSTATE_UINT64_ARRAY(env.CSR_PERFCTRL, LoongArchCPU, MAX_PERF_EVENTS), - VMSTATE_UINT64_ARRAY(env.CSR_PERFCNTR, LoongArchCPU, MAX_PERF_EVENTS), + VMSTATE_UINT64_ARRAY(env.sys_states[0].CSR_PERFCTRL, LoongArchCPU,\ + MAX_PERF_EVENTS), + VMSTATE_UINT64_ARRAY(env.sys_states[0].CSR_PERFCNTR, LoongArchCPU, \ + MAX_PERF_EVENTS), VMSTATE_END_OF_LIST() }, }; @@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_loongarch_cpu = { VMSTATE_UINT64(env.pc, LoongArchCPU), /* Remaining CSRs */ - VMSTATE_UINT64(env.CSR_CRMD, LoongArchCPU), - VMSTATE_UINT64(env.CSR_PRMD, LoongArchCPU), - VMSTATE_UINT64(env.CSR_EUEN, LoongArchCPU), - VMSTATE_UINT64(env.CSR_MISC, LoongArchCPU), - VMSTATE_UINT64(env.CSR_ECFG, LoongArchCPU), - VMSTATE_UINT64(env.CSR_ESTAT, LoongArchCPU), - VMSTATE_UINT64(env.CSR_ERA, LoongArchCPU), - VMSTATE_UINT64(env.CSR_BADV, LoongArchCPU), - VMSTATE_UINT64(env.CSR_BADI, LoongArchCPU), - VMSTATE_UINT64(env.CSR_EENTRY, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBIDX, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBEHI, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBELO0, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBELO1, LoongArchCPU), - VMSTATE_UINT64(env.CSR_ASID, LoongArchCPU), - VMSTATE_UINT64(env.CSR_PGDL, LoongArchCPU), - VMSTATE_UINT64(env.CSR_PGDH, LoongArchCPU), - VMSTATE_UINT64(env.CSR_PGD, LoongArchCPU), - VMSTATE_UINT64(env.CSR_PWCL, LoongArchCPU), - VMSTATE_UINT64(env.CSR_PWCH, LoongArchCPU), - VMSTATE_UINT64(env.CSR_STLBPS, LoongArchCPU), - VMSTATE_UINT64(env.CSR_RVACFG, LoongArchCPU), - VMSTATE_UINT64(env.CSR_PRCFG1, LoongArchCPU), - VMSTATE_UINT64(env.CSR_PRCFG2, LoongArchCPU), - VMSTATE_UINT64(env.CSR_PRCFG3, LoongArchCPU), - VMSTATE_UINT64_ARRAY(env.CSR_SAVE, LoongArchCPU, 16), - VMSTATE_UINT64(env.CSR_TID, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TCFG, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TVAL, LoongArchCPU), - VMSTATE_UINT64(env.CSR_CNTC, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TICLR, LoongArchCPU), - VMSTATE_UINT64(env.CSR_LLBCTL, LoongArchCPU), - VMSTATE_UINT64(env.CSR_IMPCTL1, LoongArchCPU), - VMSTATE_UINT64(env.CSR_IMPCTL2, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBRENTRY, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBRBADV, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBRERA, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBRSAVE, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBRELO0, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBRELO1, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBREHI, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBRPRMD, LoongArchCPU), - VMSTATE_UINT64(env.CSR_MERRCTL, LoongArchCPU), - VMSTATE_UINT64(env.CSR_MERRINFO1, LoongArchCPU), - VMSTATE_UINT64(env.CSR_MERRINFO2, LoongArchCPU), - VMSTATE_UINT64(env.CSR_MERRENTRY, LoongArchCPU), - VMSTATE_UINT64(env.CSR_MERRERA, LoongArchCPU), - VMSTATE_UINT64(env.CSR_MERRSAVE, LoongArchCPU), - VMSTATE_UINT64(env.CSR_CTAG, LoongArchCPU), - VMSTATE_UINT64_ARRAY(env.CSR_DMW, LoongArchCPU, 4), + VMSTATE_UINT64(env.sys_states[0].CSR_CRMD, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_PRMD, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_EUEN, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_MISC, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_ECFG, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_ESTAT, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_ERA, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_BADV, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_BADI, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_EENTRY, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBIDX, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBEHI, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBELO0, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBELO1, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_ASID, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_PGDL, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_PGDH, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_PGD, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_PWCL, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_PWCH, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_STLBPS, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_RVACFG, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_PRCFG1, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_PRCFG2, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_PRCFG3, LoongArchCPU), + VMSTATE_UINT64_ARRAY(env.sys_states[0].CSR_SAVE, LoongArchCPU, 16), + VMSTATE_UINT64(env.sys_states[0].CSR_TID, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TCFG, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TVAL, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_CNTC, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TICLR, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_LLBCTL, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_IMPCTL1, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_IMPCTL2, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBRENTRY, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBRBADV, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBRERA, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBRSAVE, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBRELO0, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBRELO1, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBREHI, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBRPRMD, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_MERRCTL, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_MERRINFO1, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_MERRINFO2, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_MERRENTRY, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_MERRERA, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_MERRSAVE, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_CTAG, LoongArchCPU), + VMSTATE_UINT64_ARRAY(env.sys_states[0].CSR_DMW, LoongArchCPU, 4), /* Debug CSRs */ - VMSTATE_UINT64(env.CSR_DBG, LoongArchCPU), - VMSTATE_UINT64(env.CSR_DERA, LoongArchCPU), - VMSTATE_UINT64(env.CSR_DSAVE, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_DBG, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_DERA, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_DSAVE, LoongArchCPU), VMSTATE_UINT64(kvm_state_counter, LoongArchCPU), /* PV steal time */ -- 2.54.0