[PULL v2 6/8] linux-headers: Update to Linux v6.12-rc5
From: Bibo Mao update linux-headers to v6.12-rc5. Pass to compile on aarch64, arm, loongarch64, x86_64, i386, riscv64,riscv32 softmmu and linux-user. Signed-off-by: Bibo Mao Acked-by: Song Gao Message-Id: <20241028023809.1554405-4-maob...@loongson.cn> Signed-off-by: Song Gao --- include/standard-headers/drm/drm_fourcc.h | 43 +++ include/standard-headers/linux/const.h| 17 + include/standard-headers/linux/ethtool.h | 226 include/standard-headers/linux/fuse.h | 22 +- .../linux/input-event-codes.h | 2 + include/standard-headers/linux/pci_regs.h | 41 ++- .../standard-headers/linux/virtio_balloon.h | 16 +- include/standard-headers/linux/virtio_gpu.h | 1 + linux-headers/asm-arm64/mman.h| 9 + linux-headers/asm-arm64/unistd.h | 25 +- linux-headers/asm-arm64/unistd_64.h | 324 + linux-headers/asm-generic/unistd.h| 6 +- linux-headers/asm-loongarch/kvm.h | 24 ++ linux-headers/asm-loongarch/kvm_para.h| 21 ++ linux-headers/asm-loongarch/unistd.h | 4 +- linux-headers/asm-loongarch/unistd_64.h | 320 + linux-headers/asm-riscv/kvm.h | 7 + linux-headers/asm-riscv/unistd.h | 41 +-- linux-headers/asm-riscv/unistd_32.h | 315 + linux-headers/asm-riscv/unistd_64.h | 325 ++ linux-headers/asm-x86/kvm.h | 2 + linux-headers/asm-x86/unistd_64.h | 1 + linux-headers/asm-x86/unistd_x32.h| 1 + linux-headers/linux/bits.h| 3 + linux-headers/linux/const.h | 17 + linux-headers/linux/iommufd.h | 143 +++- linux-headers/linux/kvm.h | 23 +- linux-headers/linux/mman.h| 1 + linux-headers/linux/psp-sev.h | 28 ++ 29 files changed, 1915 insertions(+), 93 deletions(-) create mode 100644 linux-headers/asm-arm64/unistd_64.h create mode 100644 linux-headers/asm-loongarch/kvm_para.h create mode 100644 linux-headers/asm-loongarch/unistd_64.h create mode 100644 linux-headers/asm-riscv/unistd_32.h create mode 100644 linux-headers/asm-riscv/unistd_64.h diff --git a/include/standard-headers/drm/drm_fourcc.h b/include/standard-headers/drm/drm_fourcc.h index b72917073d..d4a2231306 100644 --- a/include/standard-headers/drm/drm_fourcc.h +++ b/include/standard-headers/drm/drm_fourcc.h @@ -701,6 +701,31 @@ extern "C" { */ #define I915_FORMAT_MOD_4_TILED_MTL_RC_CCS_CC fourcc_mod_code(INTEL, 15) +/* + * Intel Color Control Surfaces (CCS) for graphics ver. 20 unified compression + * on integrated graphics + * + * The main surface is Tile 4 and at plane index 0. For semi-planar formats + * like NV12, the Y and UV planes are Tile 4 and are located at plane indices + * 0 and 1, respectively. The CCS for all planes are stored outside of the + * GEM object in a reserved memory area dedicated for the storage of the + * CCS data for all compressible GEM objects. + */ +#define I915_FORMAT_MOD_4_TILED_LNL_CCS fourcc_mod_code(INTEL, 16) + +/* + * Intel Color Control Surfaces (CCS) for graphics ver. 20 unified compression + * on discrete graphics + * + * The main surface is Tile 4 and at plane index 0. For semi-planar formats + * like NV12, the Y and UV planes are Tile 4 and are located at plane indices + * 0 and 1, respectively. The CCS for all planes are stored outside of the + * GEM object in a reserved memory area dedicated for the storage of the + * CCS data for all compressible GEM objects. The GEM object must be stored in + * contiguous memory with a size aligned to 64KB + */ +#define I915_FORMAT_MOD_4_TILED_BMG_CCS fourcc_mod_code(INTEL, 17) + /* * Tiled, NV12MT, grouped in 64 (pixels) x 32 (lines) -sized macroblocks * @@ -1475,6 +1500,7 @@ drm_fourcc_canonicalize_nvidia_format_mod(uint64_t modifier) #define AMD_FMT_MOD_TILE_VER_GFX10 2 #define AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS 3 #define AMD_FMT_MOD_TILE_VER_GFX11 4 +#define AMD_FMT_MOD_TILE_VER_GFX12 5 /* * 64K_S is the same for GFX9/GFX10/GFX10_RBPLUS and hence has GFX9 as canonical @@ -1485,6 +1511,8 @@ drm_fourcc_canonicalize_nvidia_format_mod(uint64_t modifier) /* * 64K_D for non-32 bpp is the same for GFX9/GFX10/GFX10_RBPLUS and hence has * GFX9 as canonical version. + * + * 64K_D_2D on GFX12 is identical to 64K_D on GFX11. */ #define AMD_FMT_MOD_TILE_GFX9_64K_D 10 #define AMD_FMT_MOD_TILE_GFX9_64K_S_X 25 @@ -1492,6 +1520,21 @@ drm_fourcc_canonicalize_nvidia_format_mod(uint64_t modifier) #define AMD_FMT_MOD_TILE_GFX9_64K_R_X 27 #define AMD_FMT_MOD_TILE_GFX11_256K_R_X 31 +/* Gfx12 swizzle modes: + *0 - LINEAR + *1 - 256B_2D - 2D block dimensions + *2 - 4KB_2D + *3 - 64KB_2D + *4 - 256KB_2D + *5 - 4KB_3D - 3D block dimensions + *6 - 64KB_3D + *
[PULL v2 5/8] linux-headers: loongarch: Add kvm_para.h
From: Bibo Mao KVM LBT supports on LoongArch depends on the linux-header file kvm_para.h, add header file kvm_para.h here. Signed-off-by: Bibo Mao Acked-by: Song Gao Message-Id: <20241028023809.1554405-3-maob...@loongson.cn> Signed-off-by: Song Gao --- scripts/update-linux-headers.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh index 203f48d089..99a8d9fa4c 100755 --- a/scripts/update-linux-headers.sh +++ b/scripts/update-linux-headers.sh @@ -190,6 +190,7 @@ EOF cp "$hdrdir/include/asm/unistd_64.h" "$output/linux-headers/asm-riscv/" fi if [ $arch = loongarch ]; then +cp "$hdrdir/include/asm/kvm_para.h" "$output/linux-headers/asm-loongarch/" cp "$hdrdir/include/asm/unistd_64.h" "$output/linux-headers/asm-loongarch/" fi done -- 2.34.1
[PULL v2 8/8] target/loongarch: Add steal time support on migration
From: Bibo Mao With pv steal time supported, VM machine needs get physical address of each vcpu and notify new host during migration. Here two functions kvm_get_stealtime/kvm_set_stealtime, and guest steal time physical address is only updated on KVM_PUT_FULL_STATE stage. Signed-off-by: Bibo Mao Reviewed-by: Song Gao Message-Id: <20240930064040.753929-1-maob...@loongson.cn> Signed-off-by: Song Gao --- target/loongarch/cpu.h | 3 ++ target/loongarch/kvm/kvm.c | 65 ++ target/loongarch/machine.c | 6 ++-- 3 files changed, 72 insertions(+), 2 deletions(-) diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index 95be58dd66..86c86c6c95 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -364,6 +364,9 @@ typedef struct CPUArchState { uint64_t CSR_DBG; uint64_t CSR_DERA; uint64_t CSR_DSAVE; +struct { +uint64_t guest_addr; +} stealtime; #ifdef CONFIG_TCG float_status fp_status; diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c index 8bda8ae540..ff81806ca3 100644 --- a/target/loongarch/kvm/kvm.c +++ b/target/loongarch/kvm/kvm.c @@ -34,6 +34,55 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = { KVM_CAP_LAST_INFO }; +static int kvm_get_stealtime(CPUState *cs) +{ +CPULoongArchState *env = cpu_env(cs); +int err; +struct kvm_device_attr attr = { +.group = KVM_LOONGARCH_VCPU_PVTIME_CTRL, +.attr = KVM_LOONGARCH_VCPU_PVTIME_GPA, +.addr = (uint64_t)&env->stealtime.guest_addr, +}; + +err = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, attr); +if (err) { +return 0; +} + +err = kvm_vcpu_ioctl(cs, KVM_GET_DEVICE_ATTR, attr); +if (err) { +error_report("PVTIME: KVM_GET_DEVICE_ATTR: %s", strerror(errno)); +return err; +} + +return 0; +} + +static int kvm_set_stealtime(CPUState *cs) +{ +CPULoongArchState *env = cpu_env(cs); +int err; +struct kvm_device_attr attr = { +.group = KVM_LOONGARCH_VCPU_PVTIME_CTRL, +.attr = KVM_LOONGARCH_VCPU_PVTIME_GPA, +.addr = (uint64_t)&env->stealtime.guest_addr, +}; + +err = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, attr); +if (err) { +return 0; +} + +err = kvm_vcpu_ioctl(cs, KVM_SET_DEVICE_ATTR, attr); +if (err) { +error_report("PVTIME: KVM_SET_DEVICE_ATTR %s with gpa "TARGET_FMT_lx, + strerror(errno), env->stealtime.guest_addr); +return err; +} + +return 0; +} + static int kvm_loongarch_get_regs_core(CPUState *cs) { int ret = 0; @@ -670,6 +719,11 @@ int kvm_arch_get_registers(CPUState *cs, Error **errp) return ret; } +ret = kvm_get_stealtime(cs); +if (ret) { +return ret; +} + ret = kvm_loongarch_get_mpstate(cs); return ret; } @@ -703,6 +757,17 @@ int kvm_arch_put_registers(CPUState *cs, int level, Error **errp) return ret; } +if (level >= KVM_PUT_FULL_STATE) { +/* + * only KVM_PUT_FULL_STATE is required, kvm kernel will clear + * guest_addr for KVM_PUT_RESET_STATE + */ +ret = kvm_set_stealtime(cs); +if (ret) { +return ret; +} +} + ret = kvm_loongarch_put_mpstate(cs); return ret; } diff --git a/target/loongarch/machine.c b/target/loongarch/machine.c index 3d5c84ae9c..efb20e2fbe 100644 --- a/target/loongarch/machine.c +++ b/target/loongarch/machine.c @@ -168,8 +168,8 @@ static const VMStateDescription vmstate_tlb = { /* LoongArch CPU state */ const VMStateDescription vmstate_loongarch_cpu = { .name = "cpu", -.version_id = 2, -.minimum_version_id = 2, +.version_id = 3, +.minimum_version_id = 3, .fields = (const VMStateField[]) { VMSTATE_UINTTL_ARRAY(env.gpr, LoongArchCPU, 32), VMSTATE_UINTTL(env.pc, LoongArchCPU), @@ -232,6 +232,8 @@ const VMStateDescription vmstate_loongarch_cpu = { VMSTATE_UINT64(env.CSR_DSAVE, LoongArchCPU), VMSTATE_UINT64(kvm_state_counter, LoongArchCPU), +/* PV steal time */ +VMSTATE_UINT64(env.stealtime.guest_addr, LoongArchCPU), VMSTATE_END_OF_LIST() }, -- 2.34.1
[PULL v2 3/8] target/loongarch/kvm: Implement LoongArch PMU extension
From: Bibo Mao Implement PMU extension for LoongArch kvm mode. Use OnOffAuto type variable pmu to check the PMU feature. If the PMU Feature is not supported with KVM host, it reports error if there is pmu=on command line. If there is no any command line about pmu parameter, it checks whether KVM host supports the PMU Feature and set the corresponding value in cpucfg. This patch is based on lbt patch located at https://lore.kernel.org/qemu-devel/20240904061859.86615-1-maob...@loongson.cn Co-developed-by: Song Gao Signed-off-by: Bibo Mao Reviewed-by: Song Gao Message-Id: <20240918082315.2345034-1-maob...@loongson.cn> Signed-off-by: Song Gao --- target/loongarch/cpu.c| 19 + target/loongarch/cpu.h| 2 ++ target/loongarch/kvm/kvm.c| 41 +++ target/loongarch/loongarch-qmp-cmds.c | 2 +- 4 files changed, 63 insertions(+), 1 deletion(-) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 29577e6b71..57cc4f314b 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -676,6 +676,18 @@ static void loongarch_set_lbt(Object *obj, bool value, Error **errp) cpu->lbt = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF; } +static bool loongarch_get_pmu(Object *obj, Error **errp) +{ +return LOONGARCH_CPU(obj)->pmu != ON_OFF_AUTO_OFF; +} + +static void loongarch_set_pmu(Object *obj, bool value, Error **errp) +{ +LoongArchCPU *cpu = LOONGARCH_CPU(obj); + +cpu->pmu = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF; +} + void loongarch_cpu_post_init(Object *obj) { LoongArchCPU *cpu = LOONGARCH_CPU(obj); @@ -691,6 +703,13 @@ void loongarch_cpu_post_init(Object *obj) loongarch_set_lbt); object_property_set_description(obj, "lbt", "Set off to disable Binary Tranlation."); + +cpu->pmu = ON_OFF_AUTO_AUTO; +object_property_add_bool(obj, "pmu", loongarch_get_pmu, + loongarch_set_pmu); +object_property_set_description(obj, "pmu", + "Set off to performance monitor unit."); + } else { cpu->lbt = ON_OFF_AUTO_OFF; } diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index 136866b7b8..95be58dd66 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -284,6 +284,7 @@ typedef struct LoongArchTLB LoongArchTLB; enum loongarch_features { LOONGARCH_FEATURE_LBT, /* loongson binary translation extension */ +LOONGARCH_FEATURE_PMU, }; typedef struct LoongArchBT { @@ -399,6 +400,7 @@ struct ArchCPU { QEMUTimer timer; uint32_t phy_id; OnOffAuto lbt; +OnOffAuto pmu; /* 'compatible' string for this CPU for Linux device trees */ const char *dtb_compatible; diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c index 40115aff56..8bda8ae540 100644 --- a/target/loongarch/kvm/kvm.c +++ b/target/loongarch/kvm/kvm.c @@ -750,9 +750,18 @@ static bool kvm_feature_supported(CPUState *cs, enum loongarch_features feature) attr.attr = KVM_LOONGARCH_VM_FEAT_MIPSBT; ret |= kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr); return (ret == 0); + +case LOONGARCH_FEATURE_PMU: +attr.group = KVM_LOONGARCH_VM_FEAT_CTRL; +attr.attr = KVM_LOONGARCH_VM_FEAT_PMU; +ret = kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr); +return (ret == 0); + default: return false; } + +return false; } static int kvm_cpu_check_lbt(CPUState *cs, Error **errp) @@ -776,6 +785,32 @@ static int kvm_cpu_check_lbt(CPUState *cs, Error **errp) return 0; } +static int kvm_cpu_check_pmu(CPUState *cs, Error **errp) +{ +LoongArchCPU *cpu = LOONGARCH_CPU(cs); +CPULoongArchState *env = cpu_env(cs); +bool kvm_supported; + +kvm_supported = kvm_feature_supported(cs, LOONGARCH_FEATURE_PMU); +if (cpu->pmu == ON_OFF_AUTO_ON) { +if (!kvm_supported) { +error_setg(errp, "'pmu' feature not supported by KVM on the host"); +return -ENOTSUP; +} +} else if (cpu->pmu != ON_OFF_AUTO_AUTO) { +/* disable pmu if ON_OFF_AUTO_OFF is set */ +kvm_supported = false; +} + +if (kvm_supported) { +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, PMBITS, 63); +env->cpucfg[6] = FIELD_DP32(env->cpucfg[6], CPUCFG6, UPM, 1); +} +return 0; +} + int kvm_arch_init_vcpu(CPUState *cs) { uint64_t val; @@ -793,6 +828,12 @@ int kvm_arch_init_vcpu(CPUState *cs) if (ret < 0) { error_report_err(local_err); } + +ret = kvm_cpu_che
[PULL v2 1/8] target/loongarch: Add loongson binary translation feature
From: Bibo Mao Loongson Binary Translation (LBT) is used to accelerate binary translation, which contains 4 scratch registers (scr0 to scr3), x86/ARM eflags (eflags) and x87 fpu stack pointer (ftop). Now LBT feature is added in kvm mode, not supported in TCG mode since it is not emulated. Feature variable lbt is added with OnOffAuto type, If lbt feature is not supported with KVM host, it reports error if there is lbt=on command line. If there is no any command line about lbt parameter, it checks whether KVM host supports lbt feature and set the corresponding value in cpucfg. Signed-off-by: Bibo Mao Reviewed-by: Song Gao Message-Id: <20240929070405.235200-2-maob...@loongson.cn> Signed-off-by: Song Gao --- target/loongarch/cpu.c| 24 +++ target/loongarch/cpu.h| 6 +++ target/loongarch/kvm/kvm.c| 57 ++- target/loongarch/loongarch-qmp-cmds.c | 2 +- 4 files changed, 87 insertions(+), 2 deletions(-) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 7212fb5f8f..29577e6b71 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -664,12 +664,36 @@ static void loongarch_set_lasx(Object *obj, bool value, Error **errp) } } +static bool loongarch_get_lbt(Object *obj, Error **errp) +{ +return LOONGARCH_CPU(obj)->lbt != ON_OFF_AUTO_OFF; +} + +static void loongarch_set_lbt(Object *obj, bool value, Error **errp) +{ +LoongArchCPU *cpu = LOONGARCH_CPU(obj); + +cpu->lbt = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF; +} + void loongarch_cpu_post_init(Object *obj) { +LoongArchCPU *cpu = LOONGARCH_CPU(obj); + object_property_add_bool(obj, "lsx", loongarch_get_lsx, loongarch_set_lsx); object_property_add_bool(obj, "lasx", loongarch_get_lasx, loongarch_set_lasx); +/* lbt is enabled only in kvm mode, not supported in tcg mode */ +if (kvm_enabled()) { +cpu->lbt = ON_OFF_AUTO_AUTO; +object_property_add_bool(obj, "lbt", loongarch_get_lbt, + loongarch_set_lbt); +object_property_set_description(obj, "lbt", + "Set off to disable Binary Tranlation."); +} else { +cpu->lbt = ON_OFF_AUTO_OFF; +} } static void loongarch_cpu_init(Object *obj) diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index 6c41fafb70..2b3f2758f6 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -153,6 +153,7 @@ FIELD(CPUCFG2, LLFTP_VER, 15, 3) FIELD(CPUCFG2, LBT_X86, 18, 1) FIELD(CPUCFG2, LBT_ARM, 19, 1) FIELD(CPUCFG2, LBT_MIPS, 20, 1) +FIELD(CPUCFG2, LBT_ALL, 18, 3) FIELD(CPUCFG2, LSPW, 21, 1) FIELD(CPUCFG2, LAM, 22, 1) @@ -281,6 +282,10 @@ struct LoongArchTLB { typedef struct LoongArchTLB LoongArchTLB; #endif +enum loongarch_features { +LOONGARCH_FEATURE_LBT, /* loongson binary translation extension */ +}; + typedef struct CPUArchState { uint64_t gpr[32]; uint64_t pc; @@ -381,6 +386,7 @@ struct ArchCPU { CPULoongArchState env; QEMUTimer timer; uint32_t phy_id; +OnOffAuto lbt; /* 'compatible' string for this CPU for Linux device trees */ const char *dtb_compatible; diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c index 30ec16025d..079f8ca5d7 100644 --- a/target/loongarch/kvm/kvm.c +++ b/target/loongarch/kvm/kvm.c @@ -9,6 +9,7 @@ #include #include +#include "qapi/error.h" #include "qemu/timer.h" #include "qemu/error-report.h" #include "qemu/main-loop.h" @@ -666,17 +667,71 @@ static void kvm_loongarch_vm_stage_change(void *opaque, bool running, } } +static bool kvm_feature_supported(CPUState *cs, enum loongarch_features feature) +{ +int ret; +struct kvm_device_attr attr; + +switch (feature) { +case LOONGARCH_FEATURE_LBT: +/* + * Return all if all the LBT features are supported such as: + * KVM_LOONGARCH_VM_FEAT_X86BT + * KVM_LOONGARCH_VM_FEAT_ARMBT + * KVM_LOONGARCH_VM_FEAT_MIPSBT + */ +attr.group = KVM_LOONGARCH_VM_FEAT_CTRL; +attr.attr = KVM_LOONGARCH_VM_FEAT_X86BT; +ret = kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr); +attr.attr = KVM_LOONGARCH_VM_FEAT_ARMBT; +ret |= kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr); +attr.attr = KVM_LOONGARCH_VM_FEAT_MIPSBT; +ret |= kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr); +return (ret == 0); +default: +return false; +} +} + +static int kvm_cpu_check_lbt(CPUState *cs, Error **errp) +{ +CPULoongArchState *env = cpu_env(cs); +LoongArchCPU *cpu = LOONGARCH_CPU(cs); +bool kvm_supported; + +kvm_supported = kvm_feature_supported(cs, LOONGARCH_FEATURE_LBT); +if (cpu-&g
[PULL v2 2/8] target/loongarch: Implement lbt registers save/restore function
From: Bibo Mao Six registers scr0 - scr3, eflags and ftop are added in percpu vmstate. And two functions kvm_loongarch_get_lbt/kvm_loongarch_put_lbt are added to save/restore lbt registers. Signed-off-by: Bibo Mao Reviewed-by: Song Gao Message-Id: <20240929070405.235200-3-maob...@loongson.cn> Signed-off-by: Song Gao --- target/loongarch/cpu.h | 12 target/loongarch/kvm/kvm.c | 62 ++ target/loongarch/machine.c | 24 +++ 3 files changed, 98 insertions(+) diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index 2b3f2758f6..136866b7b8 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -286,6 +286,17 @@ enum loongarch_features { LOONGARCH_FEATURE_LBT, /* loongson binary translation extension */ }; +typedef struct LoongArchBT { +/* scratch registers */ +uint64_t scr0; +uint64_t scr1; +uint64_t scr2; +uint64_t scr3; +/* loongarch eflags */ +uint32_t eflags; +uint32_t ftop; +} lbt_t; + typedef struct CPUArchState { uint64_t gpr[32]; uint64_t pc; @@ -293,6 +304,7 @@ typedef struct CPUArchState { fpr_t fpr[32]; bool cf[8]; uint32_t fcsr0; +lbt_t lbt; uint32_t cpucfg[21]; diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c index 079f8ca5d7..40115aff56 100644 --- a/target/loongarch/kvm/kvm.c +++ b/target/loongarch/kvm/kvm.c @@ -477,6 +477,58 @@ static int kvm_loongarch_put_regs_fp(CPUState *cs) return ret; } +static int kvm_loongarch_put_lbt(CPUState *cs) +{ +CPULoongArchState *env = cpu_env(cs); +uint64_t val; +int ret; + +/* check whether vm support LBT firstly */ +if (FIELD_EX32(env->cpucfg[2], CPUCFG2, LBT_ALL) != 7) { +return 0; +} + +/* set six LBT registers including scr0-scr3, eflags, ftop */ +ret = kvm_set_one_reg(cs, KVM_REG_LOONGARCH_LBT_SCR0, &env->lbt.scr0); +ret |= kvm_set_one_reg(cs, KVM_REG_LOONGARCH_LBT_SCR1, &env->lbt.scr1); +ret |= kvm_set_one_reg(cs, KVM_REG_LOONGARCH_LBT_SCR2, &env->lbt.scr2); +ret |= kvm_set_one_reg(cs, KVM_REG_LOONGARCH_LBT_SCR3, &env->lbt.scr3); +/* + * Be cautious, KVM_REG_LOONGARCH_LBT_FTOP is defined as 64-bit however + * lbt.ftop is 32-bit; the same with KVM_REG_LOONGARCH_LBT_EFLAGS register + */ +val = env->lbt.eflags; +ret |= kvm_set_one_reg(cs, KVM_REG_LOONGARCH_LBT_EFLAGS, &val); +val = env->lbt.ftop; +ret |= kvm_set_one_reg(cs, KVM_REG_LOONGARCH_LBT_FTOP, &val); + +return ret; +} + +static int kvm_loongarch_get_lbt(CPUState *cs) +{ +CPULoongArchState *env = cpu_env(cs); +uint64_t val; +int ret; + +/* check whether vm support LBT firstly */ +if (FIELD_EX32(env->cpucfg[2], CPUCFG2, LBT_ALL) != 7) { +return 0; +} + +/* get six LBT registers including scr0-scr3, eflags, ftop */ +ret = kvm_get_one_reg(cs, KVM_REG_LOONGARCH_LBT_SCR0, &env->lbt.scr0); +ret |= kvm_get_one_reg(cs, KVM_REG_LOONGARCH_LBT_SCR1, &env->lbt.scr1); +ret |= kvm_get_one_reg(cs, KVM_REG_LOONGARCH_LBT_SCR2, &env->lbt.scr2); +ret |= kvm_get_one_reg(cs, KVM_REG_LOONGARCH_LBT_SCR3, &env->lbt.scr3); +ret |= kvm_get_one_reg(cs, KVM_REG_LOONGARCH_LBT_EFLAGS, &val); +env->lbt.eflags = (uint32_t)val; +ret |= kvm_get_one_reg(cs, KVM_REG_LOONGARCH_LBT_FTOP, &val); +env->lbt.ftop = (uint32_t)val; + +return ret; +} + void kvm_arch_reset_vcpu(CPUState *cs) { CPULoongArchState *env = cpu_env(cs); @@ -613,6 +665,11 @@ int kvm_arch_get_registers(CPUState *cs, Error **errp) return ret; } +ret = kvm_loongarch_get_lbt(cs); +if (ret) { +return ret; +} + ret = kvm_loongarch_get_mpstate(cs); return ret; } @@ -641,6 +698,11 @@ int kvm_arch_put_registers(CPUState *cs, int level, Error **errp) return ret; } +ret = kvm_loongarch_put_lbt(cs); +if (ret) { +return ret; +} + ret = kvm_loongarch_put_mpstate(cs); return ret; } diff --git a/target/loongarch/machine.c b/target/loongarch/machine.c index 08a7fa5370..3d5c84ae9c 100644 --- a/target/loongarch/machine.c +++ b/target/loongarch/machine.c @@ -110,6 +110,29 @@ static const VMStateDescription vmstate_lasx = { }, }; +static bool lbt_needed(void *opaque) +{ +LoongArchCPU *cpu = opaque; + +return !!FIELD_EX64(cpu->env.cpucfg[2], CPUCFG2, LBT_ALL); +} + +static const VMStateDescription vmstate_lbt = { +.name = "cpu/lbt", +.version_id = 0, +.minimum_version_id = 0, +.needed = lbt_needed, +.fields = (const VMStateField[]) { +VMSTATE_UINT64(env.lbt.scr0, LoongArchCPU), +VMSTATE_UINT64(env.lbt.scr1, LoongArchCPU), +VMSTATE_UINT64(env.lbt.scr2, LoongArchCPU), +VMSTATE_UINT64(env.lbt.scr3, LoongArchCPU), +VMSTATE_UINT32(env.lbt.eflags, LoongArchC
[PULL v2 7/8] hw/loongarch/boot: Use warn_report when no kernel filename
When we run “qemu-system-loongarch64 -qmp stdio -vnc none -S”, we get an error message “Need kernel filename” and then we can't use qmp cmd to query some information. So, we just throw a warning and then the cpus starts running from address VIRT_FLASH0_BASE. Signed-off-by: Song Gao Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20241030012359.4040817-1-gaos...@loongson.cn> --- hw/loongarch/boot.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c index cb668703bd..f258eefe9a 100644 --- a/hw/loongarch/boot.c +++ b/hw/loongarch/boot.c @@ -278,7 +278,7 @@ static void init_boot_rom(struct loongarch_boot_info *info, void *p) static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info) { void *p, *bp; -int64_t kernel_addr = 0; +int64_t kernel_addr = VIRT_FLASH0_BASE; LoongArchCPU *lacpu; CPUState *cs; @@ -286,8 +286,7 @@ static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info) kernel_addr = load_kernel_info(info); } else { if(!qtest_enabled()) { -error_report("Need kernel filename\n"); -exit(1); +warn_report("No kernel provided, booting from flash drive."); } } -- 2.34.1
[PULL v2 4/8] linux-headers: Add unistd_64.h
From: Bibo Mao since 6.11, unistd.h includes header file unistd_64.h directly on some platforms, here add unistd_64.h on these platforms. Affected platforms are ARM64, LoongArch64 and Riscv. Otherwise there will be compiling error such as: linux-headers/asm/unistd.h:3:10: fatal error: asm/unistd_64.h: No such file or directory #include Signed-off-by: Bibo Mao Acked-by: Song Gao Message-Id: <20241028023809.1554405-2-maob...@loongson.cn> Signed-off-by: Song Gao --- scripts/update-linux-headers.sh | 6 ++ 1 file changed, 6 insertions(+) diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh index c34ac6454e..203f48d089 100755 --- a/scripts/update-linux-headers.sh +++ b/scripts/update-linux-headers.sh @@ -163,6 +163,7 @@ EOF fi if [ $arch = arm64 ]; then cp "$hdrdir/include/asm/sve_context.h" "$output/linux-headers/asm-arm64/" +cp "$hdrdir/include/asm/unistd_64.h" "$output/linux-headers/asm-arm64/" fi if [ $arch = x86 ]; then cp "$hdrdir/include/asm/unistd_32.h" "$output/linux-headers/asm-x86/" @@ -185,6 +186,11 @@ EOF fi if [ $arch = riscv ]; then cp "$hdrdir/include/asm/ptrace.h" "$output/linux-headers/asm-riscv/" +cp "$hdrdir/include/asm/unistd_32.h" "$output/linux-headers/asm-riscv/" +cp "$hdrdir/include/asm/unistd_64.h" "$output/linux-headers/asm-riscv/" +fi +if [ $arch = loongarch ]; then +cp "$hdrdir/include/asm/unistd_64.h" "$output/linux-headers/asm-loongarch/" fi done arch= -- 2.34.1
[PULL v2 0/8] loongarch-to-apply queue
The following changes since commit 92ec7805190313c9e628f8fc4eb4f932c15247bd: Merge tag 'pull-riscv-to-apply-20241031-1' of https://github.com/alistair23/qemu into staging (2024-10-31 16:34:25 +) are available in the Git repository at: https://gitlab.com/gaosong/qemu.git tags/pull-loongarch-20241102 for you to fetch changes up to 47b54e15bbe78722c62dfafc3e04deded820c05e: target/loongarch: Add steal time support on migration (2024-11-02 15:45:45 +0800) pull-loongarch-20241102 V2: Fix no 'asm/unistd_64.h' build error. Add a new patch (hw/loongarch/boot: Use warn_report when no kernel filename). Bibo Mao (7): target/loongarch: Add loongson binary translation feature target/loongarch: Implement lbt registers save/restore function target/loongarch/kvm: Implement LoongArch PMU extension linux-headers: Add unistd_64.h linux-headers: loongarch: Add kvm_para.h linux-headers: Update to Linux v6.12-rc5 target/loongarch: Add steal time support on migration Song Gao (1): hw/loongarch/boot: Use warn_report when no kernel filename hw/loongarch/boot.c| 5 +- include/standard-headers/drm/drm_fourcc.h | 43 +++ include/standard-headers/linux/const.h | 17 ++ include/standard-headers/linux/ethtool.h | 226 ++ include/standard-headers/linux/fuse.h | 22 +- include/standard-headers/linux/input-event-codes.h | 2 + include/standard-headers/linux/pci_regs.h | 41 ++- include/standard-headers/linux/virtio_balloon.h| 16 +- include/standard-headers/linux/virtio_gpu.h| 1 + linux-headers/asm-arm64/mman.h | 9 + linux-headers/asm-arm64/unistd.h | 25 +- linux-headers/asm-arm64/unistd_64.h| 324 linux-headers/asm-generic/unistd.h | 6 +- linux-headers/asm-loongarch/kvm.h | 24 ++ linux-headers/asm-loongarch/kvm_para.h | 21 ++ linux-headers/asm-loongarch/unistd.h | 4 +- linux-headers/asm-loongarch/unistd_64.h| 320 linux-headers/asm-riscv/kvm.h | 7 + linux-headers/asm-riscv/unistd.h | 41 +-- linux-headers/asm-riscv/unistd_32.h| 315 linux-headers/asm-riscv/unistd_64.h| 325 + linux-headers/asm-x86/kvm.h| 2 + linux-headers/asm-x86/unistd_64.h | 1 + linux-headers/asm-x86/unistd_x32.h | 1 + linux-headers/linux/bits.h | 3 + linux-headers/linux/const.h| 17 ++ linux-headers/linux/iommufd.h | 143 +++-- linux-headers/linux/kvm.h | 23 +- linux-headers/linux/mman.h | 1 + linux-headers/linux/psp-sev.h | 28 ++ scripts/update-linux-headers.sh| 7 + target/loongarch/cpu.c | 43 +++ target/loongarch/cpu.h | 23 ++ target/loongarch/kvm/kvm.c | 225 +- target/loongarch/loongarch-qmp-cmds.c | 2 +- target/loongarch/machine.c | 30 +- 36 files changed, 2243 insertions(+), 100 deletions(-) create mode 100644 linux-headers/asm-arm64/unistd_64.h create mode 100644 linux-headers/asm-loongarch/kvm_para.h create mode 100644 linux-headers/asm-loongarch/unistd_64.h create mode 100644 linux-headers/asm-riscv/unistd_32.h create mode 100644 linux-headers/asm-riscv/unistd_64.h
[PATCH v2] hw/loongarch/boot: Use warn_report when no kernel filename
When we run “qemu-system-loongarch64 -qmp stdio -vnc none -S”, we get an error message “Need kernel filename” and then we can't use qmp cmd to query some information. So, we just throw a warning and then the cpus starts running from address VIRT_FLASH0_BASE. Signed-off-by: Song Gao --- hw/loongarch/boot.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c index cb668703bd..5f194e1a77 100644 --- a/hw/loongarch/boot.c +++ b/hw/loongarch/boot.c @@ -278,7 +278,7 @@ static void init_boot_rom(struct loongarch_boot_info *info, void *p) static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info) { void *p, *bp; -int64_t kernel_addr = 0; +int64_t kernel_addr = VIRT_FLASH0_BASE; LoongArchCPU *lacpu; CPUState *cs; @@ -286,8 +286,7 @@ static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info) kernel_addr = load_kernel_info(info); } else { if(!qtest_enabled()) { -error_report("Need kernel filename\n"); -exit(1); +warn_report("No kernel provided, booting from flash drive. \n"); } } -- 2.34.1
[PATCH 1/1] hw/loongarch/boot: Use warn_report when no kernel filename
When we run “qemu-system-loongarch64 -qmp stdio -vnc none -S”, we get an error message “Need kernel filename” and then we can't use qmp cmd to query some information. So, we just throw a warning and then the cpus starts running from address VIRT_FLASH0_BASE. Signed-off-by: Song Gao --- hw/loongarch/boot.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c index cb668703bd..9c37abed3a 100644 --- a/hw/loongarch/boot.c +++ b/hw/loongarch/boot.c @@ -278,7 +278,7 @@ static void init_boot_rom(struct loongarch_boot_info *info, void *p) static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info) { void *p, *bp; -int64_t kernel_addr = 0; +int64_t kernel_addr = VIRT_FLASH0_BASE; LoongArchCPU *lacpu; CPUState *cs; @@ -286,8 +286,7 @@ static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info) kernel_addr = load_kernel_info(info); } else { if(!qtest_enabled()) { -error_report("Need kernel filename\n"); -exit(1); +warn_report("Need kernel filename\n"); } } -- 2.34.1
[PULL 1/6] target/loongarch: Add loongson binary translation feature
From: Bibo Mao Loongson Binary Translation (LBT) is used to accelerate binary translation, which contains 4 scratch registers (scr0 to scr3), x86/ARM eflags (eflags) and x87 fpu stack pointer (ftop). Now LBT feature is added in kvm mode, not supported in TCG mode since it is not emulated. Feature variable lbt is added with OnOffAuto type, If lbt feature is not supported with KVM host, it reports error if there is lbt=on command line. If there is no any command line about lbt parameter, it checks whether KVM host supports lbt feature and set the corresponding value in cpucfg. Signed-off-by: Bibo Mao Reviewed-by: Song Gao Message-Id: <20240929070405.235200-2-maob...@loongson.cn> Signed-off-by: Song Gao --- target/loongarch/cpu.c| 24 +++ target/loongarch/cpu.h| 6 +++ target/loongarch/kvm/kvm.c| 57 ++- target/loongarch/loongarch-qmp-cmds.c | 2 +- 4 files changed, 87 insertions(+), 2 deletions(-) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 7212fb5f8f..29577e6b71 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -664,12 +664,36 @@ static void loongarch_set_lasx(Object *obj, bool value, Error **errp) } } +static bool loongarch_get_lbt(Object *obj, Error **errp) +{ +return LOONGARCH_CPU(obj)->lbt != ON_OFF_AUTO_OFF; +} + +static void loongarch_set_lbt(Object *obj, bool value, Error **errp) +{ +LoongArchCPU *cpu = LOONGARCH_CPU(obj); + +cpu->lbt = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF; +} + void loongarch_cpu_post_init(Object *obj) { +LoongArchCPU *cpu = LOONGARCH_CPU(obj); + object_property_add_bool(obj, "lsx", loongarch_get_lsx, loongarch_set_lsx); object_property_add_bool(obj, "lasx", loongarch_get_lasx, loongarch_set_lasx); +/* lbt is enabled only in kvm mode, not supported in tcg mode */ +if (kvm_enabled()) { +cpu->lbt = ON_OFF_AUTO_AUTO; +object_property_add_bool(obj, "lbt", loongarch_get_lbt, + loongarch_set_lbt); +object_property_set_description(obj, "lbt", + "Set off to disable Binary Tranlation."); +} else { +cpu->lbt = ON_OFF_AUTO_OFF; +} } static void loongarch_cpu_init(Object *obj) diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index 6c41fafb70..2b3f2758f6 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -153,6 +153,7 @@ FIELD(CPUCFG2, LLFTP_VER, 15, 3) FIELD(CPUCFG2, LBT_X86, 18, 1) FIELD(CPUCFG2, LBT_ARM, 19, 1) FIELD(CPUCFG2, LBT_MIPS, 20, 1) +FIELD(CPUCFG2, LBT_ALL, 18, 3) FIELD(CPUCFG2, LSPW, 21, 1) FIELD(CPUCFG2, LAM, 22, 1) @@ -281,6 +282,10 @@ struct LoongArchTLB { typedef struct LoongArchTLB LoongArchTLB; #endif +enum loongarch_features { +LOONGARCH_FEATURE_LBT, /* loongson binary translation extension */ +}; + typedef struct CPUArchState { uint64_t gpr[32]; uint64_t pc; @@ -381,6 +386,7 @@ struct ArchCPU { CPULoongArchState env; QEMUTimer timer; uint32_t phy_id; +OnOffAuto lbt; /* 'compatible' string for this CPU for Linux device trees */ const char *dtb_compatible; diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c index 30ec16025d..079f8ca5d7 100644 --- a/target/loongarch/kvm/kvm.c +++ b/target/loongarch/kvm/kvm.c @@ -9,6 +9,7 @@ #include #include +#include "qapi/error.h" #include "qemu/timer.h" #include "qemu/error-report.h" #include "qemu/main-loop.h" @@ -666,17 +667,71 @@ static void kvm_loongarch_vm_stage_change(void *opaque, bool running, } } +static bool kvm_feature_supported(CPUState *cs, enum loongarch_features feature) +{ +int ret; +struct kvm_device_attr attr; + +switch (feature) { +case LOONGARCH_FEATURE_LBT: +/* + * Return all if all the LBT features are supported such as: + * KVM_LOONGARCH_VM_FEAT_X86BT + * KVM_LOONGARCH_VM_FEAT_ARMBT + * KVM_LOONGARCH_VM_FEAT_MIPSBT + */ +attr.group = KVM_LOONGARCH_VM_FEAT_CTRL; +attr.attr = KVM_LOONGARCH_VM_FEAT_X86BT; +ret = kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr); +attr.attr = KVM_LOONGARCH_VM_FEAT_ARMBT; +ret |= kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr); +attr.attr = KVM_LOONGARCH_VM_FEAT_MIPSBT; +ret |= kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr); +return (ret == 0); +default: +return false; +} +} + +static int kvm_cpu_check_lbt(CPUState *cs, Error **errp) +{ +CPULoongArchState *env = cpu_env(cs); +LoongArchCPU *cpu = LOONGARCH_CPU(cs); +bool kvm_supported; + +kvm_supported = kvm_feature_supported(cs, LOONGARCH_FEATURE_LBT); +if (cpu-&g
[PULL 5/6] linux-headers: Update to Linux v6.12-rc3
From: Bibo Mao This update contains the required header changes for LoongArch KVM LBT feature. Signed-off-by: Bibo Mao Acked-by: Song Gao Message-Id: <20241017020708.1728620-3-maob...@loongson.cn> Signed-off-by: Song Gao --- include/standard-headers/drm/drm_fourcc.h | 43 +++ include/standard-headers/linux/const.h| 17 + include/standard-headers/linux/ethtool.h | 226 + include/standard-headers/linux/fuse.h | 22 +- .../linux/input-event-codes.h | 2 + include/standard-headers/linux/pci_regs.h | 41 ++- .../standard-headers/linux/virtio_balloon.h | 16 +- include/standard-headers/linux/virtio_gpu.h | 1 + linux-headers/asm-arm64/mman.h| 9 + linux-headers/asm-arm64/unistd.h | 25 +- linux-headers/asm-generic/unistd.h| 6 +- linux-headers/asm-loongarch/kvm.h | 24 ++ linux-headers/asm-loongarch/kvm_para.h| 21 ++ linux-headers/asm-loongarch/unistd.h | 4 +- linux-headers/asm-loongarch/unistd_64.h | 320 ++ linux-headers/asm-riscv/kvm.h | 7 + linux-headers/asm-riscv/unistd.h | 41 +-- linux-headers/asm-x86/kvm.h | 2 + linux-headers/asm-x86/unistd_64.h | 1 + linux-headers/asm-x86/unistd_x32.h| 1 + linux-headers/linux/bits.h| 3 + linux-headers/linux/const.h | 17 + linux-headers/linux/iommufd.h | 143 ++-- linux-headers/linux/kvm.h | 23 +- linux-headers/linux/mman.h| 1 + linux-headers/linux/psp-sev.h | 28 ++ 26 files changed, 951 insertions(+), 93 deletions(-) create mode 100644 linux-headers/asm-loongarch/kvm_para.h create mode 100644 linux-headers/asm-loongarch/unistd_64.h diff --git a/include/standard-headers/drm/drm_fourcc.h b/include/standard-headers/drm/drm_fourcc.h index b72917073d..d4a2231306 100644 --- a/include/standard-headers/drm/drm_fourcc.h +++ b/include/standard-headers/drm/drm_fourcc.h @@ -701,6 +701,31 @@ extern "C" { */ #define I915_FORMAT_MOD_4_TILED_MTL_RC_CCS_CC fourcc_mod_code(INTEL, 15) +/* + * Intel Color Control Surfaces (CCS) for graphics ver. 20 unified compression + * on integrated graphics + * + * The main surface is Tile 4 and at plane index 0. For semi-planar formats + * like NV12, the Y and UV planes are Tile 4 and are located at plane indices + * 0 and 1, respectively. The CCS for all planes are stored outside of the + * GEM object in a reserved memory area dedicated for the storage of the + * CCS data for all compressible GEM objects. + */ +#define I915_FORMAT_MOD_4_TILED_LNL_CCS fourcc_mod_code(INTEL, 16) + +/* + * Intel Color Control Surfaces (CCS) for graphics ver. 20 unified compression + * on discrete graphics + * + * The main surface is Tile 4 and at plane index 0. For semi-planar formats + * like NV12, the Y and UV planes are Tile 4 and are located at plane indices + * 0 and 1, respectively. The CCS for all planes are stored outside of the + * GEM object in a reserved memory area dedicated for the storage of the + * CCS data for all compressible GEM objects. The GEM object must be stored in + * contiguous memory with a size aligned to 64KB + */ +#define I915_FORMAT_MOD_4_TILED_BMG_CCS fourcc_mod_code(INTEL, 17) + /* * Tiled, NV12MT, grouped in 64 (pixels) x 32 (lines) -sized macroblocks * @@ -1475,6 +1500,7 @@ drm_fourcc_canonicalize_nvidia_format_mod(uint64_t modifier) #define AMD_FMT_MOD_TILE_VER_GFX10 2 #define AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS 3 #define AMD_FMT_MOD_TILE_VER_GFX11 4 +#define AMD_FMT_MOD_TILE_VER_GFX12 5 /* * 64K_S is the same for GFX9/GFX10/GFX10_RBPLUS and hence has GFX9 as canonical @@ -1485,6 +1511,8 @@ drm_fourcc_canonicalize_nvidia_format_mod(uint64_t modifier) /* * 64K_D for non-32 bpp is the same for GFX9/GFX10/GFX10_RBPLUS and hence has * GFX9 as canonical version. + * + * 64K_D_2D on GFX12 is identical to 64K_D on GFX11. */ #define AMD_FMT_MOD_TILE_GFX9_64K_D 10 #define AMD_FMT_MOD_TILE_GFX9_64K_S_X 25 @@ -1492,6 +1520,21 @@ drm_fourcc_canonicalize_nvidia_format_mod(uint64_t modifier) #define AMD_FMT_MOD_TILE_GFX9_64K_R_X 27 #define AMD_FMT_MOD_TILE_GFX11_256K_R_X 31 +/* Gfx12 swizzle modes: + *0 - LINEAR + *1 - 256B_2D - 2D block dimensions + *2 - 4KB_2D + *3 - 64KB_2D + *4 - 256KB_2D + *5 - 4KB_3D - 3D block dimensions + *6 - 64KB_3D + *7 - 256KB_3D + */ +#define AMD_FMT_MOD_TILE_GFX12_256B_2D 1 +#define AMD_FMT_MOD_TILE_GFX12_4K_2D 2 +#define AMD_FMT_MOD_TILE_GFX12_64K_2D 3 +#define AMD_FMT_MOD_TILE_GFX12_256K_2D 4 + #define AMD_FMT_MOD_DCC_BLOCK_64B 0 #define AMD_FMT_MOD_DCC_BLOCK_128B 1 #define AMD_FMT_MOD_DCC_BLOCK_256B 2 diff --git a/include/standard-headers/linux/const.h b/include/standard-headers/linux/const.h index 1eb84b5087..2122610de7 100644 --- a/include/
[PULL 2/6] target/loongarch: Implement lbt registers save/restore function
From: Bibo Mao Six registers scr0 - scr3, eflags and ftop are added in percpu vmstate. And two functions kvm_loongarch_get_lbt/kvm_loongarch_put_lbt are added to save/restore lbt registers. Signed-off-by: Bibo Mao Reviewed-by: Song Gao Message-Id: <20240929070405.235200-3-maob...@loongson.cn> Signed-off-by: Song Gao --- target/loongarch/cpu.h | 12 target/loongarch/kvm/kvm.c | 62 ++ target/loongarch/machine.c | 24 +++ 3 files changed, 98 insertions(+) diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index 2b3f2758f6..136866b7b8 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -286,6 +286,17 @@ enum loongarch_features { LOONGARCH_FEATURE_LBT, /* loongson binary translation extension */ }; +typedef struct LoongArchBT { +/* scratch registers */ +uint64_t scr0; +uint64_t scr1; +uint64_t scr2; +uint64_t scr3; +/* loongarch eflags */ +uint32_t eflags; +uint32_t ftop; +} lbt_t; + typedef struct CPUArchState { uint64_t gpr[32]; uint64_t pc; @@ -293,6 +304,7 @@ typedef struct CPUArchState { fpr_t fpr[32]; bool cf[8]; uint32_t fcsr0; +lbt_t lbt; uint32_t cpucfg[21]; diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c index 079f8ca5d7..40115aff56 100644 --- a/target/loongarch/kvm/kvm.c +++ b/target/loongarch/kvm/kvm.c @@ -477,6 +477,58 @@ static int kvm_loongarch_put_regs_fp(CPUState *cs) return ret; } +static int kvm_loongarch_put_lbt(CPUState *cs) +{ +CPULoongArchState *env = cpu_env(cs); +uint64_t val; +int ret; + +/* check whether vm support LBT firstly */ +if (FIELD_EX32(env->cpucfg[2], CPUCFG2, LBT_ALL) != 7) { +return 0; +} + +/* set six LBT registers including scr0-scr3, eflags, ftop */ +ret = kvm_set_one_reg(cs, KVM_REG_LOONGARCH_LBT_SCR0, &env->lbt.scr0); +ret |= kvm_set_one_reg(cs, KVM_REG_LOONGARCH_LBT_SCR1, &env->lbt.scr1); +ret |= kvm_set_one_reg(cs, KVM_REG_LOONGARCH_LBT_SCR2, &env->lbt.scr2); +ret |= kvm_set_one_reg(cs, KVM_REG_LOONGARCH_LBT_SCR3, &env->lbt.scr3); +/* + * Be cautious, KVM_REG_LOONGARCH_LBT_FTOP is defined as 64-bit however + * lbt.ftop is 32-bit; the same with KVM_REG_LOONGARCH_LBT_EFLAGS register + */ +val = env->lbt.eflags; +ret |= kvm_set_one_reg(cs, KVM_REG_LOONGARCH_LBT_EFLAGS, &val); +val = env->lbt.ftop; +ret |= kvm_set_one_reg(cs, KVM_REG_LOONGARCH_LBT_FTOP, &val); + +return ret; +} + +static int kvm_loongarch_get_lbt(CPUState *cs) +{ +CPULoongArchState *env = cpu_env(cs); +uint64_t val; +int ret; + +/* check whether vm support LBT firstly */ +if (FIELD_EX32(env->cpucfg[2], CPUCFG2, LBT_ALL) != 7) { +return 0; +} + +/* get six LBT registers including scr0-scr3, eflags, ftop */ +ret = kvm_get_one_reg(cs, KVM_REG_LOONGARCH_LBT_SCR0, &env->lbt.scr0); +ret |= kvm_get_one_reg(cs, KVM_REG_LOONGARCH_LBT_SCR1, &env->lbt.scr1); +ret |= kvm_get_one_reg(cs, KVM_REG_LOONGARCH_LBT_SCR2, &env->lbt.scr2); +ret |= kvm_get_one_reg(cs, KVM_REG_LOONGARCH_LBT_SCR3, &env->lbt.scr3); +ret |= kvm_get_one_reg(cs, KVM_REG_LOONGARCH_LBT_EFLAGS, &val); +env->lbt.eflags = (uint32_t)val; +ret |= kvm_get_one_reg(cs, KVM_REG_LOONGARCH_LBT_FTOP, &val); +env->lbt.ftop = (uint32_t)val; + +return ret; +} + void kvm_arch_reset_vcpu(CPUState *cs) { CPULoongArchState *env = cpu_env(cs); @@ -613,6 +665,11 @@ int kvm_arch_get_registers(CPUState *cs, Error **errp) return ret; } +ret = kvm_loongarch_get_lbt(cs); +if (ret) { +return ret; +} + ret = kvm_loongarch_get_mpstate(cs); return ret; } @@ -641,6 +698,11 @@ int kvm_arch_put_registers(CPUState *cs, int level, Error **errp) return ret; } +ret = kvm_loongarch_put_lbt(cs); +if (ret) { +return ret; +} + ret = kvm_loongarch_put_mpstate(cs); return ret; } diff --git a/target/loongarch/machine.c b/target/loongarch/machine.c index 08a7fa5370..3d5c84ae9c 100644 --- a/target/loongarch/machine.c +++ b/target/loongarch/machine.c @@ -110,6 +110,29 @@ static const VMStateDescription vmstate_lasx = { }, }; +static bool lbt_needed(void *opaque) +{ +LoongArchCPU *cpu = opaque; + +return !!FIELD_EX64(cpu->env.cpucfg[2], CPUCFG2, LBT_ALL); +} + +static const VMStateDescription vmstate_lbt = { +.name = "cpu/lbt", +.version_id = 0, +.minimum_version_id = 0, +.needed = lbt_needed, +.fields = (const VMStateField[]) { +VMSTATE_UINT64(env.lbt.scr0, LoongArchCPU), +VMSTATE_UINT64(env.lbt.scr1, LoongArchCPU), +VMSTATE_UINT64(env.lbt.scr2, LoongArchCPU), +VMSTATE_UINT64(env.lbt.scr3, LoongArchCPU), +VMSTATE_UINT32(env.lbt.eflags, LoongArchC
[PULL 0/6] loongarch-to-apply queue
The following changes since commit 6f625ce2f21d6a1243065d236298277c56f972d5: Merge tag 'pull-request-2024-10-21' of https://gitlab.com/thuth/qemu into staging (2024-10-21 17:12:59 +0100) are available in the Git repository at: https://gitlab.com/gaosong/qemu.git tags/pull-loongarch-20241024 for you to fetch changes up to c44e0d6ba280dcc6bdf4ed555020c61d564b526c: target/loongarch: Add steal time support on migration (2024-10-24 17:27:55 +0800) pull-loongarch-20241024 Bibo Mao (6): target/loongarch: Add loongson binary translation feature target/loongarch: Implement lbt registers save/restore function target/loongarch/kvm: Implement LoongArch PMU extension linux-headers: loongarch: Add kvm_para.h and unistd_64.h linux-headers: Update to Linux v6.12-rc3 target/loongarch: Add steal time support on migration include/standard-headers/drm/drm_fourcc.h | 43 +++ include/standard-headers/linux/const.h | 17 ++ include/standard-headers/linux/ethtool.h | 226 +++ include/standard-headers/linux/fuse.h | 22 +- include/standard-headers/linux/input-event-codes.h | 2 + include/standard-headers/linux/pci_regs.h | 41 ++- include/standard-headers/linux/virtio_balloon.h| 16 +- include/standard-headers/linux/virtio_gpu.h| 1 + linux-headers/asm-arm64/mman.h | 9 + linux-headers/asm-arm64/unistd.h | 25 +- linux-headers/asm-generic/unistd.h | 6 +- linux-headers/asm-loongarch/kvm.h | 24 ++ linux-headers/asm-loongarch/kvm_para.h | 21 ++ linux-headers/asm-loongarch/unistd.h | 4 +- linux-headers/asm-loongarch/unistd_64.h| 320 + linux-headers/asm-riscv/kvm.h | 7 + linux-headers/asm-riscv/unistd.h | 41 +-- linux-headers/asm-x86/kvm.h| 2 + linux-headers/asm-x86/unistd_64.h | 1 + linux-headers/asm-x86/unistd_x32.h | 1 + linux-headers/linux/bits.h | 3 + linux-headers/linux/const.h| 17 ++ linux-headers/linux/iommufd.h | 143 +++-- linux-headers/linux/kvm.h | 23 +- linux-headers/linux/mman.h | 1 + linux-headers/linux/psp-sev.h | 28 ++ scripts/update-linux-headers.sh| 4 + target/loongarch/cpu.c | 43 +++ target/loongarch/cpu.h | 23 ++ target/loongarch/kvm/kvm.c | 225 ++- target/loongarch/loongarch-qmp-cmds.c | 2 +- target/loongarch/machine.c | 30 +- 32 files changed, 1274 insertions(+), 97 deletions(-) create mode 100644 linux-headers/asm-loongarch/kvm_para.h create mode 100644 linux-headers/asm-loongarch/unistd_64.h
[PULL 3/6] target/loongarch/kvm: Implement LoongArch PMU extension
From: Bibo Mao Implement PMU extension for LoongArch kvm mode. Use OnOffAuto type variable pmu to check the PMU feature. If the PMU Feature is not supported with KVM host, it reports error if there is pmu=on command line. If there is no any command line about pmu parameter, it checks whether KVM host supports the PMU Feature and set the corresponding value in cpucfg. This patch is based on lbt patch located at https://lore.kernel.org/qemu-devel/20240904061859.86615-1-maob...@loongson.cn Co-developed-by: Song Gao Signed-off-by: Bibo Mao Reviewed-by: Song Gao Message-Id: <20240918082315.2345034-1-maob...@loongson.cn> Signed-off-by: Song Gao --- target/loongarch/cpu.c| 19 + target/loongarch/cpu.h| 2 ++ target/loongarch/kvm/kvm.c| 41 +++ target/loongarch/loongarch-qmp-cmds.c | 2 +- 4 files changed, 63 insertions(+), 1 deletion(-) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 29577e6b71..57cc4f314b 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -676,6 +676,18 @@ static void loongarch_set_lbt(Object *obj, bool value, Error **errp) cpu->lbt = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF; } +static bool loongarch_get_pmu(Object *obj, Error **errp) +{ +return LOONGARCH_CPU(obj)->pmu != ON_OFF_AUTO_OFF; +} + +static void loongarch_set_pmu(Object *obj, bool value, Error **errp) +{ +LoongArchCPU *cpu = LOONGARCH_CPU(obj); + +cpu->pmu = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF; +} + void loongarch_cpu_post_init(Object *obj) { LoongArchCPU *cpu = LOONGARCH_CPU(obj); @@ -691,6 +703,13 @@ void loongarch_cpu_post_init(Object *obj) loongarch_set_lbt); object_property_set_description(obj, "lbt", "Set off to disable Binary Tranlation."); + +cpu->pmu = ON_OFF_AUTO_AUTO; +object_property_add_bool(obj, "pmu", loongarch_get_pmu, + loongarch_set_pmu); +object_property_set_description(obj, "pmu", + "Set off to performance monitor unit."); + } else { cpu->lbt = ON_OFF_AUTO_OFF; } diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index 136866b7b8..95be58dd66 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -284,6 +284,7 @@ typedef struct LoongArchTLB LoongArchTLB; enum loongarch_features { LOONGARCH_FEATURE_LBT, /* loongson binary translation extension */ +LOONGARCH_FEATURE_PMU, }; typedef struct LoongArchBT { @@ -399,6 +400,7 @@ struct ArchCPU { QEMUTimer timer; uint32_t phy_id; OnOffAuto lbt; +OnOffAuto pmu; /* 'compatible' string for this CPU for Linux device trees */ const char *dtb_compatible; diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c index 40115aff56..8bda8ae540 100644 --- a/target/loongarch/kvm/kvm.c +++ b/target/loongarch/kvm/kvm.c @@ -750,9 +750,18 @@ static bool kvm_feature_supported(CPUState *cs, enum loongarch_features feature) attr.attr = KVM_LOONGARCH_VM_FEAT_MIPSBT; ret |= kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr); return (ret == 0); + +case LOONGARCH_FEATURE_PMU: +attr.group = KVM_LOONGARCH_VM_FEAT_CTRL; +attr.attr = KVM_LOONGARCH_VM_FEAT_PMU; +ret = kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr); +return (ret == 0); + default: return false; } + +return false; } static int kvm_cpu_check_lbt(CPUState *cs, Error **errp) @@ -776,6 +785,32 @@ static int kvm_cpu_check_lbt(CPUState *cs, Error **errp) return 0; } +static int kvm_cpu_check_pmu(CPUState *cs, Error **errp) +{ +LoongArchCPU *cpu = LOONGARCH_CPU(cs); +CPULoongArchState *env = cpu_env(cs); +bool kvm_supported; + +kvm_supported = kvm_feature_supported(cs, LOONGARCH_FEATURE_PMU); +if (cpu->pmu == ON_OFF_AUTO_ON) { +if (!kvm_supported) { +error_setg(errp, "'pmu' feature not supported by KVM on the host"); +return -ENOTSUP; +} +} else if (cpu->pmu != ON_OFF_AUTO_AUTO) { +/* disable pmu if ON_OFF_AUTO_OFF is set */ +kvm_supported = false; +} + +if (kvm_supported) { +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, PMBITS, 63); +env->cpucfg[6] = FIELD_DP32(env->cpucfg[6], CPUCFG6, UPM, 1); +} +return 0; +} + int kvm_arch_init_vcpu(CPUState *cs) { uint64_t val; @@ -793,6 +828,12 @@ int kvm_arch_init_vcpu(CPUState *cs) if (ret < 0) { error_report_err(local_err); } + +ret = kvm_cpu_che
[PULL 6/6] target/loongarch: Add steal time support on migration
From: Bibo Mao With pv steal time supported, VM machine needs get physical address of each vcpu and notify new host during migration. Here two functions kvm_get_stealtime/kvm_set_stealtime, and guest steal time physical address is only updated on KVM_PUT_FULL_STATE stage. Signed-off-by: Bibo Mao Reviewed-by: Song Gao Message-Id: <20240930064040.753929-1-maob...@loongson.cn> Signed-off-by: Song Gao --- target/loongarch/cpu.h | 3 ++ target/loongarch/kvm/kvm.c | 65 ++ target/loongarch/machine.c | 6 ++-- 3 files changed, 72 insertions(+), 2 deletions(-) diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index 95be58dd66..86c86c6c95 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -364,6 +364,9 @@ typedef struct CPUArchState { uint64_t CSR_DBG; uint64_t CSR_DERA; uint64_t CSR_DSAVE; +struct { +uint64_t guest_addr; +} stealtime; #ifdef CONFIG_TCG float_status fp_status; diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c index 8bda8ae540..ff81806ca3 100644 --- a/target/loongarch/kvm/kvm.c +++ b/target/loongarch/kvm/kvm.c @@ -34,6 +34,55 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = { KVM_CAP_LAST_INFO }; +static int kvm_get_stealtime(CPUState *cs) +{ +CPULoongArchState *env = cpu_env(cs); +int err; +struct kvm_device_attr attr = { +.group = KVM_LOONGARCH_VCPU_PVTIME_CTRL, +.attr = KVM_LOONGARCH_VCPU_PVTIME_GPA, +.addr = (uint64_t)&env->stealtime.guest_addr, +}; + +err = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, attr); +if (err) { +return 0; +} + +err = kvm_vcpu_ioctl(cs, KVM_GET_DEVICE_ATTR, attr); +if (err) { +error_report("PVTIME: KVM_GET_DEVICE_ATTR: %s", strerror(errno)); +return err; +} + +return 0; +} + +static int kvm_set_stealtime(CPUState *cs) +{ +CPULoongArchState *env = cpu_env(cs); +int err; +struct kvm_device_attr attr = { +.group = KVM_LOONGARCH_VCPU_PVTIME_CTRL, +.attr = KVM_LOONGARCH_VCPU_PVTIME_GPA, +.addr = (uint64_t)&env->stealtime.guest_addr, +}; + +err = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, attr); +if (err) { +return 0; +} + +err = kvm_vcpu_ioctl(cs, KVM_SET_DEVICE_ATTR, attr); +if (err) { +error_report("PVTIME: KVM_SET_DEVICE_ATTR %s with gpa "TARGET_FMT_lx, + strerror(errno), env->stealtime.guest_addr); +return err; +} + +return 0; +} + static int kvm_loongarch_get_regs_core(CPUState *cs) { int ret = 0; @@ -670,6 +719,11 @@ int kvm_arch_get_registers(CPUState *cs, Error **errp) return ret; } +ret = kvm_get_stealtime(cs); +if (ret) { +return ret; +} + ret = kvm_loongarch_get_mpstate(cs); return ret; } @@ -703,6 +757,17 @@ int kvm_arch_put_registers(CPUState *cs, int level, Error **errp) return ret; } +if (level >= KVM_PUT_FULL_STATE) { +/* + * only KVM_PUT_FULL_STATE is required, kvm kernel will clear + * guest_addr for KVM_PUT_RESET_STATE + */ +ret = kvm_set_stealtime(cs); +if (ret) { +return ret; +} +} + ret = kvm_loongarch_put_mpstate(cs); return ret; } diff --git a/target/loongarch/machine.c b/target/loongarch/machine.c index 3d5c84ae9c..efb20e2fbe 100644 --- a/target/loongarch/machine.c +++ b/target/loongarch/machine.c @@ -168,8 +168,8 @@ static const VMStateDescription vmstate_tlb = { /* LoongArch CPU state */ const VMStateDescription vmstate_loongarch_cpu = { .name = "cpu", -.version_id = 2, -.minimum_version_id = 2, +.version_id = 3, +.minimum_version_id = 3, .fields = (const VMStateField[]) { VMSTATE_UINTTL_ARRAY(env.gpr, LoongArchCPU, 32), VMSTATE_UINTTL(env.pc, LoongArchCPU), @@ -232,6 +232,8 @@ const VMStateDescription vmstate_loongarch_cpu = { VMSTATE_UINT64(env.CSR_DSAVE, LoongArchCPU), VMSTATE_UINT64(kvm_state_counter, LoongArchCPU), +/* PV steal time */ +VMSTATE_UINT64(env.stealtime.guest_addr, LoongArchCPU), VMSTATE_END_OF_LIST() }, -- 2.34.1
[PULL 4/6] linux-headers: loongarch: Add kvm_para.h and unistd_64.h
From: Bibo Mao KVM LBT supports on LoongArch depends on the linux-header file kvm_para.h, also unistd_64.h is required by unistd.h on LoongArch since 6.11, otherwise there will be compiling error such as: linux-headers/asm/unistd.h:3:10: fatal error: asm/unistd_64.h: No such file or directory #include Signed-off-by: Bibo Mao Acked-by: Song Gao Message-Id: <20241017020708.1728620-2-maob...@loongson.cn> Signed-off-by: Song Gao --- scripts/update-linux-headers.sh | 4 1 file changed, 4 insertions(+) diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh index c34ac6454e..3c411f0318 100755 --- a/scripts/update-linux-headers.sh +++ b/scripts/update-linux-headers.sh @@ -186,6 +186,10 @@ EOF if [ $arch = riscv ]; then cp "$hdrdir/include/asm/ptrace.h" "$output/linux-headers/asm-riscv/" fi +if [ $arch = loongarch ]; then +cp "$hdrdir/include/asm/kvm_para.h" "$output/linux-headers/asm-loongarch/" +cp "$hdrdir/include/asm/unistd_64.h" "$output/linux-headers/asm-loongarch/" +fi done arch= -- 2.34.1
[PULL 5/5] hw/loongarch/fw_cfg: Build in common_ss[]
From: Philippe Mathieu-Daudé Nothing in LoongArch fw_cfg.c requires target specific definitions. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Song Gao Reviewed-by: Thomas Huth Message-Id: <20240927213254.17552-3-phi...@linaro.org> Signed-off-by: Song Gao --- hw/loongarch/meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/loongarch/meson.build b/hw/loongarch/meson.build index bce7ebac97..005f017e21 100644 --- a/hw/loongarch/meson.build +++ b/hw/loongarch/meson.build @@ -1,8 +1,8 @@ loongarch_ss = ss.source_set() loongarch_ss.add(files( -'fw_cfg.c', 'boot.c', )) +common_ss.add(when: 'CONFIG_LOONGARCH_VIRT', if_true: files('fw_cfg.c')) loongarch_ss.add(when: 'CONFIG_LOONGARCH_VIRT', if_true: files('virt.c')) loongarch_ss.add(when: 'CONFIG_ACPI', if_true: files('acpi-build.c')) -- 2.34.1
[PULL 1/5] acpi: ged: Add macro for acpi sleep control register
From: Bibo Mao Macro definition is added for acpi sleep control register, ged emulation driver can use the macro , also it can be used in FDT table if ged is exposed with FDT table. Signed-off-by: Bibo Mao Reviewed-by: Igor Mammedov Message-Id: <20240918014206.2165821-2-maob...@loongson.cn> Signed-off-by: Song Gao --- hw/acpi/generic_event_device.c | 6 +++--- include/hw/acpi/generic_event_device.h | 7 +-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c index 15b4c3ebbf..d00f5a6c1c 100644 --- a/hw/acpi/generic_event_device.c +++ b/hw/acpi/generic_event_device.c @@ -201,9 +201,9 @@ static void ged_regs_write(void *opaque, hwaddr addr, uint64_t data, switch (addr) { case ACPI_GED_REG_SLEEP_CTL: -slp_typ = (data >> 2) & 0x07; -slp_en = (data >> 5) & 0x01; -if (slp_en && slp_typ == 5) { +slp_typ = (data >> ACPI_GED_SLP_TYP_POS) & ACPI_GED_SLP_TYP_MASK; +slp_en = !!(data & ACPI_GED_SLP_EN); +if (slp_en && slp_typ == ACPI_GED_SLP_TYP_S5) { qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); } return; diff --git a/include/hw/acpi/generic_event_device.h b/include/hw/acpi/generic_event_device.h index 40af3550b5..d2dac87b4a 100644 --- a/include/hw/acpi/generic_event_device.h +++ b/include/hw/acpi/generic_event_device.h @@ -81,8 +81,11 @@ OBJECT_DECLARE_SIMPLE_TYPE(AcpiGedState, ACPI_GED) /* ACPI_GED_REG_RESET value for reset*/ #define ACPI_GED_RESET_VALUE 0x42 -/* ACPI_GED_REG_SLEEP_CTL.SLP_TYP value for S5 (aka poweroff) */ -#define ACPI_GED_SLP_TYP_S50x05 +/* [ACPI 5.0 Chapter 4.8.3.7] Sleep Control and Status Register */ +#define ACPI_GED_SLP_TYP_POS 0x2 /* SLP_TYPx Bit Offset */ +#define ACPI_GED_SLP_TYP_MASK 0x07 /* SLP_TYPx 3-bit mask */ +#define ACPI_GED_SLP_TYP_S50x05 /* System _S5 State (Soft Off) */ +#define ACPI_GED_SLP_EN0x20 /* SLP_EN write-only bit */ #define GED_DEVICE "GED" #define AML_GED_EVT_REG "EREG" -- 2.34.1
[PULL 2/5] hw/loongarch/virt: Add FDT table support with acpi ged pm register
From: Bibo Mao ACPI ged is used for power management on LoongArch virt platform, in general it is parsed from acpi table. However if system boot directly from elf kernel, no UEFI bios is provided and acpi table cannot be used also. Here acpi ged pm register is exposed with FDT table, it is compatbile with syscon method in FDT table, only that acpi ged pm register is accessed with 8-bit mode, rather with 32-bit mode. Signed-off-by: Bibo Mao Reviewed-by: Song Gao Tested-by: Song Gao Message-Id: <20240918014206.2165821-3-maob...@loongson.cn> Signed-off-by: Song Gao --- hw/loongarch/virt.c | 39 +++ 1 file changed, 39 insertions(+) diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index ddd886f69b..9a635d1d3d 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -280,6 +280,44 @@ static void fdt_add_rtc_node(LoongArchVirtMachineState *lvms, g_free(nodename); } +static void fdt_add_ged_reset(LoongArchVirtMachineState *lvms) +{ +char *name; +uint32_t ged_handle; +MachineState *ms = MACHINE(lvms); +hwaddr base = VIRT_GED_REG_ADDR; +hwaddr size = ACPI_GED_REG_COUNT; + +ged_handle = qemu_fdt_alloc_phandle(ms->fdt); +name = g_strdup_printf("/ged@%" PRIx64, base); +qemu_fdt_add_subnode(ms->fdt, name); +qemu_fdt_setprop_string(ms->fdt, name, "compatible", "syscon"); +qemu_fdt_setprop_cells(ms->fdt, name, "reg", 0x0, base, 0x0, size); +/* 8 bit registers */ +qemu_fdt_setprop_cell(ms->fdt, name, "reg-shift", 0); +qemu_fdt_setprop_cell(ms->fdt, name, "reg-io-width", 1); +qemu_fdt_setprop_cell(ms->fdt, name, "phandle", ged_handle); +ged_handle = qemu_fdt_get_phandle(ms->fdt, name); +g_free(name); + +name = g_strdup_printf("/reboot"); +qemu_fdt_add_subnode(ms->fdt, name); +qemu_fdt_setprop_string(ms->fdt, name, "compatible", "syscon-reboot"); +qemu_fdt_setprop_cell(ms->fdt, name, "regmap", ged_handle); +qemu_fdt_setprop_cell(ms->fdt, name, "offset", ACPI_GED_REG_RESET); +qemu_fdt_setprop_cell(ms->fdt, name, "value", ACPI_GED_RESET_VALUE); +g_free(name); + +name = g_strdup_printf("/poweroff"); +qemu_fdt_add_subnode(ms->fdt, name); +qemu_fdt_setprop_string(ms->fdt, name, "compatible", "syscon-poweroff"); +qemu_fdt_setprop_cell(ms->fdt, name, "regmap", ged_handle); +qemu_fdt_setprop_cell(ms->fdt, name, "offset", ACPI_GED_REG_SLEEP_CTL); +qemu_fdt_setprop_cell(ms->fdt, name, "value", ACPI_GED_SLP_EN | + (ACPI_GED_SLP_TYP_S5 << ACPI_GED_SLP_TYP_POS)); +g_free(name); +} + static void fdt_add_uart_node(LoongArchVirtMachineState *lvms, uint32_t *pch_pic_phandle, hwaddr base, int irq, bool chosen) @@ -737,6 +775,7 @@ static void virt_devices_init(DeviceState *pch_pic, qdev_get_gpio_in(pch_pic, VIRT_RTC_IRQ - VIRT_GSI_BASE)); fdt_add_rtc_node(lvms, pch_pic_phandle); +fdt_add_ged_reset(lvms); /* acpi ged */ lvms->acpi_ged = create_acpi_ged(pch_pic, lvms); -- 2.34.1
[PULL 3/5] target/loongarch: Avoid bits shift exceeding width of bool type
From: Bibo Mao Variable env->cf[i] is defined as bool type, it is treated as int type with shift operation. However the max possible width is 56 for the shift operation, exceeding the width of int type. And there is existing api read_fcc() which is converted to u64 type with bitwise shift, it can be used to dump fp registers into coredump note segment. Resolves: Coverity CID 1561133 Signed-off-by: Bibo Mao Reviewed-by: Richard Henderson Message-Id: <20240914064645.2099169-1-maob...@loongson.cn> Signed-off-by: Song Gao --- target/loongarch/arch_dump.c | 6 +- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/target/loongarch/arch_dump.c b/target/loongarch/arch_dump.c index 4986db970e..d9e1120333 100644 --- a/target/loongarch/arch_dump.c +++ b/target/loongarch/arch_dump.c @@ -97,11 +97,7 @@ static int loongarch_write_elf64_fprpreg(WriteCoreDumpFunction f, loongarch_note_init(¬e, s, "CORE", 5, NT_PRFPREG, sizeof(note.fpu)); note.fpu.fcsr = cpu_to_dump64(s, env->fcsr0); - -for (i = 0; i < 8; i++) { -note.fpu.fcc |= env->cf[i] << (8 * i); -} -note.fpu.fcc = cpu_to_dump64(s, note.fpu.fcc); +note.fpu.fcc = cpu_to_dump64(s, read_fcc(env)); for (i = 0; i < 32; ++i) { note.fpu.fpr[i] = cpu_to_dump64(s, env->fpr[i].vreg.UD[0]); -- 2.34.1
[PULL 4/5] hw/loongarch/virt: Remove unnecessary 'cpu.h' inclusion
From: Philippe Mathieu-Daudé Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Song Gao Reviewed-by: Thomas Huth Message-Id: <20240927213254.17552-2-phi...@linaro.org> Signed-off-by: Song Gao --- include/hw/loongarch/virt.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h index c373e48f27..9ba47793ef 100644 --- a/include/hw/loongarch/virt.h +++ b/include/hw/loongarch/virt.h @@ -8,7 +8,6 @@ #ifndef HW_LOONGARCH_H #define HW_LOONGARCH_H -#include "target/loongarch/cpu.h" #include "hw/boards.h" #include "qemu/queue.h" #include "hw/block/flash.h" -- 2.34.1
[PULL 0/5] loongarch-to-apply queue
The following changes since commit f774a677507966222624a9b2859f06ede7608100: Merge tag 'pull-target-arm-20241015-1' of https://git.linaro.org/people/pmaydell/qemu-arm into staging (2024-10-15 15:18:22 +0100) are available in the Git repository at: https://gitlab.com/gaosong/qemu.git tags/pull-loongarch-20241016 for you to fetch changes up to e376c2d87cbbad3483adcd5e827bdd144edb7d2c: hw/loongarch/fw_cfg: Build in common_ss[] (2024-10-16 16:06:07 +0800) pull-loongarch-20241016 Bibo Mao (3): acpi: ged: Add macro for acpi sleep control register hw/loongarch/virt: Add FDT table support with acpi ged pm register target/loongarch: Avoid bits shift exceeding width of bool type Philippe Mathieu-Daudé (2): hw/loongarch/virt: Remove unnecessary 'cpu.h' inclusion hw/loongarch/fw_cfg: Build in common_ss[] hw/acpi/generic_event_device.c | 6 +++--- hw/loongarch/meson.build | 2 +- hw/loongarch/virt.c| 39 ++ include/hw/acpi/generic_event_device.h | 7 -- include/hw/loongarch/virt.h| 1 - target/loongarch/arch_dump.c | 6 +- 6 files changed, 49 insertions(+), 12 deletions(-)
[PATCH v2 3/5] target/loongarch: Add do_fill_tlb_entry()
do_fill_tlb_entry is used to fill a tlb entry. Signed-off-by: Song Gao --- target/loongarch/tcg/tlb_helper.c | 43 ++- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c index 3c3452b316..bc6d708484 100644 --- a/target/loongarch/tcg/tlb_helper.c +++ b/target/loongarch/tcg/tlb_helper.c @@ -160,11 +160,33 @@ static void invalidate_tlb(CPULoongArchState *env, int index) invalidate_tlb_entry(env, index); } -static void fill_tlb_entry(CPULoongArchState *env, int index) +static void do_fill_tlb_entry(CPULoongArchState *env, uint64_t vppn, + uint64_t lo0, uint64_t lo1, int index, uint8_t ps) { LoongArchTLB *tlb = &env->tlb[index]; +uint16_t asid; + +if (ps == 0) { +qemu_log_mask(CPU_LOG_MMU, "page size is 0\n"); +} + +/* Only MTLB has the ps fields */ +if (index >= LOONGARCH_STLB) { +tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, PS, ps); +} + +tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, VPPN, vppn); +tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, E, 1); +asid = FIELD_EX64(env->CSR_ASID, CSR_ASID, ASID); +tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, ASID, asid); + +tlb->tlb_entry0 = lo0; +tlb->tlb_entry1 = lo1; +} + +static void fill_tlb_entry(CPULoongArchState *env, int index) +{ uint64_t lo0, lo1, csr_vppn; -uint16_t csr_asid; uint8_t csr_ps; if (FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) { @@ -187,22 +209,7 @@ static void fill_tlb_entry(CPULoongArchState *env, int index) lo1 = env->CSR_TLBELO1; } -if (csr_ps == 0) { -qemu_log_mask(CPU_LOG_MMU, "page size is 0\n"); -} - -/* Only MTLB has the ps fields */ -if (index >= LOONGARCH_STLB) { -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); -tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, ASID, csr_asid); - -tlb->tlb_entry0 = lo0; -tlb->tlb_entry1 = lo1; +do_fill_tlb_entry(env, csr_vppn, lo0, lo1, index, csr_ps); } /* Return an random value between low and high */ -- 2.33.0
[PATCH v2 0/5] LoongArch/tcg: Add hardware page table walker support
Loongson-3A6000 and newer processors have hardware page table walker (PTW) support. PTW can handle all fastpaths of PIL/PIS/PIF/PIE exceptions by hardware. V2: - Remove the '21' magic value, patch1; - Add a flag is_debug for debug access, patch5; - Use qatomic_cmpxchg to change the new pte_val, patch5. Song Gao (5): target/loongarch: Add a new cpu_type la664 target/loongarch: Add do_lddir/ldpte() target/loongarch: Add do_fill_tlb_entry() target/loongarch: Add get_random_tlb_index() target/loongarch/tcg: Add hardware page table walker support target/loongarch/cpu-csr.h| 3 + target/loongarch/cpu.c| 51 -- target/loongarch/cpu.h| 1 + target/loongarch/cpu_helper.c | 26 ++- target/loongarch/internals.h | 4 +- target/loongarch/tcg/tlb_helper.c | 277 -- 6 files changed, 293 insertions(+), 69 deletions(-) -- 2.33.0
[PATCH v2 5/5] target/loongarch/tcg: Add hardware page table walker support
Add hardware page table walker (HPTW) feature for la664. Set CPUCFG2.HPTW = 1 to indicate that HPTW is implemented on this CPU. Set PWCH.HPTW_EN = 1 to enable HPTW. Signed-off-by: Song Gao --- target/loongarch/cpu-csr.h| 3 + target/loongarch/cpu.c| 1 + target/loongarch/cpu.h| 1 + target/loongarch/cpu_helper.c | 26 +- target/loongarch/internals.h | 4 +- target/loongarch/tcg/tlb_helper.c | 147 +- 6 files changed, 176 insertions(+), 6 deletions(-) diff --git a/target/loongarch/cpu-csr.h b/target/loongarch/cpu-csr.h index 0834e91f30..1aa015dc44 100644 --- a/target/loongarch/cpu-csr.h +++ b/target/loongarch/cpu-csr.h @@ -68,6 +68,8 @@ FIELD(TLBENTRY, PLV, 2, 2) FIELD(TLBENTRY, MAT, 4, 2) FIELD(TLBENTRY, G, 6, 1) FIELD(TLBENTRY, HUGE, 6, 1) +FIELD(TLBENTRY, PRESENT, 7, 1) +FIELD(TLBENTRY, WRITE, 8, 1) FIELD(TLBENTRY, HGLOBAL, 12, 1) FIELD(TLBENTRY, LEVEL, 13, 2) FIELD(TLBENTRY_32, PPN, 8, 24) @@ -103,6 +105,7 @@ FIELD(CSR_PWCH, DIR3_BASE, 0, 6) FIELD(CSR_PWCH, DIR3_WIDTH, 6, 6) FIELD(CSR_PWCH, DIR4_BASE, 12, 6) FIELD(CSR_PWCH, DIR4_WIDTH, 18, 6) +FIELD(CSR_PWCH, HPTW_EN, 24, 1) #define LOONGARCH_CSR_STLBPS 0x1e /* Stlb page size */ FIELD(CSR_STLBPS, PS, 0, 5) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index d55b4110a9..9dbf2ce67b 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -476,6 +476,7 @@ static void loongarch_la664_initfn(Object *obj) env->cpucfg[0] = 0x14d000; /* PRID */ loongarch_common_initfn(env, obj); +env->cpucfg[2] = FIELD_DP32(env->cpucfg[2], CPUCFG2, HPTW, 1); } static void loongarch_la464_initfn(Object *obj) diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index 6c41fafb70..84f92507d6 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -155,6 +155,7 @@ FIELD(CPUCFG2, LBT_ARM, 19, 1) FIELD(CPUCFG2, LBT_MIPS, 20, 1) FIELD(CPUCFG2, LSPW, 21, 1) FIELD(CPUCFG2, LAM, 22, 1) +FIELD(CPUCFG2, HPTW, 24, 1) /* cpucfg[3] bits */ FIELD(CPUCFG3, CCDMA, 0, 1) diff --git a/target/loongarch/cpu_helper.c b/target/loongarch/cpu_helper.c index 580362ac3e..35c95e9a27 100644 --- a/target/loongarch/cpu_helper.c +++ b/target/loongarch/cpu_helper.c @@ -178,10 +178,11 @@ static hwaddr dmw_va2pa(CPULoongArchState *env, target_ulong va, int get_physical_address(CPULoongArchState *env, hwaddr *physical, int *prot, target_ulong address, - MMUAccessType access_type, int mmu_idx) + MMUAccessType access_type, int mmu_idx, bool is_debug) { int user_mode = mmu_idx == MMU_USER_IDX; int kernel_mode = mmu_idx == MMU_KERNEL_IDX; +int ret; uint32_t plv, base_c, base_v; int64_t addr_high; uint8_t da = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, DA); @@ -221,8 +222,25 @@ int get_physical_address(CPULoongArchState *env, hwaddr *physical, } /* Mapped address */ -return loongarch_map_address(env, physical, prot, address, - access_type, mmu_idx); +ret = loongarch_map_address(env, physical, prot, address, +access_type, mmu_idx); +#ifdef CONFIG_TCG +if (!FIELD_EX32(env->cpucfg[2], CPUCFG2, HPTW)) { +return ret; +} + +if (!FIELD_EX32(env->CSR_PWCH, CSR_PWCH, HPTW_EN)) { +return ret; +} + +if (do_page_walk(env, address, access_type, ret, physical, is_debug)) { +if (!is_debug) { +ret = loongarch_map_address(env, physical, prot, address, +access_type, mmu_idx); +} +} +#endif +return ret; } hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) @@ -232,7 +250,7 @@ hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) int prot; if (get_physical_address(env, &phys_addr, &prot, addr, MMU_DATA_LOAD, - cpu_mmu_index(cs, false)) != 0) { + cpu_mmu_index(cs, false), true) != 0) { return -1; } return phys_addr; diff --git a/target/loongarch/internals.h b/target/loongarch/internals.h index 1a02427627..fc8357914b 100644 --- a/target/loongarch/internals.h +++ b/target/loongarch/internals.h @@ -56,13 +56,15 @@ bool loongarch_tlb_search(CPULoongArchState *env, target_ulong vaddr, int *index); int get_physical_address(CPULoongArchState *env, hwaddr *physical, int *prot, target_ulong address, - MMUAccessType access_type, int mmu_idx); + MMUAccessType access_type, int mmu_idx, bool is_debug); hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); #ifdef CONFIG_TCG bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size, MMUAccessType access_type, int mmu_idx,
[PATCH v2 1/5] target/loongarch: Add a new cpu_type la664
Add a new LoongArch cpu type la664. The la664 has many new features, such as new atomic instructions, hardware page table walk, etc. We will implement them later. Signed-off-by: Song Gao --- target/loongarch/cpu.c | 50 +- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 7212fb5f8f..d55b4110a9 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -374,20 +374,11 @@ static int loongarch_cpu_mmu_index(CPUState *cs, bool ifetch) return MMU_DA_IDX; } -static void loongarch_la464_initfn(Object *obj) +static void loongarch_common_initfn(CPULoongArchState *env, Object *obj) { -LoongArchCPU *cpu = LOONGARCH_CPU(obj); -CPULoongArchState *env = &cpu->env; -int i; - -for (i = 0; i < 21; i++) { -env->cpucfg[i] = 0x0; -} - -cpu->dtb_compatible = "loongarch,Loongson-3A5000"; -env->cpucfg[0] = 0x14c010; /* PRID */ +uint32_t data; -uint32_t data = 0; +data = 0; data = FIELD_DP32(data, CPUCFG1, ARCH, 2); data = FIELD_DP32(data, CPUCFG1, PGMMU, 1); data = FIELD_DP32(data, CPUCFG1, IOCSR, 1); @@ -472,14 +463,42 @@ static void loongarch_la464_initfn(Object *obj) loongarch_cpu_post_init(obj); } -static void loongarch_la132_initfn(Object *obj) +static void loongarch_la664_initfn(Object *obj) { LoongArchCPU *cpu = LOONGARCH_CPU(obj); CPULoongArchState *env = &cpu->env; -int i; +for (unsigned i = 0; i < ARRAY_SIZE(env->cpucfg); i++) { +env->cpucfg[i] = 0x0; +} + +cpu->dtb_compatible = "loongarch,Loongson-3A6000"; +env->cpucfg[0] = 0x14d000; /* PRID */ + +loongarch_common_initfn(env, obj); +} + +static void loongarch_la464_initfn(Object *obj) +{ +LoongArchCPU *cpu = LOONGARCH_CPU(obj); +CPULoongArchState *env = &cpu->env; + +for (unsigned i = 0; i < ARRAY_SIZE(env->cpucfg); i++) { +env->cpucfg[i] = 0x0; +} + +cpu->dtb_compatible = "loongarch,Loongson-3A5000"; +env->cpucfg[0] = 0x14c010; /* PRID */ + +loongarch_common_initfn(env, obj); +} + +static void loongarch_la132_initfn(Object *obj) +{ +LoongArchCPU *cpu = LOONGARCH_CPU(obj); +CPULoongArchState *env = &cpu->env; -for (i = 0; i < 21; i++) { +for (unsigned i = 0; i < ARRAY_SIZE(env->cpucfg); i++) { env->cpucfg[i] = 0x0; } @@ -872,6 +891,7 @@ static const TypeInfo loongarch_cpu_type_infos[] = { .abstract = true, .class_init = loongarch64_cpu_class_init, }, +DEFINE_LOONGARCH_CPU_TYPE(64, "la664", loongarch_la664_initfn), DEFINE_LOONGARCH_CPU_TYPE(64, "la464", loongarch_la464_initfn), DEFINE_LOONGARCH_CPU_TYPE(32, "la132", loongarch_la132_initfn), DEFINE_LOONGARCH_CPU_TYPE(64, "max", loongarch_max_initfn), -- 2.33.0
[PATCH v2 4/5] target/loongarch: Add get_random_tlb_index()
get_random_tlb_index() is used to get a random tlb index. Signed-off-by: Song Gao --- target/loongarch/tcg/tlb_helper.c | 34 +-- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c index bc6d708484..463e9be7f2 100644 --- a/target/loongarch/tcg/tlb_helper.c +++ b/target/loongarch/tcg/tlb_helper.c @@ -291,19 +291,12 @@ void helper_tlbwr(CPULoongArchState *env) fill_tlb_entry(env, index); } -void helper_tlbfill(CPULoongArchState *env) +static int get_random_tlb_index(CPULoongArchState *env, +uint64_t entryhi, uint16_t pagesize) { -uint64_t address, entryhi; +uint64_t address; +uint16_t stlb_ps; int index, set, stlb_idx; -uint16_t pagesize, stlb_ps; - -if (FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) { -entryhi = env->CSR_TLBREHI; -pagesize = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI, PS); -} else { -entryhi = env->CSR_TLBEHI; -pagesize = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, PS); -} stlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS); @@ -323,6 +316,25 @@ void helper_tlbfill(CPULoongArchState *env) index = get_random_tlb(LOONGARCH_STLB, LOONGARCH_TLB_MAX - 1); } +return index; +} + +void helper_tlbfill(CPULoongArchState *env) +{ +uint64_t entryhi; +uint16_t pagesize; +int index; + +if (FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) { +entryhi = env->CSR_TLBREHI; +pagesize = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI, PS); +} else { +entryhi = env->CSR_TLBEHI; +pagesize = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, PS); +} + +index = get_random_tlb_index(env, entryhi, pagesize); + invalidate_tlb(env, index); fill_tlb_entry(env, index); } -- 2.33.0
[PATCH v2 2/5] target/loongarch: Add do_lddir/ldpte()
do_lddir is used for accessing directory entries during page table walking, do_ldpte is used for page table entry accesses during page table walking. Signed-off-by: Song Gao --- target/loongarch/tcg/tlb_helper.c | 53 --- 1 file changed, 34 insertions(+), 19 deletions(-) diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c index 97f38fc391..3c3452b316 100644 --- a/target/loongarch/tcg/tlb_helper.c +++ b/target/loongarch/tcg/tlb_helper.c @@ -507,11 +507,11 @@ bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size, cpu_loop_exit_restore(cs, retaddr); } -target_ulong helper_lddir(CPULoongArchState *env, target_ulong base, - target_ulong level, uint32_t mem_idx) +static target_ulong do_lddir(CPULoongArchState *env, target_ulong base, + target_ulong badvaddr, target_ulong level) { CPUState *cs = env_cpu(env); -target_ulong badvaddr, index, phys, ret; +target_ulong index, phys, ret; int shift; uint64_t dir_base, dir_width; @@ -535,7 +535,6 @@ target_ulong helper_lddir(CPULoongArchState *env, target_ulong base, } } -badvaddr = env->CSR_TLBRBADV; base = base & TARGET_PHYS_MASK; /* 0:64bit, 1:128bit, 2:192bit, 3:256bit */ @@ -549,11 +548,18 @@ target_ulong helper_lddir(CPULoongArchState *env, target_ulong base, return ret; } -void helper_ldpte(CPULoongArchState *env, target_ulong base, target_ulong odd, - uint32_t mem_idx) +target_ulong helper_lddir(CPULoongArchState *env, target_ulong base, + target_ulong level, uint32_t mem_idx) +{ +return do_lddir(env, base, env->CSR_TLBRBADV, level); +} + +static void do_ldpte(CPULoongArchState *env, target_ulong base, + target_ulong badvaddr, target_ulong *ptval0, + target_ulong *ptval1, target_ulong *ps) { CPUState *cs = env_cpu(env); -target_ulong phys, tmp0, ptindex, ptoffset0, ptoffset1, ps, badv; +target_ulong ptindex, ptoffset0, ptoffset1, phys0, phys1; int shift; uint64_t ptbase = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTBASE); uint64_t ptwidth = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTWIDTH); @@ -584,34 +590,43 @@ void helper_ldpte(CPULoongArchState *env, target_ulong base, target_ulong odd, base = FIELD_DP64(base, TLBENTRY, G, 1); } -ps = dir_base + dir_width - 1; +*ps = dir_base + dir_width - 1; /* * Huge pages are evenly split into parity pages * when loaded into the tlb, * so the tlb page size needs to be divided by 2. */ -tmp0 = base; -if (odd) { -tmp0 += MAKE_64BIT_MASK(ps, 1); -} +*ptval0 = base; +*ptval1 = base + MAKE_64BIT_MASK(*ps, 1); } else { /* 0:64bit, 1:128bit, 2:192bit, 3:256bit */ shift = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTEWIDTH); shift = (shift + 1) * 3; -badv = env->CSR_TLBRBADV; -ptindex = (badv >> ptbase) & ((1 << ptwidth) - 1); -ptindex = ptindex & ~0x1; /* clear bit 0 */ +ptindex = (badvaddr >> ptbase) & ((1 << ptwidth) - 1); +ptindex = ptindex & ~0x1; /* clear bit 0 */ ptoffset0 = ptindex << shift; ptoffset1 = (ptindex + 1) << shift; -phys = base | (odd ? ptoffset1 : ptoffset0); -tmp0 = ldq_phys(cs->as, phys) & TARGET_PHYS_MASK; -ps = ptbase; +phys0 = base | ptoffset0; +phys1 = base | ptoffset1; +*ptval0 = ldq_phys(cs->as, phys0) & TARGET_PHYS_MASK; +*ptval1 = ldq_phys(cs->as, phys1) & TARGET_PHYS_MASK; +*ps = ptbase; } +return; +} + +void helper_ldpte(CPULoongArchState *env, target_ulong base, target_ulong odd, + uint32_t mem_idx) +{ +target_ulong tmp0, tmp1, ps; + +do_ldpte(env, base, env->CSR_TLBRBADV, &tmp0, &tmp1, &ps); + if (odd) { -env->CSR_TLBRELO1 = tmp0; +env->CSR_TLBRELO1 = tmp1; } else { env->CSR_TLBRELO0 = tmp0; } -- 2.33.0
[PULL 7/7] hw/loongarch/fw_cfg: Build in common_ss[]
From: Philippe Mathieu-Daudé Nothing in LoongArch fw_cfg.c requires target specific definitions. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Song Gao Message-Id: <20240927213254.17552-3-phi...@linaro.org> Signed-off-by: Song Gao --- hw/loongarch/meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/loongarch/meson.build b/hw/loongarch/meson.build index bce7ebac97..005f017e21 100644 --- a/hw/loongarch/meson.build +++ b/hw/loongarch/meson.build @@ -1,8 +1,8 @@ loongarch_ss = ss.source_set() loongarch_ss.add(files( -'fw_cfg.c', 'boot.c', )) +common_ss.add(when: 'CONFIG_LOONGARCH_VIRT', if_true: files('fw_cfg.c')) loongarch_ss.add(when: 'CONFIG_LOONGARCH_VIRT', if_true: files('virt.c')) loongarch_ss.add(when: 'CONFIG_ACPI', if_true: files('acpi-build.c')) -- 2.34.1
[PULL 5/7] target/loongarch: Avoid bits shift exceeding width of bool type
From: Bibo Mao Variable env->cf[i] is defined as bool type, it is treated as int type with shift operation. However the max possible width is 56 for the shift operation, exceeding the width of int type. And there is existing api read_fcc() which is converted to u64 type with bitwise shift, it can be used to dump fp registers into coredump note segment. Resolves: Coverity CID 1561133 Signed-off-by: Bibo Mao Reviewed-by: Richard Henderson Message-Id: <20240914064645.2099169-1-maob...@loongson.cn> Signed-off-by: Song Gao --- target/loongarch/arch_dump.c | 6 +- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/target/loongarch/arch_dump.c b/target/loongarch/arch_dump.c index 4986db970e..d9e1120333 100644 --- a/target/loongarch/arch_dump.c +++ b/target/loongarch/arch_dump.c @@ -97,11 +97,7 @@ static int loongarch_write_elf64_fprpreg(WriteCoreDumpFunction f, loongarch_note_init(¬e, s, "CORE", 5, NT_PRFPREG, sizeof(note.fpu)); note.fpu.fcsr = cpu_to_dump64(s, env->fcsr0); - -for (i = 0; i < 8; i++) { -note.fpu.fcc |= env->cf[i] << (8 * i); -} -note.fpu.fcc = cpu_to_dump64(s, note.fpu.fcc); +note.fpu.fcc = cpu_to_dump64(s, read_fcc(env)); for (i = 0; i < 32; ++i) { note.fpu.fpr[i] = cpu_to_dump64(s, env->fpr[i].vreg.UD[0]); -- 2.34.1
[PULL 4/7] hw/loongarch/boot: Rework boot code generation
From: Jiaxun Yang Use stl_p to write instructions so that host endian conversion will be performed. Replace mailbox read/write on LoongArch32 systems with 32bit IOCSR instructions to prevent illegal instructions. Signed-off-by: Jiaxun Yang Reviewed-by: Song Gao Message-Id: <20240914-loongarch-booting-v1-2-1517cae11...@flygoat.com> Signed-off-by: Song Gao --- hw/loongarch/boot.c | 107 1 file changed, 59 insertions(+), 48 deletions(-) diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c index 4d01c01594..5a1cc5b79b 100644 --- a/hw/loongarch/boot.c +++ b/hw/loongarch/boot.c @@ -22,53 +22,64 @@ unsigned memmap_entries; ram_addr_t initrd_offset; uint64_t initrd_size; -static const unsigned int slave_boot_code[] = { - /* Configure reset ebase.*/ -0x0400302c, /* csrwr $t0, LOONGARCH_CSR_EENTRY */ - - /* Disable interrupt.*/ -0x0380100c, /* ori$t0, $zero,0x4 */ -0x04000180, /* csrxchg$zero, $t0, LOONGARCH_CSR_CRMD */ - - /* Clear mailbox.*/ -0x142d, /* lu12i.w$t1, 1(0x1)*/ -0x038081ad, /* ori$t1, $t1, CORE_BUF_20 */ -0x06481da0, /* iocsrwr.d $zero, $t1 */ - - /* Enable IPI interrupt. */ -0x142c, /* lu12i.w$t0, 1(0x1)*/ -0x0400118c, /* csrxchg$t0, $t0, LOONGARCH_CSR_ECFG */ -0x02fffc0c, /* addi.d $t0, $r0,-1(0xfff) */ -0x142d, /* lu12i.w$t1, 1(0x1)*/ -0x038011ad, /* ori$t1, $t1, CORE_EN_OFF */ -0x064819ac, /* iocsrwr.w $t0, $t1 */ -0x142d, /* lu12i.w$t1, 1(0x1)*/ -0x038081ad, /* ori$t1, $t1, CORE_BUF_20 */ - - /* Wait for wakeup <.L11>: */ -0x06488000, /* idle 0x0*/ -0x0340, /* andi $zero, $zero, 0x0 */ -0x064809ac, /* iocsrrd.w $t0, $t1 */ -0x43fff59f, /* beqz $t0, -12(0x74) # 48 <.L11> */ - - /* Read and clear IPI interrupt. */ -0x142d, /* lu12i.w$t1, 1(0x1)*/ -0x064809ac, /* iocsrrd.w $t0, $t1 */ -0x142d, /* lu12i.w$t1, 1(0x1)*/ -0x038031ad, /* ori$t1, $t1, CORE_CLEAR_OFF */ -0x064819ac, /* iocsrwr.w $t0, $t1 */ - - /* Disable IPI interrupt. */ -0x142c, /* lu12i.w$t0, 1(0x1)*/ -0x04001180, /* csrxchg$zero, $t0, LOONGARCH_CSR_ECFG */ - - /* Read mail buf and jump to specified entry */ -0x142d, /* lu12i.w$t1, 1(0x1)*/ -0x038081ad, /* ori$t1, $t1, CORE_BUF_20 */ -0x06480dac, /* iocsrrd.d $t0, $t1 */ -0x00150181, /* move $ra, $t0 */ -0x4c20, /* jirl $zero, $ra,0 */ -}; +static void generate_secondary_boot_code(void *boot_code, bool is_64bit) +{ +uint32_t *p = boot_code; + +/* Configure reset ebase. */ +stl_p(p++, 0x0400302c); /* csrwr $t0, LOONGARCH_CSR_EENTRY */ + +/* Disable interrupt. */ +stl_p(p++, 0x0380100c); /* ori$t0, $zero,0x4 */ +stl_p(p++, 0x04000180); /* csrxchg$zero, $t0, LOONGARCH_CSR_CRMD */ + +/* Clear mailbox. */ +stl_p(p++, 0x142d); /* lu12i.w$t1, 1(0x1)*/ +stl_p(p++, 0x038081ad); /* ori$t1, $t1, CORE_BUF_20 */ +if (is_64bit) { +stl_p(p++, 0x06481da0); /* iocsrwr.d $zero, $t1 */ +} else { +stl_p(p++, 0x064819a0); /* iocsrwr.w $zero, $t1 */ +} + +/* Enable IPI interrupt. */ +stl_p(p++, 0x142c); /* lu12i.w$t0, 1(0x1)*/ +stl_p(p++, 0x0400118c); /* csrxchg$t0, $t0, LOONGARCH_CSR_ECFG */ +stl_p(p++, 0x02fffc0c); /* addi.d $t0, $r0, -1(0xfff)*/ +stl_p(p++, 0x142d); /* lu12i.w$t1, 1(0x1)*/ +stl_p(p++, 0x038011ad); /* ori$t1, $t1, CORE_EN_OFF */ +stl_p(p++, 0x064819ac); /* iocsrwr.w $t0, $t1 */ +stl_p(p++, 0x142d); /* lu12i.w$t1, 1(0x1)*/ +stl_p(p++, 0x038081ad); /* ori$t1, $t1, CORE_BUF_20 */ + +/* Wait for wakeup <.L11>: */ +stl_p(p++, 0x06488000); /* idle 0x0*/ +stl_p(p++, 0x0340); /* andi $zero, $zero, 0x0 */ +stl_p(p++, 0x064809ac); /* iocsrrd.w $t0, $t1
[PULL 3/7] hw/loongarch/boot: Refactor EFI booting protocol generation
From: Jiaxun Yang Refector EFI style booting data structure generation to support 32bit EFI variant on LoongArch32 CPU. All data structs are filled with padding members if necessary and marked as QEMU_PACKED to avoid host ABI alignment impact. Host endian is being cared as well. It also fixed various problems in old implementation such as null pointer on empty string, memory desc map_size not set, incorrect memory map definition and so on. Signed-off-by: Jiaxun Yang Reviewed-by: Song Gao Message-Id: <20240914-loongarch-booting-v1-1-1517cae11...@flygoat.com> Signed-off-by: Song Gao --- hw/loongarch/boot.c | 220 include/hw/loongarch/boot.h | 106 + 2 files changed, 237 insertions(+), 89 deletions(-) diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c index cb668703bd..4d01c01594 100644 --- a/hw/loongarch/boot.c +++ b/hw/loongarch/boot.c @@ -5,6 +5,7 @@ * Copyright (c) 2023 Loongson Technology Corporation Limited */ +#include #include "qemu/osdep.h" #include "qemu/units.h" #include "target/loongarch/cpu.h" @@ -31,7 +32,7 @@ static const unsigned int slave_boot_code[] = { /* Clear mailbox.*/ 0x142d, /* lu12i.w$t1, 1(0x1)*/ -0x038081ad, /* ori$t1, $t1, CORE_BUF_20 */ +0x038081ad, /* ori$t1, $t1, CORE_BUF_20 */ 0x06481da0, /* iocsrwr.d $zero, $t1 */ /* Enable IPI interrupt. */ @@ -74,88 +75,163 @@ static inline void *guidcpy(void *dst, const void *src) return memcpy(dst, src, sizeof(efi_guid_t)); } -static void init_efi_boot_memmap(struct efi_system_table *systab, - void *p, void *start) +static void efi_hdr_crc32(efi_table_hdr_t *hdr) { -unsigned i; -struct efi_boot_memmap *boot_memmap = p; -efi_guid_t tbl_guid = LINUX_EFI_BOOT_MEMMAP_GUID; - -/* efi_configuration_table 1 */ -guidcpy(&systab->tables[0].guid, &tbl_guid); -systab->tables[0].table = (struct efi_configuration_table *)(p - start); -systab->nr_tables = 1; - -boot_memmap->desc_size = sizeof(efi_memory_desc_t); -boot_memmap->desc_ver = 1; -boot_memmap->map_size = 0; +uint32_t val; -efi_memory_desc_t *map = p + sizeof(struct efi_boot_memmap); -for (i = 0; i < memmap_entries; i++) { -map = (void *)boot_memmap + sizeof(*map); -map[i].type = memmap_table[i].type; -map[i].phys_addr = ROUND_UP(memmap_table[i].address, 64 * KiB); -map[i].num_pages = ROUND_DOWN(memmap_table[i].address + -memmap_table[i].length - map[i].phys_addr, 64 * KiB); -p += sizeof(efi_memory_desc_t); -} +hdr->crc32 = 0; +val = crc32(0, (const unsigned char *)hdr, hdr->headersize); +hdr->crc32 = cpu_to_le32(val); } -static void init_efi_initrd_table(struct efi_system_table *systab, - void *p, void *start) +static void init_efi_vendor_string(void **p) { -efi_guid_t tbl_guid = LINUX_EFI_INITRD_MEDIA_GUID; -struct efi_initrd *initrd_table = p; +uint16_t *vendor_str = *p; -/* efi_configuration_table 2 */ -guidcpy(&systab->tables[1].guid, &tbl_guid); -systab->tables[1].table = (struct efi_configuration_table *)(p - start); -systab->nr_tables = 2; +/* QEMU in UTF16-LE */ +stw_le_p(vendor_str++, 0x0051); /* Q */ +stw_le_p(vendor_str++, 0x0045); /* E */ +stw_le_p(vendor_str++, 0x004D); /* M */ +stw_le_p(vendor_str++, 0x0055); /* U */ +stw_le_p(vendor_str++, 0x); /* \0 */ -initrd_table->base = initrd_offset; -initrd_table->size = initrd_size; +*p = vendor_str; +*p = QEMU_ALIGN_PTR_UP(*p, sizeof(target_long)); } -static void init_efi_fdt_table(struct efi_system_table *systab) +static void memmap_write_descs(efi_memory_desc_t *map) { -efi_guid_t tbl_guid = DEVICE_TREE_GUID; - -/* efi_configuration_table 3 */ -guidcpy(&systab->tables[2].guid, &tbl_guid); -systab->tables[2].table = (void *)FDT_BASE; -systab->nr_tables = 3; -} - -static void init_systab(struct loongarch_boot_info *info, void *p, void *start) -{ -void *bp_tables_start; -struct efi_system_table *systab = p; +int i; -info->a2 = p - start; +for (i = 0; i < memmap_entries; i++) { +uint32_t efi_type; +hwaddr start = memmap_table[i].address; +hwaddr end = memmap_table[i].address + memmap_table[i].length; + +switch (memmap_table[i].type) { +case MEMMAP_TYPE_MEMORY: +efi_type = EFI_CONVENTIONAL_MEMORY; +break; +case MEMMAP_TYPE_RESERVED: +efi_type = EFI_RESERVED_TYPE; +break; +case MEMMAP_TYPE_ACPI: +efi_type =
[PULL 6/7] hw/loongarch/virt: Remove unnecessary 'cpu.h' inclusion
From: Philippe Mathieu-Daudé Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Song Gao Message-Id: <20240927213254.17552-2-phi...@linaro.org> Signed-off-by: Song Gao --- include/hw/loongarch/virt.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h index c373e48f27..9ba47793ef 100644 --- a/include/hw/loongarch/virt.h +++ b/include/hw/loongarch/virt.h @@ -8,7 +8,6 @@ #ifndef HW_LOONGARCH_H #define HW_LOONGARCH_H -#include "target/loongarch/cpu.h" #include "hw/boards.h" #include "qemu/queue.h" #include "hw/block/flash.h" -- 2.34.1
[PULL 0/7] loongarch-to-apply queue
The following changes since commit 3b14a767eaca3df5534a162851f04787b363670e: Merge tag 'qemu-openbios-20240924' of https://github.com/mcayland/qemu into staging (2024-09-28 12:34:44 +0100) are available in the Git repository at: https://gitlab.com/gaosong/qemu.git tags/pull-loongarch-20240929 for you to fetch changes up to f7c8ef7bad7495d8c84b262a8b243efe39e56b13: hw/loongarch/fw_cfg: Build in common_ss[] (2024-09-29 16:22:56 +0800) pull-loongarch-20240929 Bibo Mao (3): acpi: ged: Add macro for acpi sleep control register hw/loongarch/virt: Add FDT table support with acpi ged pm register target/loongarch: Avoid bits shift exceeding width of bool type Jiaxun Yang (2): hw/loongarch/boot: Refactor EFI booting protocol generation hw/loongarch/boot: Rework boot code generation Philippe Mathieu-Daudé (2): hw/loongarch/virt: Remove unnecessary 'cpu.h' inclusion hw/loongarch/fw_cfg: Build in common_ss[] hw/acpi/generic_event_device.c | 6 +- hw/loongarch/boot.c| 321 + hw/loongarch/meson.build | 2 +- hw/loongarch/virt.c| 39 include/hw/acpi/generic_event_device.h | 7 +- include/hw/loongarch/boot.h| 106 +-- include/hw/loongarch/virt.h| 1 - target/loongarch/arch_dump.c | 6 +- 8 files changed, 342 insertions(+), 146 deletions(-)
[PULL 2/7] hw/loongarch/virt: Add FDT table support with acpi ged pm register
From: Bibo Mao ACPI ged is used for power management on LoongArch virt platform, in general it is parsed from acpi table. However if system boot directly from elf kernel, no UEFI bios is provided and acpi table cannot be used also. Here acpi ged pm register is exposed with FDT table, it is compatbile with syscon method in FDT table, only that acpi ged pm register is accessed with 8-bit mode, rather with 32-bit mode. Signed-off-by: Bibo Mao Reviewed-by: Song Gao Tested-by: Song Gao Message-Id: <20240918014206.2165821-3-maob...@loongson.cn> Signed-off-by: Song Gao --- hw/loongarch/virt.c | 39 +++ 1 file changed, 39 insertions(+) diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index 75980b6e3c..6e64e1a856 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -280,6 +280,44 @@ static void fdt_add_rtc_node(LoongArchVirtMachineState *lvms, g_free(nodename); } +static void fdt_add_ged_reset(LoongArchVirtMachineState *lvms) +{ +char *name; +uint32_t ged_handle; +MachineState *ms = MACHINE(lvms); +hwaddr base = VIRT_GED_REG_ADDR; +hwaddr size = ACPI_GED_REG_COUNT; + +ged_handle = qemu_fdt_alloc_phandle(ms->fdt); +name = g_strdup_printf("/ged@%" PRIx64, base); +qemu_fdt_add_subnode(ms->fdt, name); +qemu_fdt_setprop_string(ms->fdt, name, "compatible", "syscon"); +qemu_fdt_setprop_cells(ms->fdt, name, "reg", 0x0, base, 0x0, size); +/* 8 bit registers */ +qemu_fdt_setprop_cell(ms->fdt, name, "reg-shift", 0); +qemu_fdt_setprop_cell(ms->fdt, name, "reg-io-width", 1); +qemu_fdt_setprop_cell(ms->fdt, name, "phandle", ged_handle); +ged_handle = qemu_fdt_get_phandle(ms->fdt, name); +g_free(name); + +name = g_strdup_printf("/reboot"); +qemu_fdt_add_subnode(ms->fdt, name); +qemu_fdt_setprop_string(ms->fdt, name, "compatible", "syscon-reboot"); +qemu_fdt_setprop_cell(ms->fdt, name, "regmap", ged_handle); +qemu_fdt_setprop_cell(ms->fdt, name, "offset", ACPI_GED_REG_RESET); +qemu_fdt_setprop_cell(ms->fdt, name, "value", ACPI_GED_RESET_VALUE); +g_free(name); + +name = g_strdup_printf("/poweroff"); +qemu_fdt_add_subnode(ms->fdt, name); +qemu_fdt_setprop_string(ms->fdt, name, "compatible", "syscon-poweroff"); +qemu_fdt_setprop_cell(ms->fdt, name, "regmap", ged_handle); +qemu_fdt_setprop_cell(ms->fdt, name, "offset", ACPI_GED_REG_SLEEP_CTL); +qemu_fdt_setprop_cell(ms->fdt, name, "value", ACPI_GED_SLP_EN | + (ACPI_GED_SLP_TYP_S5 << ACPI_GED_SLP_TYP_POS)); +g_free(name); +} + static void fdt_add_uart_node(LoongArchVirtMachineState *lvms, uint32_t *pch_pic_phandle, hwaddr base, int irq, bool chosen) @@ -737,6 +775,7 @@ static void virt_devices_init(DeviceState *pch_pic, qdev_get_gpio_in(pch_pic, VIRT_RTC_IRQ - VIRT_GSI_BASE)); fdt_add_rtc_node(lvms, pch_pic_phandle); +fdt_add_ged_reset(lvms); /* acpi ged */ lvms->acpi_ged = create_acpi_ged(pch_pic, lvms); -- 2.34.1
[PULL 1/7] acpi: ged: Add macro for acpi sleep control register
From: Bibo Mao Macro definition is added for acpi sleep control register, ged emulation driver can use the macro , also it can be used in FDT table if ged is exposed with FDT table. Signed-off-by: Bibo Mao Reviewed-by: Igor Mammedov Message-Id: <20240918014206.2165821-2-maob...@loongson.cn> Signed-off-by: Song Gao --- hw/acpi/generic_event_device.c | 6 +++--- include/hw/acpi/generic_event_device.h | 7 +-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c index 15b4c3ebbf..d00f5a6c1c 100644 --- a/hw/acpi/generic_event_device.c +++ b/hw/acpi/generic_event_device.c @@ -201,9 +201,9 @@ static void ged_regs_write(void *opaque, hwaddr addr, uint64_t data, switch (addr) { case ACPI_GED_REG_SLEEP_CTL: -slp_typ = (data >> 2) & 0x07; -slp_en = (data >> 5) & 0x01; -if (slp_en && slp_typ == 5) { +slp_typ = (data >> ACPI_GED_SLP_TYP_POS) & ACPI_GED_SLP_TYP_MASK; +slp_en = !!(data & ACPI_GED_SLP_EN); +if (slp_en && slp_typ == ACPI_GED_SLP_TYP_S5) { qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); } return; diff --git a/include/hw/acpi/generic_event_device.h b/include/hw/acpi/generic_event_device.h index 40af3550b5..d2dac87b4a 100644 --- a/include/hw/acpi/generic_event_device.h +++ b/include/hw/acpi/generic_event_device.h @@ -81,8 +81,11 @@ OBJECT_DECLARE_SIMPLE_TYPE(AcpiGedState, ACPI_GED) /* ACPI_GED_REG_RESET value for reset*/ #define ACPI_GED_RESET_VALUE 0x42 -/* ACPI_GED_REG_SLEEP_CTL.SLP_TYP value for S5 (aka poweroff) */ -#define ACPI_GED_SLP_TYP_S50x05 +/* [ACPI 5.0 Chapter 4.8.3.7] Sleep Control and Status Register */ +#define ACPI_GED_SLP_TYP_POS 0x2 /* SLP_TYPx Bit Offset */ +#define ACPI_GED_SLP_TYP_MASK 0x07 /* SLP_TYPx 3-bit mask */ +#define ACPI_GED_SLP_TYP_S50x05 /* System _S5 State (Soft Off) */ +#define ACPI_GED_SLP_EN0x20 /* SLP_EN write-only bit */ #define GED_DEVICE "GED" #define AML_GED_EVT_REG "EREG" -- 2.34.1
[PULL 6/7] hw/loongarch: virt: pass random seed to fdt
From: "Jason A. Donenfeld" If the FDT contains /chosen/rng-seed, then the Linux RNG will use it to initialize early. Set this using the usual guest random number generation function. This is the same procedure that's done in b91b6b5a2c ("hw/microblaze: pass random seed to fdt"), e4b4f0b71c ("hw/riscv: virt: pass random seed to fdt"), c6fe3e6b4c ("hw/openrisc: virt: pass random seed to fdt"), 67f7e426e5 ("hw/i386: pass RNG seed via setup_data entry"), c287941a4d ("hw/rx: pass random seed to fdt"), 5e19cc68fb ("hw/mips: boston: pass random seed to fdt"), 6b23a67916 ("hw/nios2: virt: pass random seed to fdt") c4b075318e ("hw/ppc: pass random seed to fdt"), and 5242876f37 ("hw/arm/virt: dt: add rng-seed property"). These earlier commits later were amended to rerandomize the RNG seed on snapshot load, but the LoongArch code somehow already does that, despite not having this patch here, presumably due to some lucky copy and pasting. Signed-off-by: Jason A. Donenfeld Reviewed-by: Song Gao Message-Id: <20240905153316.2038769-1-ja...@zx2c4.com> Signed-off-by: Song Gao --- hw/loongarch/virt.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index 76dd29a391..81b1f9486f 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -48,6 +48,7 @@ #include "hw/block/flash.h" #include "hw/virtio/virtio-iommu.h" #include "qemu/error-report.h" +#include "qemu/guest-random.h" static bool virt_is_veiointc_enabled(LoongArchVirtMachineState *lvms) { @@ -303,6 +304,7 @@ static void fdt_add_uart_node(LoongArchVirtMachineState *lvms, static void create_fdt(LoongArchVirtMachineState *lvms) { MachineState *ms = MACHINE(lvms); +uint8_t rng_seed[32]; ms->fdt = create_device_tree(&lvms->fdt_size); if (!ms->fdt) { @@ -316,6 +318,10 @@ static void create_fdt(LoongArchVirtMachineState *lvms) qemu_fdt_setprop_cell(ms->fdt, "/", "#address-cells", 0x2); qemu_fdt_setprop_cell(ms->fdt, "/", "#size-cells", 0x2); qemu_fdt_add_subnode(ms->fdt, "/chosen"); + +/* Pass seed to RNG */ +qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed)); +qemu_fdt_setprop(ms->fdt, "/chosen", "rng-seed", rng_seed, sizeof(rng_seed)); } static void fdt_add_cpu_nodes(const LoongArchVirtMachineState *lvms) -- 2.34.1
[PULL 3/7] target/loongarch/kvm: Add vCPU reset function
From: Bibo Mao KVM provides interface KVM_REG_LOONGARCH_VCPU_RESET to reset vCPU, it can be used to clear internal state about kvm kernel. vCPU reset function is added here for kvm mode. Signed-off-by: Bibo Mao Reviewed-by: Song Gao Message-Id: <20240822022827.2273534-1-maob...@loongson.cn> Signed-off-by: Song Gao --- target/loongarch/cpu.c | 2 +- target/loongarch/kvm/kvm.c | 5 - target/loongarch/kvm/kvm_loongarch.h | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 115922113a..6a569285b8 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -577,7 +577,7 @@ static void loongarch_cpu_reset_hold(Object *obj, ResetType type) memset(env->tlb, 0, sizeof(env->tlb)); #endif if (kvm_enabled()) { -kvm_arch_reset_vcpu(env); +kvm_arch_reset_vcpu(cs); } #endif diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c index e1be6a6959..4786cd5efa 100644 --- a/target/loongarch/kvm/kvm.c +++ b/target/loongarch/kvm/kvm.c @@ -476,9 +476,12 @@ static int kvm_loongarch_put_regs_fp(CPUState *cs) return ret; } -void kvm_arch_reset_vcpu(CPULoongArchState *env) +void kvm_arch_reset_vcpu(CPUState *cs) { +CPULoongArchState *env = cpu_env(cs); + env->mp_state = KVM_MP_STATE_RUNNABLE; +kvm_set_one_reg(cs, KVM_REG_LOONGARCH_VCPU_RESET, 0); } static int kvm_loongarch_get_mpstate(CPUState *cs) diff --git a/target/loongarch/kvm/kvm_loongarch.h b/target/loongarch/kvm/kvm_loongarch.h index d945b6bb82..1051a341ec 100644 --- a/target/loongarch/kvm/kvm_loongarch.h +++ b/target/loongarch/kvm/kvm_loongarch.h @@ -11,6 +11,6 @@ #define QEMU_KVM_LOONGARCH_H int kvm_loongarch_set_interrupt(LoongArchCPU *cpu, int irq, int level); -void kvm_arch_reset_vcpu(CPULoongArchState *env); +void kvm_arch_reset_vcpu(CPUState *cs); #endif -- 2.34.1
[PULL 2/7] hw/loongarch: Remove default enable with VIRTIO_VGA device
From: Bibo Mao For virtio VGA deivce libvirt will select VIRTIO_VGA firstly rather than VIRTIO_GPU, VIRTIO_VGA device supports frame buffer however it requires legacy VGA compatible support. Frame buffer area 0xa -- 0xc conflicts with low memory area 0 -- 0x1000. Here remove default support for VIRTIO_VGA device, VIRTIO_GPU is prefered on LoongArch system. For frame buffer video card support, standard VGA can be used. Signed-off-by: Bibo Mao Reviewed-by: Song Gao Message-Id: <20240823073050.2619484-1-maob...@loongson.cn> Signed-off-by: Song Gao --- hw/loongarch/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig index 0de713a439..9c69170968 100644 --- a/hw/loongarch/Kconfig +++ b/hw/loongarch/Kconfig @@ -5,7 +5,6 @@ config LOONGARCH_VIRT select DEVICE_TREE select PCI select PCI_EXPRESS_GENERIC_BRIDGE -imply VIRTIO_VGA imply PCI_DEVICES imply NVDIMM imply TPM_TIS_SYSBUS -- 2.34.1
[PULL 5/7] hw/loongarch: virt: support up to 4 serial ports
From: "Jason A. Donenfeld" In order to support additional channels of communication using `-serial`, add several serial ports, up to the standard 4 generally supported by the 8250 driver. Fixed: https://lore.kernel.org/all/20240907143439.2792924-1-ja...@zx2c4.com/ Signed-off-by: Jason A. Donenfeld Tested-by: Bibo Mao [gaosong: ACPI uart need't reverse order] Signed-off-by: Song Gao Message-Id: <20240907143439.2792924-1-ja...@zx2c4.com> --- hw/loongarch/acpi-build.c | 23 +++ hw/loongarch/virt.c| 27 +-- include/hw/pci-host/ls7a.h | 9 + 3 files changed, 37 insertions(+), 22 deletions(-) diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c index 2638f87434..04107c84ba 100644 --- a/hw/loongarch/acpi-build.c +++ b/hw/loongarch/acpi-build.c @@ -31,6 +31,7 @@ #include "hw/acpi/generic_event_device.h" #include "hw/pci-host/gpex.h" +#include "sysemu/sysemu.h" #include "sysemu/tpm.h" #include "hw/platform-bus.h" #include "hw/acpi/aml-build.h" @@ -252,23 +253,27 @@ struct AcpiBuildState { MemoryRegion *linker_mr; } AcpiBuildState; -static void build_uart_device_aml(Aml *table) +static void build_uart_device_aml(Aml *table, int index) { Aml *dev; Aml *crs; Aml *pkg0, *pkg1, *pkg2; -uint32_t uart_irq = VIRT_UART_IRQ; - -Aml *scope = aml_scope("_SB"); -dev = aml_device("COMA"); +Aml *scope; +uint32_t uart_irq; +uint64_t base; + +uart_irq = VIRT_UART_IRQ + index; +base = VIRT_UART_BASE + index * VIRT_UART_SIZE; +scope = aml_scope("_SB"); +dev = aml_device("COM%d", index); aml_append(dev, aml_name_decl("_HID", aml_string("PNP0501"))); -aml_append(dev, aml_name_decl("_UID", aml_int(0))); +aml_append(dev, aml_name_decl("_UID", aml_int(index))); aml_append(dev, aml_name_decl("_CCA", aml_int(1))); crs = aml_resource_template(); aml_append(crs, aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED, AML_NON_CACHEABLE, AML_READ_WRITE, - 0, VIRT_UART_BASE, VIRT_UART_BASE + VIRT_UART_SIZE - 1, + 0, base, base + VIRT_UART_SIZE - 1, 0, VIRT_UART_SIZE)); aml_append(crs, aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH, AML_SHARED, &uart_irq, 1)); @@ -401,6 +406,7 @@ static void acpi_dsdt_add_tpm(Aml *scope, LoongArchVirtMachineState *vms) static void build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine) { +int i; Aml *dsdt, *scope, *pkg; LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine); AcpiTable table = { .sig = "DSDT", .rev = 1, .oem_id = lvms->oem_id, @@ -408,7 +414,8 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine) acpi_table_begin(&table, table_data); dsdt = init_aml_allocator(); -build_uart_device_aml(dsdt); +for (i = 0; i < VIRT_UART_COUNT; i++) +build_uart_device_aml(dsdt, i); build_pci_device_aml(dsdt, lvms); build_la_ged_aml(dsdt, machine); build_flash_aml(dsdt, lvms); diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index 29040422aa..76dd29a391 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -280,10 +280,10 @@ static void fdt_add_rtc_node(LoongArchVirtMachineState *lvms, } static void fdt_add_uart_node(LoongArchVirtMachineState *lvms, - uint32_t *pch_pic_phandle) + uint32_t *pch_pic_phandle, hwaddr base, + int irq, bool chosen) { char *nodename; -hwaddr base = VIRT_UART_BASE; hwaddr size = VIRT_UART_SIZE; MachineState *ms = MACHINE(lvms); @@ -292,9 +292,9 @@ static void fdt_add_uart_node(LoongArchVirtMachineState *lvms, qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "ns16550a"); qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", 0x0, base, 0x0, size); qemu_fdt_setprop_cell(ms->fdt, nodename, "clock-frequency", 1); -qemu_fdt_setprop_string(ms->fdt, "/chosen", "stdout-path", nodename); -qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", - VIRT_UART_IRQ - VIRT_GSI_BASE, 0x4); +if (chosen) +qemu_fdt_setprop_string(ms->fdt, "/chosen", "stdout-path", nodename); +qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", irq, 0x4); qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent", *pch_pic_phandle); g_free(nodename); @@ -706,11 +706,18 @@ static void virt_devices_ini
[PULL 1/7] target/loongarch: Add compatible support about VM reboot
From: Bibo Mao With edk2-stable202408 LoongArch UEFI bios, CSR PGD register is set only if its value is equal to zero for boot cpu, it causes reboot issue. Since CSR PGD register is changed with linux kernel, UEFI BIOS cannot use it. Add workaround to clear CSR registers relative with TLB in function loongarch_cpu_reset_hold(), so that VM can reboot with edk2-stable202408 UEFI bios. Signed-off-by: Bibo Mao Reviewed-by: Song Gao Message-Id: <20240827035807.3326293-1-maob...@loongson.cn> Signed-off-by: Song Gao --- target/loongarch/cpu.c | 14 ++ 1 file changed, 14 insertions(+) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 5e85b9dbef..115922113a 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -549,6 +549,20 @@ static void loongarch_cpu_reset_hold(Object *obj, ResetType type) 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; +/* + * 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_PWCL = 0; +env->CSR_PWCH = 0; +env->CSR_STLBPS = 0; +env->CSR_EENTRY = 0; +env->CSR_TLBRENTRY = 0; +env->CSR_MERRENTRY = 0; for (n = 0; n < 4; n++) { env->CSR_DMW[n] = FIELD_DP64(env->CSR_DMW[n], CSR_DMW, PLV0, 0); -- 2.34.1
[PULL 7/7] hw/loongarch: Add acpi SPCR table support
From: Bibo Mao Serial port console redirection table can be used for default serial port selection, like chosen stdout-path selection with FDT method. With acpi SPCR table added, early debug console can be parsed from SPCR table with simple kernel parameter earlycon rather than earlycon=uart,mmio,0x1fe001e0 Signed-off-by: Bibo Mao Reviewed-by: Song Gao Message-Id: <20240907073037.243353-1-maob...@loongson.cn> Signed-off-by: Song Gao --- hw/loongarch/acpi-build.c | 40 +++ 1 file changed, 40 insertions(+) diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c index 04107c84ba..50709bda0f 100644 --- a/hw/loongarch/acpi-build.c +++ b/hw/loongarch/acpi-build.c @@ -242,6 +242,44 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine) acpi_table_end(linker, &table); } +/* + * Serial Port Console Redirection Table (SPCR) + * https://learn.microsoft.com/en-us/windows-hardware/drivers/serports/serial-port-console-redirection-table + */ +static void +spcr_setup(GArray *table_data, BIOSLinker *linker, MachineState *machine) +{ +LoongArchVirtMachineState *lvms; +AcpiSpcrData serial = { +.interface_type = 0, /* 16550 compatible */ +.base_addr.id = AML_AS_SYSTEM_MEMORY, +.base_addr.width = 32, +.base_addr.offset = 0, +.base_addr.size = 1, +.base_addr.addr = VIRT_UART_BASE, +.interrupt_type = 0, /* Interrupt not supported */ +.pc_interrupt = 0, +.interrupt = VIRT_UART_IRQ, +.baud_rate = 7,/* 115200 */ +.parity = 0, +.stop_bits = 1, +.flow_control = 0, +.terminal_type = 3,/* ANSI */ +.language = 0, /* Language */ +.pci_device_id = 0x, /* not a PCI device*/ +.pci_vendor_id = 0x, /* not a PCI device*/ +.pci_bus = 0, +.pci_device = 0, +.pci_function = 0, +.pci_flags = 0, +.pci_segment = 0, +}; + +lvms = LOONGARCH_VIRT_MACHINE(machine); +build_spcr(table_data, linker, &serial, 2, lvms->oem_id, + lvms->oem_table_id); +} + typedef struct AcpiBuildState { /* Copy of table in RAM (for patching). */ @@ -484,6 +522,8 @@ static void acpi_build(AcpiBuildTables *tables, MachineState *machine) acpi_add_table(table_offsets, tables_blob); build_srat(tables_blob, tables->linker, machine); +acpi_add_table(table_offsets, tables_blob); +spcr_setup(tables_blob, tables->linker, machine); if (machine->numa_state->num_nodes) { if (machine->numa_state->have_numa_distance) { -- 2.34.1
[PULL 4/7] target/loongarch: Support QMP dump-guest-memory
From: Bibo Mao Add the support needed for creating prstatus elf notes. This allows us to use QMP dump-guest-memory. Now ELF notes of LoongArch only supports general elf notes, LSX and LASX is not supported, since it is mainly used to dump guest memory. Signed-off-by: Bibo Mao Reviewed-by: Song Gao Tested-by: Song Gao Message-Id: <20240822065245.2286214-1-maob...@loongson.cn> Signed-off-by: Song Gao --- target/loongarch/arch_dump.c | 167 +++ target/loongarch/cpu.c | 1 + target/loongarch/internals.h | 2 + target/loongarch/meson.build | 1 + 4 files changed, 171 insertions(+) create mode 100644 target/loongarch/arch_dump.c diff --git a/target/loongarch/arch_dump.c b/target/loongarch/arch_dump.c new file mode 100644 index 00..4986db970e --- /dev/null +++ b/target/loongarch/arch_dump.c @@ -0,0 +1,167 @@ +/* + * Support for writing ELF notes for LoongArch architectures + * + * Copyright (c) 2023 Loongarch Technology + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2 or later, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "elf.h" +#include "sysemu/dump.h" +#include "internals.h" + +/* struct user_pt_regs from arch/loongarch/include/uapi/asm/ptrace.h */ +struct loongarch_user_regs { +uint64_t gpr[32]; +uint64_t pad1[1]; +/* Special CSR registers. */ +uint64_t csr_era; +uint64_t csr_badv; +uint64_t pad2[10]; +} QEMU_PACKED; + +QEMU_BUILD_BUG_ON(sizeof(struct loongarch_user_regs) != 360); + +/* struct elf_prstatus from include/uapi/linux/elfcore.h */ +struct loongarch_elf_prstatus { +char pad1[32]; /* 32 == offsetof(struct elf_prstatus, pr_pid) */ +uint32_t pr_pid; +/* + * 76 == offsetof(struct elf_prstatus, pr_reg) - + * offsetof(struct elf_prstatus, pr_ppid) + */ +char pad2[76]; +struct loongarch_user_regs pr_reg; +uint32_t pr_fpvalid; +char pad3[4]; +} QEMU_PACKED; + +QEMU_BUILD_BUG_ON(sizeof(struct loongarch_elf_prstatus) != 480); + +/* struct user_fp_state from arch/loongarch/include/uapi/asm/ptrace.h */ +struct loongarch_fpu_struct { +uint64_t fpr[32]; +uint64_t fcc; +unsigned int fcsr; +} QEMU_PACKED; + +QEMU_BUILD_BUG_ON(sizeof(struct loongarch_fpu_struct) != 268); + +struct loongarch_note { +Elf64_Nhdr hdr; +char name[8]; /* align_up(sizeof("CORE"), 4) */ +union { +struct loongarch_elf_prstatus prstatus; +struct loongarch_fpu_struct fpu; +}; +} QEMU_PACKED; + +#define LOONGARCH_NOTE_HEADER_SIZE offsetof(struct loongarch_note, prstatus) +#define LOONGARCH_PRSTATUS_NOTE_SIZE \ +(LOONGARCH_NOTE_HEADER_SIZE + sizeof(struct loongarch_elf_prstatus)) +#define LOONGARCH_PRFPREG_NOTE_SIZE \ +(LOONGARCH_NOTE_HEADER_SIZE + sizeof(struct loongarch_fpu_struct)) + +static void loongarch_note_init(struct loongarch_note *note, DumpState *s, +const char *name, Elf64_Word namesz, +Elf64_Word type, Elf64_Word descsz) +{ +memset(note, 0, sizeof(*note)); + +note->hdr.n_namesz = cpu_to_dump32(s, namesz); +note->hdr.n_descsz = cpu_to_dump32(s, descsz); +note->hdr.n_type = cpu_to_dump32(s, type); + +memcpy(note->name, name, namesz); +} + +static int loongarch_write_elf64_fprpreg(WriteCoreDumpFunction f, + CPULoongArchState *env, int cpuid, + DumpState *s) +{ +struct loongarch_note note; +int ret, i; + +loongarch_note_init(¬e, s, "CORE", 5, NT_PRFPREG, sizeof(note.fpu)); +note.fpu.fcsr = cpu_to_dump64(s, env->fcsr0); + +for (i = 0; i < 8; i++) { +note.fpu.fcc |= env->cf[i] << (8 * i); +} +note.fpu.fcc = cpu_to_dump64(s, note.fpu.fcc); + +for (i = 0; i < 32; ++i) { +note.fpu.fpr[i] = cpu_to_dump64(s, env->fpr[i].vreg.UD[0]); +} + +ret = f(¬e, LOONGARCH_PRFPREG_NOTE_SIZE, s); +if (ret < 0) { +return -1; +} + +return 0; +} + +int loongarch_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs, + int cpuid, DumpState *s) +{ +struct loongarch_note note; +CPULoongArchState *env = &LOONGARCH_CPU(cs)->
[PULL 0/7] loongarch-to-apply queue
The following changes since commit 4b7ea33074450bc6148c8e1545d78f179e64adb4: Merge tag 'pull-request-2024-09-11' of https://gitlab.com/thuth/qemu into staging (2024-09-11 19:28:23 +0100) are available in the Git repository at: https://gitlab.com/gaosong/qemu.git tags/pull-loongarch-20240912 for you to fetch changes up to 45d1fe46e5a6fe2b22b034e2b2bc0d941acd4b9e: hw/loongarch: Add acpi SPCR table support (2024-09-12 20:57:54 +0800) pull-loongarch-20240912 Bibo Mao (5): target/loongarch: Add compatible support about VM reboot hw/loongarch: Remove default enable with VIRTIO_VGA device target/loongarch/kvm: Add vCPU reset function target/loongarch: Support QMP dump-guest-memory hw/loongarch: Add acpi SPCR table support Jason A. Donenfeld (2): hw/loongarch: virt: support up to 4 serial ports hw/loongarch: virt: pass random seed to fdt hw/loongarch/Kconfig | 1 - hw/loongarch/acpi-build.c| 63 +++-- hw/loongarch/virt.c | 33 --- include/hw/pci-host/ls7a.h | 9 +- target/loongarch/arch_dump.c | 167 +++ target/loongarch/cpu.c | 17 +++- target/loongarch/internals.h | 2 + target/loongarch/kvm/kvm.c | 5 +- target/loongarch/kvm/kvm_loongarch.h | 2 +- target/loongarch/meson.build | 1 + 10 files changed, 274 insertions(+), 26 deletions(-) create mode 100644 target/loongarch/arch_dump.c
[PULL 1/1] hw/loongarch: Fix length for lowram in ACPI SRAT
From: Jiaxun Yang The size of lowram should be "gap" instead of the whole node. This is failing kernel's sanity check: [0.00] ACPI: SRAT: Node 0 PXM 0 [mem 0x-0x] [0.00] ACPI: SRAT: Node 0 PXM 0 [mem 0x8000-0x16fff] [0.00] ACPI: SRAT: Node 1 PXM 1 [mem 0x17000-0x26fff] [0.00] Warning: node 0 [mem 0x-0x] overlaps with itself [mem 0x8000-0x16fff] Fixes: fc100011f38d ("hw/loongarch: Refine acpi srat table for numa memory") Signed-off-by: Jiaxun Yang Reviewed-by: Bibo Mao Signed-off-by: Song Gao --- hw/loongarch/acpi-build.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c index 72bfc35ae6..2638f87434 100644 --- a/hw/loongarch/acpi-build.c +++ b/hw/loongarch/acpi-build.c @@ -218,7 +218,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine) * highram: [VIRT_HIGHMEM_BASE, +(len - gap)) */ if (len >= gap) { -build_srat_memory(table_data, base, len, i, MEM_AFFINITY_ENABLED); +build_srat_memory(table_data, base, gap, i, MEM_AFFINITY_ENABLED); len -= gap; base = VIRT_HIGHMEM_BASE; gap = machine->ram_size - VIRT_LOWMEM_SIZE; -- 2.34.1
[PULL 0/1] LoongArch: Fix for 9.1
The following changes since commit 4220ebde107c44412755d593fb46e168eeaed936: Merge tag 'migration-20240820-pull-request' of https://gitlab.com/farosas/qemu into staging (2024-08-21 08:46:45 +1000) are available in the Git repository at: https://gitlab.com/gaosong/qemu.git tags/pull-loongarch-20240821 for you to fetch changes up to d4f5e5af86d2e28edb578e556b307e3ad01ebf08: hw/loongarch: Fix length for lowram in ACPI SRAT (2024-08-21 11:01:09 +0800) Fix for 9.1 Jiaxun Yang (1): hw/loongarch: Fix length for lowram in ACPI SRAT hw/loongarch/acpi-build.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
[PATCH 5/5] target/loongarch/tcg: Add hardware page table walker support
Add hardware page table walker (HPTW) feature for la664. Set CPUCFG2.HPTW = 1 to indicate that HPTW is implemented on this CPU. Set PWCH.HPTW_EN = 1 to enable HPTW. Signed-off-by: Song Gao --- target/loongarch/cpu-csr.h| 3 + target/loongarch/cpu.c| 1 + target/loongarch/cpu.h| 1 + target/loongarch/cpu_helper.c | 20 - target/loongarch/internals.h | 2 + target/loongarch/tcg/tlb_helper.c | 122 ++ 6 files changed, 147 insertions(+), 2 deletions(-) diff --git a/target/loongarch/cpu-csr.h b/target/loongarch/cpu-csr.h index 0834e91f30..1aa015dc44 100644 --- a/target/loongarch/cpu-csr.h +++ b/target/loongarch/cpu-csr.h @@ -68,6 +68,8 @@ FIELD(TLBENTRY, PLV, 2, 2) FIELD(TLBENTRY, MAT, 4, 2) FIELD(TLBENTRY, G, 6, 1) FIELD(TLBENTRY, HUGE, 6, 1) +FIELD(TLBENTRY, PRESENT, 7, 1) +FIELD(TLBENTRY, WRITE, 8, 1) FIELD(TLBENTRY, HGLOBAL, 12, 1) FIELD(TLBENTRY, LEVEL, 13, 2) FIELD(TLBENTRY_32, PPN, 8, 24) @@ -103,6 +105,7 @@ FIELD(CSR_PWCH, DIR3_BASE, 0, 6) FIELD(CSR_PWCH, DIR3_WIDTH, 6, 6) FIELD(CSR_PWCH, DIR4_BASE, 12, 6) FIELD(CSR_PWCH, DIR4_WIDTH, 18, 6) +FIELD(CSR_PWCH, HPTW_EN, 24, 1) #define LOONGARCH_CSR_STLBPS 0x1e /* Stlb page size */ FIELD(CSR_STLBPS, PS, 0, 5) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 1b975f1de8..df355eee79 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -477,6 +477,7 @@ static void loongarch_la664_initfn(Object *obj) env->cpucfg[0] = 0x14d000; /* PRID */ loongarch_common_initfn(env, obj); +env->cpucfg[2] = FIELD_DP32(env->cpucfg[2], CPUCFG2, HPTW, 1); } static void loongarch_la464_initfn(Object *obj) diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index 6c41fafb70..84f92507d6 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -155,6 +155,7 @@ FIELD(CPUCFG2, LBT_ARM, 19, 1) FIELD(CPUCFG2, LBT_MIPS, 20, 1) FIELD(CPUCFG2, LSPW, 21, 1) FIELD(CPUCFG2, LAM, 22, 1) +FIELD(CPUCFG2, HPTW, 24, 1) /* cpucfg[3] bits */ FIELD(CPUCFG3, CCDMA, 0, 1) diff --git a/target/loongarch/cpu_helper.c b/target/loongarch/cpu_helper.c index 580362ac3e..fed0fd8788 100644 --- a/target/loongarch/cpu_helper.c +++ b/target/loongarch/cpu_helper.c @@ -182,6 +182,7 @@ int get_physical_address(CPULoongArchState *env, hwaddr *physical, { int user_mode = mmu_idx == MMU_USER_IDX; int kernel_mode = mmu_idx == MMU_KERNEL_IDX; +int ret; uint32_t plv, base_c, base_v; int64_t addr_high; uint8_t da = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, DA); @@ -221,8 +222,23 @@ int get_physical_address(CPULoongArchState *env, hwaddr *physical, } /* Mapped address */ -return loongarch_map_address(env, physical, prot, address, - access_type, mmu_idx); +ret = loongarch_map_address(env, physical, prot, address, +access_type, mmu_idx); +#ifdef CONFIG_TCG +if (!FIELD_EX32(env->cpucfg[2], CPUCFG2, HPTW)) { +return ret; +} + +if (!FIELD_EX32(env->CSR_PWCH, CSR_PWCH, HPTW_EN)) { +return ret; +} + +if (do_page_walk(env, address, access_type, ret)) { +ret = loongarch_map_address(env, physical, prot, address, +access_type, mmu_idx); +} +#endif +return ret; } hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) diff --git a/target/loongarch/internals.h b/target/loongarch/internals.h index 944153b180..6aa15fa36d 100644 --- a/target/loongarch/internals.h +++ b/target/loongarch/internals.h @@ -63,6 +63,8 @@ hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size, MMUAccessType access_type, int mmu_idx, bool probe, uintptr_t retaddr); +bool do_page_walk(CPULoongArchState *env, vaddr address, + MMUAccessType, int tlb_error); #endif #endif /* !CONFIG_USER_ONLY */ diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c index 463e9be7f2..a4f9f996fd 100644 --- a/target/loongarch/tcg/tlb_helper.c +++ b/target/loongarch/tcg/tlb_helper.c @@ -651,3 +651,125 @@ void helper_ldpte(CPULoongArchState *env, target_ulong base, target_ulong odd, } env->CSR_TLBREHI = FIELD_DP64(env->CSR_TLBREHI, CSR_TLBREHI, PS, ps); } + +static target_ulong get_pte_base(CPULoongArchState *env, vaddr address) +{ +uint64_t dir_base, dir_width; +target_ulong base; +int i; + +/* Get PGD */ +base = ((address >> 63) & 0x1) ? env->CSR_PGDH : env->CSR_PGDL; + +for (i = 4; i > 0; i--) { +get_dir_base_width(env, &dir_base, &dir_width, i); +/* + * LDDIR: level = 2 corresponds to Dir1 in PWCL. + * PWCL/PWCH: dir >= 1 && dir_width == 0 means no such level. + */
[PATCH 1/5] target/loongarch: Add a new cpu_type la664
Add a new LoongArch cpu type la664. The la664 has many new features, such as new atomic instructions, hardware page table walk, etc. We will implement them later. Signed-off-by: Song Gao --- target/loongarch/cpu.c | 48 +++--- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 5e85b9dbef..1b975f1de8 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -374,20 +374,11 @@ static int loongarch_cpu_mmu_index(CPUState *cs, bool ifetch) return MMU_DA_IDX; } -static void loongarch_la464_initfn(Object *obj) +static void loongarch_common_initfn(CPULoongArchState *env, Object *obj) { -LoongArchCPU *cpu = LOONGARCH_CPU(obj); -CPULoongArchState *env = &cpu->env; -int i; - -for (i = 0; i < 21; i++) { -env->cpucfg[i] = 0x0; -} - -cpu->dtb_compatible = "loongarch,Loongson-3A5000"; -env->cpucfg[0] = 0x14c010; /* PRID */ +uint32_t data; -uint32_t data = 0; +data = 0; data = FIELD_DP32(data, CPUCFG1, ARCH, 2); data = FIELD_DP32(data, CPUCFG1, PGMMU, 1); data = FIELD_DP32(data, CPUCFG1, IOCSR, 1); @@ -472,6 +463,38 @@ static void loongarch_la464_initfn(Object *obj) loongarch_cpu_post_init(obj); } +static void loongarch_la664_initfn(Object *obj) +{ +LoongArchCPU *cpu = LOONGARCH_CPU(obj); +CPULoongArchState *env = &cpu->env; +int i; + +for (i = 0; i < 21; i++) { +env->cpucfg[i] = 0x0; +} + +cpu->dtb_compatible = "loongarch,Loongson-3A6000"; +env->cpucfg[0] = 0x14d000; /* PRID */ + +loongarch_common_initfn(env, obj); +} + +static void loongarch_la464_initfn(Object *obj) +{ +LoongArchCPU *cpu = LOONGARCH_CPU(obj); +CPULoongArchState *env = &cpu->env; +int i; + +for (i = 0; i < 21; i++) { +env->cpucfg[i] = 0x0; +} + +cpu->dtb_compatible = "loongarch,Loongson-3A5000"; +env->cpucfg[0] = 0x14c010; /* PRID */ + +loongarch_common_initfn(env, obj); +} + static void loongarch_la132_initfn(Object *obj) { LoongArchCPU *cpu = LOONGARCH_CPU(obj); @@ -857,6 +880,7 @@ static const TypeInfo loongarch_cpu_type_infos[] = { .abstract = true, .class_init = loongarch64_cpu_class_init, }, +DEFINE_LOONGARCH_CPU_TYPE(64, "la664", loongarch_la664_initfn), DEFINE_LOONGARCH_CPU_TYPE(64, "la464", loongarch_la464_initfn), DEFINE_LOONGARCH_CPU_TYPE(32, "la132", loongarch_la132_initfn), DEFINE_LOONGARCH_CPU_TYPE(64, "max", loongarch_max_initfn), -- 2.33.0
[PATCH 4/5] target/loongarch: Add get_random_tlb_index()
get_random_tlb_index() is used to get a random tlb index. Signed-off-by: Song Gao --- target/loongarch/tcg/tlb_helper.c | 34 +-- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c index bc6d708484..463e9be7f2 100644 --- a/target/loongarch/tcg/tlb_helper.c +++ b/target/loongarch/tcg/tlb_helper.c @@ -291,19 +291,12 @@ void helper_tlbwr(CPULoongArchState *env) fill_tlb_entry(env, index); } -void helper_tlbfill(CPULoongArchState *env) +static int get_random_tlb_index(CPULoongArchState *env, +uint64_t entryhi, uint16_t pagesize) { -uint64_t address, entryhi; +uint64_t address; +uint16_t stlb_ps; int index, set, stlb_idx; -uint16_t pagesize, stlb_ps; - -if (FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) { -entryhi = env->CSR_TLBREHI; -pagesize = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI, PS); -} else { -entryhi = env->CSR_TLBEHI; -pagesize = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, PS); -} stlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS); @@ -323,6 +316,25 @@ void helper_tlbfill(CPULoongArchState *env) index = get_random_tlb(LOONGARCH_STLB, LOONGARCH_TLB_MAX - 1); } +return index; +} + +void helper_tlbfill(CPULoongArchState *env) +{ +uint64_t entryhi; +uint16_t pagesize; +int index; + +if (FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) { +entryhi = env->CSR_TLBREHI; +pagesize = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI, PS); +} else { +entryhi = env->CSR_TLBEHI; +pagesize = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, PS); +} + +index = get_random_tlb_index(env, entryhi, pagesize); + invalidate_tlb(env, index); fill_tlb_entry(env, index); } -- 2.33.0
[PATCH 3/5] target/loongarch: Add do_fill_tlb_entry()
do_fill_tlb_entry is used to fill a tlb entry. Signed-off-by: Song Gao --- target/loongarch/tcg/tlb_helper.c | 43 ++- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c index 3c3452b316..bc6d708484 100644 --- a/target/loongarch/tcg/tlb_helper.c +++ b/target/loongarch/tcg/tlb_helper.c @@ -160,11 +160,33 @@ static void invalidate_tlb(CPULoongArchState *env, int index) invalidate_tlb_entry(env, index); } -static void fill_tlb_entry(CPULoongArchState *env, int index) +static void do_fill_tlb_entry(CPULoongArchState *env, uint64_t vppn, + uint64_t lo0, uint64_t lo1, int index, uint8_t ps) { LoongArchTLB *tlb = &env->tlb[index]; +uint16_t asid; + +if (ps == 0) { +qemu_log_mask(CPU_LOG_MMU, "page size is 0\n"); +} + +/* Only MTLB has the ps fields */ +if (index >= LOONGARCH_STLB) { +tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, PS, ps); +} + +tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, VPPN, vppn); +tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, E, 1); +asid = FIELD_EX64(env->CSR_ASID, CSR_ASID, ASID); +tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, ASID, asid); + +tlb->tlb_entry0 = lo0; +tlb->tlb_entry1 = lo1; +} + +static void fill_tlb_entry(CPULoongArchState *env, int index) +{ uint64_t lo0, lo1, csr_vppn; -uint16_t csr_asid; uint8_t csr_ps; if (FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) { @@ -187,22 +209,7 @@ static void fill_tlb_entry(CPULoongArchState *env, int index) lo1 = env->CSR_TLBELO1; } -if (csr_ps == 0) { -qemu_log_mask(CPU_LOG_MMU, "page size is 0\n"); -} - -/* Only MTLB has the ps fields */ -if (index >= LOONGARCH_STLB) { -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); -tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, ASID, csr_asid); - -tlb->tlb_entry0 = lo0; -tlb->tlb_entry1 = lo1; +do_fill_tlb_entry(env, csr_vppn, lo0, lo1, index, csr_ps); } /* Return an random value between low and high */ -- 2.33.0
[PATCH 2/5] target/loongarch: Add do_lddir/ldpte()
do_lddir is used for accessing directory entries during page table walking, do_ldpte is used for page table entry accesses during page table walking. Signed-off-by: Song Gao --- target/loongarch/tcg/tlb_helper.c | 53 --- 1 file changed, 34 insertions(+), 19 deletions(-) diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c index 97f38fc391..3c3452b316 100644 --- a/target/loongarch/tcg/tlb_helper.c +++ b/target/loongarch/tcg/tlb_helper.c @@ -507,11 +507,11 @@ bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size, cpu_loop_exit_restore(cs, retaddr); } -target_ulong helper_lddir(CPULoongArchState *env, target_ulong base, - target_ulong level, uint32_t mem_idx) +static target_ulong do_lddir(CPULoongArchState *env, target_ulong base, + target_ulong badvaddr, target_ulong level) { CPUState *cs = env_cpu(env); -target_ulong badvaddr, index, phys, ret; +target_ulong index, phys, ret; int shift; uint64_t dir_base, dir_width; @@ -535,7 +535,6 @@ target_ulong helper_lddir(CPULoongArchState *env, target_ulong base, } } -badvaddr = env->CSR_TLBRBADV; base = base & TARGET_PHYS_MASK; /* 0:64bit, 1:128bit, 2:192bit, 3:256bit */ @@ -549,11 +548,18 @@ target_ulong helper_lddir(CPULoongArchState *env, target_ulong base, return ret; } -void helper_ldpte(CPULoongArchState *env, target_ulong base, target_ulong odd, - uint32_t mem_idx) +target_ulong helper_lddir(CPULoongArchState *env, target_ulong base, + target_ulong level, uint32_t mem_idx) +{ +return do_lddir(env, base, env->CSR_TLBRBADV, level); +} + +static void do_ldpte(CPULoongArchState *env, target_ulong base, + target_ulong badvaddr, target_ulong *ptval0, + target_ulong *ptval1, target_ulong *ps) { CPUState *cs = env_cpu(env); -target_ulong phys, tmp0, ptindex, ptoffset0, ptoffset1, ps, badv; +target_ulong ptindex, ptoffset0, ptoffset1, phys0, phys1; int shift; uint64_t ptbase = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTBASE); uint64_t ptwidth = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTWIDTH); @@ -584,34 +590,43 @@ void helper_ldpte(CPULoongArchState *env, target_ulong base, target_ulong odd, base = FIELD_DP64(base, TLBENTRY, G, 1); } -ps = dir_base + dir_width - 1; +*ps = dir_base + dir_width - 1; /* * Huge pages are evenly split into parity pages * when loaded into the tlb, * so the tlb page size needs to be divided by 2. */ -tmp0 = base; -if (odd) { -tmp0 += MAKE_64BIT_MASK(ps, 1); -} +*ptval0 = base; +*ptval1 = base + MAKE_64BIT_MASK(*ps, 1); } else { /* 0:64bit, 1:128bit, 2:192bit, 3:256bit */ shift = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTEWIDTH); shift = (shift + 1) * 3; -badv = env->CSR_TLBRBADV; -ptindex = (badv >> ptbase) & ((1 << ptwidth) - 1); -ptindex = ptindex & ~0x1; /* clear bit 0 */ +ptindex = (badvaddr >> ptbase) & ((1 << ptwidth) - 1); +ptindex = ptindex & ~0x1; /* clear bit 0 */ ptoffset0 = ptindex << shift; ptoffset1 = (ptindex + 1) << shift; -phys = base | (odd ? ptoffset1 : ptoffset0); -tmp0 = ldq_phys(cs->as, phys) & TARGET_PHYS_MASK; -ps = ptbase; +phys0 = base | ptoffset0; +phys1 = base | ptoffset1; +*ptval0 = ldq_phys(cs->as, phys0) & TARGET_PHYS_MASK; +*ptval1 = ldq_phys(cs->as, phys1) & TARGET_PHYS_MASK; +*ps = ptbase; } +return; +} + +void helper_ldpte(CPULoongArchState *env, target_ulong base, target_ulong odd, + uint32_t mem_idx) +{ +target_ulong tmp0, tmp1, ps; + +do_ldpte(env, base, env->CSR_TLBRBADV, &tmp0, &tmp1, &ps); + if (odd) { -env->CSR_TLBRELO1 = tmp0; +env->CSR_TLBRELO1 = tmp1; } else { env->CSR_TLBRELO0 = tmp0; } -- 2.33.0
[PATCH 0/5] LoongArch/tcg: Add hardware page table walker support
Loongson-3A6000 and newer processors have hardware page table walker (PTW) support. PTW can handle all fastpaths of PIL/PIS/PIF/PIE exceptions by hardware, Song Gao (5): target/loongarch: Add a new cpu_type la664 target/loongarch: Add do_lddir/ldpte() target/loongarch: Add do_fill_tlb_entry() target/loongarch: Add get_random_tlb_index() target/loongarch/tcg: Add hardware page table walk support target/loongarch/cpu-csr.h| 3 + target/loongarch/cpu.c| 49 -- target/loongarch/cpu.h| 1 + target/loongarch/cpu_helper.c | 20 ++- target/loongarch/internals.h | 2 + target/loongarch/tcg/tlb_helper.c | 252 -- 6 files changed, 265 insertions(+), 62 deletions(-) -- 2.33.0
[PULL 1/1] target/loongarch: Fix helper_lddir() a CID INTEGER_OVERFLOW issue
When the lddir level is 4 and the base is a HugePage, we may try to put value 4 into a field in the TLBENTRY that is only 2 bits wide. Fixes: Coverity CID 1547717 Fixes: 9c70db9a43388 ("target/loongarch: Fix tlb huge page loading issue") Signed-off-by: Song Gao Reviewed-by: Richard Henderson Message-Id: <20240724015853.1317396-1-gaos...@loongson.cn> --- target/loongarch/tcg/tlb_helper.c | 1 + 1 file changed, 1 insertion(+) diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c index d6331f9b0b..97f38fc391 100644 --- a/target/loongarch/tcg/tlb_helper.c +++ b/target/loongarch/tcg/tlb_helper.c @@ -525,6 +525,7 @@ target_ulong helper_lddir(CPULoongArchState *env, target_ulong base, if (unlikely(level == 4)) { qemu_log_mask(LOG_GUEST_ERROR, "Attempted use of level 4 huge page\n"); +return base; } if (FIELD_EX64(base, TLBENTRY, LEVEL)) { -- 2.34.1
[PULL 0/1] LoongArch fix for 9.1
The following changes since commit 6410f877f5ed535acd01bbfaa4baec379e44d0ef: Merge tag 'hw-misc-20240723' of https://github.com/philmd/qemu into staging (2024-07-24 15:39:43 +1000) are available in the Git repository at: https://gitlab.com/gaosong/qemu.git tags/pull-loongarch-20240724 for you to fetch changes up to a18ffbcf8b9fabfc6c850ebb1d3e40a21b885c67: target/loongarch: Fix helper_lddir() a CID INTEGER_OVERFLOW issue (2024-07-24 16:52:18 +0800) Fix for 9.1 -------- Song Gao (1): target/loongarch: Fix helper_lddir() a CID INTEGER_OVERFLOW issue target/loongarch/tcg/tlb_helper.c | 1 + 1 file changed, 1 insertion(+)
[PATCH] target/loongarch: Fix helper_lddir() a CID INTEGER_OVERFLOW issue
When the lddir level is 4 and the base is a HugePage, we may try to put value 4 into a field in the TLBENTRY that is only 2 bits wide. Fixes: Coverity CID 1547717 Fixes: 9c70db9a43388 ("target/loongarch: Fix tlb huge page loading issue") Signed-off-by: Song Gao --- target/loongarch/tcg/tlb_helper.c | 1 + 1 file changed, 1 insertion(+) diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c index d6331f9b0b..97f38fc391 100644 --- a/target/loongarch/tcg/tlb_helper.c +++ b/target/loongarch/tcg/tlb_helper.c @@ -525,6 +525,7 @@ target_ulong helper_lddir(CPULoongArchState *env, target_ulong base, if (unlikely(level == 4)) { qemu_log_mask(LOG_GUEST_ERROR, "Attempted use of level 4 huge page\n"); +return base; } if (FIELD_EX64(base, TLBENTRY, LEVEL)) { -- 2.34.1
[PULL 1/3] target/loongarch/gdbstub: Add vector registers support
GDB already support LoongArch vector extension[1], QEMU gdb adds LoongArch vector registers support, so that users can use 'info all-registers' to get all vector registers values. [1]: https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=1e9569f383a3d5a88ee07d0c2401bd95613c222e Signed-off-by: Song Gao Reviewed-by: Philippe Mathieu-Daudé Reviewd-by: Bibo Mao Message-Id: <20240711024454.3075183-1-gaos...@loongson.cn> --- configs/targets/loongarch64-linux-user.mak | 2 +- configs/targets/loongarch64-softmmu.mak| 2 +- gdb-xml/loongarch-lasx.xml | 60 ++ gdb-xml/loongarch-lsx.xml | 59 + target/loongarch/gdbstub.c | 73 +- 5 files changed, 192 insertions(+), 4 deletions(-) create mode 100644 gdb-xml/loongarch-lasx.xml create mode 100644 gdb-xml/loongarch-lsx.xml diff --git a/configs/targets/loongarch64-linux-user.mak b/configs/targets/loongarch64-linux-user.mak index d878e5a113..ea9b7e839a 100644 --- a/configs/targets/loongarch64-linux-user.mak +++ b/configs/targets/loongarch64-linux-user.mak @@ -1,4 +1,4 @@ # Default configuration for loongarch64-linux-user TARGET_ARCH=loongarch64 TARGET_BASE_ARCH=loongarch -TARGET_XML_FILES=gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu.xml +TARGET_XML_FILES=gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu.xml gdb-xml/loongarch-lsx.xml gdb-xml/loongarch-lasx.xml diff --git a/configs/targets/loongarch64-softmmu.mak b/configs/targets/loongarch64-softmmu.mak index 65b65e0c34..ce19ab6a16 100644 --- a/configs/targets/loongarch64-softmmu.mak +++ b/configs/targets/loongarch64-softmmu.mak @@ -2,6 +2,6 @@ TARGET_ARCH=loongarch64 TARGET_BASE_ARCH=loongarch TARGET_KVM_HAVE_GUEST_DEBUG=y TARGET_SUPPORTS_MTTCG=y -TARGET_XML_FILES= gdb-xml/loongarch-base32.xml gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu.xml +TARGET_XML_FILES= gdb-xml/loongarch-base32.xml gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu.xml gdb-xml/loongarch-lsx.xml gdb-xml/loongarch-lasx.xml # all boards require libfdt TARGET_NEED_FDT=y diff --git a/gdb-xml/loongarch-lasx.xml b/gdb-xml/loongarch-lasx.xml new file mode 100644 index 00..753b982c65 --- /dev/null +++ b/gdb-xml/loongarch-lasx.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gdb-xml/loongarch-lsx.xml b/gdb-xml/loongarch-lsx.xml new file mode 100644 index 00..51af1c6fd5 --- /dev/null +++ b/gdb-xml/loongarch-lsx.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/target/loongarch/gdbstub.c b/target/loongarch/gdbstub.c index a0e1439bd0..7ca245ee81 100644 --- a/target/loongarch/gdbstub.c +++ b/target/loongarch/gdbstub.c @@ -116,8 +116,77 @@ static int loongarch_gdb_set_fpu(CPUState *cs, uint8_t *mem_buf, int n) return length; } +#define VREG_NUM 32 +#define REG64_LEN 64 + +static int loongarch_gdb_get_vec(CPUState *cs, GByteArray *mem_buf, int n, int vl) +{ +LoongArchCPU *cpu = LOONGARCH_CPU(cs); +CPULoongArchState *env = &cpu->env; +int i, length = 0; + +if (0 <= n && n < VREG_NUM) { +for (i = 0; i < vl / REG64_LEN; i++) { +length += gdb_get_reg64(mem_buf, env->fpr[n].vreg.D(i)); +} +} + +return length; +} + +static int loongarch_gdb_set_vec(CPUState *cs, uint8_t *mem_buf, int n, int vl) +{ +LoongArchCPU *cpu = LOONGARCH_CPU(cs); +CPULoongArchState *env = &cpu->env; +int i, length = 0; + +if (0 <= n && n < VREG_NUM) { +for (i = 0; i < vl / REG64_LEN; i++) { +env->fpr[n].vreg.D(i) = ldq_le_p(mem_buf + 8 * i); +length += 8; +} +} + +return length; +} + +static int loongarch_gdb_get_lsx(CPUState *cs, GByteArray *mem_buf, int n) +{ +return loongarch_gdb_get_vec(cs, mem_buf, n, LSX_LEN); +} + +static int loongarch_gdb_set_lsx(CPUState *cs, uint8_t *mem_buf, int n) +{ +return loongarch_gdb_set_vec(cs, mem_buf, n, LSX_LEN); +} + +static int loongarch_gdb_get_lasx(CPUState *cs, GByteArray *mem_buf, int n) +{ +return loongarch_gdb_get_vec(cs, mem_buf, n, LASX_LEN); +} + +static int loongarch_gdb_set_lasx(CPUState *cs, uint8_t *mem_buf, int n) +{ +return loongarch_gdb_set_vec(cs, mem_buf, n, LASX_LEN); +} + void loongarch_cpu_register_gdb_regs_for_features(CPUState *cs) { -gdb_register_coprocessor(cs, loongarch_gdb_get_fpu, loongarch_gdb_set_fpu, - gdb_find_static_feature("loongarch-fpu.xml"), 0); +LoongArchCPU *cpu = LOONGARCH_CPU(c
[PULL 2/3] hw/loongarch: Remove unimplemented extioi INT_encode mode
Remove extioi INT_encode encode mode, because we don't emulate it. Signed-off-by: Song Gao Reviewed-by: Bibo Mao Message-Id: <20240718083254.748179-1-gaos...@loongson.cn> --- include/hw/intc/loongarch_extioi.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/hw/intc/loongarch_extioi.h b/include/hw/intc/loongarch_extioi.h index eccc2e0d18..626a37dfa1 100644 --- a/include/hw/intc/loongarch_extioi.h +++ b/include/hw/intc/loongarch_extioi.h @@ -50,7 +50,6 @@ #define EXTIOI_HAS_CPU_ENCODE (3) #define EXTIOI_VIRT_HAS_FEATURES(BIT(EXTIOI_HAS_VIRT_EXTENSION) \ | BIT(EXTIOI_HAS_ENABLE_OPTION) \ - | BIT(EXTIOI_HAS_INT_ENCODE)\ | BIT(EXTIOI_HAS_CPU_ENCODE)) #define EXTIOI_VIRT_CONFIG (0x4) #define EXTIOI_ENABLE (1) -- 2.34.1
[PULL 3/3] hw/loongarch: Modify flash block size to 256K
From: Xianglai Li loongarch added a common library for edk2 to parse flash base addresses through fdt. For compatibility with other architectures, the flash block size in qemu is now changed to 256k. Signed-off-by: Xianglai Li Reviewed-by: Song Gao Message-Id: <20240624033319.999631-1-lixiang...@loongson.cn> Signed-off-by: Song Gao --- include/hw/loongarch/virt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h index 8fdfacf268..603c1cebdb 100644 --- a/include/hw/loongarch/virt.h +++ b/include/hw/loongarch/virt.h @@ -20,7 +20,7 @@ #define VIRT_FWCFG_BASE 0x1e02UL #define VIRT_BIOS_BASE 0x1c00UL #define VIRT_BIOS_SIZE (16 * MiB) -#define VIRT_FLASH_SECTOR_SIZE (128 * KiB) +#define VIRT_FLASH_SECTOR_SIZE (256 * KiB) #define VIRT_FLASH0_BASEVIRT_BIOS_BASE #define VIRT_FLASH0_SIZEVIRT_BIOS_SIZE #define VIRT_FLASH1_BASE0x1d00UL -- 2.34.1
[PULL 0/3] loongarch-to-apply queue
The following changes since commit 23fa74974d8c96bc95cbecc0d4e2d90f984939f6: Merge tag 'pull-target-arm-20240718' of https://git.linaro.org/people/pmaydell/qemu-arm into staging (2024-07-19 07:02:17 +1000) are available in the Git repository at: https://gitlab.com/gaosong/qemu.git tags/pull-loongarch-20240719 for you to fetch changes up to 3ed016f525c8010e66be62d3ca6829eaa9b7cfb5: hw/loongarch: Modify flash block size to 256K (2024-07-19 10:40:04 +0800) pull-loongarch-20240719 -------- Song Gao (2): target/loongarch/gdbstub: Add vector registers support hw/loongarch: Remove unimplemented extioi INT_encode mode Xianglai Li (1): hw/loongarch: Modify flash block size to 256K configs/targets/loongarch64-linux-user.mak | 2 +- configs/targets/loongarch64-softmmu.mak| 2 +- gdb-xml/loongarch-lasx.xml | 60 gdb-xml/loongarch-lsx.xml | 59 include/hw/intc/loongarch_extioi.h | 1 - include/hw/loongarch/virt.h| 2 +- target/loongarch/gdbstub.c | 73 +- 7 files changed, 193 insertions(+), 6 deletions(-) create mode 100644 gdb-xml/loongarch-lasx.xml create mode 100644 gdb-xml/loongarch-lsx.xml
[PATCH v2] hw/loongarch: Remove unimplemented extioi INT_encode mode
Remove extioi INT_encode encode mode, because we don't emulate it. Signed-off-by: Song Gao --- include/hw/intc/loongarch_extioi.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/hw/intc/loongarch_extioi.h b/include/hw/intc/loongarch_extioi.h index eccc2e0d18..626a37dfa1 100644 --- a/include/hw/intc/loongarch_extioi.h +++ b/include/hw/intc/loongarch_extioi.h @@ -50,7 +50,6 @@ #define EXTIOI_HAS_CPU_ENCODE (3) #define EXTIOI_VIRT_HAS_FEATURES(BIT(EXTIOI_HAS_VIRT_EXTENSION) \ | BIT(EXTIOI_HAS_ENABLE_OPTION) \ - | BIT(EXTIOI_HAS_INT_ENCODE)\ | BIT(EXTIOI_HAS_CPU_ENCODE)) #define EXTIOI_VIRT_CONFIG (0x4) #define EXTIOI_ENABLE (1) -- 2.33.0
[PATCH] hw/loongarch: Remove unimplemented extioi INT_encode mode
Remove extioi INT_encode encode mode, because we don't emulate it. Signed-off-by: Song Gao --- hw/loongarch/virt.c| 6 -- include/hw/intc/loongarch_extioi.h | 1 - 2 files changed, 7 deletions(-) diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index e592b1b6b7..2103a1069f 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -951,9 +951,6 @@ static MemTxResult virt_iocsr_misc_write(void *opaque, hwaddr addr, if (val & BIT_ULL(IOCSRM_EXTIOI_EN)) { features |= BIT(EXTIOI_ENABLE); } -if (val & BIT_ULL(IOCSRM_EXTIOI_INT_ENCODE)) { -features |= BIT(EXTIOI_ENABLE_INT_ENCODE); -} address_space_stl(&lvms->as_iocsr, EXTIOI_VIRT_BASE + EXTIOI_VIRT_CONFIG, @@ -1002,9 +999,6 @@ static MemTxResult virt_iocsr_misc_read(void *opaque, hwaddr addr, if (features & BIT(EXTIOI_ENABLE)) { ret |= BIT_ULL(IOCSRM_EXTIOI_EN); } -if (features & BIT(EXTIOI_ENABLE_INT_ENCODE)) { -ret |= BIT_ULL(IOCSRM_EXTIOI_INT_ENCODE); -} break; default: g_assert_not_reached(); diff --git a/include/hw/intc/loongarch_extioi.h b/include/hw/intc/loongarch_extioi.h index eccc2e0d18..626a37dfa1 100644 --- a/include/hw/intc/loongarch_extioi.h +++ b/include/hw/intc/loongarch_extioi.h @@ -50,7 +50,6 @@ #define EXTIOI_HAS_CPU_ENCODE (3) #define EXTIOI_VIRT_HAS_FEATURES(BIT(EXTIOI_HAS_VIRT_EXTENSION) \ | BIT(EXTIOI_HAS_ENABLE_OPTION) \ - | BIT(EXTIOI_HAS_INT_ENCODE)\ | BIT(EXTIOI_HAS_CPU_ENCODE)) #define EXTIOI_VIRT_CONFIG (0x4) #define EXTIOI_ENABLE (1) -- 2.33.0
[PATCH] qemu/timer: Add host ticks function for LoongArch
Signed-off-by: Song Gao --- include/qemu/timer.h | 9 + 1 file changed, 9 insertions(+) diff --git a/include/qemu/timer.h b/include/qemu/timer.h index 5ce83c7911..fa56ec9481 100644 --- a/include/qemu/timer.h +++ b/include/qemu/timer.h @@ -1016,6 +1016,15 @@ static inline int64_t cpu_get_host_ticks(void) return val; } +#elif defined(__loongarch64) +static inline int64_t cpu_get_host_ticks(void) +{ +uint64_t val; + +asm volatile("rdtime.d %0, $zero" : "=r"(val)); +return val; +} + #else /* The host CPU doesn't have an easily accessible cycle counter. Just return a monotonically increasing value. This will be -- 2.33.0
[PULL v2 4/8] MAINTAINERS: Add myself as a reviewer of LoongArch virt machine
From: Jiaxun Yang I would like to be informed on changes made to the LoongArch virt machine. I'm fairly familiar with Loongson-3 series platform hardware and doing firmwre (U-Boot) development as hobbyist on LoongArch virt platform, so I believe I can give positive review input to changes on that machine. Signed-off-by: Jiaxun Yang Reviewed-by: Song Gao Message-Id: <20240627-ipi-fixes-v1-2-9b061dc28...@flygoat.com> Signed-off-by: Song Gao --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 6725913c8b..41bece23c1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1240,6 +1240,7 @@ LoongArch Machines -- Virt M: Song Gao +R: Jiaxun Yang S: Maintained F: docs/system/loongarch/virt.rst F: configs/targets/loongarch64-softmmu.mak -- 2.34.1
[PULL v2 1/8] hw/loongarch/boot.c: fix out-of-bound reading
From: Dmitry Frolov memcpy() is trying to READ 512 bytes from memory, pointed by info->kernel_cmdline, which was (presumable) allocated by g_strdup(""); Found with ASAN, making check with enabled sanitizers. Signed-off-by: Dmitry Frolov Reviewed-by: Song Gao Message-Id: <20240628123910.577740-1-fro...@swemel.ru> Signed-off-by: Song Gao --- hw/loongarch/boot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c index b8e1aa18d5..cb668703bd 100644 --- a/hw/loongarch/boot.c +++ b/hw/loongarch/boot.c @@ -163,7 +163,7 @@ static void init_cmdline(struct loongarch_boot_info *info, void *p, void *start) info->a0 = 1; info->a1 = cmdline_addr; -memcpy(p, info->kernel_cmdline, COMMAND_LINE_SIZE); +g_strlcpy(p, info->kernel_cmdline, COMMAND_LINE_SIZE); } static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr) -- 2.34.1
[PULL v2 3/8] hw/loongarch/virt: Remove unused assignment
From: Bibo Mao There is abuse usage about local variable gap. Remove duplicated assignment and solve Coverity reported error. Resolves: Coverity CID 1546441 Fixes: 3cc451cbce ("hw/loongarch: Refine fwcfg memory map") Signed-off-by: Bibo Mao Reviewed-by: Song Gao Message-Id: <20240612033637.167787-1-maob...@loongson.cn> Signed-off-by: Song Gao --- hw/loongarch/virt.c | 15 +++ 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index 8be2d2ff6a..e592b1b6b7 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -1054,7 +1054,6 @@ static void fw_cfg_add_memory(MachineState *ms) memmap_add_entry(base, gap, 1); size -= gap; base = VIRT_HIGHMEM_BASE; -gap = ram_size - VIRT_LOWMEM_SIZE; } if (size) { @@ -1067,17 +1066,17 @@ static void fw_cfg_add_memory(MachineState *ms) } /* add fw_cfg memory map of other nodes */ -size = ram_size - numa_info[0].node_mem; -gap = VIRT_LOWMEM_BASE + VIRT_LOWMEM_SIZE; -if (base < gap && (base + size) > gap) { +if (numa_info[0].node_mem < gap && ram_size > gap) { /* * memory map for the maining nodes splited into two part - * lowram: [base, +(gap - base)) - * highram: [VIRT_HIGHMEM_BASE, +(size - (gap - base))) + * lowram: [base, +(gap - numa_info[0].node_mem)) + * highram: [VIRT_HIGHMEM_BASE, +(ram_size - gap)) */ -memmap_add_entry(base, gap - base, 1); -size -= gap - base; +memmap_add_entry(base, gap - numa_info[0].node_mem, 1); +size = ram_size - gap; base = VIRT_HIGHMEM_BASE; +} else { +size = ram_size - numa_info[0].node_mem; } if (size) -- 2.34.1
[PULL v2 8/8] target/loongarch: Fix cpu_reset set wrong CSR_CRMD
After cpu_reset, DATF in CSR_CRMD is 0, DATM is 0. See the manual[1] 6.4. [1]: https://github.com/loongson/LoongArch-Documentation/releases/download/2023.04.20/LoongArch-Vol1-v1.10-EN.pdf Signed-off-by: Song Gao Reviewed-by: Bibo Mao Message-Id: <20240705021839.1004374-2-gaos...@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 61af018eec..5e85b9dbef 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -523,13 +523,13 @@ static void loongarch_cpu_reset_hold(Object *obj, ResetType type) env->fcsr0 = 0x0; int n; -/* Set csr registers value after reset */ +/* 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, 1); -env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DATM, 1); +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); -- 2.34.1
[PULL v2 7/8] target/loongarch: Set CSR_PRCFG1 and CSR_PRCFG2 values
We set the value of register CSR_PRCFG3, but left out CSR_PRCFG1 and CSR_PRCFG2. Set CSR_PRCFG1 and CSR_PRCFG2 according to the default values of the physical machine. Signed-off-by: Song Gao Reviewed-by: Bibo Mao Message-Id: <20240705021839.1004374-1-gaos...@loongson.cn> --- target/loongarch/cpu.c | 17 - 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 69f9ad7711..61af018eec 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -457,6 +457,18 @@ static void loongarch_la464_initfn(Object *obj) env->cpucfg[20] = data; env->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); + +env->CSR_PRCFG2 = 0x3000; + +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); + loongarch_cpu_post_init(obj); } @@ -538,11 +550,6 @@ static void loongarch_cpu_reset_hold(Object *obj, ResetType type) env->CSR_MERRCTL = FIELD_DP64(env->CSR_MERRCTL, CSR_MERRCTL, ISMERR, 0); env->CSR_TID = cs->cpu_index; -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); - 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); -- 2.34.1
[PULL v2 2/8] hw/loongarch: Change the tpm support by default
From: Xianglai Li Add devices that support tpm by default, Fixed incomplete tpm acpi table information. Signed-off-by: Xianglai Li Reviewed-by: Song Gao Message-Id: <20240624032300.999157-1-lixiang...@loongson.cn> Signed-off-by: Song Gao --- hw/loongarch/Kconfig | 1 + hw/loongarch/acpi-build.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig index 90a0dba9d5..89be737726 100644 --- a/hw/loongarch/Kconfig +++ b/hw/loongarch/Kconfig @@ -8,6 +8,7 @@ config LOONGARCH_VIRT imply VIRTIO_VGA imply PCI_DEVICES imply NVDIMM +imply TPM_TIS_SYSBUS select SERIAL select VIRTIO_PCI select PLATFORM_BUS diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c index af45ce526d..72bfc35ae6 100644 --- a/hw/loongarch/acpi-build.c +++ b/hw/loongarch/acpi-build.c @@ -646,6 +646,9 @@ void loongarch_acpi_setup(LoongArchVirtMachineState *lvms) build_state, tables.rsdp, ACPI_BUILD_RSDP_FILE); +fw_cfg_add_file(lvms->fw_cfg, ACPI_BUILD_TPMLOG_FILE, tables.tcpalog->data, +acpi_data_len(tables.tcpalog)); + qemu_register_reset(acpi_build_reset, build_state); acpi_build_reset(build_state); vmstate_register(NULL, 0, &vmstate_acpi_build, build_state); -- 2.34.1
[PULL v2 0/8] loongarch-to-apply queue
The following changes since commit 23901b2b721c0576007ab7580da8aa855d6042a9: Merge tag 'pull-target-arm-20240711' of https://git.linaro.org/people/pmaydell/qemu-arm into staging (2024-07-11 12:00:00 -0700) are available in the Git repository at: https://gitlab.com/gaosong/qemu.git tags/pull-loongarch-20240712 for you to fetch changes up to 3ef4b21a5c767ff0b15047e709762abef490ad07: target/loongarch: Fix cpu_reset set wrong CSR_CRMD (2024-07-12 09:41:18 +0800) pull-loongarch-20240712 v2: drop patch 'hw/loongarch: Modify flash block size to 256K'. Bibo Mao (2): hw/loongarch/virt: Remove unused assignment target/loongarch/kvm: Add software breakpoint support Dmitry Frolov (1): hw/loongarch/boot.c: fix out-of-bound reading Feiyang Chen (1): target/loongarch: Remove avail_64 in trans_srai_w() and simplify it Jiaxun Yang (1): MAINTAINERS: Add myself as a reviewer of LoongArch virt machine Song Gao (2): target/loongarch: Set CSR_PRCFG1 and CSR_PRCFG2 values target/loongarch: Fix cpu_reset set wrong CSR_CRMD Xianglai Li (1): hw/loongarch: Change the tpm support by default MAINTAINERS | 1 + configs/targets/loongarch64-softmmu.mak | 1 + hw/loongarch/Kconfig | 1 + hw/loongarch/acpi-build.c | 3 + hw/loongarch/boot.c | 2 +- hw/loongarch/virt.c | 15 +++-- target/loongarch/cpu.c| 23 --- target/loongarch/kvm/kvm.c| 76 +++ target/loongarch/tcg/insn_trans/trans_shift.c.inc | 15 + 9 files changed, 108 insertions(+), 29 deletions(-)
[PULL v2 5/8] target/loongarch/kvm: Add software breakpoint support
From: Bibo Mao With KVM virtualization, debug exception is injected to guest kernel rather than host for normal break intruction. Here hypercall instruction with special code is used for sw breakpoint usage, and detailed instruction comes from kvm kernel with user API KVM_REG_LOONGARCH_DEBUG_INST. Now only software breakpoint is supported, and it is allowed to insert/remove software breakpoint. We can debug guest kernel with gdb method after kernel is loaded, hardware breakpoint will be added in later. Signed-off-by: Bibo Mao Reviewed-by: Song Gao Tested-by: Song Gao Message-Id: <20240607035016.2975799-1-maob...@loongson.cn> Signed-off-by: Song Gao --- configs/targets/loongarch64-softmmu.mak | 1 + target/loongarch/kvm/kvm.c | 76 + 2 files changed, 77 insertions(+) diff --git a/configs/targets/loongarch64-softmmu.mak b/configs/targets/loongarch64-softmmu.mak index 84beb19b90..65b65e0c34 100644 --- a/configs/targets/loongarch64-softmmu.mak +++ b/configs/targets/loongarch64-softmmu.mak @@ -1,5 +1,6 @@ TARGET_ARCH=loongarch64 TARGET_BASE_ARCH=loongarch +TARGET_KVM_HAVE_GUEST_DEBUG=y TARGET_SUPPORTS_MTTCG=y TARGET_XML_FILES= gdb-xml/loongarch-base32.xml gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu.xml # all boards require libfdt diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c index 8e6e27c8bf..e1be6a6959 100644 --- a/target/loongarch/kvm/kvm.c +++ b/target/loongarch/kvm/kvm.c @@ -28,6 +28,7 @@ #include "trace.h" static bool cap_has_mp_state; +static unsigned int brk_insn; const KVMCapabilityInfo kvm_arch_required_capabilities[] = { KVM_CAP_LAST_INFO }; @@ -664,7 +665,14 @@ static void kvm_loongarch_vm_stage_change(void *opaque, bool running, int kvm_arch_init_vcpu(CPUState *cs) { +uint64_t val; + qemu_add_vm_change_state_handler(kvm_loongarch_vm_stage_change, cs); + +if (!kvm_get_one_reg(cs, KVM_REG_LOONGARCH_DEBUG_INST, &val)) { +brk_insn = val; +} + return 0; } @@ -739,6 +747,67 @@ bool kvm_arch_stop_on_emulation_error(CPUState *cs) return true; } +void kvm_arch_update_guest_debug(CPUState *cpu, struct kvm_guest_debug *dbg) +{ +if (kvm_sw_breakpoints_active(cpu)) { +dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP; +} +} + +int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) +{ +if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, 0) || +cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&brk_insn, 4, 1)) { +error_report("%s failed", __func__); +return -EINVAL; +} +return 0; +} + +int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) +{ +static uint32_t brk; + +if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&brk, 4, 0) || +brk != brk_insn || +cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, 1)) { +error_report("%s failed", __func__); +return -EINVAL; +} +return 0; +} + +int kvm_arch_insert_hw_breakpoint(vaddr addr, vaddr len, int type) +{ +return -ENOSYS; +} + +int kvm_arch_remove_hw_breakpoint(vaddr addr, vaddr len, int type) +{ +return -ENOSYS; +} + +void kvm_arch_remove_all_hw_breakpoints(void) +{ +} + +static bool kvm_loongarch_handle_debug(CPUState *cs, struct kvm_run *run) +{ +LoongArchCPU *cpu = LOONGARCH_CPU(cs); +CPULoongArchState *env = &cpu->env; + +kvm_cpu_synchronize_state(cs); +if (cs->singlestep_enabled) { +return true; +} + +if (kvm_find_sw_breakpoint(cs, env->pc)) { +return true; +} + +return false; +} + int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) { int ret = 0; @@ -757,6 +826,13 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) run->iocsr_io.len, run->iocsr_io.is_write); break; + +case KVM_EXIT_DEBUG: +if (kvm_loongarch_handle_debug(cs, run)) { +ret = EXCP_DEBUG; +} +break; + default: ret = -1; warn_report("KVM: unknown exit reason %d", run->exit_reason); -- 2.34.1
[PULL v2 6/8] target/loongarch: Remove avail_64 in trans_srai_w() and simplify it
From: Feiyang Chen Since srai.w is a valid instruction on la32, remove the avail_64 check and simplify trans_srai_w(). Fixes: c0c0461e3a06 ("target/loongarch: Add avail_64 to check la64-only instructions") Reviewed-by: Richard Henderson Signed-off-by: Feiyang Chen Message-Id: <20240628033357.50027-1-chris.chenfeiy...@gmail.com> Signed-off-by: Song Gao --- target/loongarch/tcg/insn_trans/trans_shift.c.inc | 15 +++ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/target/loongarch/tcg/insn_trans/trans_shift.c.inc b/target/loongarch/tcg/insn_trans/trans_shift.c.inc index 2f4bd6ff28..377307785a 100644 --- a/target/loongarch/tcg/insn_trans/trans_shift.c.inc +++ b/target/loongarch/tcg/insn_trans/trans_shift.c.inc @@ -67,19 +67,9 @@ static void gen_rotr_d(TCGv dest, TCGv src1, TCGv src2) tcg_gen_rotr_tl(dest, src1, t0); } -static bool trans_srai_w(DisasContext *ctx, arg_srai_w *a) +static void gen_sari_w(TCGv dest, TCGv src1, target_long imm) { -TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); -TCGv src1 = gpr_src(ctx, a->rj, EXT_ZERO); - -if (!avail_64(ctx)) { -return false; -} - -tcg_gen_sextract_tl(dest, src1, a->imm, 32 - a->imm); -gen_set_gpr(a->rd, dest, EXT_NONE); - -return true; +tcg_gen_sextract_tl(dest, src1, imm, 32 - imm); } TRANS(sll_w, ALL, gen_rrr, EXT_ZERO, EXT_NONE, EXT_SIGN, gen_sll_w) @@ -94,6 +84,7 @@ TRANS(slli_w, ALL, gen_rri_c, EXT_NONE, EXT_SIGN, tcg_gen_shli_tl) TRANS(slli_d, 64, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_shli_tl) TRANS(srli_w, ALL, gen_rri_c, EXT_ZERO, EXT_SIGN, tcg_gen_shri_tl) TRANS(srli_d, 64, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_shri_tl) +TRANS(srai_w, ALL, gen_rri_c, EXT_NONE, EXT_NONE, gen_sari_w) TRANS(srai_d, 64, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_sari_tl) TRANS(rotri_w, 64, gen_rri_v, EXT_NONE, EXT_NONE, gen_rotr_w) TRANS(rotri_d, 64, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_rotri_tl) -- 2.34.1
[PULL 7/9] target/loongarch: Remove avail_64 in trans_srai_w() and simplify it
From: Feiyang Chen Since srai.w is a valid instruction on la32, remove the avail_64 check and simplify trans_srai_w(). Fixes: c0c0461e3a06 ("target/loongarch: Add avail_64 to check la64-only instructions") Reviewed-by: Richard Henderson Signed-off-by: Feiyang Chen Message-Id: <20240628033357.50027-1-chris.chenfeiy...@gmail.com> Signed-off-by: Song Gao --- target/loongarch/tcg/insn_trans/trans_shift.c.inc | 15 +++ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/target/loongarch/tcg/insn_trans/trans_shift.c.inc b/target/loongarch/tcg/insn_trans/trans_shift.c.inc index 2f4bd6ff28..377307785a 100644 --- a/target/loongarch/tcg/insn_trans/trans_shift.c.inc +++ b/target/loongarch/tcg/insn_trans/trans_shift.c.inc @@ -67,19 +67,9 @@ static void gen_rotr_d(TCGv dest, TCGv src1, TCGv src2) tcg_gen_rotr_tl(dest, src1, t0); } -static bool trans_srai_w(DisasContext *ctx, arg_srai_w *a) +static void gen_sari_w(TCGv dest, TCGv src1, target_long imm) { -TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); -TCGv src1 = gpr_src(ctx, a->rj, EXT_ZERO); - -if (!avail_64(ctx)) { -return false; -} - -tcg_gen_sextract_tl(dest, src1, a->imm, 32 - a->imm); -gen_set_gpr(a->rd, dest, EXT_NONE); - -return true; +tcg_gen_sextract_tl(dest, src1, imm, 32 - imm); } TRANS(sll_w, ALL, gen_rrr, EXT_ZERO, EXT_NONE, EXT_SIGN, gen_sll_w) @@ -94,6 +84,7 @@ TRANS(slli_w, ALL, gen_rri_c, EXT_NONE, EXT_SIGN, tcg_gen_shli_tl) TRANS(slli_d, 64, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_shli_tl) TRANS(srli_w, ALL, gen_rri_c, EXT_ZERO, EXT_SIGN, tcg_gen_shri_tl) TRANS(srli_d, 64, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_shri_tl) +TRANS(srai_w, ALL, gen_rri_c, EXT_NONE, EXT_NONE, gen_sari_w) TRANS(srai_d, 64, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_sari_tl) TRANS(rotri_w, 64, gen_rri_v, EXT_NONE, EXT_NONE, gen_rotr_w) TRANS(rotri_d, 64, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_rotri_tl) -- 2.34.1
[PULL 2/9] hw/loongarch: Change the tpm support by default
From: Xianglai Li Add devices that support tpm by default, Fixed incomplete tpm acpi table information. Signed-off-by: Xianglai Li Reviewed-by: Song Gao Message-Id: <20240624032300.999157-1-lixiang...@loongson.cn> Signed-off-by: Song Gao --- hw/loongarch/Kconfig | 1 + hw/loongarch/acpi-build.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig index 90a0dba9d5..89be737726 100644 --- a/hw/loongarch/Kconfig +++ b/hw/loongarch/Kconfig @@ -8,6 +8,7 @@ config LOONGARCH_VIRT imply VIRTIO_VGA imply PCI_DEVICES imply NVDIMM +imply TPM_TIS_SYSBUS select SERIAL select VIRTIO_PCI select PLATFORM_BUS diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c index af45ce526d..72bfc35ae6 100644 --- a/hw/loongarch/acpi-build.c +++ b/hw/loongarch/acpi-build.c @@ -646,6 +646,9 @@ void loongarch_acpi_setup(LoongArchVirtMachineState *lvms) build_state, tables.rsdp, ACPI_BUILD_RSDP_FILE); +fw_cfg_add_file(lvms->fw_cfg, ACPI_BUILD_TPMLOG_FILE, tables.tcpalog->data, +acpi_data_len(tables.tcpalog)); + qemu_register_reset(acpi_build_reset, build_state); acpi_build_reset(build_state); vmstate_register(NULL, 0, &vmstate_acpi_build, build_state); -- 2.34.1
[PULL 8/9] target/loongarch: Set CSR_PRCFG1 and CSR_PRCFG2 values
We set the value of register CSR_PRCFG3, but left out CSR_PRCFG1 and CSR_PRCFG2. Set CSR_PRCFG1 and CSR_PRCFG2 according to the default values of the physical machine. Signed-off-by: Song Gao Reviewed-by: Bibo Mao Message-Id: <20240705021839.1004374-1-gaos...@loongson.cn> --- target/loongarch/cpu.c | 17 - 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 270f711f11..55d468af3c 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -457,6 +457,18 @@ static void loongarch_la464_initfn(Object *obj) env->cpucfg[20] = data; env->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); + +env->CSR_PRCFG2 = 0x3000; + +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); + loongarch_cpu_post_init(obj); } @@ -538,11 +550,6 @@ static void loongarch_cpu_reset_hold(Object *obj, ResetType type) env->CSR_MERRCTL = FIELD_DP64(env->CSR_MERRCTL, CSR_MERRCTL, ISMERR, 0); env->CSR_TID = cs->cpu_index; -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); - 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); -- 2.34.1
[PULL 9/9] target/loongarch: Fix cpu_reset set wrong CSR_CRMD
After cpu_reset, DATF in CSR_CRMD is 0, DATM is 0. See the manual[1] 6.4. [1]: https://github.com/loongson/LoongArch-Documentation/releases/download/2023.04.20/LoongArch-Vol1-v1.10-EN.pdf Signed-off-by: Song Gao Reviewed-by: Bibo Mao Message-Id: <20240705021839.1004374-2-gaos...@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 55d468af3c..d3b5d37938 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -523,13 +523,13 @@ static void loongarch_cpu_reset_hold(Object *obj, ResetType type) env->fcsr0 = 0x0; int n; -/* Set csr registers value after reset */ +/* 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, 1); -env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DATM, 1); +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); -- 2.34.1
[PULL 4/9] hw/loongarch/virt: Remove unused assignment
From: Bibo Mao There is abuse usage about local variable gap. Remove duplicated assignment and solve Coverity reported error. Resolves: Coverity CID 1546441 Fixes: 3cc451cbce ("hw/loongarch: Refine fwcfg memory map") Signed-off-by: Bibo Mao Reviewed-by: Song Gao Message-Id: <20240612033637.167787-1-maob...@loongson.cn> Signed-off-by: Song Gao --- hw/loongarch/virt.c | 15 +++ 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index 8be2d2ff6a..e592b1b6b7 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -1054,7 +1054,6 @@ static void fw_cfg_add_memory(MachineState *ms) memmap_add_entry(base, gap, 1); size -= gap; base = VIRT_HIGHMEM_BASE; -gap = ram_size - VIRT_LOWMEM_SIZE; } if (size) { @@ -1067,17 +1066,17 @@ static void fw_cfg_add_memory(MachineState *ms) } /* add fw_cfg memory map of other nodes */ -size = ram_size - numa_info[0].node_mem; -gap = VIRT_LOWMEM_BASE + VIRT_LOWMEM_SIZE; -if (base < gap && (base + size) > gap) { +if (numa_info[0].node_mem < gap && ram_size > gap) { /* * memory map for the maining nodes splited into two part - * lowram: [base, +(gap - base)) - * highram: [VIRT_HIGHMEM_BASE, +(size - (gap - base))) + * lowram: [base, +(gap - numa_info[0].node_mem)) + * highram: [VIRT_HIGHMEM_BASE, +(ram_size - gap)) */ -memmap_add_entry(base, gap - base, 1); -size -= gap - base; +memmap_add_entry(base, gap - numa_info[0].node_mem, 1); +size = ram_size - gap; base = VIRT_HIGHMEM_BASE; +} else { +size = ram_size - numa_info[0].node_mem; } if (size) -- 2.34.1
[PULL 1/9] hw/loongarch/boot.c: fix out-of-bound reading
From: Dmitry Frolov memcpy() is trying to READ 512 bytes from memory, pointed by info->kernel_cmdline, which was (presumable) allocated by g_strdup(""); Found with ASAN, making check with enabled sanitizers. Signed-off-by: Dmitry Frolov Reviewed-by: Song Gao Message-Id: <20240628123910.577740-1-fro...@swemel.ru> Signed-off-by: Song Gao --- hw/loongarch/boot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c index b8e1aa18d5..cb668703bd 100644 --- a/hw/loongarch/boot.c +++ b/hw/loongarch/boot.c @@ -163,7 +163,7 @@ static void init_cmdline(struct loongarch_boot_info *info, void *p, void *start) info->a0 = 1; info->a1 = cmdline_addr; -memcpy(p, info->kernel_cmdline, COMMAND_LINE_SIZE); +g_strlcpy(p, info->kernel_cmdline, COMMAND_LINE_SIZE); } static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr) -- 2.34.1
[PULL 5/9] MAINTAINERS: Add myself as a reviewer of LoongArch virt machine
From: Jiaxun Yang I would like to be informed on changes made to the LoongArch virt machine. I'm fairly familiar with Loongson-3 series platform hardware and doing firmwre (U-Boot) development as hobbyist on LoongArch virt platform, so I believe I can give positive review input to changes on that machine. Signed-off-by: Jiaxun Yang Reviewed-by: Song Gao Message-Id: <20240627-ipi-fixes-v1-2-9b061dc28...@flygoat.com> Signed-off-by: Song Gao --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 6725913c8b..41bece23c1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1240,6 +1240,7 @@ LoongArch Machines -- Virt M: Song Gao +R: Jiaxun Yang S: Maintained F: docs/system/loongarch/virt.rst F: configs/targets/loongarch64-softmmu.mak -- 2.34.1
[PULL 3/9] hw/loongarch: Modify flash block size to 256K
From: Xianglai Li loongarch added a common library for edk2 to parse flash base addresses through fdt. For compatibility with other architectures, the flash block size in qemu is now changed to 256k. Signed-off-by: Xianglai Li Reviewed-by: Song Gao Message-Id: <20240624033319.999631-1-lixiang...@loongson.cn> Signed-off-by: Song Gao --- include/hw/loongarch/virt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h index 8fdfacf268..603c1cebdb 100644 --- a/include/hw/loongarch/virt.h +++ b/include/hw/loongarch/virt.h @@ -20,7 +20,7 @@ #define VIRT_FWCFG_BASE 0x1e02UL #define VIRT_BIOS_BASE 0x1c00UL #define VIRT_BIOS_SIZE (16 * MiB) -#define VIRT_FLASH_SECTOR_SIZE (128 * KiB) +#define VIRT_FLASH_SECTOR_SIZE (256 * KiB) #define VIRT_FLASH0_BASEVIRT_BIOS_BASE #define VIRT_FLASH0_SIZEVIRT_BIOS_SIZE #define VIRT_FLASH1_BASE0x1d00UL -- 2.34.1
[PULL 6/9] target/loongarch/kvm: Add software breakpoint support
From: Bibo Mao With KVM virtualization, debug exception is injected to guest kernel rather than host for normal break intruction. Here hypercall instruction with special code is used for sw breakpoint usage, and detailed instruction comes from kvm kernel with user API KVM_REG_LOONGARCH_DEBUG_INST. Now only software breakpoint is supported, and it is allowed to insert/remove software breakpoint. We can debug guest kernel with gdb method after kernel is loaded, hardware breakpoint will be added in later. Signed-off-by: Bibo Mao Reviewed-by: Song Gao Tested-by: Song Gao Message-Id: <20240607035016.2975799-1-maob...@loongson.cn> Signed-off-by: Song Gao --- configs/targets/loongarch64-softmmu.mak | 1 + target/loongarch/kvm/kvm.c | 76 + 2 files changed, 77 insertions(+) diff --git a/configs/targets/loongarch64-softmmu.mak b/configs/targets/loongarch64-softmmu.mak index 84beb19b90..65b65e0c34 100644 --- a/configs/targets/loongarch64-softmmu.mak +++ b/configs/targets/loongarch64-softmmu.mak @@ -1,5 +1,6 @@ TARGET_ARCH=loongarch64 TARGET_BASE_ARCH=loongarch +TARGET_KVM_HAVE_GUEST_DEBUG=y TARGET_SUPPORTS_MTTCG=y TARGET_XML_FILES= gdb-xml/loongarch-base32.xml gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu.xml # all boards require libfdt diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c index 8e6e27c8bf..e1be6a6959 100644 --- a/target/loongarch/kvm/kvm.c +++ b/target/loongarch/kvm/kvm.c @@ -28,6 +28,7 @@ #include "trace.h" static bool cap_has_mp_state; +static unsigned int brk_insn; const KVMCapabilityInfo kvm_arch_required_capabilities[] = { KVM_CAP_LAST_INFO }; @@ -664,7 +665,14 @@ static void kvm_loongarch_vm_stage_change(void *opaque, bool running, int kvm_arch_init_vcpu(CPUState *cs) { +uint64_t val; + qemu_add_vm_change_state_handler(kvm_loongarch_vm_stage_change, cs); + +if (!kvm_get_one_reg(cs, KVM_REG_LOONGARCH_DEBUG_INST, &val)) { +brk_insn = val; +} + return 0; } @@ -739,6 +747,67 @@ bool kvm_arch_stop_on_emulation_error(CPUState *cs) return true; } +void kvm_arch_update_guest_debug(CPUState *cpu, struct kvm_guest_debug *dbg) +{ +if (kvm_sw_breakpoints_active(cpu)) { +dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP; +} +} + +int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) +{ +if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, 0) || +cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&brk_insn, 4, 1)) { +error_report("%s failed", __func__); +return -EINVAL; +} +return 0; +} + +int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp) +{ +static uint32_t brk; + +if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&brk, 4, 0) || +brk != brk_insn || +cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, 1)) { +error_report("%s failed", __func__); +return -EINVAL; +} +return 0; +} + +int kvm_arch_insert_hw_breakpoint(vaddr addr, vaddr len, int type) +{ +return -ENOSYS; +} + +int kvm_arch_remove_hw_breakpoint(vaddr addr, vaddr len, int type) +{ +return -ENOSYS; +} + +void kvm_arch_remove_all_hw_breakpoints(void) +{ +} + +static bool kvm_loongarch_handle_debug(CPUState *cs, struct kvm_run *run) +{ +LoongArchCPU *cpu = LOONGARCH_CPU(cs); +CPULoongArchState *env = &cpu->env; + +kvm_cpu_synchronize_state(cs); +if (cs->singlestep_enabled) { +return true; +} + +if (kvm_find_sw_breakpoint(cs, env->pc)) { +return true; +} + +return false; +} + int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) { int ret = 0; @@ -757,6 +826,13 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) run->iocsr_io.len, run->iocsr_io.is_write); break; + +case KVM_EXIT_DEBUG: +if (kvm_loongarch_handle_debug(cs, run)) { +ret = EXCP_DEBUG; +} +break; + default: ret = -1; warn_report("KVM: unknown exit reason %d", run->exit_reason); -- 2.34.1
[PULL 0/9] loongarch-to-apply queue
The following changes since commit 59084feb256c617063e0dbe7e64821ae8852d7cf: Merge tag 'pull-aspeed-20240709' of https://github.com/legoater/qemu into staging (2024-07-09 07:13:55 -0700) are available in the Git repository at: https://gitlab.com/gaosong/qemu.git tags/pull-loongarch-20240711 for you to fetch changes up to 78341408e705e1b8dc92eaae2071ae0023d586b0: target/loongarch: Fix cpu_reset set wrong CSR_CRMD (2024-07-11 15:56:50 +0800) pull-loongarch-20240711 Bibo Mao (2): hw/loongarch/virt: Remove unused assignment target/loongarch/kvm: Add software breakpoint support Dmitry Frolov (1): hw/loongarch/boot.c: fix out-of-bound reading Feiyang Chen (1): target/loongarch: Remove avail_64 in trans_srai_w() and simplify it Jiaxun Yang (1): MAINTAINERS: Add myself as a reviewer of LoongArch virt machine Song Gao (2): target/loongarch: Set CSR_PRCFG1 and CSR_PRCFG2 values target/loongarch: Fix cpu_reset set wrong CSR_CRMD Xianglai Li (2): hw/loongarch: Change the tpm support by default hw/loongarch: Modify flash block size to 256K MAINTAINERS | 1 + configs/targets/loongarch64-softmmu.mak | 1 + hw/loongarch/Kconfig | 1 + hw/loongarch/acpi-build.c | 3 + hw/loongarch/boot.c | 2 +- hw/loongarch/virt.c | 15 +++-- include/hw/loongarch/virt.h | 2 +- target/loongarch/cpu.c| 23 --- target/loongarch/kvm/kvm.c| 76 +++ target/loongarch/tcg/insn_trans/trans_shift.c.inc | 15 + 10 files changed, 109 insertions(+), 30 deletions(-)
[PATCH v2] target/loongarch/gdbstub: Add vector registers support
GDB already support LoongArch vector extension[1], QEMU gdb adds LoongArch vector registers support, so that users can use 'info all-registers' to get all vector registers values. [1]: https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=1e9569f383a3d5a88ee07d0c2401bd95613c222e Signed-off-by: Song Gao --- based-on: https://patchew.org/QEMU/20240607035016.2975799-1-maob...@loongson.cn/ v2: - fix tab line wrapper issue. - Link to v1: https://patchew.org/QEMU/20240621065406.864232-1-gaos...@loongson.cn/ configs/targets/loongarch64-linux-user.mak | 2 +- configs/targets/loongarch64-softmmu.mak| 2 +- target/loongarch/gdbstub.c | 70 +- gdb-xml/loongarch-lasx.xml | 60 +++ gdb-xml/loongarch-lsx.xml | 59 ++ 5 files changed, 189 insertions(+), 4 deletions(-) create mode 100644 gdb-xml/loongarch-lasx.xml create mode 100644 gdb-xml/loongarch-lsx.xml diff --git a/configs/targets/loongarch64-linux-user.mak b/configs/targets/loongarch64-linux-user.mak index d878e5a113..ea9b7e839a 100644 --- a/configs/targets/loongarch64-linux-user.mak +++ b/configs/targets/loongarch64-linux-user.mak @@ -1,4 +1,4 @@ # Default configuration for loongarch64-linux-user TARGET_ARCH=loongarch64 TARGET_BASE_ARCH=loongarch -TARGET_XML_FILES=gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu.xml +TARGET_XML_FILES=gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu.xml gdb-xml/loongarch-lsx.xml gdb-xml/loongarch-lasx.xml diff --git a/configs/targets/loongarch64-softmmu.mak b/configs/targets/loongarch64-softmmu.mak index 65b65e0c34..ce19ab6a16 100644 --- a/configs/targets/loongarch64-softmmu.mak +++ b/configs/targets/loongarch64-softmmu.mak @@ -2,6 +2,6 @@ TARGET_ARCH=loongarch64 TARGET_BASE_ARCH=loongarch TARGET_KVM_HAVE_GUEST_DEBUG=y TARGET_SUPPORTS_MTTCG=y -TARGET_XML_FILES= gdb-xml/loongarch-base32.xml gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu.xml +TARGET_XML_FILES= gdb-xml/loongarch-base32.xml gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu.xml gdb-xml/loongarch-lsx.xml gdb-xml/loongarch-lasx.xml # all boards require libfdt TARGET_NEED_FDT=y diff --git a/target/loongarch/gdbstub.c b/target/loongarch/gdbstub.c index a0e1439bd0..8ac327d286 100644 --- a/target/loongarch/gdbstub.c +++ b/target/loongarch/gdbstub.c @@ -116,8 +116,74 @@ static int loongarch_gdb_set_fpu(CPUState *cs, uint8_t *mem_buf, int n) return length; } +static int loongarch_gdb_get_vec(CPUState *cs, GByteArray *mem_buf, int n, int vl) +{ +LoongArchCPU *cpu = LOONGARCH_CPU(cs); +CPULoongArchState *env = &cpu->env; +int i, length = 0; + +if (0 <= n && n < 32) { +for (i = 0; i < vl / 64; i++) { +length += gdb_get_reg64(mem_buf, env->fpr[n].vreg.D(i)); +} +} + +return length; +} + +static int loongarch_gdb_set_vec(CPUState *cs, uint8_t *mem_buf, int n, int vl) +{ +LoongArchCPU *cpu = LOONGARCH_CPU(cs); +CPULoongArchState *env = &cpu->env; +int i, length = 0; + +if (0 <= n && n < 32) { +for (i = 0; i < vl / 64; i++) { +env->fpr[n].vreg.D(i) = ldq_le_p(mem_buf + 8 * i); +length += 8; +} +} + +return length; +} + +static int loongarch_gdb_get_lsx(CPUState *cs, GByteArray *mem_buf, int n) +{ +return loongarch_gdb_get_vec(cs, mem_buf, n, LSX_LEN); +} + +static int loongarch_gdb_set_lsx(CPUState *cs, uint8_t *mem_buf, int n) +{ +return loongarch_gdb_set_vec(cs, mem_buf, n, LSX_LEN); +} + +static int loongarch_gdb_get_lasx(CPUState *cs, GByteArray *mem_buf, int n) +{ +return loongarch_gdb_get_vec(cs, mem_buf, n, LASX_LEN); +} + +static int loongarch_gdb_set_lasx(CPUState *cs, uint8_t *mem_buf, int n) +{ +return loongarch_gdb_set_vec(cs, mem_buf, n, LASX_LEN); +} + void loongarch_cpu_register_gdb_regs_for_features(CPUState *cs) { -gdb_register_coprocessor(cs, loongarch_gdb_get_fpu, loongarch_gdb_set_fpu, - gdb_find_static_feature("loongarch-fpu.xml"), 0); +LoongArchCPU *cpu = LOONGARCH_CPU(cs); +CPULoongArchState *env = &cpu->env; + +if (FIELD_EX32(env->cpucfg[2], CPUCFG2, FP)) { +gdb_register_coprocessor(cs, loongarch_gdb_get_fpu, loongarch_gdb_set_fpu, + gdb_find_static_feature("loongarch-fpu.xml"), 0); +} + +if (FIELD_EX32(env->cpucfg[2], CPUCFG2, LSX)) { +gdb_register_coprocessor(cs, loongarch_gdb_get_lsx, loongarch_gdb_set_lsx, + gdb_find_static_feature("loongarch-lsx.xml"), 0); +} + +if (FIELD_EX32(env->cpucfg[2], CPUCFG2, LASX)) { +gdb_register_coprocessor(cs, loongarch_gdb_get_lasx, loongarch_gdb_set_lasx, + gdb_find_static_feature("loongarch-lasx.xml"), 0); +} } diff --git a
[PATCH v2 1/2] target/loongarch: Set CSR_PRCFG1 and CSR_PRCFG2 values
We set the value of register CSR_PRCFG3, but left out CSR_PRCFG1 and CSR_PRCFG2. Set CSR_PRCFG1 and CSR_PRCFG2 according to the default values of the physical machine. Signed-off-by: Song Gao --- v2: - Add a new patch fix set CSR_CRMD wrong value; - Set PRCFG1-PRCFG3 values in loongarch_la464_initfn. target/loongarch/cpu.c | 17 - 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 270f711f11..55d468af3c 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -457,6 +457,18 @@ static void loongarch_la464_initfn(Object *obj) env->cpucfg[20] = data; env->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); + +env->CSR_PRCFG2 = 0x3000; + +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); + loongarch_cpu_post_init(obj); } @@ -538,11 +550,6 @@ static void loongarch_cpu_reset_hold(Object *obj, ResetType type) env->CSR_MERRCTL = FIELD_DP64(env->CSR_MERRCTL, CSR_MERRCTL, ISMERR, 0); env->CSR_TID = cs->cpu_index; -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); - 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); -- 2.33.0
[PATCH v2 2/2] target/loongarch: Fix cpu_reset set wrong CSR_CRMD
After cpu_reset, DATF in CSR_CRMD is 0, DATM is 0. See the manual[1] 6.4. [1]: https://github.com/loongson/LoongArch-Documentation/releases/download/2023.04.20/LoongArch-Vol1-v1.10-EN.pdf Signed-off-by: Song Gao --- 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 55d468af3c..763cde41c3 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -523,13 +523,13 @@ static void loongarch_cpu_reset_hold(Object *obj, ResetType type) env->fcsr0 = 0x0; int n; -/* Set csr registers value after reset */ +/* 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, 1); -env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DATM, 1); +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); -- 2.33.0
[PATCH] target/loongarch: Set CSR_PRCFG1 and CSR_PRCFG2 values
We set the value of register CSR_PRCFG3, but left out CSR_PRCFG1 and CSR_PRCFG2. Set CSR_PRCFG1 and CSR_PRCFG2 according to the default values of the physical machine. Signed-off-by: Song Gao --- target/loongarch/cpu.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 270f711f11..ad40750701 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -538,6 +538,12 @@ static void loongarch_cpu_reset_hold(Object *obj, ResetType type) env->CSR_MERRCTL = FIELD_DP64(env->CSR_MERRCTL, CSR_MERRCTL, ISMERR, 0); env->CSR_TID = cs->cpu_index; +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); + +env->CSR_PRCFG2 = 0x3000; + 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); -- 2.33.0
[RESEND PATCH 0/2] hw/intc: Restore loongarch_ipi for LoongArch
Currently LoongArch and MIPS architectures share loongson_ipi, and modifications to loongson_ipi by the MIPS architecture may lead to some unknown problems in the LoongArch architecture. In order to minimize the impact of this inter-architectural interaction, we believe that it is necessary to restore loongarch_ipi. Song Gao (2): Revert "hw/intc: Remove loongarch_ipi.c" hw/intc: Restore loongarch_ipi for LoongArch MAINTAINERS | 2 - include/hw/intc/loongarch_ipi.h | 54 + include/hw/loongarch/virt.h | 2 +- hw/intc/loongarch_ipi.c | 347 hw/loongarch/virt.c | 4 +- hw/intc/Kconfig | 3 + hw/intc/meson.build | 1 + hw/intc/trace-events| 3 + hw/loongarch/Kconfig| 2 +- 9 files changed, 412 insertions(+), 6 deletions(-) create mode 100644 include/hw/intc/loongarch_ipi.h create mode 100644 hw/intc/loongarch_ipi.c -- 2.34.1
[RESEND PATCH 1/2] Revert "hw/intc: Remove loongarch_ipi.c"
Restore 'loongarch_ipi.c' for LoongArch. This reverts commit 5f82fb2a3a71bb510b3e1b7229929d468c01740a. --- hw/intc/loongarch_ipi.c | 347 1 file changed, 347 insertions(+) create mode 100644 hw/intc/loongarch_ipi.c diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c new file mode 100644 index 00..44b3b9c138 --- /dev/null +++ b/hw/intc/loongarch_ipi.c @@ -0,0 +1,347 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * LoongArch ipi interrupt support + * + * Copyright (C) 2021 Loongson Technology Corporation Limited + */ + +#include "qemu/osdep.h" +#include "hw/boards.h" +#include "hw/sysbus.h" +#include "hw/intc/loongarch_ipi.h" +#include "hw/irq.h" +#include "hw/qdev-properties.h" +#include "qapi/error.h" +#include "qemu/log.h" +#include "exec/address-spaces.h" +#include "migration/vmstate.h" +#include "target/loongarch/cpu.h" +#include "trace.h" + +static MemTxResult loongarch_ipi_readl(void *opaque, hwaddr addr, + uint64_t *data, + unsigned size, MemTxAttrs attrs) +{ +IPICore *s; +LoongArchIPI *ipi = opaque; +uint64_t ret = 0; +int index = 0; + +s = &ipi->cpu[attrs.requester_id]; +addr &= 0xff; +switch (addr) { +case CORE_STATUS_OFF: +ret = s->status; +break; +case CORE_EN_OFF: +ret = s->en; +break; +case CORE_SET_OFF: +ret = 0; +break; +case CORE_CLEAR_OFF: +ret = 0; +break; +case CORE_BUF_20 ... CORE_BUF_38 + 4: +index = (addr - CORE_BUF_20) >> 2; +ret = s->buf[index]; +break; +default: +qemu_log_mask(LOG_UNIMP, "invalid read: %x", (uint32_t)addr); +break; +} + +trace_loongarch_ipi_read(size, (uint64_t)addr, ret); +*data = ret; +return MEMTX_OK; +} + +static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr, + MemTxAttrs attrs) +{ +int i, mask = 0, data = 0; + +/* + * bit 27-30 is mask for byte writing, + * if the mask is 0, we need not to do anything. + */ +if ((val >> 27) & 0xf) { +data = address_space_ldl(env->address_space_iocsr, addr, + attrs, NULL); +for (i = 0; i < 4; i++) { +/* get mask for byte writing */ +if (val & (0x1 << (27 + i))) { +mask |= 0xff << (i * 8); +} +} +} + +data &= mask; +data |= (val >> 32) & ~mask; +address_space_stl(env->address_space_iocsr, addr, + data, attrs, NULL); +} + +static int archid_cmp(const void *a, const void *b) +{ + CPUArchId *archid_a = (CPUArchId *)a; + CPUArchId *archid_b = (CPUArchId *)b; + + return archid_a->arch_id - archid_b->arch_id; +} + +static CPUArchId *find_cpu_by_archid(MachineState *ms, uint32_t id) +{ +CPUArchId apic_id, *found_cpu; + +apic_id.arch_id = id; +found_cpu = bsearch(&apic_id, ms->possible_cpus->cpus, +ms->possible_cpus->len, sizeof(*ms->possible_cpus->cpus), +archid_cmp); + +return found_cpu; +} + +static CPUState *ipi_getcpu(int arch_id) +{ +MachineState *machine = MACHINE(qdev_get_machine()); +CPUArchId *archid; + +archid = find_cpu_by_archid(machine, arch_id); +if (archid) { +return CPU(archid->cpu); +} + +return NULL; +} + +static MemTxResult mail_send(uint64_t val, MemTxAttrs attrs) +{ +uint32_t cpuid; +hwaddr addr; +CPUState *cs; + +cpuid = extract32(val, 16, 10); +cs = ipi_getcpu(cpuid); +if (cs == NULL) { +return MEMTX_DECODE_ERROR; +} + +/* override requester_id */ +addr = SMP_IPI_MAILBOX + CORE_BUF_20 + (val & 0x1c); +attrs.requester_id = cs->cpu_index; +send_ipi_data(&LOONGARCH_CPU(cs)->env, val, addr, attrs); +return MEMTX_OK; +} + +static MemTxResult any_send(uint64_t val, MemTxAttrs attrs) +{ +uint32_t cpuid; +hwaddr addr; +CPUState *cs; + +cpuid = extract32(val, 16, 10); +cs = ipi_getcpu(cpuid); +if (cs == NULL) { +return MEMTX_DECODE_ERROR; +} + +/* override requester_id */ +addr = val & 0x; +attrs.requester_id = cs->cpu_index; +send_ipi_data(&LOONGARCH_CPU(cs)->env, val, addr, attrs); +return MEMTX_OK; +} + +static MemTxResult loongarch_ipi_writel(void *opaque, hwaddr addr, uint64_t val, +unsigned size, MemTxAttrs attrs) +{ +LoongArchIPI *ipi = opaque; +IPICore *s; +int index = 0; +uint32_t cpuid; +uint8_t vector; +CPUState *cs; + +s = &ipi->cpu[attrs.requester_id]; +addr &= 0xff; +trace_loongarch_ipi_write(size, (uint64_t)addr, val); +switch (addr) { +case CORE_STATUS_OFF: +qemu_log_mask(LOG_GUEST_ERROR, "can not be written"); +break; +case CORE_EN_OFF: +s->en = val; +break; +case CORE_S
[RESEND PATCH 2/2] hw/intc: Restore loongarch_ipi for LoongArch
Currently LoongArch and MIPS architectures share loongson_ipi, and modifications to loongson_ipi by the MIPS architecture may lead to some unknown problems in the LoongArch architecture. In order to minimize the impact of this inter-architectural interaction, we believe that it is necessary to restore loongarch_ipi. Signed-off-by: Song Gao --- MAINTAINERS | 2 -- include/hw/intc/loongarch_ipi.h | 54 + include/hw/loongarch/virt.h | 2 +- hw/loongarch/virt.c | 4 +-- hw/intc/Kconfig | 3 ++ hw/intc/meson.build | 1 + hw/intc/trace-events| 3 ++ hw/loongarch/Kconfig| 2 +- 8 files changed, 65 insertions(+), 6 deletions(-) create mode 100644 include/hw/intc/loongarch_ipi.h diff --git a/MAINTAINERS b/MAINTAINERS index 19f67dc5d2..9d7575a7f1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1246,9 +1246,7 @@ F: configs/devices/loongarch64-softmmu/default.mak F: hw/loongarch/ F: include/hw/loongarch/virt.h F: include/hw/intc/loongarch_*.h -F: include/hw/intc/loongson_ipi.h F: hw/intc/loongarch_*.c -F: hw/intc/loongson_ipi.c F: include/hw/pci-host/ls7a.h F: hw/rtc/ls7a_rtc.c F: gdb-xml/loongarch*.xml diff --git a/include/hw/intc/loongarch_ipi.h b/include/hw/intc/loongarch_ipi.h new file mode 100644 index 00..1c1e834849 --- /dev/null +++ b/include/hw/intc/loongarch_ipi.h @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * LoongArch ipi interrupt header files + * + * Copyright (C) 2021 Loongson Technology Corporation Limited + */ + +#ifndef HW_LOONGARCH_IPI_H +#define HW_LOONGARCH_IPI_H + +#include "hw/sysbus.h" + +/* Mainy used by iocsr read and write */ +#define SMP_IPI_MAILBOX 0x1000ULL +#define CORE_STATUS_OFF 0x0 +#define CORE_EN_OFF 0x4 +#define CORE_SET_OFF 0x8 +#define CORE_CLEAR_OFF0xc +#define CORE_BUF_20 0x20 +#define CORE_BUF_28 0x28 +#define CORE_BUF_30 0x30 +#define CORE_BUF_38 0x38 +#define IOCSR_IPI_SEND0x40 +#define IOCSR_MAIL_SEND 0x48 +#define IOCSR_ANY_SEND0x158 + +#define MAIL_SEND_ADDR(SMP_IPI_MAILBOX + IOCSR_MAIL_SEND) +#define MAIL_SEND_OFFSET 0 +#define ANY_SEND_OFFSET (IOCSR_ANY_SEND - IOCSR_MAIL_SEND) + +#define IPI_MBX_NUM 4 + +#define TYPE_LOONGARCH_IPI "loongarch_ipi" +OBJECT_DECLARE_SIMPLE_TYPE(LoongArchIPI, LOONGARCH_IPI) + +typedef struct IPICore { +uint32_t status; +uint32_t en; +uint32_t set; +uint32_t clear; +/* 64bit buf divide into 2 32bit buf */ +uint32_t buf[IPI_MBX_NUM * 2]; +qemu_irq irq; +} IPICore; + +struct LoongArchIPI { +SysBusDevice parent_obj; +MemoryRegion ipi_iocsr_mem; +MemoryRegion ipi64_iocsr_mem; +uint32_t num_cpu; +IPICore *cpu; +}; + +#endif diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h index 8fdfacf268..fe92971de1 100644 --- a/include/hw/loongarch/virt.h +++ b/include/hw/loongarch/virt.h @@ -11,7 +11,7 @@ #include "target/loongarch/cpu.h" #include "hw/boards.h" #include "qemu/queue.h" -#include "hw/intc/loongson_ipi.h" +#include "hw/intc/loongarch_ipi.h" #include "hw/block/flash.h" #include "hw/loongarch/boot.h" diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index 8be2d2ff6a..6bef2f1165 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -23,7 +23,7 @@ #include "net/net.h" #include "hw/loader.h" #include "elf.h" -#include "hw/intc/loongson_ipi.h" +#include "hw/intc/loongarch_ipi.h" #include "hw/intc/loongarch_extioi.h" #include "hw/intc/loongarch_pch_pic.h" #include "hw/intc/loongarch_pch_msi.h" @@ -788,7 +788,7 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms) */ /* Create IPI device */ -ipi = qdev_new(TYPE_LOONGSON_IPI); +ipi = qdev_new(TYPE_LOONGARCH_IPI); qdev_prop_set_uint32(ipi, "num-cpu", ms->smp.cpus); sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal); diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig index 58b6d3a710..576c04e4e4 100644 --- a/hw/intc/Kconfig +++ b/hw/intc/Kconfig @@ -87,6 +87,9 @@ config GOLDFISH_PIC config M68K_IRQC bool +config LOONGARCH_IPI +bool + config LOONGSON_IPI bool diff --git a/hw/intc/meson.build b/hw/intc/meson.build index afd1aa51ee..19b719c336 100644 --- a/hw/intc/meson.build +++ b/hw/intc/meson.build @@ -70,6 +70,7 @@ specific_ss.add(when: ['CONFIG_KVM', 'CONFIG_XIVE'], if_true: files('spapr_xive_kvm.c')) specific_ss.add(when: 'CONFIG_M68K_IRQC', if_true: files('m68k_irqc.c')) specific_ss.add(when: 'CONFIG_LOONGSON_IPI', if_true: files('loongson_ipi.c')) +specific_ss.add(when: '
[PATCH] target/loongarch/gdbstub: Add vector registers support
GDB already support LoongArch vector extension[1], QEMU gdb adds LoongArch vector registers support, so that users can use 'info all-registers' to get all vector registers values. [1]: https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=1e9569f383a3d5a88ee07d0c2401bd95613c222e Signed-off-by: Song Gao --- based-on: https://patchew.org/QEMU/20240607035016.2975799-1-maob...@loongson.cn/ configs/targets/loongarch64-linux-user.mak | 2 +- configs/targets/loongarch64-softmmu.mak| 2 +- gdb-xml/loongarch-lasx.xml | 60 +++ gdb-xml/loongarch-lsx.xml | 59 ++ target/loongarch/gdbstub.c | 70 +- 5 files changed, 189 insertions(+), 4 deletions(-) create mode 100644 gdb-xml/loongarch-lasx.xml create mode 100644 gdb-xml/loongarch-lsx.xml diff --git a/configs/targets/loongarch64-linux-user.mak b/configs/targets/loongarch64-linux-user.mak index d878e5a113..ea9b7e839a 100644 --- a/configs/targets/loongarch64-linux-user.mak +++ b/configs/targets/loongarch64-linux-user.mak @@ -1,4 +1,4 @@ # Default configuration for loongarch64-linux-user TARGET_ARCH=loongarch64 TARGET_BASE_ARCH=loongarch -TARGET_XML_FILES=gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu.xml +TARGET_XML_FILES=gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu.xml gdb-xml/loongarch-lsx.xml gdb-xml/loongarch-lasx.xml diff --git a/configs/targets/loongarch64-softmmu.mak b/configs/targets/loongarch64-softmmu.mak index 65b65e0c34..ce19ab6a16 100644 --- a/configs/targets/loongarch64-softmmu.mak +++ b/configs/targets/loongarch64-softmmu.mak @@ -2,6 +2,6 @@ TARGET_ARCH=loongarch64 TARGET_BASE_ARCH=loongarch TARGET_KVM_HAVE_GUEST_DEBUG=y TARGET_SUPPORTS_MTTCG=y -TARGET_XML_FILES= gdb-xml/loongarch-base32.xml gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu.xml +TARGET_XML_FILES= gdb-xml/loongarch-base32.xml gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu.xml gdb-xml/loongarch-lsx.xml gdb-xml/loongarch-lasx.xml # all boards require libfdt TARGET_NEED_FDT=y diff --git a/gdb-xml/loongarch-lasx.xml b/gdb-xml/loongarch-lasx.xml new file mode 100644 index 00..753b982c65 --- /dev/null +++ b/gdb-xml/loongarch-lasx.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gdb-xml/loongarch-lsx.xml b/gdb-xml/loongarch-lsx.xml new file mode 100644 index 00..51af1c6fd5 --- /dev/null +++ b/gdb-xml/loongarch-lsx.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/target/loongarch/gdbstub.c b/target/loongarch/gdbstub.c index a0e1439bd0..c9e2ddd943 100644 --- a/target/loongarch/gdbstub.c +++ b/target/loongarch/gdbstub.c @@ -116,8 +116,74 @@ static int loongarch_gdb_set_fpu(CPUState *cs, uint8_t *mem_buf, int n) return length; } +static int loongarch_gdb_get_vec(CPUState *cs, GByteArray *mem_buf, int n, int vl) +{ +LoongArchCPU *cpu = LOONGARCH_CPU(cs); +CPULoongArchState *env = &cpu->env; +int i, length = 0; + +if (0 <= n && n < 32) { +for (i = 0; i < vl / 64; i++) { +length += gdb_get_reg64(mem_buf, env->fpr[n].vreg.D(i)); + } +} + +return length; +} + +static int loongarch_gdb_set_vec(CPUState *cs, uint8_t *mem_buf, int n, int vl) +{ +LoongArchCPU *cpu = LOONGARCH_CPU(cs); +CPULoongArchState *env = &cpu->env; +int i, length = 0; + +if (0 <= n && n < 32) { +for (i = 0; i < vl / 64; i++) { +env->fpr[n].vreg.D(i) = ldq_le_p(mem_buf + 8 * i); +length += 8; +} +} + +return length; +} + +static int loongarch_gdb_get_lsx(CPUState *cs, GByteArray *mem_buf, int n) +{ +return loongarch_gdb_get_vec(cs, mem_buf, n, LSX_LEN); +} + +static int loongarch_gdb_set_lsx(CPUState *cs, uint8_t *mem_buf, int n) +{ +return loongarch_gdb_set_vec(cs, mem_buf, n, LSX_LEN); +} + +static int loongarch_gdb_get_lasx(CPUState *cs, GByteArray *mem_buf, int n) +{ +return loongarch_gdb_get_vec(cs, mem_buf, n, LASX_LEN); +} + +static int loongarch_gdb_set_lasx(CPUState *cs, uint8_t *mem_buf, int n) +{ +return loongarch_gdb_set_vec(cs, mem_buf, n, LASX_LEN); +} + void loongarch_cpu_register_gdb_regs_for_features(CPUState *cs) { -gdb_register_coprocessor(cs, loongarch_gdb_get_fpu, loongarch_gdb_set_fpu, - gdb_find_static_feature("loongarch-fpu.xml"), 0); +LoongArchCPU *cpu = LOONGARCH_CPU(cs); +CPULoongArchState *env = &cpu->env; + +if (FIELD_EX32(env->cpucfg[2], CPUCFG2, FP)) {
[PATCH] tcg/loongarch64: Fix tcg_out_movi tcg_debug_assert() error
On Loongnix 20.5 systems, QEMU configure with option '--enable-debug' or '--enable-debug-tcg ', booting the Loongnix 20.5 VM in tcg mode will get an assertion error. "... [ 31.484992] [drm] Initialized virtio_gpu 0.0.1 0 for virtio1 on minor 0 qemu-system-loongarch64: /home1/gaosong/code/github/clean/qemu/tcg/loongarch64/tcg-target.c.inc:394:tcg_out_movi: 假设 ‘offset_hi == sextreg(offset_hi, 0, 20)’ 失败。 ./start.sh: 行 14: 2433006 已放弃 (核心已转储)./build/qemu-system-loongarch64 --accel tcg -m 8G -cpu la464 -machine virt -smp 8 -serial stdio -bios ./QEMU_EFI.fd -monitor telnet:localhost:4498,server,nowait -device virtio-gpu-pci -net nic, -net user -device nec-usb-xhci,id=xhci,addr=0x1b -device usb-tablet,id=tablet,bus=xhci.0,port=1 -device usb-kbd,id=keyboard,bus=xhci.0,port=2 -device virtio-blk-pci,drive=test -drive if=none,id=test,file=./Loongnix-20.5.cartoon.mini.loongarch64.cn.qcow2 " The values of offset_hi and sextreg(offset_hi, 0, 20) are: "[ 29.975240] virtio_gpu virtio1: fb0: virtiodrmfb frame buffer device offset_hi is 8 sextreg(offset_hi, 0, 20) is fff8 offset_hi is 8 sextreg(offset_hi, 0, 20) is fff8 offset_hi is 8 sextreg(offset_hi, 0, 20) is fff8 ..." When pcalau12i + ori is not satisfied, we should use other methods instead, instead of generating an assertion error. Cc: qemu-sta...@nongnu.org Reported-by: yijun Signed-off-by: Song Gao --- tcg/loongarch64/tcg-target.c.inc | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc index 06ca1ab11c..592494c48d 100644 --- a/tcg/loongarch64/tcg-target.c.inc +++ b/tcg/loongarch64/tcg-target.c.inc @@ -391,7 +391,9 @@ static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd, pc_hi = (val - pc_offset) >> 12; offset_hi = val_hi - pc_hi; -tcg_debug_assert(offset_hi == sextreg(offset_hi, 0, 20)); +if (offset_hi != sextreg(offset_hi, 0, 20)) { +goto out; +} tcg_out_opc_pcalau12i(s, rd, offset_hi); if (val_lo != 0) { tcg_out_opc_ori(s, rd, rd, val_lo & 0xfff); @@ -399,6 +401,7 @@ static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd, return; } +out: hi12 = sextreg(val, 12, 20); hi32 = sextreg(val, 32, 20); hi52 = sextreg(val, 52, 12); -- 2.39.3
[RFC PATCH v3] target/loongarch/kvm: Implement LoongArch PMU extension.
Implement PMU extension for LoongArch kvm mode. Use OnOffAuto type variable pmu to check the PMU feature. If the PMU Feature is not supported with KVM host, it reports error if there is pmu=on command line. If there is no any command line about pmu parameter, it checks whether KVM host supports the PMU Feature and set the corresponding value in cpucfg. Signed-off-by: Song Gao --- v3: - Use OnOffAuto type variable pmu to check the PMU feature. - Link to v2: https://patchew.org/QEMU/20240515040611.998507-1-gaos...@loongson.cn/ v2: - Drop the property 'pmnum'. - Link to v1: https://patchew.org/QEMU/20240514094630.988617-1-gaos...@loongson.cn/ This patch adds the 'RFC' heading because it requires the kernel to merge into patch[1] first [1]:https://lore.kernel.org/all/20240613120539.41021-1-gaos...@loongson.cn/ linux-headers/asm-loongarch/kvm.h | 3 ++ target/loongarch/cpu.c| 56 +++ target/loongarch/cpu.h| 5 +++ target/loongarch/kvm/kvm.c| 16 target/loongarch/kvm/kvm_loongarch.h | 16 target/loongarch/loongarch-qmp-cmds.c | 2 +- 6 files changed, 97 insertions(+), 1 deletion(-) diff --git a/linux-headers/asm-loongarch/kvm.h b/linux-headers/asm-loongarch/kvm.h index f9abef3823..afe604d301 100644 --- a/linux-headers/asm-loongarch/kvm.h +++ b/linux-headers/asm-loongarch/kvm.h @@ -83,6 +83,9 @@ struct kvm_fpu { #define KVM_IOC_CPUCFG(REG) LOONGARCH_REG_64(KVM_REG_LOONGARCH_CPUCFG, REG) #define KVM_LOONGARCH_VCPU_CPUCFG 0 +#define KVM_LOONGARCH_VM_FEAT_CTRL 0 +#define KVM_LOONGARCH_VM_FEAT_PMU 0 + struct kvm_debug_exit_arch { }; diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 270f711f11..e973f611e5 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -571,6 +571,35 @@ static void loongarch_cpu_disas_set_info(CPUState *s, disassemble_info *info) info->print_insn = print_insn_loongarch; } +static void loongarch_cpu_check_pmu(CPUState *cs, Error **errp) +{ +LoongArchCPU *cpu = LOONGARCH_CPU(cs); +bool kvm_supported; + +kvm_supported = kvm_feature_supported(cs, LOONGARCH_FEATURE_PMU); +if (cpu->pmu == ON_OFF_AUTO_ON) { +if (kvm_supported) { +cpu->env.cpucfg[6] = FIELD_DP32(cpu->env.cpucfg[6], CPUCFG6, PMP, 1); +cpu->env.cpucfg[6] = FIELD_DP32(cpu->env.cpucfg[6], CPUCFG6, PMNUM, 3); +cpu->env.cpucfg[6] = FIELD_DP32(cpu->env.cpucfg[6], CPUCFG6, PMBITS, 63); +cpu->env.cpucfg[6] = FIELD_DP32(cpu->env.cpucfg[6], CPUCFG6, UPM, 1); +} else { +error_setg(errp, "'pmu' feature not supported by KVM on this host."); +return; +} +} else if ((cpu->pmu == ON_OFF_AUTO_AUTO) && kvm_supported) { +cpu->env.cpucfg[6] = FIELD_DP32(cpu->env.cpucfg[6], CPUCFG6, PMP, 1); +cpu->env.cpucfg[6] = FIELD_DP32(cpu->env.cpucfg[6], CPUCFG6, PMNUM, 3); +cpu->env.cpucfg[6] = FIELD_DP32(cpu->env.cpucfg[6], CPUCFG6, PMBITS, 63); +cpu->env.cpucfg[6] = FIELD_DP32(cpu->env.cpucfg[6], CPUCFG6, UPM, 1); +} +} + +static void loongarch_cpu_feature_realize(CPUState *cs, Error **errp) +{ +loongarch_cpu_check_pmu(cs, errp); +} + static void loongarch_cpu_realizefn(DeviceState *dev, Error **errp) { CPUState *cs = CPU(dev); @@ -584,6 +613,11 @@ static void loongarch_cpu_realizefn(DeviceState *dev, Error **errp) } loongarch_cpu_register_gdb_regs_for_features(cs); +loongarch_cpu_feature_realize(cs, &local_err); +if (local_err != NULL) { +error_propagate(errp, local_err); +return; +} cpu_reset(cs); qemu_init_vcpu(cs); @@ -643,12 +677,34 @@ static void loongarch_set_lasx(Object *obj, bool value, Error **errp) } } +static bool loongarch_get_pmu(Object *obj, Error **errp) +{ +return LOONGARCH_CPU(obj)->pmu != ON_OFF_AUTO_OFF; +} + +static void loongarch_set_pmu(Object *obj, bool value, Error **errp) +{ +LoongArchCPU *cpu = LOONGARCH_CPU(obj); + +cpu->pmu = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF; +} + void loongarch_cpu_post_init(Object *obj) { +LoongArchCPU *cpu = LOONGARCH_CPU(obj); + object_property_add_bool(obj, "lsx", loongarch_get_lsx, loongarch_set_lsx); object_property_add_bool(obj, "lasx", loongarch_get_lasx, loongarch_set_lasx); + +if (kvm_enabled()) { +cpu->pmu = ON_OFF_AUTO_AUTO; +object_property_add_bool(obj, "pmu", loongarch_get_pmu, + loongarch_set_pmu); +} else { +cpu->pmu = ON_OFF_AUTO_OFF; +} } static void loongarch_cpu_init(Object *obj) diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index 6c41fafb70..cfc87f7f09 100644
[PULL 0/6] loongarch-to-apply queue
The following changes since commit db2feb2df8d19592c9859efb3f682404e0052957: Merge tag 'pull-misc-20240605' of https://gitlab.com/rth7680/qemu into staging (2024-06-05 14:17:01 -0700) are available in the Git repository at: https://gitlab.com/gaosong/qemu.git tags/pull-loongarch-20240606 for you to fetch changes up to 78f932ea1f7b3b9b0ac628dc2a91281318fe51fa: target/loongarch: fix a wrong print in cpu dump (2024-06-06 11:58:06 +0800) pull-loongarch-20240606 Bibo Mao (2): tests/libqos: Add loongarch virt machine node tests/qtest: Add numa test for loongarch system Song Gao (3): hw/intc/loongarch_extioi: Add extioi virt extension definition hw/loongarch/virt: Use MemTxAttrs interface for misc ops hw/loongarch/virt: Enable extioi virt extension lanyanzhi (1): target/loongarch: fix a wrong print in cpu dump hw/intc/loongarch_extioi.c | 88 - hw/loongarch/virt.c | 184 +++- include/hw/intc/loongarch_extioi.h | 21 include/hw/loongarch/virt.h | 1 + target/loongarch/cpu.c | 2 +- target/loongarch/cpu.h | 1 + tests/qtest/libqos/loongarch-virt-machine.c | 114 + tests/qtest/libqos/meson.build | 1 + tests/qtest/meson.build | 2 +- tests/qtest/numa-test.c | 53 10 files changed, 428 insertions(+), 39 deletions(-) create mode 100644 tests/qtest/libqos/loongarch-virt-machine.c
[PULL 4/6] hw/loongarch/virt: Use MemTxAttrs interface for misc ops
Use MemTxAttrs interface read_with_attrs/write_with_attrs for virt_iocsr_misc_ops. Signed-off-by: Song Gao Reviewed-by: Bibo Mao Message-Id: <20240528083855.1912757-3-gaos...@loongson.cn> --- hw/loongarch/virt.c | 36 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index 2b5ae45939..0cef33a904 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -900,37 +900,49 @@ static void virt_firmware_init(LoongArchVirtMachineState *lvms) } -static void virt_iocsr_misc_write(void *opaque, hwaddr addr, - uint64_t val, unsigned size) +static MemTxResult virt_iocsr_misc_write(void *opaque, hwaddr addr, + uint64_t val, unsigned size, + MemTxAttrs attrs) { +return MEMTX_OK; } -static uint64_t virt_iocsr_misc_read(void *opaque, hwaddr addr, unsigned size) +static MemTxResult virt_iocsr_misc_read(void *opaque, hwaddr addr, +uint64_t *data, +unsigned size, MemTxAttrs attrs) { -uint64_t ret; +uint64_t ret = 0; switch (addr) { case VERSION_REG: -return 0x11ULL; +ret = 0x11ULL; +break; case FEATURE_REG: ret = BIT(IOCSRF_MSI) | BIT(IOCSRF_EXTIOI) | BIT(IOCSRF_CSRIPI); if (kvm_enabled()) { ret |= BIT(IOCSRF_VM); } -return ret; +break; case VENDOR_REG: -return 0x6e6f73676e6f6f4cULL; /* "Loongson" */ +ret = 0x6e6f73676e6f6f4cULL; /* "Loongson" */ +break; case CPUNAME_REG: -return 0x303030354133ULL; /* "3A5000" */ +ret = 0x303030354133ULL; /* "3A5000" */ +break; case MISC_FUNC_REG: -return BIT_ULL(IOCSRM_EXTIOI_EN); +ret = BIT_ULL(IOCSRM_EXTIOI_EN); +break; +default: +g_assert_not_reached(); } -return 0ULL; + +*data = ret; +return MEMTX_OK; } static const MemoryRegionOps virt_iocsr_misc_ops = { -.read = virt_iocsr_misc_read, -.write = virt_iocsr_misc_write, +.read_with_attrs = virt_iocsr_misc_read, +.write_with_attrs = virt_iocsr_misc_write, .endianness = DEVICE_LITTLE_ENDIAN, .valid = { .min_access_size = 4, -- 2.34.1
[PULL 2/6] tests/qtest: Add numa test for loongarch system
From: Bibo Mao Add numa test case for loongarch system, it passes to run with command "make check-qtest". Signed-off-by: Bibo Mao Acked-by: Thomas Huth Tested-by: Song Gao Message-Id: <20240528082155.938586-1-maob...@loongson.cn> Signed-off-by: Song Gao --- tests/qtest/meson.build | 2 +- tests/qtest/numa-test.c | 53 + 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index b98fae6a6d..12792948ff 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -140,7 +140,7 @@ qtests_hppa = ['boot-serial-test'] + \ (config_all_devices.has_key('CONFIG_VGA') ? ['display-vga-test'] : []) qtests_loongarch64 = qtests_filter + \ - ['boot-serial-test'] + ['boot-serial-test', 'numa-test'] qtests_m68k = ['boot-serial-test'] + \ qtests_filter diff --git a/tests/qtest/numa-test.c b/tests/qtest/numa-test.c index 7aa262dbb9..5518f6596b 100644 --- a/tests/qtest/numa-test.c +++ b/tests/qtest/numa-test.c @@ -265,6 +265,54 @@ static void aarch64_numa_cpu(const void *data) qtest_quit(qts); } +static void loongarch64_numa_cpu(const void *data) +{ +QDict *resp; +QList *cpus; +QObject *e; +QTestState *qts; +g_autofree char *cli = NULL; + +cli = make_cli(data, "-machine " +"smp.cpus=2,smp.sockets=2,smp.cores=1,smp.threads=1 " +"-numa node,nodeid=0,memdev=ram -numa node,nodeid=1 " +"-numa cpu,node-id=0,socket-id=1,core-id=0,thread-id=0 " +"-numa cpu,node-id=1,socket-id=0,core-id=0,thread-id=0"); +qts = qtest_init(cli); +cpus = get_cpus(qts, &resp); +g_assert(cpus); + +while ((e = qlist_pop(cpus))) { +QDict *cpu, *props; +int64_t socket, core, thread, node; + +cpu = qobject_to(QDict, e); +g_assert(qdict_haskey(cpu, "props")); +props = qdict_get_qdict(cpu, "props"); + +g_assert(qdict_haskey(props, "node-id")); +node = qdict_get_int(props, "node-id"); +g_assert(qdict_haskey(props, "socket-id")); +socket = qdict_get_int(props, "socket-id"); +g_assert(qdict_haskey(props, "core-id")); +core = qdict_get_int(props, "core-id"); +g_assert(qdict_haskey(props, "thread-id")); +thread = qdict_get_int(props, "thread-id"); + +if (socket == 0 && core == 0 && thread == 0) { +g_assert_cmpint(node, ==, 1); +} else if (socket == 1 && core == 0 && thread == 0) { +g_assert_cmpint(node, ==, 0); +} else { +g_assert(false); +} +qobject_unref(e); +} + +qobject_unref(resp); +qtest_quit(qts); +} + static void pc_dynamic_cpu_cfg(const void *data) { QObject *e; @@ -593,6 +641,11 @@ int main(int argc, char **argv) aarch64_numa_cpu); } +if (!strcmp(arch, "loongarch64")) { +qtest_add_data_func("/numa/loongarch64/cpu/explicit", args, +loongarch64_numa_cpu); +} + out: return g_test_run(); } -- 2.34.1
[PULL 5/6] hw/loongarch/virt: Enable extioi virt extension
This patch adds a new board attribute 'v-eiointc'. A value of true enables the virt extended I/O interrupt controller. VMs working in kvm mode have 'v-eiointc' enabled by default. Signed-off-by: Song Gao Reviewed-by: Bibo Mao Message-Id: <20240528083855.1912757-4-gaos...@loongson.cn> --- hw/loongarch/virt.c | 88 +++-- include/hw/loongarch/virt.h | 1 + target/loongarch/cpu.h | 1 + 3 files changed, 87 insertions(+), 3 deletions(-) diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index 0cef33a904..66cef201ab 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -11,6 +11,7 @@ #include "hw/boards.h" #include "hw/char/serial.h" #include "sysemu/kvm.h" +#include "sysemu/tcg.h" #include "sysemu/sysemu.h" #include "sysemu/qtest.h" #include "sysemu/runstate.h" @@ -48,6 +49,31 @@ #include "hw/virtio/virtio-iommu.h" #include "qemu/error-report.h" +static bool virt_is_veiointc_enabled(LoongArchVirtMachineState *lvms) +{ +if (lvms->veiointc == ON_OFF_AUTO_OFF) { +return false; +} +return true; +} + +static void virt_get_veiointc(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ +LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj); +OnOffAuto veiointc = lvms->veiointc; + +visit_type_OnOffAuto(v, name, &veiointc, errp); +} + +static void virt_set_veiointc(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ +LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj); + +visit_type_OnOffAuto(v, name, &lvms->veiointc, errp); +} + static PFlashCFI01 *virt_flash_create1(LoongArchVirtMachineState *lvms, const char *name, const char *alias_prop_name) @@ -790,9 +816,16 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms) /* Create EXTIOI device */ extioi = qdev_new(TYPE_LOONGARCH_EXTIOI); qdev_prop_set_uint32(extioi, "num-cpu", ms->smp.cpus); +if (virt_is_veiointc_enabled(lvms)) { +qdev_prop_set_bit(extioi, "has-virtualization-extension", true); +} sysbus_realize_and_unref(SYS_BUS_DEVICE(extioi), &error_fatal); memory_region_add_subregion(&lvms->system_iocsr, APIC_BASE, - sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 0)); +sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 0)); +if (virt_is_veiointc_enabled(lvms)) { +memory_region_add_subregion(&lvms->system_iocsr, EXTIOI_VIRT_BASE, +sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 1)); +} /* * connect ext irq to the cpu irq @@ -899,11 +932,37 @@ static void virt_firmware_init(LoongArchVirtMachineState *lvms) } } - static MemTxResult virt_iocsr_misc_write(void *opaque, hwaddr addr, uint64_t val, unsigned size, MemTxAttrs attrs) { +LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(opaque); +uint64_t features; + +switch (addr) { +case MISC_FUNC_REG: +if (!virt_is_veiointc_enabled(lvms)) { +return MEMTX_OK; +} + +features = address_space_ldl(&lvms->as_iocsr, + EXTIOI_VIRT_BASE + EXTIOI_VIRT_CONFIG, + attrs, NULL); +if (val & BIT_ULL(IOCSRM_EXTIOI_EN)) { +features |= BIT(EXTIOI_ENABLE); +} +if (val & BIT_ULL(IOCSRM_EXTIOI_INT_ENCODE)) { +features |= BIT(EXTIOI_ENABLE_INT_ENCODE); +} + +address_space_stl(&lvms->as_iocsr, + EXTIOI_VIRT_BASE + EXTIOI_VIRT_CONFIG, + features, attrs, NULL); +break; +default: +g_assert_not_reached(); +} + return MEMTX_OK; } @@ -911,7 +970,9 @@ static MemTxResult virt_iocsr_misc_read(void *opaque, hwaddr addr, uint64_t *data, unsigned size, MemTxAttrs attrs) { +LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(opaque); uint64_t ret = 0; +int features; switch (addr) { case VERSION_REG: @@ -930,7 +991,20 @@ static MemTxResult virt_iocsr_misc_read(void *opaque, hwaddr addr, ret = 0x303030354133ULL; /* "3A5000" */ break; case MISC_FUNC_REG: -ret = BIT_ULL(IOCSRM_EXTIOI_EN); +if (!virt_is_veiointc_enabled(lvms)) { +ret |= BIT_ULL(IOCSRM_EXTIOI_EN); +break; +} + +features = address_space_ldl(&lvms->as_iocsr, +
[PULL 1/6] tests/libqos: Add loongarch virt machine node
From: Bibo Mao Add loongarch virt machine to the graph. It is a modified copy of the existing riscv virtmachine in riscv-virt-machine.c It contains a generic-pcihost controller, and an extra function loongarch_config_qpci_bus() to configure GPEX pci host controller information, such as ecam and pio_base addresses. Also hotplug handle checking about TYPE_VIRTIO_IOMMU_PCI device is added on loongarch virt machine, since virtio_mmu_pci device requires it. Signed-off-by: Bibo Mao Acked-by: Thomas Huth Message-Id: <20240528082053.938564-1-maob...@loongson.cn> Signed-off-by: Song Gao --- hw/loongarch/virt.c | 2 + tests/qtest/libqos/loongarch-virt-machine.c | 114 tests/qtest/libqos/meson.build | 1 + 3 files changed, 117 insertions(+) create mode 100644 tests/qtest/libqos/loongarch-virt-machine.c diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index 3e6e93edf3..2d7f718570 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -45,6 +45,7 @@ #include "sysemu/tpm.h" #include "sysemu/block-backend.h" #include "hw/block/flash.h" +#include "hw/virtio/virtio-iommu.h" #include "qemu/error-report.h" static PFlashCFI01 *virt_flash_create1(LoongArchVirtMachineState *lvms, @@ -1213,6 +1214,7 @@ static HotplugHandler *virt_get_hotplug_handler(MachineState *machine, MachineClass *mc = MACHINE_GET_CLASS(machine); if (device_is_dynamic_sysbus(mc, dev) || +object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI) || memhp_type_supported(dev)) { return HOTPLUG_HANDLER(machine); } diff --git a/tests/qtest/libqos/loongarch-virt-machine.c b/tests/qtest/libqos/loongarch-virt-machine.c new file mode 100644 index 00..c12089c015 --- /dev/null +++ b/tests/qtest/libqos/loongarch-virt-machine.c @@ -0,0 +1,114 @@ +/* + * libqos driver framework + * + * Copyright (c) 2018 Emanuele Giuseppe Esposito + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/> + */ + +#include "qemu/osdep.h" +#include "../libqtest.h" +#include "qemu/module.h" +#include "libqos-malloc.h" +#include "qgraph.h" +#include "virtio-mmio.h" +#include "generic-pcihost.h" +#include "hw/pci/pci_regs.h" + +#define LOONGARCH_PAGE_SIZE 0x1000 +#define LOONGARCH_VIRT_RAM_ADDR 0x10 +#define LOONGARCH_VIRT_RAM_SIZE 0xFF0 + +#define LOONGARCH_VIRT_PIO_BASE 0x1800 +#define LOONGARCH_VIRT_PCIE_PIO_OFFSET0x4000 +#define LOONGARCH_VIRT_PCIE_PIO_LIMIT 0x1 +#define LOONGARCH_VIRT_PCIE_ECAM_BASE 0x2000 +#define LOONGARCH_VIRT_PCIE_MMIO32_BASE 0x4000 +#define LOONGARCH_VIRT_PCIE_MMIO32_LIMIT 0x8000 + +typedef struct QVirtMachine QVirtMachine; + +struct QVirtMachine { +QOSGraphObject obj; +QGuestAllocator alloc; +QVirtioMMIODevice virtio_mmio; +QGenericPCIHost bridge; +}; + +static void virt_destructor(QOSGraphObject *obj) +{ +QVirtMachine *machine = (QVirtMachine *) obj; +alloc_destroy(&machine->alloc); +} + +static void *virt_get_driver(void *object, const char *interface) +{ +QVirtMachine *machine = object; +if (!g_strcmp0(interface, "memory")) { +return &machine->alloc; +} + +fprintf(stderr, "%s not present in loongarch/virtio\n", interface); +g_assert_not_reached(); +} + +static QOSGraphObject *virt_get_device(void *obj, const char *device) +{ +QVirtMachine *machine = obj; +if (!g_strcmp0(device, "generic-pcihost")) { +return &machine->bridge.obj; +} else if (!g_strcmp0(device, "virtio-mmio")) { +return &machine->virtio_mmio.obj; +} + +fprintf(stderr, "%s not present in loongarch/virt\n", device); +g_assert_not_reached(); +} + +static void loongarch_config_qpci_bus(QGenericPCIBus *qpci) +{ +qpci->gpex_pio_base = LOONGARCH_VIRT_PIO_BASE; +qpci->bus.pio_alloc_ptr = LOONGARCH_VIRT_PCIE_PIO_OFFSET; +qpci->bus.pio_limit = LOONGARCH_VIRT_PCIE_PIO_LIMIT; +qpci->bus.mmio_alloc_ptr = LOONGARCH_VIRT_PCIE_MMIO32_BASE; +qpci->bus.mmio_limit = LOONGARCH_VIRT_PCIE_MMIO32_LIMIT; +qpci->ecam_alloc_ptr = LOONGARCH_VIRT_PCIE_ECAM_BASE; +} + +static void *qos_create_mac
[PULL 3/6] hw/intc/loongarch_extioi: Add extioi virt extension definition
On LoongArch, IRQs can be routed to four vcpus with hardware extended IRQ model. This patch adds the virt extension definition so that the IRQ can route to 256 vcpus. 1.Extended IRQ model: | +---+ +-|+ +---+ | IPI/Timer | --> | CPUINTC(0-3)|(4-255) | <-- | IPI/Timer | +---+ +-|+ +---+ ^ | | +-+ | EIOINTC | +-+ ^ ^ | | +-+ +-+ | PCH-PIC | | PCH-MSI | +-+ +-+ ^ ^ ^ | | | ++ +-+ +-+ | UARTs | | Devices | | Devices | ++ +-+ +-+ 2.Virt extended IRQ model: +-++---+ +---+ | IPI |--> | CPUINTC(0-255)| <-- | Timer | +-++---+ +---+ ^ | +---+ | V-EIOINTC | +---+ ^ ^ | | +-+ +-+ | PCH-PIC | | PCH-MSI | +-+ +-+ ^ ^ ^ | | | ++ +-+ +-+ | UARTs | | Devices | | Devices | ++ +-+ +-+ Signed-off-by: Song Gao Reviewed-by: Bibo Mao Message-Id: <20240528083855.1912757-2-gaos...@loongson.cn> --- hw/intc/loongarch_extioi.c | 88 -- hw/loongarch/virt.c| 60 +--- include/hw/intc/loongarch_extioi.h | 21 +++ 3 files changed, 146 insertions(+), 23 deletions(-) diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c index 0b358548eb..1e8e0114dc 100644 --- a/hw/intc/loongarch_extioi.c +++ b/hw/intc/loongarch_extioi.c @@ -143,10 +143,13 @@ static inline void extioi_update_sw_coremap(LoongArchExtIOI *s, int irq, for (i = 0; i < 4; i++) { cpu = val & 0xff; -cpu = ctz32(cpu); -cpu = (cpu >= 4) ? 0 : cpu; val = val >> 8; +if (!(s->status & BIT(EXTIOI_ENABLE_CPU_ENCODE))) { +cpu = ctz32(cpu); +cpu = (cpu >= 4) ? 0 : cpu; +} + if (s->sw_coremap[irq + i] == cpu) { continue; } @@ -265,6 +268,61 @@ static const MemoryRegionOps extioi_ops = { .endianness = DEVICE_LITTLE_ENDIAN, }; +static MemTxResult extioi_virt_readw(void *opaque, hwaddr addr, uint64_t *data, + unsigned size, MemTxAttrs attrs) +{ +LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque); + +switch (addr) { +case EXTIOI_VIRT_FEATURES: +*data = s->features; +break; +case EXTIOI_VIRT_CONFIG: +*data = s->status; +break; +default: +g_assert_not_reached(); +} + +return MEMTX_OK; +} + +static MemTxResult extioi_virt_writew(void *opaque, hwaddr addr, + uint64_t val, unsigned size, + MemTxAttrs attrs) +{ +LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque); + +switch (addr) { +case EXTIOI_VIRT_FEATURES: +return MEMTX_ACCESS_ERROR; + +case EXTIOI_VIRT_CONFIG: +/* + * extioi features can only be set at disabled status + */ +if ((s->status & BIT(EXTIOI_ENABLE)) && val) { +return MEMTX_ACCESS_ERROR; +} + +s->status = val & s->features; +break; +default: +g_assert_not_reached(); +} +return MEMTX_OK; +} + +static const MemoryRegionOps extioi_virt_ops = { +.read_with_attrs = extioi_virt_readw, +.write_with_attrs = extioi_virt_writew, +.impl.min_access_size = 4, +.impl.max_access_size = 4, +.valid.min_access_size = 4, +.valid.max_access_size = 8, +.endianness = DEVICE_LITTLE_ENDIAN, +}; + static void loongarch_extioi_realize(DeviceState *dev, Error **errp) { LoongArchExtIOI *s = LOONGARCH_EXTIOI(dev); @@ -284,6 +342,16 @@ static void loongarch_extioi_realize(DeviceState *dev, Error **errp) memory_region_init_io(&s->extioi_system_mem, OBJECT(s), &extioi_ops, s, "extioi_system_mem", 0x900); sysbus_init_mmio(sbd, &s->extioi_system_mem); + +if (s->features & BIT(EXTIOI_HAS_VIRT_EXTENSION)) { +memory_region_init_io(&s->virt_extend, OBJECT(s), &extioi_virt_ops, + s, "extioi_virt", EXTIOI_VIRT_SIZE
[PULL 6/6] target/loongarch: fix a wrong print in cpu dump
From: lanyanzhi description: loongarch_cpu_dump_state() want to dump all loongarch cpu state registers, but there is a tiny typographical error when printing "PRCFG2". Cc: qemu-sta...@nongnu.org Signed-off-by: lanyanzhi Reviewed-by: Richard Henderson Reviewed-by: Song Gao Message-Id: <20240604073831.90-1-lanyanzhi...@ict.ac.cn> Signed-off-by: Song Gao --- target/loongarch/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index b5c1ec94af..270f711f11 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -707,7 +707,7 @@ void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int flags) qemu_fprintf(f, "EENTRY=%016" PRIx64 "\n", env->CSR_EENTRY); qemu_fprintf(f, "PRCFG1=%016" PRIx64 ", PRCFG2=%016" PRIx64 "," " PRCFG3=%016" PRIx64 "\n", - env->CSR_PRCFG1, env->CSR_PRCFG3, env->CSR_PRCFG3); + env->CSR_PRCFG1, env->CSR_PRCFG2, env->CSR_PRCFG3); qemu_fprintf(f, "TLBRENTRY=%016" PRIx64 "\n", env->CSR_TLBRENTRY); qemu_fprintf(f, "TLBRBADV=%016" PRIx64 "\n", env->CSR_TLBRBADV); qemu_fprintf(f, "TLBRERA=%016" PRIx64 "\n", env->CSR_TLBRERA); -- 2.34.1