:p
atchew
Login
The following changes since commit e090e0312dc9030d94e38e3d98a88718d3561e4e: Merge tag 'pull-trivial-patches' of https://gitlab.com/mjt0k/qemu into staging (2025-10-29 10:44:15 +0100) are available in the Git repository at: https://github.com/bibo-mao/qemu.git tags/pull-loongarch-20251030 for you to fetch changes up to c981119dab04ac20f86ae755a669d74fc1373cb7: target/loongarch: Add PTW feature support in KVM mode (2025-10-30 10:34:58 +0800) ---------------------------------------------------------------- pull-loongarch-20251030 queue ---------------------------------------------------------------- Bibo Mao (2): linux-headers: Update to Linux v6.18-rc3 target/loongarch: Add PTW feature support in KVM mode include/standard-headers/linux/ethtool.h | 1 + include/standard-headers/linux/fuse.h | 22 ++++++++++++-- include/standard-headers/linux/input-event-codes.h | 1 + include/standard-headers/linux/input.h | 22 +++++++++++++- include/standard-headers/linux/pci_regs.h | 10 +++++++ include/standard-headers/linux/virtio_ids.h | 1 + linux-headers/asm-loongarch/kvm.h | 1 + linux-headers/asm-riscv/kvm.h | 23 +++++++++++++- linux-headers/asm-riscv/ptrace.h | 4 +-- linux-headers/asm-x86/kvm.h | 34 +++++++++++++++++++++ linux-headers/asm-x86/unistd_64.h | 1 + linux-headers/asm-x86/unistd_x32.h | 1 + linux-headers/linux/kvm.h | 3 ++ linux-headers/linux/psp-sev.h | 10 ++++++- linux-headers/linux/stddef.h | 1 - linux-headers/linux/vduse.h | 2 +- linux-headers/linux/vhost.h | 4 +-- target/loongarch/cpu.c | 6 ++-- target/loongarch/cpu.h | 1 + target/loongarch/kvm/kvm.c | 35 ++++++++++++++++++++++ 20 files changed, 169 insertions(+), 14 deletions(-)
Update headers to retrieve the latest KVM caps for LoongArch. It is added to the tree by running `update-linux-headers.sh` on linux v6.18-rc3. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Song Gao <gaosong@loongson.cn> --- include/standard-headers/linux/ethtool.h | 1 + include/standard-headers/linux/fuse.h | 22 ++++++++++-- .../linux/input-event-codes.h | 1 + include/standard-headers/linux/input.h | 22 +++++++++++- include/standard-headers/linux/pci_regs.h | 10 ++++++ include/standard-headers/linux/virtio_ids.h | 1 + linux-headers/asm-loongarch/kvm.h | 1 + linux-headers/asm-riscv/kvm.h | 23 ++++++++++++- linux-headers/asm-riscv/ptrace.h | 4 +-- linux-headers/asm-x86/kvm.h | 34 +++++++++++++++++++ linux-headers/asm-x86/unistd_64.h | 1 + linux-headers/asm-x86/unistd_x32.h | 1 + linux-headers/linux/kvm.h | 3 ++ linux-headers/linux/psp-sev.h | 10 +++++- linux-headers/linux/stddef.h | 1 - linux-headers/linux/vduse.h | 2 +- linux-headers/linux/vhost.h | 4 +-- 17 files changed, 130 insertions(+), 11 deletions(-) diff --git a/include/standard-headers/linux/ethtool.h b/include/standard-headers/linux/ethtool.h index XXXXXXX..XXXXXXX 100644 --- a/include/standard-headers/linux/ethtool.h +++ b/include/standard-headers/linux/ethtool.h @@ -XXX,XX +XXX,XX @@ enum { #define RXH_L4_B_0_1 (1 << 6) /* src port in case of TCP/UDP/SCTP */ #define RXH_L4_B_2_3 (1 << 7) /* dst port in case of TCP/UDP/SCTP */ #define RXH_GTP_TEID (1 << 8) /* teid in case of GTP */ +#define RXH_IP6_FL (1 << 9) /* IPv6 flow label */ #define RXH_DISCARD (1 << 31) #define RX_CLS_FLOW_DISC 0xffffffffffffffffULL diff --git a/include/standard-headers/linux/fuse.h b/include/standard-headers/linux/fuse.h index XXXXXXX..XXXXXXX 100644 --- a/include/standard-headers/linux/fuse.h +++ b/include/standard-headers/linux/fuse.h @@ -XXX,XX +XXX,XX @@ * * 7.44 * - add FUSE_NOTIFY_INC_EPOCH + * + * 7.45 + * - add FUSE_COPY_FILE_RANGE_64 + * - add struct fuse_copy_file_range_out + * - add FUSE_NOTIFY_PRUNE */ #ifndef _LINUX_FUSE_H @@ -XXX,XX +XXX,XX @@ #define FUSE_KERNEL_VERSION 7 /** Minor version number of this interface */ -#define FUSE_KERNEL_MINOR_VERSION 44 +#define FUSE_KERNEL_MINOR_VERSION 45 /** The node ID of the root inode */ #define FUSE_ROOT_ID 1 @@ -XXX,XX +XXX,XX @@ enum fuse_opcode { FUSE_SYNCFS = 50, FUSE_TMPFILE = 51, FUSE_STATX = 52, + FUSE_COPY_FILE_RANGE_64 = 53, /* CUSE specific operations */ CUSE_INIT = 4096, @@ -XXX,XX +XXX,XX @@ enum fuse_notify_code { FUSE_NOTIFY_DELETE = 6, FUSE_NOTIFY_RESEND = 7, FUSE_NOTIFY_INC_EPOCH = 8, - FUSE_NOTIFY_CODE_MAX, + FUSE_NOTIFY_PRUNE = 9, }; /* The read buffer is required to be at least 8k, but may be much larger */ @@ -XXX,XX +XXX,XX @@ struct fuse_notify_retrieve_in { uint64_t dummy4; }; +struct fuse_notify_prune_out { + uint32_t count; + uint32_t padding; + uint64_t spare; +}; + struct fuse_backing_map { int32_t fd; uint32_t flags; @@ -XXX,XX +XXX,XX @@ struct fuse_backing_map { #define FUSE_DEV_IOC_BACKING_OPEN _IOW(FUSE_DEV_IOC_MAGIC, 1, \ struct fuse_backing_map) #define FUSE_DEV_IOC_BACKING_CLOSE _IOW(FUSE_DEV_IOC_MAGIC, 2, uint32_t) +#define FUSE_DEV_IOC_SYNC_INIT _IO(FUSE_DEV_IOC_MAGIC, 3) struct fuse_lseek_in { uint64_t fh; @@ -XXX,XX +XXX,XX @@ struct fuse_copy_file_range_in { uint64_t flags; }; +/* For FUSE_COPY_FILE_RANGE_64 */ +struct fuse_copy_file_range_out { + uint64_t bytes_copied; +}; + #define FUSE_SETUPMAPPING_FLAG_WRITE (1ull << 0) #define FUSE_SETUPMAPPING_FLAG_READ (1ull << 1) struct fuse_setupmapping_in { diff --git a/include/standard-headers/linux/input-event-codes.h b/include/standard-headers/linux/input-event-codes.h index XXXXXXX..XXXXXXX 100644 --- a/include/standard-headers/linux/input-event-codes.h +++ b/include/standard-headers/linux/input-event-codes.h @@ -XXX,XX +XXX,XX @@ #define INPUT_PROP_TOPBUTTONPAD 0x04 /* softbuttons at top of pad */ #define INPUT_PROP_POINTING_STICK 0x05 /* is a pointing stick */ #define INPUT_PROP_ACCELEROMETER 0x06 /* has accelerometer */ +#define INPUT_PROP_HAPTIC_TOUCHPAD 0x07 /* is a haptic touchpad */ #define INPUT_PROP_MAX 0x1f #define INPUT_PROP_CNT (INPUT_PROP_MAX + 1) diff --git a/include/standard-headers/linux/input.h b/include/standard-headers/linux/input.h index XXXXXXX..XXXXXXX 100644 --- a/include/standard-headers/linux/input.h +++ b/include/standard-headers/linux/input.h @@ -XXX,XX +XXX,XX @@ struct ff_rumble_effect { uint16_t weak_magnitude; }; +/** + * struct ff_haptic_effect + * @hid_usage: hid_usage according to Haptics page (WAVEFORM_CLICK, etc.) + * @vendor_id: the waveform vendor ID if hid_usage is in the vendor-defined range + * @vendor_waveform_page: the vendor waveform page if hid_usage is in the vendor-defined range + * @intensity: strength of the effect as percentage + * @repeat_count: number of times to retrigger effect + * @retrigger_period: time before effect is retriggered (in ms) + */ +struct ff_haptic_effect { + uint16_t hid_usage; + uint16_t vendor_id; + uint8_t vendor_waveform_page; + uint16_t intensity; + uint16_t repeat_count; + uint16_t retrigger_period; +}; + /** * struct ff_effect - defines force feedback effect * @type: type of the effect (FF_CONSTANT, FF_PERIODIC, FF_RAMP, FF_SPRING, @@ -XXX,XX +XXX,XX @@ struct ff_effect { struct ff_periodic_effect periodic; struct ff_condition_effect condition[2]; /* One for each axis */ struct ff_rumble_effect rumble; + struct ff_haptic_effect haptic; } u; }; @@ -XXX,XX +XXX,XX @@ struct ff_effect { * Force feedback effect types */ +#define FF_HAPTIC 0x4f #define FF_RUMBLE 0x50 #define FF_PERIODIC 0x51 #define FF_CONSTANT 0x52 @@ -XXX,XX +XXX,XX @@ struct ff_effect { #define FF_INERTIA 0x56 #define FF_RAMP 0x57 -#define FF_EFFECT_MIN FF_RUMBLE +#define FF_EFFECT_MIN FF_HAPTIC #define FF_EFFECT_MAX FF_RAMP /* diff --git a/include/standard-headers/linux/pci_regs.h b/include/standard-headers/linux/pci_regs.h index XXXXXXX..XXXXXXX 100644 --- a/include/standard-headers/linux/pci_regs.h +++ b/include/standard-headers/linux/pci_regs.h @@ -XXX,XX +XXX,XX @@ /* Capability lists */ +#define PCI_CAP_ID_MASK 0x00ff /* Capability ID mask */ +#define PCI_CAP_LIST_NEXT_MASK 0xff00 /* Next Capability Pointer mask */ + #define PCI_CAP_LIST_ID 0 /* Capability ID */ #define PCI_CAP_ID_PM 0x01 /* Power Management */ #define PCI_CAP_ID_AGP 0x02 /* Accelerated Graphics Port */ @@ -XXX,XX +XXX,XX @@ #define PCI_ERR_UNC_MCBTLP 0x00800000 /* MC blocked TLP */ #define PCI_ERR_UNC_ATOMEG 0x01000000 /* Atomic egress blocked */ #define PCI_ERR_UNC_TLPPRE 0x02000000 /* TLP prefix blocked */ +#define PCI_ERR_UNC_POISON_BLK 0x04000000 /* Poisoned TLP Egress Blocked */ +#define PCI_ERR_UNC_DMWR_BLK 0x08000000 /* DMWr Request Egress Blocked */ +#define PCI_ERR_UNC_IDE_CHECK 0x10000000 /* IDE Check Failed */ +#define PCI_ERR_UNC_MISR_IDE 0x20000000 /* Misrouted IDE TLP */ +#define PCI_ERR_UNC_PCRC_CHECK 0x40000000 /* PCRC Check Failed */ +#define PCI_ERR_UNC_XLAT_BLK 0x80000000 /* TLP Translation Egress Blocked */ #define PCI_ERR_UNCOR_MASK 0x08 /* Uncorrectable Error Mask */ /* Same bits as above */ #define PCI_ERR_UNCOR_SEVER 0x0c /* Uncorrectable Error Severity */ @@ -XXX,XX +XXX,XX @@ #define PCI_ERR_CAP_ECRC_CHKC 0x00000080 /* ECRC Check Capable */ #define PCI_ERR_CAP_ECRC_CHKE 0x00000100 /* ECRC Check Enable */ #define PCI_ERR_CAP_PREFIX_LOG_PRESENT 0x00000800 /* TLP Prefix Log Present */ +#define PCI_ERR_CAP_COMP_TIME_LOG 0x00001000 /* Completion Timeout Prefix/Header Log Capable */ #define PCI_ERR_CAP_TLP_LOG_FLIT 0x00040000 /* TLP was logged in Flit Mode */ #define PCI_ERR_CAP_TLP_LOG_SIZE 0x00f80000 /* Logged TLP Size (only in Flit mode) */ #define PCI_ERR_HEADER_LOG 0x1c /* Header Log Register (16 bytes) */ diff --git a/include/standard-headers/linux/virtio_ids.h b/include/standard-headers/linux/virtio_ids.h index XXXXXXX..XXXXXXX 100644 --- a/include/standard-headers/linux/virtio_ids.h +++ b/include/standard-headers/linux/virtio_ids.h @@ -XXX,XX +XXX,XX @@ #define VIRTIO_ID_AUDIO_POLICY 39 /* virtio audio policy */ #define VIRTIO_ID_BT 40 /* virtio bluetooth */ #define VIRTIO_ID_GPIO 41 /* virtio gpio */ +#define VIRTIO_ID_SPI 45 /* virtio spi */ /* * Virtio Transitional IDs diff --git a/linux-headers/asm-loongarch/kvm.h b/linux-headers/asm-loongarch/kvm.h index XXXXXXX..XXXXXXX 100644 --- a/linux-headers/asm-loongarch/kvm.h +++ b/linux-headers/asm-loongarch/kvm.h @@ -XXX,XX +XXX,XX @@ struct kvm_fpu { #define KVM_LOONGARCH_VM_FEAT_PMU 5 #define KVM_LOONGARCH_VM_FEAT_PV_IPI 6 #define KVM_LOONGARCH_VM_FEAT_PV_STEALTIME 7 +#define KVM_LOONGARCH_VM_FEAT_PTW 8 /* Device Control API on vcpu fd */ #define KVM_LOONGARCH_VCPU_CPUCFG 0 diff --git a/linux-headers/asm-riscv/kvm.h b/linux-headers/asm-riscv/kvm.h index XXXXXXX..XXXXXXX 100644 --- a/linux-headers/asm-riscv/kvm.h +++ b/linux-headers/asm-riscv/kvm.h @@ -XXX,XX +XXX,XX @@ #ifndef __LINUX_KVM_RISCV_H #define __LINUX_KVM_RISCV_H -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #include <linux/types.h> #include <asm/bitsperlong.h> @@ -XXX,XX +XXX,XX @@ struct kvm_riscv_config { unsigned long mimpid; unsigned long zicboz_block_size; unsigned long satp_mode; + unsigned long zicbop_block_size; }; /* CORE registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */ @@ -XXX,XX +XXX,XX @@ enum KVM_RISCV_ISA_EXT_ID { KVM_RISCV_ISA_EXT_ZICCRSE, KVM_RISCV_ISA_EXT_ZAAMO, KVM_RISCV_ISA_EXT_ZALRSC, + KVM_RISCV_ISA_EXT_ZICBOP, + KVM_RISCV_ISA_EXT_ZFBFMIN, + KVM_RISCV_ISA_EXT_ZVFBFMIN, + KVM_RISCV_ISA_EXT_ZVFBFWMA, KVM_RISCV_ISA_EXT_MAX, }; @@ -XXX,XX +XXX,XX @@ enum KVM_RISCV_SBI_EXT_ID { KVM_RISCV_SBI_EXT_DBCN, KVM_RISCV_SBI_EXT_STA, KVM_RISCV_SBI_EXT_SUSP, + KVM_RISCV_SBI_EXT_FWFT, KVM_RISCV_SBI_EXT_MAX, }; @@ -XXX,XX +XXX,XX @@ struct kvm_riscv_sbi_sta { unsigned long shmem_hi; }; +struct kvm_riscv_sbi_fwft_feature { + unsigned long enable; + unsigned long flags; + unsigned long value; +}; + +/* SBI FWFT extension registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */ +struct kvm_riscv_sbi_fwft { + struct kvm_riscv_sbi_fwft_feature misaligned_deleg; + struct kvm_riscv_sbi_fwft_feature pointer_masking; +}; + /* Possible states for kvm_riscv_timer */ #define KVM_RISCV_TIMER_STATE_OFF 0 #define KVM_RISCV_TIMER_STATE_ON 1 @@ -XXX,XX +XXX,XX @@ struct kvm_riscv_sbi_sta { #define KVM_REG_RISCV_SBI_STA (0x0 << KVM_REG_RISCV_SUBTYPE_SHIFT) #define KVM_REG_RISCV_SBI_STA_REG(name) \ (offsetof(struct kvm_riscv_sbi_sta, name) / sizeof(unsigned long)) +#define KVM_REG_RISCV_SBI_FWFT (0x1 << KVM_REG_RISCV_SUBTYPE_SHIFT) +#define KVM_REG_RISCV_SBI_FWFT_REG(name) \ + (offsetof(struct kvm_riscv_sbi_fwft, name) / sizeof(unsigned long)) /* Device Control API: RISC-V AIA */ #define KVM_DEV_RISCV_APLIC_ALIGN 0x1000 diff --git a/linux-headers/asm-riscv/ptrace.h b/linux-headers/asm-riscv/ptrace.h index XXXXXXX..XXXXXXX 100644 --- a/linux-headers/asm-riscv/ptrace.h +++ b/linux-headers/asm-riscv/ptrace.h @@ -XXX,XX +XXX,XX @@ #ifndef _ASM_RISCV_PTRACE_H #define _ASM_RISCV_PTRACE_H -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #include <linux/types.h> @@ -XXX,XX +XXX,XX @@ struct __riscv_v_regset_state { */ #define RISCV_MAX_VLENB (8192) -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #endif /* _ASM_RISCV_PTRACE_H */ diff --git a/linux-headers/asm-x86/kvm.h b/linux-headers/asm-x86/kvm.h index XXXXXXX..XXXXXXX 100644 --- a/linux-headers/asm-x86/kvm.h +++ b/linux-headers/asm-x86/kvm.h @@ -XXX,XX +XXX,XX @@ #define MC_VECTOR 18 #define XM_VECTOR 19 #define VE_VECTOR 20 +#define CP_VECTOR 21 + +#define HV_VECTOR 28 +#define VC_VECTOR 29 +#define SX_VECTOR 30 /* Select x86 specific features in <linux/kvm.h> */ #define __KVM_HAVE_PIT @@ -XXX,XX +XXX,XX @@ struct kvm_xcrs { __u64 padding[16]; }; +#define KVM_X86_REG_TYPE_MSR 2 +#define KVM_X86_REG_TYPE_KVM 3 + +#define KVM_X86_KVM_REG_SIZE(reg) \ +({ \ + reg == KVM_REG_GUEST_SSP ? KVM_REG_SIZE_U64 : 0; \ +}) + +#define KVM_X86_REG_TYPE_SIZE(type, reg) \ +({ \ + __u64 type_size = (__u64)type << 32; \ + \ + type_size |= type == KVM_X86_REG_TYPE_MSR ? KVM_REG_SIZE_U64 : \ + type == KVM_X86_REG_TYPE_KVM ? KVM_X86_KVM_REG_SIZE(reg) : \ + 0; \ + type_size; \ +}) + +#define KVM_X86_REG_ID(type, index) \ + (KVM_REG_X86 | KVM_X86_REG_TYPE_SIZE(type, index) | index) + +#define KVM_X86_REG_MSR(index) \ + KVM_X86_REG_ID(KVM_X86_REG_TYPE_MSR, index) +#define KVM_X86_REG_KVM(index) \ + KVM_X86_REG_ID(KVM_X86_REG_TYPE_KVM, index) + +/* KVM-defined registers starting from 0 */ +#define KVM_REG_GUEST_SSP 0 + #define KVM_SYNC_X86_REGS (1UL << 0) #define KVM_SYNC_X86_SREGS (1UL << 1) #define KVM_SYNC_X86_EVENTS (1UL << 2) diff --git a/linux-headers/asm-x86/unistd_64.h b/linux-headers/asm-x86/unistd_64.h index XXXXXXX..XXXXXXX 100644 --- a/linux-headers/asm-x86/unistd_64.h +++ b/linux-headers/asm-x86/unistd_64.h @@ -XXX,XX +XXX,XX @@ #define __NR_io_pgetevents 333 #define __NR_rseq 334 #define __NR_uretprobe 335 +#define __NR_uprobe 336 #define __NR_pidfd_send_signal 424 #define __NR_io_uring_setup 425 #define __NR_io_uring_enter 426 diff --git a/linux-headers/asm-x86/unistd_x32.h b/linux-headers/asm-x86/unistd_x32.h index XXXXXXX..XXXXXXX 100644 --- a/linux-headers/asm-x86/unistd_x32.h +++ b/linux-headers/asm-x86/unistd_x32.h @@ -XXX,XX +XXX,XX @@ #define __NR_io_pgetevents (__X32_SYSCALL_BIT + 333) #define __NR_rseq (__X32_SYSCALL_BIT + 334) #define __NR_uretprobe (__X32_SYSCALL_BIT + 335) +#define __NR_uprobe (__X32_SYSCALL_BIT + 336) #define __NR_pidfd_send_signal (__X32_SYSCALL_BIT + 424) #define __NR_io_uring_setup (__X32_SYSCALL_BIT + 425) #define __NR_io_uring_enter (__X32_SYSCALL_BIT + 426) diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h index XXXXXXX..XXXXXXX 100644 --- a/linux-headers/linux/kvm.h +++ b/linux-headers/linux/kvm.h @@ -XXX,XX +XXX,XX @@ struct kvm_enable_cap { #define KVM_CAP_ARM_EL2_E2H0 241 #define KVM_CAP_RISCV_MP_STATE_RESET 242 #define KVM_CAP_ARM_CACHEABLE_PFNMAP_SUPPORTED 243 +#define KVM_CAP_GUEST_MEMFD_FLAGS 244 struct kvm_irq_routing_irqchip { __u32 irqchip; @@ -XXX,XX +XXX,XX @@ struct kvm_memory_attributes { #define KVM_MEMORY_ATTRIBUTE_PRIVATE (1ULL << 3) #define KVM_CREATE_GUEST_MEMFD _IOWR(KVMIO, 0xd4, struct kvm_create_guest_memfd) +#define GUEST_MEMFD_FLAG_MMAP (1ULL << 0) +#define GUEST_MEMFD_FLAG_INIT_SHARED (1ULL << 1) struct kvm_create_guest_memfd { __u64 size; diff --git a/linux-headers/linux/psp-sev.h b/linux-headers/linux/psp-sev.h index XXXXXXX..XXXXXXX 100644 --- a/linux-headers/linux/psp-sev.h +++ b/linux-headers/linux/psp-sev.h @@ -XXX,XX +XXX,XX @@ struct sev_user_data_get_id2 { * @mask_chip_id: whether chip id is present in attestation reports or not * @mask_chip_key: whether attestation reports are signed or not * @vlek_en: VLEK (Version Loaded Endorsement Key) hashstick is loaded + * @feature_info: whether SNP_FEATURE_INFO command is available + * @rapl_dis: whether RAPL is disabled + * @ciphertext_hiding_cap: whether platform has ciphertext hiding capability + * @ciphertext_hiding_en: whether ciphertext hiding is enabled * @rsvd1: reserved * @guest_count: the number of guest currently managed by the firmware * @current_tcb_version: current TCB version @@ -XXX,XX +XXX,XX @@ struct sev_user_data_snp_status { __u32 mask_chip_id:1; /* Out */ __u32 mask_chip_key:1; /* Out */ __u32 vlek_en:1; /* Out */ - __u32 rsvd1:29; + __u32 feature_info:1; /* Out */ + __u32 rapl_dis:1; /* Out */ + __u32 ciphertext_hiding_cap:1; /* Out */ + __u32 ciphertext_hiding_en:1; /* Out */ + __u32 rsvd1:25; __u32 guest_count; /* Out */ __u64 current_tcb_version; /* Out */ __u64 reported_tcb_version; /* Out */ diff --git a/linux-headers/linux/stddef.h b/linux-headers/linux/stddef.h index XXXXXXX..XXXXXXX 100644 --- a/linux-headers/linux/stddef.h +++ b/linux-headers/linux/stddef.h @@ -XXX,XX +XXX,XX @@ #define _LINUX_STDDEF_H - #ifndef __always_inline #define __always_inline __inline__ #endif diff --git a/linux-headers/linux/vduse.h b/linux-headers/linux/vduse.h index XXXXXXX..XXXXXXX 100644 --- a/linux-headers/linux/vduse.h +++ b/linux-headers/linux/vduse.h @@ -XXX,XX +XXX,XX @@ struct vduse_iova_umem { * struct vduse_iova_info - information of one IOVA region * @start: start of the IOVA region * @last: last of the IOVA region - * @capability: capability of the IOVA regsion + * @capability: capability of the IOVA region * @reserved: for future use, needs to be initialized to zero * * Structure used by VDUSE_IOTLB_GET_INFO ioctl to get information of diff --git a/linux-headers/linux/vhost.h b/linux-headers/linux/vhost.h index XXXXXXX..XXXXXXX 100644 --- a/linux-headers/linux/vhost.h +++ b/linux-headers/linux/vhost.h @@ -XXX,XX +XXX,XX @@ * When fork_owner is set to VHOST_FORK_OWNER_KTHREAD: * - Vhost will create vhost workers as kernel threads. */ -#define VHOST_SET_FORK_FROM_OWNER _IOW(VHOST_VIRTIO, 0x83, __u8) +#define VHOST_SET_FORK_FROM_OWNER _IOW(VHOST_VIRTIO, 0x84, __u8) /** * VHOST_GET_FORK_OWNER - Get the current fork_owner flag for the vhost device. @@ -XXX,XX +XXX,XX @@ * * @return: An 8-bit value indicating the current thread mode. */ -#define VHOST_GET_FORK_FROM_OWNER _IOR(VHOST_VIRTIO, 0x84, __u8) +#define VHOST_GET_FORK_FROM_OWNER _IOR(VHOST_VIRTIO, 0x85, __u8) #endif -- 2.47.0
Implement Hardware page table walker(PTW for short) feature in KVM mode. Use OnOffAuto type variable ptw to check the PTW feature. If the PTW feature is not supported on KVM host, there is error reported with ptw=on option. By default PTW feature is disabled on la464 CPU type, and auto detected on max CPU type. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Song Gao <gaosong@loongson.cn> --- target/loongarch/cpu.c | 6 +++--- target/loongarch/cpu.h | 1 + target/loongarch/kvm/kvm.c | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -XXX,XX +XXX,XX @@ static void loongarch_set_ptw(Object *obj, bool value, Error **errp) cpu->ptw = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF; if (kvm_enabled()) { - /* PTW feature is only support in TCG mode now */ + /* kvm feature detection in function kvm_arch_init_vcpu */ return; } @@ -XXX,XX +XXX,XX @@ static void loongarch_la132_initfn(Object *obj) static void loongarch_max_initfn(Object *obj) { LoongArchCPU *cpu = LOONGARCH_CPU(obj); - /* '-cpu max' for TCG: we use cpu la464. */ + /* '-cpu max': use it for max supported CPU features */ loongarch_la464_initfn(obj); + cpu->ptw = ON_OFF_AUTO_AUTO; if (tcg_enabled()) { cpu->env.cpucfg[1] = FIELD_DP32(cpu->env.cpucfg[1], CPUCFG1, MSG_INT, 1); cpu->msgint = ON_OFF_AUTO_AUTO; cpu->env.cpucfg[2] = FIELD_DP32(cpu->env.cpucfg[2], CPUCFG2, HPTW, 1); - cpu->ptw = ON_OFF_AUTO_AUTO; } } diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -XXX,XX +XXX,XX @@ enum loongarch_features { LOONGARCH_FEATURE_PMU, LOONGARCH_FEATURE_PV_IPI, LOONGARCH_FEATURE_STEALTIME, + LOONGARCH_FEATURE_PTW, }; typedef struct LoongArchBT { diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/kvm/kvm.c +++ b/target/loongarch/kvm/kvm.c @@ -XXX,XX +XXX,XX @@ static bool kvm_feature_supported(CPUState *cs, enum loongarch_features feature) ret = kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr); return (ret == 0); + case LOONGARCH_FEATURE_PTW: + attr.group = KVM_LOONGARCH_VM_FEAT_CTRL; + attr.attr = KVM_LOONGARCH_VM_FEAT_PTW; + ret = kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr); + return (ret == 0); + default: return false; } @@ -XXX,XX +XXX,XX @@ static int kvm_cpu_check_pmu(CPUState *cs, Error **errp) return 0; } +static int kvm_cpu_check_ptw(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_PTW); + if (cpu->ptw == ON_OFF_AUTO_ON) { + if (!kvm_supported) { + error_setg(errp, "'ptw' feature not supported by KVM on the host"); + return -ENOTSUP; + } + } else if (cpu->ptw != ON_OFF_AUTO_AUTO) { + /* disable pmu if ON_OFF_AUTO_OFF is set */ + kvm_supported = false; + } + + if (kvm_supported) { + env->cpucfg[2] = FIELD_DP32(env->cpucfg[2], CPUCFG2, HPTW, 1); + } + return 0; +} + static int kvm_cpu_check_pv_features(CPUState *cs, Error **errp) { MachineState *ms = MACHINE(qdev_get_machine()); @@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs) return ret; } + ret = kvm_cpu_check_ptw(cs, &local_err); + if (ret < 0) { + error_report_err(local_err); + return ret; + } + return 0; } -- 2.47.0
The following changes since commit cc329c491768b2d91eb0b0984f3baa0bf805776d: Merge tag 'block-pull-request' of https://gitlab.com/stefanha/qemu into staging (2026-06-08 09:30:30 -0400) are available in the Git repository at: https://github.com/gaosong715/qemu.git tags/pull-loongarch-20260609 for you to fetch changes up to b653a954d427561fc563238af6b2feb8da209e41: target/loongarch: Add new structure CPUSysState (2026-06-09 08:37:18 -0400) ---------------------------------------------------------------- pull-loongarch-20260609 ---------------------------------------------------------------- Bibo Mao (14): target/loongarch: Add new field curState in CPULoongArchState target/loongarch: Use sys_state in cpu.c when accessing CSR registers target/loongarch: Use sys_state in cpu_helper.c when accessing CSR registers target/loongarch: Use sys_state in file arch_dump.c when accessing CSR registers target/loongarch: Use sys_state in kvm.c when accessing CSR registers target/loongarch: Use sys_state in tlb_helper.c when accessing CSR registers target/loongarch: Use sys_state in tcg_cpu.c when accessing CSR registers target/loongarch: Use sys_state in csr_helper.c when accessing CSR registers target/loongarch: Use sys_state in op_helper.c when accessing CSR registers linux-user/loongarch64: Use sys_state when accessing CSR registers target/loongarch: Add default CSRFL_BASIC info with flags field target/loongarch: Add wrapper function get_csr_offset() target/loongarch: Add macro CSR_OFFSET and CPU_CSR_OFFSET target/loongarch: Add new structure CPUSysState hw/intc/loongarch_dintc.c | 4 +- linux-user/loongarch64/cpu_loop.c | 5 +- linux-user/loongarch64/elfload.c | 4 +- linux-user/loongarch64/signal.c | 16 +- target/loongarch/arch_dump.c | 5 +- target/loongarch/cpu-mmu.h | 4 +- target/loongarch/cpu.c | 120 ++++++----- target/loongarch/cpu.h | 49 +++-- target/loongarch/cpu_helper.c | 41 ++-- target/loongarch/csr.c | 10 +- target/loongarch/csr.h | 10 + target/loongarch/gdbstub.c | 3 +- target/loongarch/kvm/kvm.c | 228 +++++++++++---------- target/loongarch/machine.c | 118 +++++------ target/loongarch/tcg/constant_timer.c | 10 +- target/loongarch/tcg/csr_helper.c | 55 ++--- target/loongarch/tcg/insn_trans/trans_extra.c.inc | 6 +- .../tcg/insn_trans/trans_privileged.c.inc | 16 +- target/loongarch/tcg/op_helper.c | 45 ++-- target/loongarch/tcg/tcg_cpu.c | 107 +++++----- target/loongarch/tcg/tlb_helper.c | 137 +++++++------ 21 files changed, 549 insertions(+), 444 deletions(-)
From: Bibo Mao <maobibo@loongson.cn> New field sys_state is added in structure CPULoongArchState, it points to CPULoongArchState itself now. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Philippe Mathieu-Daudé <philmd@mailo.com> Tested-by: Song Gao <gaosong@loongson.cn> Message-ID: <20260605082552.175336-2-maobibo@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn> --- target/loongarch/cpu.c | 2 ++ target/loongarch/cpu.h | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -XXX,XX +XXX,XX @@ static void loongarch_la464_initfn(Object *obj) uint32_t data = 0, field; int i; + set_sys_state(env, env); for (i = 0; i < 21; i++) { env->cpucfg[i] = 0x0; } @@ -XXX,XX +XXX,XX @@ static void loongarch_la132_initfn(Object *obj) uint32_t data = 0; int i; + set_sys_state(env, env); for (i = 0; i < 21; i++) { env->cpucfg[i] = 0x0; } diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -XXX,XX +XXX,XX @@ typedef struct LoongArchBT { #define CPU_VENDOR_LOONGSON "Loongson" #define CPU_MODEL_3A5000 "3A5000" #define CPU_MODEL_1C101 "1C101" +struct CPUArchState; +typedef struct CPUArchState CPUSysState; typedef struct CPUArchState { uint64_t gpr[32]; @@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState { AddressSpace *address_space_iocsr; uint32_t mp_state; #endif + CPUSysState *sys_state; } CPULoongArchState; typedef struct LoongArchCPUTopo { @@ -XXX,XX +XXX,XX @@ struct LoongArchCPUClass { #define MMU_USER_IDX MMU_PLV_USER #define MMU_DA_IDX 4 +static inline CPUSysState *env_sys(CPULoongArchState *env) +{ + return env->sys_state; +} + +static inline void set_sys_state(CPULoongArchState *env, CPUSysState *sys) +{ + env->sys_state = sys; +} + static inline bool is_la64(CPULoongArchState *env) { return FIELD_EX32(env->cpucfg[1], CPUCFG1, ARCH) == CPUCFG1_ARCH_LA64; -- 2.54.0
From: Bibo Mao <maobibo@loongson.cn> When accessing CSR register in file cpu.c, use sys_state rather than env. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Philippe Mathieu-Daudé <philmd@mailo.com> Tested-by: Song Gao <gaosong@loongson.cn> Message-ID: <20260605082552.175336-3-maobibo@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn> --- target/loongarch/cpu.c | 114 ++++++++++++++++++++++------------------- target/loongarch/cpu.h | 5 +- 2 files changed, 63 insertions(+), 56 deletions(-) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -XXX,XX +XXX,XX @@ void loongarch_cpu_set_irq(void *opaque, int irq, int level) LoongArchCPU *cpu = opaque; CPULoongArchState *env = &cpu->env; CPUState *cs = CPU(cpu); + CPUSysState *sys = env_sys(env); if (irq < 0 || irq >= N_IRQS) { return; @@ -XXX,XX +XXX,XX @@ void loongarch_cpu_set_irq(void *opaque, int irq, int level) if (kvm_enabled()) { kvm_loongarch_set_interrupt(cpu, irq, level); } else if (tcg_enabled()) { - env->CSR_ESTAT = deposit64(env->CSR_ESTAT, irq, 1, level != 0); - if (FIELD_EX64(env->CSR_ESTAT, CSR_ESTAT, IS)) { + sys->CSR_ESTAT = deposit64(sys->CSR_ESTAT, irq, 1, level != 0); + if (FIELD_EX64(sys->CSR_ESTAT, CSR_ESTAT, IS)) { cpu_interrupt(cs, CPU_INTERRUPT_HARD); } else { cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); @@ -XXX,XX +XXX,XX @@ bool cpu_loongarch_hw_interrupts_pending(CPULoongArchState *env) { uint32_t pending; uint32_t status; + CPUSysState *sys = env_sys(env); - pending = FIELD_EX64(env->CSR_ESTAT, CSR_ESTAT, IS); - status = FIELD_EX64(env->CSR_ECFG, CSR_ECFG, LIE); + pending = FIELD_EX64(sys->CSR_ESTAT, CSR_ESTAT, IS); + status = FIELD_EX64(sys->CSR_ECFG, CSR_ECFG, LIE); return (pending & status) != 0; } @@ -XXX,XX +XXX,XX @@ static void loongarch_la464_init_csr(DeviceState *dev) static bool initialized; LoongArchCPU *cpu = LOONGARCH_CPU(dev); CPULoongArchState *env = &cpu->env; + CPUSysState *sys = env_sys(env); int i, num; if (!initialized) { initialized = true; - num = FIELD_EX64(env->CSR_PRCFG1, CSR_PRCFG1, SAVE_NUM); + num = FIELD_EX64(sys->CSR_PRCFG1, CSR_PRCFG1, SAVE_NUM); for (i = num; i < 16; i++) { set_csr_flag(LOONGARCH_CSR_SAVE(i), CSRFL_UNUSED); } @@ -XXX,XX +XXX,XX @@ static void loongarch_la464_initfn(Object *obj) { LoongArchCPU *cpu = LOONGARCH_CPU(obj); CPULoongArchState *env = &cpu->env; + CPUSysState *sys; uint32_t data = 0, field; int i; @@ -XXX,XX +XXX,XX @@ static void loongarch_la464_initfn(Object *obj) data = FIELD_DP32(data, CPUCFG20, L3IU_SIZE, 6); env->cpucfg[20] = data; - env->CSR_ASID = FIELD_DP64(0, CSR_ASID, ASIDBITS, 0xa); + sys = env_sys(env); + sys->CSR_ASID = FIELD_DP64(0, CSR_ASID, ASIDBITS, 0xa); - env->CSR_PRCFG1 = FIELD_DP64(env->CSR_PRCFG1, CSR_PRCFG1, SAVE_NUM, 8); - env->CSR_PRCFG1 = FIELD_DP64(env->CSR_PRCFG1, CSR_PRCFG1, TIMER_BITS, 0x2f); - env->CSR_PRCFG1 = FIELD_DP64(env->CSR_PRCFG1, CSR_PRCFG1, VSMAX, 7); + sys->CSR_PRCFG1 = FIELD_DP64(sys->CSR_PRCFG1, CSR_PRCFG1, SAVE_NUM, 8); + sys->CSR_PRCFG1 = FIELD_DP64(sys->CSR_PRCFG1, CSR_PRCFG1, TIMER_BITS, 0x2f); + sys->CSR_PRCFG1 = FIELD_DP64(sys->CSR_PRCFG1, CSR_PRCFG1, VSMAX, 7); - env->CSR_PRCFG2 = 0x3ffff000; + sys->CSR_PRCFG2 = 0x3ffff000; - env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, TLB_TYPE, 2); - env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, MTLB_ENTRY, 63); - env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, STLB_WAYS, 7); - env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, STLB_SETS, 8); + sys->CSR_PRCFG3 = FIELD_DP64(sys->CSR_PRCFG3, CSR_PRCFG3, TLB_TYPE, 2); + sys->CSR_PRCFG3 = FIELD_DP64(sys->CSR_PRCFG3, CSR_PRCFG3, MTLB_ENTRY, 63); + sys->CSR_PRCFG3 = FIELD_DP64(sys->CSR_PRCFG3, CSR_PRCFG3, STLB_WAYS, 7); + sys->CSR_PRCFG3 = FIELD_DP64(sys->CSR_PRCFG3, CSR_PRCFG3, STLB_SETS, 8); cpu->msgint = ON_OFF_AUTO_OFF; cpu->ptw = ON_OFF_AUTO_OFF; @@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_reset_hold(Object *obj, ResetType type) CPUState *cs = CPU(obj); LoongArchCPUClass *lacc = LOONGARCH_CPU_GET_CLASS(obj); CPULoongArchState *env = cpu_env(cs); + CPUSysState *sys = env_sys(env); if (lacc->parent_phases.hold) { lacc->parent_phases.hold(obj, type); @@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_reset_hold(Object *obj, ResetType type) int n; /* Set csr registers value after reset, see the manual 6.4. */ - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, PLV, 0); - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, IE, 0); - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DA, 1); - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, PG, 0); - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DATF, 0); - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DATM, 0); - - env->CSR_EUEN = FIELD_DP64(env->CSR_EUEN, CSR_EUEN, FPE, 0); - env->CSR_EUEN = FIELD_DP64(env->CSR_EUEN, CSR_EUEN, SXE, 0); - env->CSR_EUEN = FIELD_DP64(env->CSR_EUEN, CSR_EUEN, ASXE, 0); - env->CSR_EUEN = FIELD_DP64(env->CSR_EUEN, CSR_EUEN, BTE, 0); - - env->CSR_MISC = 0; - - env->CSR_ECFG = FIELD_DP64(env->CSR_ECFG, CSR_ECFG, VS, 0); - env->CSR_ECFG = FIELD_DP64(env->CSR_ECFG, CSR_ECFG, LIE, 0); - - env->CSR_ESTAT = env->CSR_ESTAT & (~MAKE_64BIT_MASK(0, 2)); - env->CSR_RVACFG = FIELD_DP64(env->CSR_RVACFG, CSR_RVACFG, RBITS, 0); - env->CSR_CPUID = cs->cpu_index; - env->CSR_TCFG = FIELD_DP64(env->CSR_TCFG, CSR_TCFG, EN, 0); - env->CSR_LLBCTL = FIELD_DP64(env->CSR_LLBCTL, CSR_LLBCTL, KLO, 0); - env->CSR_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR, 0); - env->CSR_MERRCTL = FIELD_DP64(env->CSR_MERRCTL, CSR_MERRCTL, ISMERR, 0); - env->CSR_TID = cs->cpu_index; + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, PLV, 0); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, IE, 0); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, DA, 1); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, PG, 0); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, DATF, 0); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, DATM, 0); + + sys->CSR_EUEN = FIELD_DP64(sys->CSR_EUEN, CSR_EUEN, FPE, 0); + sys->CSR_EUEN = FIELD_DP64(sys->CSR_EUEN, CSR_EUEN, SXE, 0); + sys->CSR_EUEN = FIELD_DP64(sys->CSR_EUEN, CSR_EUEN, ASXE, 0); + sys->CSR_EUEN = FIELD_DP64(sys->CSR_EUEN, CSR_EUEN, BTE, 0); + + sys->CSR_MISC = 0; + + sys->CSR_ECFG = FIELD_DP64(sys->CSR_ECFG, CSR_ECFG, VS, 0); + sys->CSR_ECFG = FIELD_DP64(sys->CSR_ECFG, CSR_ECFG, LIE, 0); + + sys->CSR_ESTAT = sys->CSR_ESTAT & (~MAKE_64BIT_MASK(0, 2)); + sys->CSR_RVACFG = FIELD_DP64(sys->CSR_RVACFG, CSR_RVACFG, RBITS, 0); + sys->CSR_CPUID = cs->cpu_index; + sys->CSR_TCFG = FIELD_DP64(sys->CSR_TCFG, CSR_TCFG, EN, 0); + sys->CSR_LLBCTL = FIELD_DP64(sys->CSR_LLBCTL, CSR_LLBCTL, KLO, 0); + sys->CSR_TLBRERA = FIELD_DP64(sys->CSR_TLBRERA, CSR_TLBRERA, ISTLBR, 0); + sys->CSR_MERRCTL = FIELD_DP64(sys->CSR_MERRCTL, CSR_MERRCTL, ISMERR, 0); + sys->CSR_TID = cs->cpu_index; /* * Workaround for edk2-stable202408, CSR PGD register is set only if * its value is equal to zero for boot cpu, it causes reboot issue. * * Here clear CSR registers relative with TLB. */ - env->CSR_PGDH = 0; - env->CSR_PGDL = 0; - env->CSR_PWCH = 0; - env->CSR_EENTRY = 0; - env->CSR_TLBRENTRY = 0; - env->CSR_MERRENTRY = 0; + sys->CSR_PGDH = 0; + sys->CSR_PGDL = 0; + sys->CSR_PWCH = 0; + sys->CSR_EENTRY = 0; + sys->CSR_TLBRENTRY = 0; + sys->CSR_MERRENTRY = 0; /* set CSR_PWCL.PTBASE and CSR_STLBPS.PS bits from CSR_PRCFG2 */ - if (env->CSR_PRCFG2 == 0) { - env->CSR_PRCFG2 = 0x3fffff000; + if (sys->CSR_PRCFG2 == 0) { + sys->CSR_PRCFG2 = 0x3fffff000; } - tlb_ps = ctz32(env->CSR_PRCFG2); - env->CSR_STLBPS = FIELD_DP64(env->CSR_STLBPS, CSR_STLBPS, PS, tlb_ps); - env->CSR_PWCL = FIELD_DP64(env->CSR_PWCL, CSR_PWCL, PTBASE, tlb_ps); + tlb_ps = ctz32(sys->CSR_PRCFG2); + sys->CSR_STLBPS = FIELD_DP64(sys->CSR_STLBPS, CSR_STLBPS, PS, tlb_ps); + sys->CSR_PWCL = FIELD_DP64(sys->CSR_PWCL, CSR_PWCL, PTBASE, tlb_ps); for (n = 0; n < 4; n++) { - env->CSR_DMW[n] = FIELD_DP64(env->CSR_DMW[n], CSR_DMW, PLV0, 0); - env->CSR_DMW[n] = FIELD_DP64(env->CSR_DMW[n], CSR_DMW, PLV1, 0); - env->CSR_DMW[n] = FIELD_DP64(env->CSR_DMW[n], CSR_DMW, PLV2, 0); - env->CSR_DMW[n] = FIELD_DP64(env->CSR_DMW[n], CSR_DMW, PLV3, 0); + sys->CSR_DMW[n] = FIELD_DP64(sys->CSR_DMW[n], CSR_DMW, PLV0, 0); + sys->CSR_DMW[n] = FIELD_DP64(sys->CSR_DMW[n], CSR_DMW, PLV1, 0); + sys->CSR_DMW[n] = FIELD_DP64(sys->CSR_DMW[n], CSR_DMW, PLV2, 0); + sys->CSR_DMW[n] = FIELD_DP64(sys->CSR_DMW[n], CSR_DMW, PLV3, 0); } #ifndef CONFIG_USER_ONLY diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -XXX,XX +XXX,XX @@ static inline bool is_va32(CPULoongArchState *env) { /* VA32 if !LA64 or VA32L[1-3] */ bool va32 = !is_la64(env); - uint64_t plv = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV); - if (plv >= 1 && (FIELD_EX64(env->CSR_MISC, CSR_MISC, VA32) & (1 << plv))) { + CPUSysState *sys = env_sys(env); + uint64_t plv = FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, PLV); + if (plv >= 1 && (FIELD_EX64(sys->CSR_MISC, CSR_MISC, VA32) & (1 << plv))) { va32 = true; } return va32; -- 2.54.0
From: Bibo Mao <maobibo@loongson.cn> When accessing CSR register in file cpu_helper.c, use sys_state rather than env. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Philippe Mathieu-Daudé <philmd@mailo.com> Tested-by: Song Gao <gaosong@loongson.cn> Message-ID: <20260605082552.175336-4-maobibo@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn> --- target/loongarch/cpu_helper.c | 41 +++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/target/loongarch/cpu_helper.c b/target/loongarch/cpu_helper.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/cpu_helper.c +++ b/target/loongarch/cpu_helper.c @@ -XXX,XX +XXX,XX @@ void get_dir_base_width(CPULoongArchState *env, uint64_t *dir_base, uint64_t *dir_width, unsigned int level) { + CPUSysState *sys = env_sys(env); + switch (level) { case 1: - *dir_base = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR1_BASE); - *dir_width = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR1_WIDTH); + *dir_base = FIELD_EX64(sys->CSR_PWCL, CSR_PWCL, DIR1_BASE); + *dir_width = FIELD_EX64(sys->CSR_PWCL, CSR_PWCL, DIR1_WIDTH); break; case 2: - *dir_base = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR2_BASE); - *dir_width = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR2_WIDTH); + *dir_base = FIELD_EX64(sys->CSR_PWCL, CSR_PWCL, DIR2_BASE); + *dir_width = FIELD_EX64(sys->CSR_PWCL, CSR_PWCL, DIR2_WIDTH); break; case 3: - *dir_base = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR3_BASE); - *dir_width = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR3_WIDTH); + *dir_base = FIELD_EX64(sys->CSR_PWCH, CSR_PWCH, DIR3_BASE); + *dir_width = FIELD_EX64(sys->CSR_PWCH, CSR_PWCH, DIR3_WIDTH); break; case 4: - *dir_base = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR4_BASE); - *dir_width = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR4_WIDTH); + *dir_base = FIELD_EX64(sys->CSR_PWCH, CSR_PWCH, DIR4_BASE); + *dir_width = FIELD_EX64(sys->CSR_PWCH, CSR_PWCH, DIR4_WIDTH); break; default: /* level may be zero for ldpte */ - *dir_base = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTBASE); - *dir_width = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTWIDTH); + *dir_base = FIELD_EX64(sys->CSR_PWCL, CSR_PWCL, PTBASE); + *dir_width = FIELD_EX64(sys->CSR_PWCL, CSR_PWCL, PTWIDTH); break; } } @@ -XXX,XX +XXX,XX @@ TLBRet loongarch_ptw(CPULoongArchState *env, MMUContext *context, vaddr address; TLBRet ret; MemTxResult ret1; - + CPUSysState *sys = env_sys(env); address = context->addr; if ((address >> 63) & 0x1) { - base = env->CSR_PGDH; + base = sys->CSR_PGDH; } else { - base = env->CSR_PGDL; + base = sys->CSR_PGDL; } base &= palen_mask; @@ -XXX,XX +XXX,XX @@ TLBRet get_physical_address(CPULoongArchState *env, MMUContext *context, int kernel_mode = mmu_idx == MMU_KERNEL_IDX; uint32_t plv, base_c, base_v; int64_t addr_high; - uint8_t da = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, DA); - uint8_t pg = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG); + CPUSysState *sys = env_sys(env); + uint8_t da = FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, DA); + uint8_t pg = FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, PG); vaddr address; /* Check PG and DA */ @@ -XXX,XX +XXX,XX @@ TLBRet get_physical_address(CPULoongArchState *env, MMUContext *context, /* Check direct map window */ for (int i = 0; i < 4; i++) { if (is_la64(env)) { - base_c = FIELD_EX64(env->CSR_DMW[i], CSR_DMW_64, VSEG); + base_c = FIELD_EX64(sys->CSR_DMW[i], CSR_DMW_64, VSEG); } else { - base_c = FIELD_EX64(env->CSR_DMW[i], CSR_DMW_32, VSEG); + base_c = FIELD_EX64(sys->CSR_DMW[i], CSR_DMW_32, VSEG); } - if ((plv & env->CSR_DMW[i]) && (base_c == base_v)) { - context->physical = dmw_va2pa(env, address, env->CSR_DMW[i]); + if ((plv & sys->CSR_DMW[i]) && (base_c == base_v)) { + context->physical = dmw_va2pa(env, address, sys->CSR_DMW[i]); context->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; context->mmu_index = MMU_DA_IDX; return TLBRET_MATCH; -- 2.54.0
From: Bibo Mao <maobibo@loongson.cn> When accessing CSR registers in file arch_dump.c, use sys_state rather than env. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Philippe Mathieu-Daudé <philmd@mailo.com> Tested-by: Song Gao <gaosong@loongson.cn> Message-ID: <20260605082552.175336-5-maobibo@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn> --- hw/intc/loongarch_dintc.c | 4 +++- target/loongarch/arch_dump.c | 5 +++-- target/loongarch/cpu-mmu.h | 4 +++- target/loongarch/gdbstub.c | 3 ++- target/loongarch/tcg/constant_timer.c | 10 ++++++---- 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/hw/intc/loongarch_dintc.c b/hw/intc/loongarch_dintc.c index XXXXXXX..XXXXXXX 100644 --- a/hw/intc/loongarch_dintc.c +++ b/hw/intc/loongarch_dintc.c @@ -XXX,XX +XXX,XX @@ static void do_set_vcpu_dintc_irq(CPUState *cs, run_on_cpu_data data) { int irq = data.host_int; CPULoongArchState *env; + CPUSysState *sys; env = &LOONGARCH_CPU(cs)->env; + sys = env_sys(env); cpu_synchronize_state(cs); - set_bit(irq, (unsigned long *)&env->CSR_MSGIS); + set_bit(irq, (unsigned long *)&sys->CSR_MSGIS); } static void loongarch_dintc_mem_write(void *opaque, hwaddr addr, diff --git a/target/loongarch/arch_dump.c b/target/loongarch/arch_dump.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/arch_dump.c +++ b/target/loongarch/arch_dump.c @@ -XXX,XX +XXX,XX @@ int loongarch_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs, { struct loongarch_note note; CPULoongArchState *env = &LOONGARCH_CPU(cs)->env; + CPUSysState *sys = env_sys(env); int ret, i; loongarch_note_init(¬e, s, "CORE", 5, NT_PRSTATUS, @@ -XXX,XX +XXX,XX @@ int loongarch_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs, for (i = 0; i < 32; ++i) { note.prstatus.pr_reg.gpr[i] = cpu_to_dump64(s, env->gpr[i]); } - note.prstatus.pr_reg.csr_era = cpu_to_dump64(s, env->CSR_ERA); - note.prstatus.pr_reg.csr_badv = cpu_to_dump64(s, env->CSR_BADV); + note.prstatus.pr_reg.csr_era = cpu_to_dump64(s, sys->CSR_ERA); + note.prstatus.pr_reg.csr_badv = cpu_to_dump64(s, sys->CSR_BADV); ret = f(¬e, LOONGARCH_PRSTATUS_NOTE_SIZE, s); if (ret < 0) { return -1; diff --git a/target/loongarch/cpu-mmu.h b/target/loongarch/cpu-mmu.h index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/cpu-mmu.h +++ b/target/loongarch/cpu-mmu.h @@ -XXX,XX +XXX,XX @@ typedef struct MMUContext { static inline bool cpu_has_ptw(CPULoongArchState *env) { - return !!FIELD_EX64(env->CSR_PWCH, CSR_PWCH, HPTW_EN); + CPUSysState *sys = env_sys(env); + + return !!FIELD_EX64(sys->CSR_PWCH, CSR_PWCH, HPTW_EN); } static inline bool pte_present(CPULoongArchState *env, uint64_t entry) diff --git a/target/loongarch/gdbstub.c b/target/loongarch/gdbstub.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/gdbstub.c +++ b/target/loongarch/gdbstub.c @@ -XXX,XX +XXX,XX @@ void write_fcc(CPULoongArchState *env, uint64_t val) int loongarch_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) { CPULoongArchState *env = cpu_env(cs); + CPUSysState *sys = env_sys(env); if (0 <= n && n <= 34) { uint64_t val; @@ -XXX,XX +XXX,XX @@ int loongarch_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) } else if (n == 33) { val = env->pc; } else /* if (n == 34) */ { - val = env->CSR_BADV; + val = sys->CSR_BADV; } if (is_la64(env)) { diff --git a/target/loongarch/tcg/constant_timer.c b/target/loongarch/tcg/constant_timer.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/tcg/constant_timer.c +++ b/target/loongarch/tcg/constant_timer.c @@ -XXX,XX +XXX,XX @@ void cpu_loongarch_store_constant_timer_config(LoongArchCPU *cpu, uint64_t value) { CPULoongArchState *env = &cpu->env; + CPUSysState *sys = env_sys(env); uint64_t now, next; - env->CSR_TCFG = value; + sys->CSR_TCFG = value; if (value & CONSTANT_TIMER_ENABLE) { now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); next = now + (value & CONSTANT_TIMER_TICK_MASK) * TIMER_PERIOD; @@ -XXX,XX +XXX,XX @@ void loongarch_constant_timer_cb(void *opaque) { LoongArchCPU *cpu = opaque; CPULoongArchState *env = &cpu->env; + CPUSysState *sys = env_sys(env); uint64_t now, next; - if (FIELD_EX64(env->CSR_TCFG, CSR_TCFG, PERIODIC)) { + if (FIELD_EX64(sys->CSR_TCFG, CSR_TCFG, PERIODIC)) { now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - next = now + (env->CSR_TCFG & CONSTANT_TIMER_TICK_MASK) * TIMER_PERIOD; + next = now + (sys->CSR_TCFG & CONSTANT_TIMER_TICK_MASK) * TIMER_PERIOD; timer_mod(&cpu->timer, next); } else { - env->CSR_TCFG = FIELD_DP64(env->CSR_TCFG, CSR_TCFG, EN, 0); + sys->CSR_TCFG = FIELD_DP64(sys->CSR_TCFG, CSR_TCFG, EN, 0); } loongarch_cpu_set_irq(opaque, IRQ_TIMER, 1); -- 2.54.0
From: Bibo Mao <maobibo@loongson.cn> When accessing CSR registers in file kvm.c, use sys_state rather than env. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Philippe Mathieu-Daudé <philmd@mailo.com> Tested-by: Song Gao <gaosong@loongson.cn> Message-ID: <20260605082552.175336-6-maobibo@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn> --- target/loongarch/kvm/kvm.c | 228 +++++++++++++++++++------------------ 1 file changed, 116 insertions(+), 112 deletions(-) diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/kvm/kvm.c +++ b/target/loongarch/kvm/kvm.c @@ -XXX,XX +XXX,XX @@ static int kvm_loongarch_put_pmu(CPUState *cs) int i, ret = 0; CPULoongArchState *env = cpu_env(cs); LoongArchCPU *cpu = LOONGARCH_CPU(cs); + CPUSysState *sys = env_sys(env); if (cpu->pmu != ON_OFF_AUTO_ON) { return 0; @@ -XXX,XX +XXX,XX @@ static int kvm_loongarch_put_pmu(CPUState *cs) for (i = 0; i < env->perf_event_num; i++) { ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PERFCTRL(i)), - &env->CSR_PERFCTRL[i]); + &sys->CSR_PERFCTRL[i]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PERFCNTR(i)), - &env->CSR_PERFCNTR[i]); + &sys->CSR_PERFCNTR[i]); } return ret; @@ -XXX,XX +XXX,XX @@ static int kvm_loongarch_get_pmu(CPUState *cs) int i, ret = 0; CPULoongArchState *env = cpu_env(cs); LoongArchCPU *cpu = LOONGARCH_CPU(cs); + CPUSysState *sys = env_sys(env); if (cpu->pmu != ON_OFF_AUTO_ON) { return 0; @@ -XXX,XX +XXX,XX @@ static int kvm_loongarch_get_pmu(CPUState *cs) for (i = 0; i < env->perf_event_num; i++) { ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PERFCTRL(i)), - &env->CSR_PERFCTRL[i]); + &sys->CSR_PERFCTRL[i]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PERFCNTR(i)), - &env->CSR_PERFCNTR[i]); + &sys->CSR_PERFCNTR[i]); } return ret; @@ -XXX,XX +XXX,XX @@ static int kvm_loongarch_get_csr(CPUState *cs) { int ret = 0; CPULoongArchState *env = cpu_env(cs); + CPUSysState *sys = env_sys(env); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CRMD), - &env->CSR_CRMD); + &sys->CSR_CRMD); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRMD), - &env->CSR_PRMD); + &sys->CSR_PRMD); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EUEN), - &env->CSR_EUEN); + &sys->CSR_EUEN); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_MISC), - &env->CSR_MISC); + &sys->CSR_MISC); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ECFG), - &env->CSR_ECFG); + &sys->CSR_ECFG); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ESTAT), - &env->CSR_ESTAT); + &sys->CSR_ESTAT); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ERA), - &env->CSR_ERA); + &sys->CSR_ERA); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADV), - &env->CSR_BADV); + &sys->CSR_BADV); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADI), - &env->CSR_BADI); + &sys->CSR_BADI); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EENTRY), - &env->CSR_EENTRY); + &sys->CSR_EENTRY); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBIDX), - &env->CSR_TLBIDX); + &sys->CSR_TLBIDX); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBEHI), - &env->CSR_TLBEHI); + &sys->CSR_TLBEHI); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO0), - &env->CSR_TLBELO0); + &sys->CSR_TLBELO0); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO1), - &env->CSR_TLBELO1); + &sys->CSR_TLBELO1); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ASID), - &env->CSR_ASID); + &sys->CSR_ASID); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDL), - &env->CSR_PGDL); + &sys->CSR_PGDL); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDH), - &env->CSR_PGDH); + &sys->CSR_PGDH); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGD), - &env->CSR_PGD); + &sys->CSR_PGD); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCL), - &env->CSR_PWCL); + &sys->CSR_PWCL); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCH), - &env->CSR_PWCH); + &sys->CSR_PWCH); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_STLBPS), - &env->CSR_STLBPS); + &sys->CSR_STLBPS); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_RVACFG), - &env->CSR_RVACFG); + &sys->CSR_RVACFG); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CPUID), - &env->CSR_CPUID); + &sys->CSR_CPUID); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG1), - &env->CSR_PRCFG1); + &sys->CSR_PRCFG1); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG2), - &env->CSR_PRCFG2); + &sys->CSR_PRCFG2); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG3), - &env->CSR_PRCFG3); + &sys->CSR_PRCFG3); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(0)), - &env->CSR_SAVE[0]); + &sys->CSR_SAVE[0]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(1)), - &env->CSR_SAVE[1]); + &sys->CSR_SAVE[1]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(2)), - &env->CSR_SAVE[2]); + &sys->CSR_SAVE[2]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(3)), - &env->CSR_SAVE[3]); + &sys->CSR_SAVE[3]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(4)), - &env->CSR_SAVE[4]); + &sys->CSR_SAVE[4]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(5)), - &env->CSR_SAVE[5]); + &sys->CSR_SAVE[5]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(6)), - &env->CSR_SAVE[6]); + &sys->CSR_SAVE[6]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(7)), - &env->CSR_SAVE[7]); + &sys->CSR_SAVE[7]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TID), - &env->CSR_TID); + &sys->CSR_TID); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CNTC), - &env->CSR_CNTC); + &sys->CSR_CNTC); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TICLR), - &env->CSR_TICLR); + &sys->CSR_TICLR); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_LLBCTL), - &env->CSR_LLBCTL); + &sys->CSR_LLBCTL); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL1), - &env->CSR_IMPCTL1); + &sys->CSR_IMPCTL1); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL2), - &env->CSR_IMPCTL2); + &sys->CSR_IMPCTL2); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRENTRY), - &env->CSR_TLBRENTRY); + &sys->CSR_TLBRENTRY); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRBADV), - &env->CSR_TLBRBADV); + &sys->CSR_TLBRBADV); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRERA), - &env->CSR_TLBRERA); + &sys->CSR_TLBRERA); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRSAVE), - &env->CSR_TLBRSAVE); + &sys->CSR_TLBRSAVE); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO0), - &env->CSR_TLBRELO0); + &sys->CSR_TLBRELO0); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO1), - &env->CSR_TLBRELO1); + &sys->CSR_TLBRELO1); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBREHI), - &env->CSR_TLBREHI); + &sys->CSR_TLBREHI); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRPRMD), - &env->CSR_TLBRPRMD); + &sys->CSR_TLBRPRMD); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(0)), - &env->CSR_DMW[0]); + &sys->CSR_DMW[0]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(1)), - &env->CSR_DMW[1]); + &sys->CSR_DMW[1]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(2)), - &env->CSR_DMW[2]); + &sys->CSR_DMW[2]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(3)), - &env->CSR_DMW[3]); + &sys->CSR_DMW[3]); ret |= kvm_loongarch_get_pmu(cs); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TVAL), - &env->CSR_TVAL); + &sys->CSR_TVAL); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TCFG), - &env->CSR_TCFG); + &sys->CSR_TCFG); return ret; } @@ -XXX,XX +XXX,XX @@ static int kvm_loongarch_put_csr(CPUState *cs, KvmPutState level) { int ret = 0; CPULoongArchState *env = cpu_env(cs); + CPUSysState *sys = env_sys(env); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CRMD), - &env->CSR_CRMD); + &sys->CSR_CRMD); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRMD), - &env->CSR_PRMD); + &sys->CSR_PRMD); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EUEN), - &env->CSR_EUEN); + &sys->CSR_EUEN); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_MISC), - &env->CSR_MISC); + &sys->CSR_MISC); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ECFG), - &env->CSR_ECFG); + &sys->CSR_ECFG); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ESTAT), - &env->CSR_ESTAT); + &sys->CSR_ESTAT); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ERA), - &env->CSR_ERA); + &sys->CSR_ERA); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADV), - &env->CSR_BADV); + &sys->CSR_BADV); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADI), - &env->CSR_BADI); + &sys->CSR_BADI); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EENTRY), - &env->CSR_EENTRY); + &sys->CSR_EENTRY); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBIDX), - &env->CSR_TLBIDX); + &sys->CSR_TLBIDX); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBEHI), - &env->CSR_TLBEHI); + &sys->CSR_TLBEHI); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO0), - &env->CSR_TLBELO0); + &sys->CSR_TLBELO0); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO1), - &env->CSR_TLBELO1); + &sys->CSR_TLBELO1); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ASID), - &env->CSR_ASID); + &sys->CSR_ASID); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDL), - &env->CSR_PGDL); + &sys->CSR_PGDL); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDH), - &env->CSR_PGDH); + &sys->CSR_PGDH); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGD), - &env->CSR_PGD); + &sys->CSR_PGD); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCL), - &env->CSR_PWCL); + &sys->CSR_PWCL); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCH), - &env->CSR_PWCH); + &sys->CSR_PWCH); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_STLBPS), - &env->CSR_STLBPS); + &sys->CSR_STLBPS); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_RVACFG), - &env->CSR_RVACFG); + &sys->CSR_RVACFG); /* CPUID is constant after poweron, it should be set only once */ if (level >= KVM_PUT_FULL_STATE) { ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CPUID), - &env->CSR_CPUID); + &sys->CSR_CPUID); } ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG1), - &env->CSR_PRCFG1); + &sys->CSR_PRCFG1); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG2), - &env->CSR_PRCFG2); + &sys->CSR_PRCFG2); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG3), - &env->CSR_PRCFG3); + &sys->CSR_PRCFG3); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(0)), - &env->CSR_SAVE[0]); + &sys->CSR_SAVE[0]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(1)), - &env->CSR_SAVE[1]); + &sys->CSR_SAVE[1]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(2)), - &env->CSR_SAVE[2]); + &sys->CSR_SAVE[2]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(3)), - &env->CSR_SAVE[3]); + &sys->CSR_SAVE[3]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(4)), - &env->CSR_SAVE[4]); + &sys->CSR_SAVE[4]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(5)), - &env->CSR_SAVE[5]); + &sys->CSR_SAVE[5]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(6)), - &env->CSR_SAVE[6]); + &sys->CSR_SAVE[6]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(7)), - &env->CSR_SAVE[7]); + &sys->CSR_SAVE[7]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TID), - &env->CSR_TID); + &sys->CSR_TID); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CNTC), - &env->CSR_CNTC); + &sys->CSR_CNTC); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TICLR), - &env->CSR_TICLR); + &sys->CSR_TICLR); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_LLBCTL), - &env->CSR_LLBCTL); + &sys->CSR_LLBCTL); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL1), - &env->CSR_IMPCTL1); + &sys->CSR_IMPCTL1); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL2), - &env->CSR_IMPCTL2); + &sys->CSR_IMPCTL2); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRENTRY), - &env->CSR_TLBRENTRY); + &sys->CSR_TLBRENTRY); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRBADV), - &env->CSR_TLBRBADV); + &sys->CSR_TLBRBADV); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRERA), - &env->CSR_TLBRERA); + &sys->CSR_TLBRERA); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRSAVE), - &env->CSR_TLBRSAVE); + &sys->CSR_TLBRSAVE); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO0), - &env->CSR_TLBRELO0); + &sys->CSR_TLBRELO0); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO1), - &env->CSR_TLBRELO1); + &sys->CSR_TLBRELO1); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBREHI), - &env->CSR_TLBREHI); + &sys->CSR_TLBREHI); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRPRMD), - &env->CSR_TLBRPRMD); + &sys->CSR_TLBRPRMD); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(0)), - &env->CSR_DMW[0]); + &sys->CSR_DMW[0]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(1)), - &env->CSR_DMW[1]); + &sys->CSR_DMW[1]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(2)), - &env->CSR_DMW[2]); + &sys->CSR_DMW[2]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(3)), - &env->CSR_DMW[3]); + &sys->CSR_DMW[3]); ret |= kvm_loongarch_put_pmu(cs); @@ -XXX,XX +XXX,XX @@ static int kvm_loongarch_put_csr(CPUState *cs, KvmPutState level) * guest timer */ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TVAL), - &env->CSR_TVAL); + &sys->CSR_TVAL); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TCFG), - &env->CSR_TCFG); + &sys->CSR_TCFG); return ret; } -- 2.54.0
From: Bibo Mao <maobibo@loongson.cn> When accessing CSR registers in file tlb_helper.c, use sys_state rather than env. There is no function change. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Philippe Mathieu-Daudé <philmd@mailo.com> Tested-by: Song Gao <gaosong@loongson.cn> Message-ID: <20260605082552.175336-7-maobibo@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn> --- target/loongarch/tcg/tlb_helper.c | 137 +++++++++++++++++------------- 1 file changed, 77 insertions(+), 60 deletions(-) diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/tcg/tlb_helper.c +++ b/target/loongarch/tcg/tlb_helper.c @@ -XXX,XX +XXX,XX @@ static bool tlb_match_asid(bool global, int asid, int tlb_asid) bool check_ps(CPULoongArchState *env, uint8_t tlb_ps) { + CPUSysState *sys = env_sys(env); + if (tlb_ps >= 64) { return false; } - return BIT_ULL(tlb_ps) & (env->CSR_PRCFG2); + return BIT_ULL(tlb_ps) & (sys->CSR_PRCFG2); } static void raise_mmu_exception(CPULoongArchState *env, vaddr address, MMUAccessType access_type, TLBRet tlb_error) { CPUState *cs = env_cpu(env); + CPUSysState *sys = env_sys(env); switch (tlb_error) { default: @@ -XXX,XX +XXX,XX @@ static void raise_mmu_exception(CPULoongArchState *env, vaddr address, } else if (access_type == MMU_INST_FETCH) { cs->exception_index = EXCCODE_PIF; } - env->CSR_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR, 1); + sys->CSR_TLBRERA = FIELD_DP64(sys->CSR_TLBRERA, CSR_TLBRERA, ISTLBR, 1); break; case TLBRET_INVALID: /* TLB match with no valid bit */ @@ -XXX,XX +XXX,XX @@ static void raise_mmu_exception(CPULoongArchState *env, vaddr address, } if (tlb_error == TLBRET_NOMATCH) { - env->CSR_TLBRBADV = address; + sys->CSR_TLBRBADV = address; if (is_la64(env)) { - env->CSR_TLBREHI = FIELD_DP64(env->CSR_TLBREHI, CSR_TLBREHI_64, + sys->CSR_TLBREHI = FIELD_DP64(sys->CSR_TLBREHI, CSR_TLBREHI_64, VPPN, extract64(address, 13, 35)); } else { - env->CSR_TLBREHI = FIELD_DP64(env->CSR_TLBREHI, CSR_TLBREHI_32, + sys->CSR_TLBREHI = FIELD_DP64(sys->CSR_TLBREHI, CSR_TLBREHI_32, VPPN, extract64(address, 13, 19)); } } else { - if (!FIELD_EX64(env->CSR_DBG, CSR_DBG, DST)) { - env->CSR_BADV = address; + if (!FIELD_EX64(sys->CSR_DBG, CSR_DBG, DST)) { + sys->CSR_BADV = address; } - env->CSR_TLBEHI = address & (TARGET_PAGE_MASK << 1); + sys->CSR_TLBEHI = address & (TARGET_PAGE_MASK << 1); } } @@ -XXX,XX +XXX,XX @@ static void invalidate_tlb(CPULoongArchState *env, int index) LoongArchTLB *tlb; uint16_t csr_asid, tlb_asid, tlb_g; uint8_t tlb_e; + CPUSysState *sys = env_sys(env); - csr_asid = FIELD_EX64(env->CSR_ASID, CSR_ASID, ASID); + csr_asid = FIELD_EX64(sys->CSR_ASID, CSR_ASID, ASID); tlb = &env->tlb[index]; tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E); if (!tlb_e) { @@ -XXX,XX +XXX,XX @@ static void sptw_prepare_context(CPULoongArchState *env, MMUContext *context) { uint64_t lo0, lo1, csr_vppn; uint8_t csr_ps; + CPUSysState *sys = env_sys(env); - if (FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) { - csr_ps = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI, PS); + if (FIELD_EX64(sys->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) { + csr_ps = FIELD_EX64(sys->CSR_TLBREHI, CSR_TLBREHI, PS); if (is_la64(env)) { - csr_vppn = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI_64, VPPN); + csr_vppn = FIELD_EX64(sys->CSR_TLBREHI, CSR_TLBREHI_64, VPPN); } else { - csr_vppn = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI_32, VPPN); + csr_vppn = FIELD_EX64(sys->CSR_TLBREHI, CSR_TLBREHI_32, VPPN); } - lo0 = env->CSR_TLBRELO0; - lo1 = env->CSR_TLBRELO1; + lo0 = sys->CSR_TLBRELO0; + lo1 = sys->CSR_TLBRELO1; } else { - csr_ps = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, PS); + csr_ps = FIELD_EX64(sys->CSR_TLBIDX, CSR_TLBIDX, PS); if (is_la64(env)) { - csr_vppn = FIELD_EX64(env->CSR_TLBEHI, CSR_TLBEHI_64, VPPN); + csr_vppn = FIELD_EX64(sys->CSR_TLBEHI, CSR_TLBEHI_64, VPPN); } else { - csr_vppn = FIELD_EX64(env->CSR_TLBEHI, CSR_TLBEHI_32, VPPN); + csr_vppn = FIELD_EX64(sys->CSR_TLBEHI, CSR_TLBEHI_32, VPPN); } - lo0 = env->CSR_TLBELO0; - lo1 = env->CSR_TLBELO1; + lo0 = sys->CSR_TLBELO0; + lo1 = sys->CSR_TLBELO1; } context->ps = csr_ps; @@ -XXX,XX +XXX,XX @@ static void fill_tlb_entry(CPULoongArchState *env, LoongArchTLB *tlb, uint64_t lo0, lo1, csr_vppn; uint16_t csr_asid; uint8_t csr_ps; + CPUSysState *sys = env_sys(env); csr_vppn = context->addr >> R_TLB_MISC_VPPN_SHIFT; csr_ps = context->ps; @@ -XXX,XX +XXX,XX @@ static void fill_tlb_entry(CPULoongArchState *env, LoongArchTLB *tlb, tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, PS, csr_ps); tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, VPPN, csr_vppn); tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, E, 1); - csr_asid = FIELD_EX64(env->CSR_ASID, CSR_ASID, ASID); + csr_asid = FIELD_EX64(sys->CSR_ASID, CSR_ASID, ASID); tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, ASID, csr_asid); tlb->tlb_entry0 = lo0; @@ -XXX,XX +XXX,XX @@ static LoongArchTLB *loongarch_tlb_search_cb(CPULoongArchState *env, bool tlb_g; int i, compare_shift; uint64_t vpn, tlb_vppn; + CPUSysState *sys = env_sys(env); - stlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS); + stlb_ps = FIELD_EX64(sys->CSR_STLBPS, CSR_STLBPS, PS); vpn = (vaddr & TARGET_VIRT_MASK) >> (stlb_ps + 1); stlb_idx = vpn & 0xff; /* VA[25:15] <==> TLBIDX.index for 16KiB Page */ compare_shift = stlb_ps + 1 - R_TLB_MISC_VPPN_SHIFT; @@ -XXX,XX +XXX,XX @@ static bool loongarch_tlb_search(CPULoongArchState *env, vaddr vaddr, int csr_asid; tlb_match func; LoongArchTLB *tlb; + CPUSysState *sys = env_sys(env); func = tlb_match_any; - csr_asid = FIELD_EX64(env->CSR_ASID, CSR_ASID, ASID); + csr_asid = FIELD_EX64(sys->CSR_ASID, CSR_ASID, ASID); tlb = loongarch_tlb_search_cb(env, vaddr, csr_asid, func); if (tlb) { *index = tlb - env->tlb; @@ -XXX,XX +XXX,XX @@ static bool loongarch_tlb_search(CPULoongArchState *env, vaddr vaddr, void helper_tlbsrch(CPULoongArchState *env) { int index, match; + CPUSysState *sys = env_sys(env); - if (FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) { - match = loongarch_tlb_search(env, env->CSR_TLBREHI, &index); + if (FIELD_EX64(sys->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) { + match = loongarch_tlb_search(env, sys->CSR_TLBREHI, &index); } else { - match = loongarch_tlb_search(env, env->CSR_TLBEHI, &index); + match = loongarch_tlb_search(env, sys->CSR_TLBEHI, &index); } if (match) { - env->CSR_TLBIDX = FIELD_DP64(env->CSR_TLBIDX, CSR_TLBIDX, INDEX, index); - env->CSR_TLBIDX = FIELD_DP64(env->CSR_TLBIDX, CSR_TLBIDX, NE, 0); + sys->CSR_TLBIDX = FIELD_DP64(sys->CSR_TLBIDX, CSR_TLBIDX, INDEX, index); + sys->CSR_TLBIDX = FIELD_DP64(sys->CSR_TLBIDX, CSR_TLBIDX, NE, 0); return; } - env->CSR_TLBIDX = FIELD_DP64(env->CSR_TLBIDX, CSR_TLBIDX, NE, 1); + sys->CSR_TLBIDX = FIELD_DP64(sys->CSR_TLBIDX, CSR_TLBIDX, NE, 1); } void helper_tlbrd(CPULoongArchState *env) @@ -XXX,XX +XXX,XX @@ void helper_tlbrd(CPULoongArchState *env) LoongArchTLB *tlb; int index; uint8_t tlb_ps, tlb_e; + CPUSysState *sys = env_sys(env); - index = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, INDEX); + index = FIELD_EX64(sys->CSR_TLBIDX, CSR_TLBIDX, INDEX); tlb = &env->tlb[index]; tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS); tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E); if (!tlb_e) { /* Invalid TLB entry */ - env->CSR_TLBIDX = FIELD_DP64(env->CSR_TLBIDX, CSR_TLBIDX, NE, 1); - env->CSR_ASID = FIELD_DP64(env->CSR_ASID, CSR_ASID, ASID, 0); - env->CSR_TLBEHI = 0; - env->CSR_TLBELO0 = 0; - env->CSR_TLBELO1 = 0; - env->CSR_TLBIDX = FIELD_DP64(env->CSR_TLBIDX, CSR_TLBIDX, PS, 0); + sys->CSR_TLBIDX = FIELD_DP64(sys->CSR_TLBIDX, CSR_TLBIDX, NE, 1); + sys->CSR_ASID = FIELD_DP64(sys->CSR_ASID, CSR_ASID, ASID, 0); + sys->CSR_TLBEHI = 0; + sys->CSR_TLBELO0 = 0; + sys->CSR_TLBELO1 = 0; + sys->CSR_TLBIDX = FIELD_DP64(sys->CSR_TLBIDX, CSR_TLBIDX, PS, 0); } else { /* Valid TLB entry */ - env->CSR_TLBIDX = FIELD_DP64(env->CSR_TLBIDX, CSR_TLBIDX, NE, 0); - env->CSR_TLBIDX = FIELD_DP64(env->CSR_TLBIDX, CSR_TLBIDX, + sys->CSR_TLBIDX = FIELD_DP64(sys->CSR_TLBIDX, CSR_TLBIDX, NE, 0); + sys->CSR_TLBIDX = FIELD_DP64(sys->CSR_TLBIDX, CSR_TLBIDX, PS, (tlb_ps & 0x3f)); - env->CSR_TLBEHI = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN) << + sys->CSR_TLBEHI = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN) << R_TLB_MISC_VPPN_SHIFT; - env->CSR_TLBELO0 = tlb->tlb_entry0; - env->CSR_TLBELO1 = tlb->tlb_entry1; + sys->CSR_TLBELO0 = tlb->tlb_entry0; + sys->CSR_TLBELO1 = tlb->tlb_entry1; } } @@ -XXX,XX +XXX,XX @@ static void update_tlb_index(CPULoongArchState *env, MMUContext *context, void helper_tlbwr(CPULoongArchState *env) { - int index = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, INDEX); + CPUSysState *sys = env_sys(env); + int index = FIELD_EX64(sys->CSR_TLBIDX, CSR_TLBIDX, INDEX); MMUContext context; - if (FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, NE)) { + if (FIELD_EX64(sys->CSR_TLBIDX, CSR_TLBIDX, NE)) { invalidate_tlb(env, index); return; } @@ -XXX,XX +XXX,XX @@ static int get_tlb_random_index(CPULoongArchState *env, vaddr addr, uint16_t asid, tlb_asid, stlb_ps; LoongArchTLB *tlb; uint8_t tlb_e, tlb_g; + CPUSysState *sys = env_sys(env); /* Validity of stlb_ps is checked in helper_csrwr_stlbps() */ - stlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS); - asid = FIELD_EX64(env->CSR_ASID, CSR_ASID, ASID); + stlb_ps = FIELD_EX64(sys->CSR_STLBPS, CSR_STLBPS, PS); + asid = FIELD_EX64(sys->CSR_ASID, CSR_ASID, ASID); if (pagesize == stlb_ps) { /* Only write into STLB bits [47:13] */ address = addr & ~MAKE_64BIT_MASK(0, R_CSR_TLBEHI_64_VPPN_SHIFT); @@ -XXX,XX +XXX,XX @@ void helper_tlbfill(CPULoongArchState *env) vaddr entryhi; int index, pagesize; MMUContext context; + CPUSysState *sys = env_sys(env); - if (FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) { - entryhi = env->CSR_TLBREHI; + if (FIELD_EX64(sys->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) { + entryhi = sys->CSR_TLBREHI; /* Validity of pagesize is checked in helper_ldpte() */ - pagesize = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI, PS); + pagesize = FIELD_EX64(sys->CSR_TLBREHI, CSR_TLBREHI, PS); } else { - entryhi = env->CSR_TLBEHI; + entryhi = sys->CSR_TLBEHI; /* Validity of pagesize is checked in helper_tlbrd() */ - pagesize = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, PS); + pagesize = FIELD_EX64(sys->CSR_TLBIDX, CSR_TLBIDX, PS); } sptw_prepare_context(env, &context); @@ -XXX,XX +XXX,XX @@ void helper_tlbclr(CPULoongArchState *env) LoongArchTLB *tlb; int i, index; uint16_t csr_asid, tlb_asid, tlb_g; + CPUSysState *sys = env_sys(env); - csr_asid = FIELD_EX64(env->CSR_ASID, CSR_ASID, ASID); - index = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, INDEX); + csr_asid = FIELD_EX64(sys->CSR_ASID, CSR_ASID, ASID); + index = FIELD_EX64(sys->CSR_TLBIDX, CSR_TLBIDX, INDEX); if (index < LOONGARCH_STLB) { /* STLB. One line per operation */ @@ -XXX,XX +XXX,XX @@ void helper_tlbclr(CPULoongArchState *env) void helper_tlbflush(CPULoongArchState *env) { int i, index; + CPUSysState *sys = env_sys(env); - index = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, INDEX); + index = FIELD_EX64(sys->CSR_TLBIDX, CSR_TLBIDX, INDEX); if (index < LOONGARCH_STLB) { /* STLB. One line per operation */ @@ -XXX,XX +XXX,XX @@ target_ulong helper_lddir(CPULoongArchState *env, target_ulong base, uint64_t palen_mask = loongarch_palen_mask(env); uint64_t dir_base, dir_width; uint64_t val; + CPUSysState *sys = env_sys(env); if (unlikely((level == 0) || (level > 4))) { qemu_log_mask(LOG_GUEST_ERROR, @@ -XXX,XX +XXX,XX @@ target_ulong helper_lddir(CPULoongArchState *env, target_ulong base, } } - badvaddr = env->CSR_TLBRBADV; + badvaddr = sys->CSR_TLBRBADV; base = base & palen_mask; get_dir_base_width(env, &dir_base, &dir_width, level); index = (badvaddr >> dir_base) & ((1 << dir_width) - 1); @@ -XXX,XX +XXX,XX @@ void helper_ldpte(CPULoongArchState *env, target_ulong base, target_ulong odd, { CPUState *cs = env_cpu(env); hwaddr phys, tmp0, ptindex, ptoffset0, ptoffset1; + CPUSysState *sys = env_sys(env); uint64_t pte_raw; uint64_t badv; - uint64_t ptbase = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTBASE); - uint64_t ptwidth = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTWIDTH); + uint64_t ptbase = FIELD_EX64(sys->CSR_PWCL, CSR_PWCL, PTBASE); + uint64_t ptwidth = FIELD_EX64(sys->CSR_PWCL, CSR_PWCL, PTWIDTH); uint64_t palen_mask = loongarch_palen_mask(env); uint64_t dir_base, dir_width; uint8_t ps; @@ -XXX,XX +XXX,XX @@ void helper_ldpte(CPULoongArchState *env, target_ulong base, target_ulong odd, return; } } else { - badv = env->CSR_TLBRBADV; + badv = sys->CSR_TLBRBADV; base = base & palen_mask; @@ -XXX,XX +XXX,XX @@ void helper_ldpte(CPULoongArchState *env, target_ulong base, target_ulong odd, } if (odd) { - env->CSR_TLBRELO1 = tmp0; + sys->CSR_TLBRELO1 = tmp0; } else { - env->CSR_TLBRELO0 = tmp0; + sys->CSR_TLBRELO0 = tmp0; } - env->CSR_TLBREHI = FIELD_DP64(env->CSR_TLBREHI, CSR_TLBREHI, PS, ps); + sys->CSR_TLBREHI = FIELD_DP64(sys->CSR_TLBREHI, CSR_TLBREHI, PS, ps); } static TLBRet loongarch_map_tlb_entry(CPULoongArchState *env, -- 2.54.0
From: Bibo Mao <maobibo@loongson.cn> When accessing CSR registers in file tcg_cpu.c, use sys_state rather than env. There is no function change. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Philippe Mathieu-Daudé <philmd@mailo.com> Tested-by: Song Gao <gaosong@loongson.cn> Message-ID: <20260605082552.175336-8-maobibo@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn> --- target/loongarch/tcg/tcg_cpu.c | 107 +++++++++++++++++---------------- 1 file changed, 56 insertions(+), 51 deletions(-) diff --git a/target/loongarch/tcg/tcg_cpu.c b/target/loongarch/tcg/tcg_cpu.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/tcg/tcg_cpu.c +++ b/target/loongarch/tcg/tcg_cpu.c @@ -XXX,XX +XXX,XX @@ void G_NORETURN do_raise_exception(CPULoongArchState *env, static void loongarch_cpu_do_interrupt(CPUState *cs) { CPULoongArchState *env = cpu_env(cs); + CPUSysState *sys = env_sys(env); bool update_badinstr = 1; int cause = -1; - bool tlbfill = FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR); - uint32_t vec_size = FIELD_EX64(env->CSR_ECFG, CSR_ECFG, VS); + bool tlbfill = FIELD_EX64(sys->CSR_TLBRERA, CSR_TLBRERA, ISTLBR); + uint32_t vec_size = FIELD_EX64(sys->CSR_ECFG, CSR_ECFG, VS); uint64_t last_pc = env->pc; if (cs->exception_index != EXCCODE_INT) { qemu_log_mask(CPU_LOG_INT, "%s enter: pc " TARGET_FMT_lx " ERA " TARGET_FMT_lx " TLBRERA " TARGET_FMT_lx " exception: %d (%s)\n", - __func__, env->pc, env->CSR_ERA, env->CSR_TLBRERA, + __func__, env->pc, sys->CSR_ERA, sys->CSR_TLBRERA, cs->exception_index, loongarch_exception_name(cs->exception_index)); } switch (cs->exception_index) { case EXCCODE_DBP: - env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, DCL, 1); - env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, ECODE, 0xC); + sys->CSR_DBG = FIELD_DP64(sys->CSR_DBG, CSR_DBG, DCL, 1); + sys->CSR_DBG = FIELD_DP64(sys->CSR_DBG, CSR_DBG, ECODE, 0xC); goto set_DERA; set_DERA: - env->CSR_DERA = env->pc; - env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, DST, 1); - set_pc(env, env->CSR_EENTRY + 0x480); + sys->CSR_DERA = env->pc; + sys->CSR_DBG = FIELD_DP64(sys->CSR_DBG, CSR_DBG, DST, 1); + set_pc(env, sys->CSR_EENTRY + 0x480); break; case EXCCODE_INT: - if (FIELD_EX64(env->CSR_DBG, CSR_DBG, DST)) { - env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, DEI, 1); + if (FIELD_EX64(sys->CSR_DBG, CSR_DBG, DST)) { + sys->CSR_DBG = FIELD_DP64(sys->CSR_DBG, CSR_DBG, DEI, 1); goto set_DERA; } QEMU_FALLTHROUGH; @@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_do_interrupt(CPUState *cs) update_badinstr = 0; break; case EXCCODE_BCE: - env->CSR_BADV = env->pc; + sys->CSR_BADV = env->pc; QEMU_FALLTHROUGH; case EXCCODE_SYS: case EXCCODE_BRK: @@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_do_interrupt(CPUState *cs) if (update_badinstr) { MemOpIdx oi = make_memop_idx(MO_LEUL, cpu_mmu_index(cs, true)); - env->CSR_BADI = cpu_ldl_code_mmu(env, env->pc, oi, 0); + sys->CSR_BADI = cpu_ldl_code_mmu(env, env->pc, oi, 0); } /* Save PLV and IE */ if (tlbfill) { - env->CSR_TLBRPRMD = FIELD_DP64(env->CSR_TLBRPRMD, CSR_TLBRPRMD, PPLV, - FIELD_EX64(env->CSR_CRMD, + sys->CSR_TLBRPRMD = FIELD_DP64(sys->CSR_TLBRPRMD, CSR_TLBRPRMD, PPLV, + FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, PLV)); - env->CSR_TLBRPRMD = FIELD_DP64(env->CSR_TLBRPRMD, CSR_TLBRPRMD, PIE, - FIELD_EX64(env->CSR_CRMD, CSR_CRMD, IE)); + sys->CSR_TLBRPRMD = FIELD_DP64(sys->CSR_TLBRPRMD, CSR_TLBRPRMD, PIE, + FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, IE)); /* set the DA mode */ - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DA, 1); - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, PG, 0); - env->CSR_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, CSR_TLBRERA, + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, DA, 1); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, PG, 0); + sys->CSR_TLBRERA = FIELD_DP64(sys->CSR_TLBRERA, CSR_TLBRERA, PC, (env->pc >> 2)); } else { - env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, ECODE, + sys->CSR_ESTAT = FIELD_DP64(sys->CSR_ESTAT, CSR_ESTAT, ECODE, EXCODE_MCODE(cause)); - env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, ESUBCODE, + sys->CSR_ESTAT = FIELD_DP64(sys->CSR_ESTAT, CSR_ESTAT, ESUBCODE, EXCODE_SUBCODE(cause)); - env->CSR_PRMD = FIELD_DP64(env->CSR_PRMD, CSR_PRMD, PPLV, - FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV)); - env->CSR_PRMD = FIELD_DP64(env->CSR_PRMD, CSR_PRMD, PIE, - FIELD_EX64(env->CSR_CRMD, CSR_CRMD, IE)); - env->CSR_ERA = env->pc; + sys->CSR_PRMD = FIELD_DP64(sys->CSR_PRMD, CSR_PRMD, PPLV, + FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, PLV)); + sys->CSR_PRMD = FIELD_DP64(sys->CSR_PRMD, CSR_PRMD, PIE, + FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, IE)); + sys->CSR_ERA = env->pc; } - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, PLV, 0); - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, IE, 0); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, PLV, 0); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, IE, 0); if (vec_size) { vec_size = (1 << vec_size) * 4; @@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_do_interrupt(CPUState *cs) if (cs->exception_index == EXCCODE_INT) { /* Interrupt */ uint32_t vector = 0; - uint32_t pending = FIELD_EX64(env->CSR_ESTAT, CSR_ESTAT, IS); - pending &= FIELD_EX64(env->CSR_ECFG, CSR_ECFG, LIE); + uint32_t pending = FIELD_EX64(sys->CSR_ESTAT, CSR_ESTAT, IS); + pending &= FIELD_EX64(sys->CSR_ECFG, CSR_ECFG, LIE); /* Find the highest-priority interrupt. */ vector = 31 - clz32(pending); - set_pc(env, env->CSR_EENTRY + \ + set_pc(env, sys->CSR_EENTRY + \ (EXCCODE_EXTERNAL_INT + vector) * vec_size); qemu_log_mask(CPU_LOG_INT, "%s: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx " cause %d\n" " A " TARGET_FMT_lx " D " TARGET_FMT_lx " vector = %d ExC " TARGET_FMT_lx "ExS" TARGET_FMT_lx "\n", - __func__, env->pc, env->CSR_ERA, - cause, env->CSR_BADV, env->CSR_DERA, vector, - env->CSR_ECFG, env->CSR_ESTAT); + __func__, env->pc, sys->CSR_ERA, + cause, sys->CSR_BADV, sys->CSR_DERA, vector, + sys->CSR_ECFG, sys->CSR_ESTAT); qemu_plugin_vcpu_interrupt_cb(cs, last_pc); } else { if (tlbfill) { - set_pc(env, env->CSR_TLBRENTRY); + set_pc(env, sys->CSR_TLBRENTRY); } else { - set_pc(env, env->CSR_EENTRY + EXCODE_MCODE(cause) * vec_size); + set_pc(env, sys->CSR_EENTRY + EXCODE_MCODE(cause) * vec_size); } qemu_log_mask(CPU_LOG_INT, "%s: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx @@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_do_interrupt(CPUState *cs) " EXCFG " TARGET_FMT_lx " BADVA " TARGET_FMT_lx "BADI " TARGET_FMT_lx " SYS_NUM " TARGET_FMT_lu " cpu %d asid " TARGET_FMT_lx "\n", __func__, env->pc, - tlbfill ? env->CSR_TLBRERA : env->CSR_ERA, - cause, tlbfill ? "(refill)" : "", env->CSR_ESTAT, - env->CSR_ECFG, - tlbfill ? env->CSR_TLBRBADV : env->CSR_BADV, - env->CSR_BADI, env->gpr[11], cs->cpu_index, - env->CSR_ASID); + tlbfill ? sys->CSR_TLBRERA : sys->CSR_ERA, + cause, tlbfill ? "(refill)" : "", sys->CSR_ESTAT, + sys->CSR_ECFG, + tlbfill ? sys->CSR_TLBRBADV : sys->CSR_BADV, + sys->CSR_BADI, env->gpr[11], cs->cpu_index, + sys->CSR_ASID); qemu_plugin_vcpu_exception_cb(cs, last_pc); } cs->exception_index = -1; @@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, uintptr_t retaddr) { CPULoongArchState *env = cpu_env(cs); + CPUSysState *sys = env_sys(env); - env->CSR_BADV = addr; + sys->CSR_BADV = addr; if (access_type == MMU_INST_FETCH) { do_raise_exception(env, EXCCODE_ADEF, retaddr); } else { @@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, static inline bool cpu_loongarch_hw_interrupts_enabled(CPULoongArchState *env) { bool ret = 0; + CPUSysState *sys = env_sys(env); - ret = (FIELD_EX64(env->CSR_CRMD, CSR_CRMD, IE) && - !(FIELD_EX64(env->CSR_DBG, CSR_DBG, DST))); + ret = (FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, IE) && + !(FIELD_EX64(sys->CSR_DBG, CSR_DBG, DST))); return ret; } @@ -XXX,XX +XXX,XX @@ static vaddr loongarch_pointer_wrap(CPUState *cs, int mmu_idx, static TCGTBCPUState loongarch_get_tb_cpu_state(CPUState *cs) { CPULoongArchState *env = cpu_env(cs); + CPUSysState *sys = env_sys(env); uint32_t flags; - flags = env->CSR_CRMD & (R_CSR_CRMD_PLV_MASK | R_CSR_CRMD_PG_MASK); - flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, FPE) * HW_FLAGS_EUEN_FPE; - flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE) * HW_FLAGS_EUEN_SXE; - flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, ASXE) * HW_FLAGS_EUEN_ASXE; + flags = sys->CSR_CRMD & (R_CSR_CRMD_PLV_MASK | R_CSR_CRMD_PG_MASK); + flags |= FIELD_EX64(sys->CSR_EUEN, CSR_EUEN, FPE) * HW_FLAGS_EUEN_FPE; + flags |= FIELD_EX64(sys->CSR_EUEN, CSR_EUEN, SXE) * HW_FLAGS_EUEN_SXE; + flags |= FIELD_EX64(sys->CSR_EUEN, CSR_EUEN, ASXE) * HW_FLAGS_EUEN_ASXE; flags |= is_va32(env) * HW_FLAGS_VA32; return (TCGTBCPUState){ .pc = env->pc, .flags = flags }; @@ -XXX,XX +XXX,XX @@ static void loongarch_restore_state_to_opc(CPUState *cs, static int loongarch_cpu_mmu_index(CPUState *cs, bool ifetch) { CPULoongArchState *env = cpu_env(cs); + CPUSysState *sys = env_sys(env); - if (FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG)) { - return FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV); + if (FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, PG)) { + return FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, PLV); } return MMU_DA_IDX; } -- 2.54.0
From: Bibo Mao <maobibo@loongson.cn> When accessing CSR registers in file csr_helper.c, use sys_state rather than env. There is no function change. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Philippe Mathieu-Daudé <philmd@mailo.com> Tested-by: Song Gao <gaosong@loongson.cn> Message-ID: <20260605082552.175336-9-maobibo@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn> --- target/loongarch/tcg/csr_helper.c | 55 ++++++++++++++++++------------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/target/loongarch/tcg/csr_helper.c b/target/loongarch/tcg/csr_helper.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/tcg/csr_helper.c +++ b/target/loongarch/tcg/csr_helper.c @@ -XXX,XX +XXX,XX @@ target_ulong helper_csrwr_stlbps(CPULoongArchState *env, target_ulong val) { - int64_t old_v = env->CSR_STLBPS; + CPUSysState *sys = env_sys(env); + int64_t old_v = sys->CSR_STLBPS; /* * The real hardware only supports the min tlb_ps is 12 @@ -XXX,XX +XXX,XX @@ target_ulong helper_csrwr_stlbps(CPULoongArchState *env, target_ulong val) } else { /* Only update PS field, reserved bit keeps zero */ val = FIELD_DP64(val, CSR_STLBPS, RESERVE, 0); - env->CSR_STLBPS = val; + sys->CSR_STLBPS = val; } return old_v; @@ -XXX,XX +XXX,XX @@ target_ulong helper_csrwr_stlbps(CPULoongArchState *env, target_ulong val) target_ulong helper_csrrd_pgd(CPULoongArchState *env) { int64_t v; + CPUSysState *sys = env_sys(env); - if (env->CSR_TLBRERA & 0x1) { - v = env->CSR_TLBRBADV; + if (sys->CSR_TLBRERA & 0x1) { + v = sys->CSR_TLBRBADV; } else { - v = env->CSR_BADV; + v = sys->CSR_BADV; } if ((v >> 63) & 0x1) { - v = env->CSR_PGDH; + v = sys->CSR_PGDH; } else { - v = env->CSR_PGDL; + v = sys->CSR_PGDL; } return v; @@ -XXX,XX +XXX,XX @@ target_ulong helper_csrrd_pgd(CPULoongArchState *env) target_ulong helper_csrrd_cpuid(CPULoongArchState *env) { LoongArchCPU *lac = env_archcpu(env); + CPUSysState *sys = env_sys(env); - env->CSR_CPUID = CPU(lac)->cpu_index; + sys->CSR_CPUID = CPU(lac)->cpu_index; - return env->CSR_CPUID; + return sys->CSR_CPUID; } target_ulong helper_csrrd_tval(CPULoongArchState *env) @@ -XXX,XX +XXX,XX @@ target_ulong helper_csrrd_tval(CPULoongArchState *env) target_ulong helper_csrrd_msgir(CPULoongArchState *env) { int irq, new; + CPUSysState *sys = env_sys(env); - irq = find_first_bit((unsigned long *)env->CSR_MSGIS, 256); + irq = find_first_bit((unsigned long *)sys->CSR_MSGIS, 256); if (irq < 256) { - clear_bit(irq, (unsigned long *)env->CSR_MSGIS); - new = find_first_bit((unsigned long *)env->CSR_MSGIS, 256); + clear_bit(irq, (unsigned long *)sys->CSR_MSGIS); + new = find_first_bit((unsigned long *)sys->CSR_MSGIS, 256); if (new < 256) { return irq; } - env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, MSGINT, 0); + sys->CSR_ESTAT = FIELD_DP64(sys->CSR_ESTAT, CSR_ESTAT, MSGINT, 0); } else { /* bit 31 set 1 for no invalid irq */ irq = BIT(31); @@ -XXX,XX +XXX,XX @@ target_ulong helper_csrrd_msgir(CPULoongArchState *env) target_ulong helper_csrwr_estat(CPULoongArchState *env, target_ulong val) { - int64_t old_v = env->CSR_ESTAT; + CPUSysState *sys = env_sys(env); + int64_t old_v = sys->CSR_ESTAT; /* Only IS[1:0] can be written */ - env->CSR_ESTAT = deposit64(env->CSR_ESTAT, 0, 2, val); + sys->CSR_ESTAT = deposit64(sys->CSR_ESTAT, 0, 2, val); return old_v; } target_ulong helper_csrwr_asid(CPULoongArchState *env, target_ulong val) { - int64_t old_v = env->CSR_ASID; + CPUSysState *sys = env_sys(env); + int64_t old_v = sys->CSR_ASID; /* Only ASID filed of CSR_ASID can be written */ - env->CSR_ASID = deposit64(env->CSR_ASID, 0, 10, val); - if (old_v != env->CSR_ASID) { + sys->CSR_ASID = deposit64(sys->CSR_ASID, 0, 10, val); + if (old_v != sys->CSR_ASID) { tlb_flush(env_cpu(env)); } return old_v; @@ -XXX,XX +XXX,XX @@ target_ulong helper_csrwr_asid(CPULoongArchState *env, target_ulong val) target_ulong helper_csrwr_tcfg(CPULoongArchState *env, target_ulong val) { LoongArchCPU *cpu = env_archcpu(env); - int64_t old_v = env->CSR_TCFG; + CPUSysState *sys = env_sys(env); + int64_t old_v = sys->CSR_TCFG; cpu_loongarch_store_constant_timer_config(cpu, val); @@ -XXX,XX +XXX,XX @@ target_ulong helper_csrwr_ticlr(CPULoongArchState *env, target_ulong val) target_ulong helper_csrwr_pwcl(CPULoongArchState *env, target_ulong val) { uint8_t shift, ptbase; - int64_t old_v = env->CSR_PWCL; + CPUSysState *sys = env_sys(env); + int64_t old_v = sys->CSR_PWCL; /* * The real hardware only supports 64bit PTE width now, 128bit or others @@ -XXX,XX +XXX,XX @@ target_ulong helper_csrwr_pwcl(CPULoongArchState *env, target_ulong val) qemu_log_mask(LOG_GUEST_ERROR, "Attempted set ptbase 2^%d\n", ptbase); } - env->CSR_PWCL = val; + sys->CSR_PWCL = val; return old_v; } target_ulong helper_csrwr_pwch(CPULoongArchState *env, target_ulong val) { uint8_t has_ptw; - int64_t old_v = env->CSR_PWCH; + CPUSysState *sys = env_sys(env); + int64_t old_v = sys->CSR_PWCH; val = FIELD_DP64(val, CSR_PWCH, RESERVE, 0); has_ptw = FIELD_EX32(env->cpucfg[2], CPUCFG2, HPTW); @@ -XXX,XX +XXX,XX @@ target_ulong helper_csrwr_pwch(CPULoongArchState *env, target_ulong val) val = FIELD_DP64(val, CSR_PWCH, HPTW_EN, 0); } - env->CSR_PWCH = val; + sys->CSR_PWCH = val; return old_v; } -- 2.54.0
From: Bibo Mao <maobibo@loongson.cn> When accessing CSR registers in file op_helper.c, use sys_state rather than env. There is no function change. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Philippe Mathieu-Daudé <philmd@mailo.com> Tested-by: Song Gao <gaosong@loongson.cn> Message-ID: <20260605083756.175598-1-maobibo@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn> --- target/loongarch/tcg/op_helper.c | 45 ++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/target/loongarch/tcg/op_helper.c b/target/loongarch/tcg/op_helper.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/tcg/op_helper.c +++ b/target/loongarch/tcg/op_helper.c @@ -XXX,XX +XXX,XX @@ target_ulong helper_bitswap(target_ulong v) /* loongarch assert op */ void helper_asrtle_d(CPULoongArchState *env, target_ulong rj, target_ulong rk) { + CPUSysState *sys = env_sys(env); + if (rj > rk) { - env->CSR_BADV = rj; + sys->CSR_BADV = rj; do_raise_exception(env, EXCCODE_BCE, GETPC()); } } void helper_asrtgt_d(CPULoongArchState *env, target_ulong rj, target_ulong rk) { + CPUSysState *sys = env_sys(env); + if (rj <= rk) { - env->CSR_BADV = rj; + sys->CSR_BADV = rj; do_raise_exception(env, EXCCODE_BCE, GETPC()); } } @@ -XXX,XX +XXX,XX @@ uint64_t helper_rdtime_d(CPULoongArchState *env) #else uint64_t plv; LoongArchCPU *cpu = env_archcpu(env); + CPUSysState *sys = env_sys(env); - plv = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV); - if (extract64(env->CSR_MISC, R_CSR_MISC_DRDTL_SHIFT + plv, 1)) { + plv = FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, PLV); + if (extract64(sys->CSR_MISC, R_CSR_MISC_DRDTL_SHIFT + plv, 1)) { do_raise_exception(env, EXCCODE_IPE, GETPC()); } @@ -XXX,XX +XXX,XX @@ uint64_t helper_rdtime_d(CPULoongArchState *env) void helper_ertn(CPULoongArchState *env) { uint64_t csr_pplv, csr_pie; - if (FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) { - csr_pplv = FIELD_EX64(env->CSR_TLBRPRMD, CSR_TLBRPRMD, PPLV); - csr_pie = FIELD_EX64(env->CSR_TLBRPRMD, CSR_TLBRPRMD, PIE); - - env->CSR_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR, 0); - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DA, 0); - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, PG, 1); - set_pc(env, env->CSR_TLBRERA); + CPUSysState *sys = env_sys(env); + + if (FIELD_EX64(sys->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) { + csr_pplv = FIELD_EX64(sys->CSR_TLBRPRMD, CSR_TLBRPRMD, PPLV); + csr_pie = FIELD_EX64(sys->CSR_TLBRPRMD, CSR_TLBRPRMD, PIE); + + sys->CSR_TLBRERA = FIELD_DP64(sys->CSR_TLBRERA, CSR_TLBRERA, ISTLBR, 0); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, DA, 0); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, PG, 1); + set_pc(env, sys->CSR_TLBRERA); qemu_log_mask(CPU_LOG_INT, "%s: TLBRERA " TARGET_FMT_lx "\n", - __func__, env->CSR_TLBRERA); + __func__, sys->CSR_TLBRERA); } else { - csr_pplv = FIELD_EX64(env->CSR_PRMD, CSR_PRMD, PPLV); - csr_pie = FIELD_EX64(env->CSR_PRMD, CSR_PRMD, PIE); + csr_pplv = FIELD_EX64(sys->CSR_PRMD, CSR_PRMD, PPLV); + csr_pie = FIELD_EX64(sys->CSR_PRMD, CSR_PRMD, PIE); - set_pc(env, env->CSR_ERA); + set_pc(env, sys->CSR_ERA); qemu_log_mask(CPU_LOG_INT, "%s: ERA " TARGET_FMT_lx "\n", - __func__, env->CSR_ERA); + __func__, sys->CSR_ERA); } - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, PLV, csr_pplv); - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, IE, csr_pie); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, PLV, csr_pplv); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, IE, csr_pie); env->lladdr = 1; } -- 2.54.0
From: Bibo Mao <maobibo@loongson.cn> When accessing CSR registers in directory linux-user/loongarch64/, use sys_state rather than env. There is no function change. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Philippe Mathieu-Daudé <philmd@mailo.com> Tested-by: Song Gao <gaosong@loongson.cn> Message-ID: <20260605083844.175612-1-maobibo@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn> --- linux-user/loongarch64/cpu_loop.c | 5 +++-- linux-user/loongarch64/elfload.c | 4 +++- linux-user/loongarch64/signal.c | 16 ++++++++++------ 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/linux-user/loongarch64/cpu_loop.c b/linux-user/loongarch64/cpu_loop.c index XXXXXXX..XXXXXXX 100644 --- a/linux-user/loongarch64/cpu_loop.c +++ b/linux-user/loongarch64/cpu_loop.c @@ -XXX,XX +XXX,XX @@ enum { void cpu_loop(CPULoongArchState *env) { + CPUSysState *sys = env_sys(env); CPUState *cs = env_cpu(env); int trapnr, si_code; abi_long ret; @@ -XXX,XX +XXX,XX @@ void cpu_loop(CPULoongArchState *env) * choose the layout of any signal frame. */ case EXCCODE_SXD: - env->CSR_EUEN |= R_CSR_EUEN_SXE_MASK; + sys->CSR_EUEN |= R_CSR_EUEN_SXE_MASK; break; case EXCCODE_ASXD: - env->CSR_EUEN |= R_CSR_EUEN_ASXE_MASK; + sys->CSR_EUEN |= R_CSR_EUEN_ASXE_MASK; break; case EXCP_ATOMIC: diff --git a/linux-user/loongarch64/elfload.c b/linux-user/loongarch64/elfload.c index XXXXXXX..XXXXXXX 100644 --- a/linux-user/loongarch64/elfload.c +++ b/linux-user/loongarch64/elfload.c @@ -XXX,XX +XXX,XX @@ const char *get_elf_platform(CPUState *cs) void elf_core_copy_regs(target_elf_gregset_t *r, const CPULoongArchState *env) { + CPUSysState *sys = env_sys((CPULoongArchState *)env); + r->pt.regs[0] = 0; for (int i = 1; i < ARRAY_SIZE(env->gpr); i++) { @@ -XXX,XX +XXX,XX @@ void elf_core_copy_regs(target_elf_gregset_t *r, const CPULoongArchState *env) } r->pt.csr_era = tswapreg(env->pc); - r->pt.csr_badv = tswapreg(env->CSR_BADV); + r->pt.csr_badv = tswapreg(sys->CSR_BADV); } diff --git a/linux-user/loongarch64/signal.c b/linux-user/loongarch64/signal.c index XXXXXXX..XXXXXXX 100644 --- a/linux-user/loongarch64/signal.c +++ b/linux-user/loongarch64/signal.c @@ -XXX,XX +XXX,XX @@ static abi_ptr extframe_alloc(struct extctx_layout *extctx, static abi_ptr setup_extcontext(CPULoongArchState *env, struct extctx_layout *extctx, abi_ptr sp) { + CPUSysState *sys = env_sys(env); + memset(extctx, 0, sizeof(struct extctx_layout)); /* Grow down, alloc "end" context info first. */ @@ -XXX,XX +XXX,XX @@ static abi_ptr setup_extcontext(CPULoongArchState *env, /* For qemu, there is no lazy fp context switch, so fp always present. */ extctx->flags = SC_USED_FP; - if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, ASXE)) { + if (FIELD_EX64(sys->CSR_EUEN, CSR_EUEN, ASXE)) { sp = extframe_alloc(extctx, &extctx->lasx, sizeof(struct target_lasx_context), LASX_CTX_ALIGN, sp); - } else if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE)) { + } else if (FIELD_EX64(sys->CSR_EUEN, CSR_EUEN, SXE)) { sp = extframe_alloc(extctx, &extctx->lsx, sizeof(struct target_lsx_context), LSX_CTX_ALIGN, sp); } else { @@ -XXX,XX +XXX,XX @@ static void setup_sigframe(CPULoongArchState *env, struct target_sigcontext *sc, struct extctx_layout *extctx) { + CPUSysState *sys = env_sys(env); struct target_sctx_info *info; int i; @@ -XXX,XX +XXX,XX @@ static void setup_sigframe(CPULoongArchState *env, * Set extension context */ - if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, ASXE)) { + if (FIELD_EX64(sys->CSR_EUEN, CSR_EUEN, ASXE)) { struct target_lasx_context *lasx_ctx; info = extctx->lasx.haddr; @@ -XXX,XX +XXX,XX @@ static void setup_sigframe(CPULoongArchState *env, } __put_user(read_fcc(env), &lasx_ctx->fcc); __put_user(env->fcsr0, &lasx_ctx->fcsr); - } else if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE)) { + } else if (FIELD_EX64(sys->CSR_EUEN, CSR_EUEN, SXE)) { struct target_lsx_context *lsx_ctx; info = extctx->lsx.haddr; @@ -XXX,XX +XXX,XX @@ void setup_rt_frame(int sig, struct target_sigaction *ka, target_siginfo_t *info, target_sigset_t *set, CPULoongArchState *env) { + CPUSysState *sys = env_sys(env); struct target_rt_sigframe *frame; struct extctx_layout extctx; abi_ptr frame_addr; @@ -XXX,XX +XXX,XX @@ void setup_rt_frame(int sig, struct target_sigaction *ka, return; } - if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, ASXE)) { + if (FIELD_EX64(sys->CSR_EUEN, CSR_EUEN, ASXE)) { extctx.lasx.haddr = (void *)frame + (extctx.lasx.gaddr - frame_addr); extctx.end.haddr = (void *)frame + (extctx.end.gaddr - frame_addr); - } else if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE)) { + } else if (FIELD_EX64(sys->CSR_EUEN, CSR_EUEN, SXE)) { extctx.lsx.haddr = (void *)frame + (extctx.lsx.gaddr - frame_addr); extctx.end.haddr = (void *)frame + (extctx.end.gaddr - frame_addr); } else { -- 2.54.0
From: Bibo Mao <maobibo@loongson.cn> With CSR array structure, its validity is checked from offset field. Now default CSRFL_BASIC information is added with flags field and its validility can be checked with flags field. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Tested-by: Song Gao <gaosong@loongson.cn> Message-ID: <20260605083854.175625-1-maobibo@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn> --- target/loongarch/csr.c | 6 +++--- target/loongarch/csr.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/target/loongarch/csr.c b/target/loongarch/csr.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/csr.c +++ b/target/loongarch/csr.c @@ -XXX,XX +XXX,XX @@ [LOONGARCH_CSR_##NAME(N)] = { \ .name = (stringify(NAME##N)), \ .offset = offsetof(CPULoongArchState, CSR_##NAME[N]), \ - .flags = 0, .readfn = NULL, .writefn = NULL \ + .flags = CSRFL_BASIC, .readfn = NULL, .writefn = NULL \ } #define CSR_OFF_FLAGS(NAME, FL) CSR_OFF_FUNCS(NAME, FL, NULL, NULL) -#define CSR_OFF(NAME) CSR_OFF_FLAGS(NAME, 0) +#define CSR_OFF(NAME) CSR_OFF_FLAGS(NAME, CSRFL_BASIC) static CSRInfo csr_info[] = { CSR_OFF_FLAGS(CRMD, CSRFL_EXITTB), @@ -XXX,XX +XXX,XX @@ CSRInfo *get_csr(unsigned int csr_num) } csr = &csr_info[csr_num]; - if (csr->offset == 0) { + if (csr->flags == 0) { return NULL; } diff --git a/target/loongarch/csr.h b/target/loongarch/csr.h index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/csr.h +++ b/target/loongarch/csr.h @@ -XXX,XX +XXX,XX @@ enum { CSRFL_EXITTB = (1 << 1), CSRFL_IO = (1 << 2), CSRFL_UNUSED = (1 << 3), + CSRFL_BASIC = (1 << 4), }; typedef struct { -- 2.54.0
From: Bibo Mao <maobibo@loongson.cn> Add wrapper function get_csr_offset(), it is to get offset from structure CPULoongArchState. There is no function change, and it is used for future LVZ feature. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Philippe Mathieu-Daudé <philmd@mailo.com> Tested-by: Song Gao <gaosong@loongson.cn> Message-ID: <20260605083904.175636-1-maobibo@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn> --- target/loongarch/cpu.c | 4 ++-- target/loongarch/csr.h | 4 ++++ .../tcg/insn_trans/trans_privileged.c.inc | 16 +++++++++++----- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_dump_csr(CPUState *cs, FILE *f) { #ifndef CONFIG_USER_ONLY CPULoongArchState *env = cpu_env(cs); - CSRInfo *csr_info; + const CSRInfo *csr_info; int64_t *addr; int i, j, len, col = 0; @@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_dump_csr(CPUState *cs, FILE *f) qemu_fprintf(f, " CSR%03d:", col); } - addr = (void *)env + csr_info->offset; + addr = (void *)env + get_csr_offset(csr_info, 0); qemu_fprintf(f, " %s ", csr_info->name); len = strlen(csr_info->name); for (; len < 6; len++) { diff --git a/target/loongarch/csr.h b/target/loongarch/csr.h index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/csr.h +++ b/target/loongarch/csr.h @@ -XXX,XX +XXX,XX @@ typedef struct { CSRInfo *get_csr(unsigned int csr_num); bool set_csr_flag(unsigned int csr_num, int flag); +static inline unsigned int get_csr_offset(const CSRInfo *csr, int vm_level) +{ + return csr->offset; +} #endif /* TARGET_LOONGARCH_CSR_H */ diff --git a/target/loongarch/tcg/insn_trans/trans_privileged.c.inc b/target/loongarch/tcg/insn_trans/trans_privileged.c.inc index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/tcg/insn_trans/trans_privileged.c.inc +++ b/target/loongarch/tcg/insn_trans/trans_privileged.c.inc @@ -XXX,XX +XXX,XX @@ static bool trans_csrrd(DisasContext *ctx, arg_csrrd *a) TCGv dest; const CSRInfo *csr; GenCSRRead readfn; + tcg_target_long offset; if (check_plv(ctx)) { return false; @@ -XXX,XX +XXX,XX @@ static bool trans_csrrd(DisasContext *ctx, arg_csrrd *a) if (readfn) { readfn(dest, tcg_env); } else { - tcg_gen_ld_tl(dest, tcg_env, csr->offset); + offset = get_csr_offset(csr, 0); + tcg_gen_ld_tl(dest, tcg_env, offset); } } gen_set_gpr(a->rd, dest, EXT_NONE); @@ -XXX,XX +XXX,XX @@ static bool trans_csrwr(DisasContext *ctx, arg_csrwr *a) TCGv dest, src1; const CSRInfo *csr; GenCSRWrite writefn; + tcg_target_long offset; if (check_plv(ctx)) { return false; @@ -XXX,XX +XXX,XX @@ static bool trans_csrwr(DisasContext *ctx, arg_csrwr *a) writefn(dest, tcg_env, src1); } else { dest = tcg_temp_new(); - tcg_gen_ld_tl(dest, tcg_env, csr->offset); - tcg_gen_st_tl(src1, tcg_env, csr->offset); + offset = get_csr_offset(csr, 0); + tcg_gen_ld_tl(dest, tcg_env, offset); + tcg_gen_st_tl(src1, tcg_env, offset); } gen_set_gpr(a->rd, dest, EXT_NONE); return true; @@ -XXX,XX +XXX,XX @@ static bool trans_csrxchg(DisasContext *ctx, arg_csrxchg *a) TCGv src1, mask, oldv, newv, temp; const CSRInfo *csr; GenCSRWrite writefn; + tcg_target_long offset; if (check_plv(ctx)) { return false; @@ -XXX,XX +XXX,XX @@ static bool trans_csrxchg(DisasContext *ctx, arg_csrxchg *a) newv = tcg_temp_new(); temp = tcg_temp_new(); - tcg_gen_ld_tl(oldv, tcg_env, csr->offset); + offset = get_csr_offset(csr, 0); + tcg_gen_ld_tl(oldv, tcg_env, offset); tcg_gen_and_tl(newv, src1, mask); tcg_gen_andc_tl(temp, oldv, mask); tcg_gen_or_tl(newv, newv, temp); @@ -XXX,XX +XXX,XX @@ static bool trans_csrxchg(DisasContext *ctx, arg_csrxchg *a) if (writefn) { writefn(oldv, tcg_env, newv); } else { - tcg_gen_st_tl(newv, tcg_env, csr->offset); + tcg_gen_st_tl(newv, tcg_env, offset); } gen_set_gpr(a->rd, oldv, EXT_NONE); return true; -- 2.54.0
From: Bibo Mao <maobibo@loongson.cn> Instruction rdtime is to read TSC timestamp and logic vCPU id, it is also used by Linux user mode emulation. However function get_csr_offset() cannot be called in user mode emulation, here macro CSR_OFFSET and CPU_CSR_OFFSET are added. The added macro can be called in both user emulation and system emulation. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Philippe Mathieu-Daudé <philmd@mailo.com> Tested-by: Song Gao <gaosong@loongson.cn> Message-ID: <20260605083910.175647-1-maobibo@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn> --- target/loongarch/csr.c | 4 ++-- target/loongarch/csr.h | 3 +++ target/loongarch/tcg/insn_trans/trans_extra.c.inc | 6 +++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/target/loongarch/csr.c b/target/loongarch/csr.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/csr.c +++ b/target/loongarch/csr.c @@ -XXX,XX +XXX,XX @@ #define CSR_OFF_FUNCS(NAME, FL, RD, WR) \ [LOONGARCH_CSR_##NAME] = { \ .name = (stringify(NAME)), \ - .offset = offsetof(CPULoongArchState, CSR_##NAME), \ + .offset = CSR_OFFSET(CSR_##NAME), \ .flags = FL, .readfn = RD, .writefn = WR \ } #define CSR_OFF_ARRAY(NAME, N) \ [LOONGARCH_CSR_##NAME(N)] = { \ .name = (stringify(NAME##N)), \ - .offset = offsetof(CPULoongArchState, CSR_##NAME[N]), \ + .offset = CSR_OFFSET(CSR_##NAME[N]), \ .flags = CSRFL_BASIC, .readfn = NULL, .writefn = NULL \ } diff --git a/target/loongarch/csr.h b/target/loongarch/csr.h index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/csr.h +++ b/target/loongarch/csr.h @@ -XXX,XX +XXX,XX @@ #include "cpu-csr.h" +#define CSR_OFFSET(id) offsetof(CPULoongArchState, id) +#define CPU_CSR_OFFSET(id, vm_level) CSR_OFFSET(id) + typedef void (*GenCSRFunc)(void); enum { CSRFL_READONLY = (1 << 0), diff --git a/target/loongarch/tcg/insn_trans/trans_extra.c.inc b/target/loongarch/tcg/insn_trans/trans_extra.c.inc index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/tcg/insn_trans/trans_extra.c.inc +++ b/target/loongarch/tcg/insn_trans/trans_extra.c.inc @@ -XXX,XX +XXX,XX @@ * Copyright (c) 2021 Loongson Technology Corporation Limited */ +#include "csr.h" static bool trans_break(DisasContext *ctx, arg_break *a) { generate_exception(ctx, EXCCODE_BRK); @@ -XXX,XX +XXX,XX @@ static bool gen_rdtime(DisasContext *ctx, arg_rr *a, { TCGv dst1 = gpr_dst(ctx, a->rd, EXT_NONE); TCGv dst2 = gpr_dst(ctx, a->rj, EXT_NONE); + tcg_target_long offset; translator_io_start(&ctx->base); gen_helper_rdtime_d(dst1, tcg_env); if (word) { tcg_gen_sextract_tl(dst1, dst1, high ? 32 : 0, 32); } - tcg_gen_ld_i64(dst2, tcg_env, offsetof(CPULoongArchState, CSR_TID)); + + offset = CPU_CSR_OFFSET(CSR_TID, 0); + tcg_gen_ld_i64(dst2, tcg_env, offset); return true; } -- 2.54.0
From: Bibo Mao <maobibo@loongson.cn> New structure CPUSysState is added here, now it only contains CSR registers, in future TLB and timer can be moved to this structure also. It is only code movement, no function change. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Tested-by: Song Gao <gaosong@loongson.cn> Message-ID: <20260605083938.175658-1-maobibo@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn> --- target/loongarch/cpu.c | 4 +- target/loongarch/cpu.h | 35 +++++------ target/loongarch/csr.h | 8 ++- target/loongarch/machine.c | 118 +++++++++++++++++++------------------ 4 files changed, 85 insertions(+), 80 deletions(-) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -XXX,XX +XXX,XX @@ static void loongarch_la464_initfn(Object *obj) uint32_t data = 0, field; int i; - set_sys_state(env, env); + set_sys_state(env, &env->sys_states[0]); for (i = 0; i < 21; i++) { env->cpucfg[i] = 0x0; } @@ -XXX,XX +XXX,XX @@ static void loongarch_la132_initfn(Object *obj) uint32_t data = 0; int i; - set_sys_state(env, env); + set_sys_state(env, &env->sys_states[0]); for (i = 0; i < 21; i++) { env->cpucfg[i] = 0x0; } diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -XXX,XX +XXX,XX @@ typedef struct LoongArchBT { #define CPU_VENDOR_LOONGSON "Loongson" #define CPU_MODEL_3A5000 "3A5000" #define CPU_MODEL_1C101 "1C101" -struct CPUArchState; -typedef struct CPUArchState CPUSysState; - -typedef struct CPUArchState { - uint64_t gpr[32]; - uint64_t pc; - - fpr_t fpr[32]; - bool cf[8]; - uint32_t fcsr0; - lbt_t lbt; - - uint32_t cpucfg[21]; - uint32_t pv_features; - uint64_t vendor_id; - uint64_t cpu_id; - +typedef struct CPUSysState { /* LoongArch CSRs */ uint64_t CSR_CRMD; uint64_t CSR_PRMD; @@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState { uint64_t CSR_MSGIS[N_MSGIS]; uint64_t CSR_MSGIR; uint64_t CSR_MSGIE; +} CPUSysState; + +typedef struct CPUArchState { + uint64_t gpr[32]; + uint64_t pc; + + fpr_t fpr[32]; + bool cf[8]; + uint32_t fcsr0; + lbt_t lbt; + + uint32_t cpucfg[21]; + uint32_t pv_features; + uint64_t vendor_id; + uint64_t cpu_id; + CPUSysState sys_states[1]; + struct { uint64_t guest_addr; } stealtime; diff --git a/target/loongarch/csr.h b/target/loongarch/csr.h index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/csr.h +++ b/target/loongarch/csr.h @@ -XXX,XX +XXX,XX @@ #include "cpu-csr.h" -#define CSR_OFFSET(id) offsetof(CPULoongArchState, id) -#define CPU_CSR_OFFSET(id, vm_level) CSR_OFFSET(id) +#define CSR_OFFSET(id) offsetof(CPUSysState, id) +#define CPU_CSR_OFFSET(id, vm_level) \ + (offsetof(CPULoongArchState, sys_states[vm_level]) \ + + CSR_OFFSET(id)) typedef void (*GenCSRFunc)(void); enum { @@ -XXX,XX +XXX,XX @@ CSRInfo *get_csr(unsigned int csr_num); bool set_csr_flag(unsigned int csr_num, int flag); static inline unsigned int get_csr_offset(const CSRInfo *csr, int vm_level) { - return csr->offset; + return csr->offset + offsetof(CPULoongArchState, sys_states[vm_level]); } #endif /* TARGET_LOONGARCH_CSR_H */ diff --git a/target/loongarch/machine.c b/target/loongarch/machine.c index XXXXXXX..XXXXXXX 100644 --- a/target/loongarch/machine.c +++ b/target/loongarch/machine.c @@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_msgint = { .minimum_version_id = 1, .needed = msgint_needed, .fields = (const VMStateField[]) { - VMSTATE_UINT64_ARRAY(env.CSR_MSGIS, LoongArchCPU, N_MSGIS), - VMSTATE_UINT64(env.CSR_MSGIR, LoongArchCPU), - VMSTATE_UINT64(env.CSR_MSGIE, LoongArchCPU), + VMSTATE_UINT64_ARRAY(env.sys_states[0].CSR_MSGIS, LoongArchCPU, N_MSGIS), + VMSTATE_UINT64(env.sys_states[0].CSR_MSGIR, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_MSGIE, LoongArchCPU), VMSTATE_END_OF_LIST() }, }; @@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pmu = { .needed = pmu_needed, .fields = (const VMStateField[]) { VMSTATE_UINT32(env.perf_event_num, LoongArchCPU), - VMSTATE_UINT64_ARRAY(env.CSR_PERFCTRL, LoongArchCPU, MAX_PERF_EVENTS), - VMSTATE_UINT64_ARRAY(env.CSR_PERFCNTR, LoongArchCPU, MAX_PERF_EVENTS), + VMSTATE_UINT64_ARRAY(env.sys_states[0].CSR_PERFCTRL, LoongArchCPU,\ + MAX_PERF_EVENTS), + VMSTATE_UINT64_ARRAY(env.sys_states[0].CSR_PERFCNTR, LoongArchCPU, \ + MAX_PERF_EVENTS), VMSTATE_END_OF_LIST() }, }; @@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_loongarch_cpu = { VMSTATE_UINT64(env.pc, LoongArchCPU), /* Remaining CSRs */ - VMSTATE_UINT64(env.CSR_CRMD, LoongArchCPU), - VMSTATE_UINT64(env.CSR_PRMD, LoongArchCPU), - VMSTATE_UINT64(env.CSR_EUEN, LoongArchCPU), - VMSTATE_UINT64(env.CSR_MISC, LoongArchCPU), - VMSTATE_UINT64(env.CSR_ECFG, LoongArchCPU), - VMSTATE_UINT64(env.CSR_ESTAT, LoongArchCPU), - VMSTATE_UINT64(env.CSR_ERA, LoongArchCPU), - VMSTATE_UINT64(env.CSR_BADV, LoongArchCPU), - VMSTATE_UINT64(env.CSR_BADI, LoongArchCPU), - VMSTATE_UINT64(env.CSR_EENTRY, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBIDX, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBEHI, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBELO0, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBELO1, LoongArchCPU), - VMSTATE_UINT64(env.CSR_ASID, LoongArchCPU), - VMSTATE_UINT64(env.CSR_PGDL, LoongArchCPU), - VMSTATE_UINT64(env.CSR_PGDH, LoongArchCPU), - VMSTATE_UINT64(env.CSR_PGD, LoongArchCPU), - VMSTATE_UINT64(env.CSR_PWCL, LoongArchCPU), - VMSTATE_UINT64(env.CSR_PWCH, LoongArchCPU), - VMSTATE_UINT64(env.CSR_STLBPS, LoongArchCPU), - VMSTATE_UINT64(env.CSR_RVACFG, LoongArchCPU), - VMSTATE_UINT64(env.CSR_PRCFG1, LoongArchCPU), - VMSTATE_UINT64(env.CSR_PRCFG2, LoongArchCPU), - VMSTATE_UINT64(env.CSR_PRCFG3, LoongArchCPU), - VMSTATE_UINT64_ARRAY(env.CSR_SAVE, LoongArchCPU, 16), - VMSTATE_UINT64(env.CSR_TID, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TCFG, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TVAL, LoongArchCPU), - VMSTATE_UINT64(env.CSR_CNTC, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TICLR, LoongArchCPU), - VMSTATE_UINT64(env.CSR_LLBCTL, LoongArchCPU), - VMSTATE_UINT64(env.CSR_IMPCTL1, LoongArchCPU), - VMSTATE_UINT64(env.CSR_IMPCTL2, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBRENTRY, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBRBADV, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBRERA, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBRSAVE, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBRELO0, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBRELO1, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBREHI, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBRPRMD, LoongArchCPU), - VMSTATE_UINT64(env.CSR_MERRCTL, LoongArchCPU), - VMSTATE_UINT64(env.CSR_MERRINFO1, LoongArchCPU), - VMSTATE_UINT64(env.CSR_MERRINFO2, LoongArchCPU), - VMSTATE_UINT64(env.CSR_MERRENTRY, LoongArchCPU), - VMSTATE_UINT64(env.CSR_MERRERA, LoongArchCPU), - VMSTATE_UINT64(env.CSR_MERRSAVE, LoongArchCPU), - VMSTATE_UINT64(env.CSR_CTAG, LoongArchCPU), - VMSTATE_UINT64_ARRAY(env.CSR_DMW, LoongArchCPU, 4), + VMSTATE_UINT64(env.sys_states[0].CSR_CRMD, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_PRMD, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_EUEN, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_MISC, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_ECFG, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_ESTAT, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_ERA, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_BADV, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_BADI, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_EENTRY, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBIDX, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBEHI, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBELO0, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBELO1, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_ASID, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_PGDL, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_PGDH, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_PGD, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_PWCL, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_PWCH, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_STLBPS, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_RVACFG, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_PRCFG1, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_PRCFG2, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_PRCFG3, LoongArchCPU), + VMSTATE_UINT64_ARRAY(env.sys_states[0].CSR_SAVE, LoongArchCPU, 16), + VMSTATE_UINT64(env.sys_states[0].CSR_TID, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TCFG, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TVAL, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_CNTC, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TICLR, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_LLBCTL, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_IMPCTL1, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_IMPCTL2, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBRENTRY, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBRBADV, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBRERA, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBRSAVE, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBRELO0, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBRELO1, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBREHI, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBRPRMD, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_MERRCTL, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_MERRINFO1, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_MERRINFO2, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_MERRENTRY, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_MERRERA, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_MERRSAVE, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_CTAG, LoongArchCPU), + VMSTATE_UINT64_ARRAY(env.sys_states[0].CSR_DMW, LoongArchCPU, 4), /* Debug CSRs */ - VMSTATE_UINT64(env.CSR_DBG, LoongArchCPU), - VMSTATE_UINT64(env.CSR_DERA, LoongArchCPU), - VMSTATE_UINT64(env.CSR_DSAVE, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_DBG, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_DERA, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_DSAVE, LoongArchCPU), VMSTATE_UINT64(kvm_state_counter, LoongArchCPU), /* PV steal time */ -- 2.54.0