[PULL v2 6/8] linux-headers: Update to Linux v6.12-rc5

2024-11-02 Thread Song Gao
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

2024-11-02 Thread Song Gao
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

2024-11-02 Thread Song Gao
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

2024-11-02 Thread Song Gao
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

2024-11-02 Thread Song Gao
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

2024-11-02 Thread Song Gao
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

2024-11-02 Thread Song Gao
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

2024-11-02 Thread Song Gao
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

2024-11-02 Thread Song Gao
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

2024-10-29 Thread Song Gao
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

2024-10-29 Thread Song Gao
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

2024-10-24 Thread Song Gao
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

2024-10-24 Thread Song Gao
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

2024-10-24 Thread Song Gao
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

2024-10-24 Thread Song Gao
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

2024-10-24 Thread Song Gao
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

2024-10-24 Thread Song Gao
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

2024-10-24 Thread Song Gao
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[]

2024-10-16 Thread Song Gao
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

2024-10-16 Thread Song Gao
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

2024-10-16 Thread Song Gao
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

2024-10-16 Thread Song Gao
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

2024-10-16 Thread Song Gao
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

2024-10-16 Thread Song Gao
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()

2024-10-09 Thread Song Gao
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

2024-10-09 Thread Song Gao
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

2024-10-09 Thread Song Gao
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

2024-10-09 Thread Song Gao
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()

2024-10-09 Thread Song Gao
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()

2024-10-09 Thread Song Gao
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[]

2024-09-29 Thread Song Gao
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

2024-09-29 Thread Song Gao
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

2024-09-29 Thread Song Gao
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

2024-09-29 Thread Song Gao
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

2024-09-29 Thread Song Gao
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

2024-09-29 Thread Song Gao
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

2024-09-29 Thread Song Gao
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

2024-09-29 Thread Song Gao
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

2024-09-12 Thread Song Gao
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

2024-09-12 Thread Song Gao
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

2024-09-12 Thread Song Gao
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

2024-09-12 Thread Song Gao
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

2024-09-12 Thread Song Gao
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

2024-09-12 Thread Song Gao
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

2024-09-12 Thread Song Gao
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

2024-09-12 Thread Song Gao
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

2024-08-20 Thread Song Gao
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

2024-08-20 Thread Song Gao
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

2024-07-28 Thread Song Gao
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

2024-07-28 Thread Song Gao
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()

2024-07-28 Thread Song Gao
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()

2024-07-28 Thread Song Gao
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()

2024-07-28 Thread Song Gao
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

2024-07-28 Thread Song Gao
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

2024-07-24 Thread Song Gao
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

2024-07-24 Thread Song Gao
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

2024-07-23 Thread Song Gao
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

2024-07-18 Thread Song Gao
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

2024-07-18 Thread Song Gao
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

2024-07-18 Thread Song Gao
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

2024-07-18 Thread Song Gao
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

2024-07-18 Thread Song Gao
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

2024-07-18 Thread Song Gao
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

2024-07-15 Thread Song Gao
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

2024-07-11 Thread Song Gao
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

2024-07-11 Thread Song Gao
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

2024-07-11 Thread Song Gao
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

2024-07-11 Thread Song Gao
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

2024-07-11 Thread Song Gao
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

2024-07-11 Thread Song Gao
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

2024-07-11 Thread Song Gao
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

2024-07-11 Thread Song Gao
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

2024-07-11 Thread Song Gao
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

2024-07-11 Thread Song Gao
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

2024-07-11 Thread Song Gao
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

2024-07-11 Thread Song Gao
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

2024-07-11 Thread Song Gao
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

2024-07-11 Thread Song Gao
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

2024-07-11 Thread Song Gao
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

2024-07-11 Thread Song Gao
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

2024-07-11 Thread Song Gao
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

2024-07-11 Thread Song Gao
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

2024-07-11 Thread Song Gao
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

2024-07-10 Thread Song Gao
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

2024-07-04 Thread Song Gao
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

2024-07-04 Thread Song Gao
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

2024-07-04 Thread Song Gao
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

2024-06-27 Thread Song Gao
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"

2024-06-27 Thread Song Gao
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

2024-06-27 Thread Song Gao
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

2024-06-21 Thread Song Gao
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

2024-06-18 Thread Song Gao
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.

2024-06-13 Thread Song Gao
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

2024-06-05 Thread Song Gao
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

2024-06-05 Thread Song Gao
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

2024-06-05 Thread Song Gao
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

2024-06-05 Thread Song Gao
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

2024-06-05 Thread Song Gao
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

2024-06-05 Thread Song Gao
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

2024-06-05 Thread Song Gao
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




  1   2   3   4   5   6   7   8   9   10   >