1
The following changes since commit 34eac35f893664eb8545b98142e23d9954722766:
1
The following changes since commit aa3a285b5bc56a4208b3b57d4a55291e9c260107:
2
2
3
Merge tag 'pull-riscv-to-apply-20240110' of https://github.com/alistair23/qemu into staging (2024-01-10 11:41:56 +0000)
3
Merge tag 'mem-2024-12-21' of https://github.com/davidhildenbrand/qemu into staging (2024-12-22 14:33:27 -0500)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
https://gitlab.com/gaosong/qemu.git tags/pull-loongarch-20240111
7
https://gitlab.com/bibo-mao/qemu.git tags/pull-loongarch-20241225
8
8
9
for you to fetch changes up to 428a6ef4396aa910c86e16c1e4409e3927a3698e:
9
for you to fetch changes up to cb91b7108cb0b3781de9a00994fe78b631d80012:
10
10
11
hw/intc/loongarch_extioi: Add vmstate post_load support (2024-01-11 19:22:47 +0800)
11
target/loongarch: Use auto method with LASX feature (2024-12-25 10:33:20 +0800)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
pull-loongarch-20240111
14
pull-loongarch-20241225
15
15
16
----------------------------------------------------------------
16
----------------------------------------------------------------
17
Bibo Mao (4):
17
Bibo Mao (5):
18
hw/intc/loongarch_ipi: Use MemTxAttrs interface for ipi ops
18
target/loongarch: Use actual operand size with vbsrl check
19
hw/loongarch/virt: Set iocsr address space per-board rather than percpu
19
hw/loongarch/virt: Create fdt table on machine creation done notification
20
hw/intc/loongarch_extioi: Add dynamic cpu number support
20
hw/loongarch/virt: Improve fdt table creation for CPU object
21
hw/intc/loongarch_extioi: Add vmstate post_load support
21
target/loongarch: Use auto method with LSX feature
22
target/loongarch: Use auto method with LASX feature
22
23
23
Tianrui Zhao (10):
24
ghy (1):
24
linux-headers: Synchronize linux headers from linux v6.7.0-rc8
25
target/loongarch: Fix vldi inst
25
target/loongarch: Define some kvm_arch interfaces
26
target/loongarch: Supplement vcpu env initial when vcpu reset
27
target/loongarch: Implement kvm get/set registers
28
target/loongarch: Implement kvm_arch_init function
29
target/loongarch: Implement kvm_arch_init_vcpu
30
target/loongarch: Implement kvm_arch_handle_exit
31
target/loongarch: Restrict TCG-specific code
32
target/loongarch: Implement set vcpu intr for kvm
33
target/loongarch: Add loongarch kvm into meson build
34
26
35
hw/intc/loongarch_extioi.c | 230 ++++++----
27
hw/loongarch/virt.c | 142 ++++++++++++++----------
36
hw/intc/loongarch_ipi.c | 191 +++++----
28
target/loongarch/cpu.c | 86 ++++++++------
37
hw/loongarch/virt.c | 94 +++--
29
target/loongarch/cpu.h | 4 +
38
include/hw/intc/loongarch_extioi.h | 12 +-
30
target/loongarch/kvm/kvm.c | 107 ++++++++++++++++++
39
include/hw/intc/loongarch_ipi.h | 3 +-
31
target/loongarch/tcg/insn_trans/trans_vec.c.inc | 4 +-
40
include/hw/loongarch/virt.h | 3 +
32
5 files changed, 249 insertions(+), 94 deletions(-)
41
include/standard-headers/linux/fuse.h | 10 +-
42
meson.build | 3 +
43
target/loongarch/cpu.c | 90 ++--
44
target/loongarch/cpu.h | 9 +-
45
target/loongarch/internals.h | 5 +-
46
target/loongarch/kvm/kvm.c | 768 ++++++++++++++++++++++++++++++++++
47
target/loongarch/kvm/kvm_loongarch.h | 16 +
48
target/loongarch/kvm/meson.build | 1 +
49
target/loongarch/meson.build | 1 +
50
target/loongarch/tcg/iocsr_helper.c | 16 +-
51
target/loongarch/trace-events | 15 +
52
target/loongarch/trace.h | 1 +
53
18 files changed, 1210 insertions(+), 258 deletions(-)
54
create mode 100644 target/loongarch/kvm/kvm.c
55
create mode 100644 target/loongarch/kvm/kvm_loongarch.h
56
create mode 100644 target/loongarch/kvm/meson.build
57
create mode 100644 target/loongarch/trace-events
58
create mode 100644 target/loongarch/trace.h
diff view generated by jsdifflib
Deleted patch
1
From: Tianrui Zhao <zhaotianrui@loongson.cn>
2
1
3
Use the scripts/update-linux-headers.sh to synchronize linux
4
headers from linux v6.7.0-rc8. We mainly want to add the
5
loongarch linux headers and then add the loongarch kvm support
6
based on it.
7
8
Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn>
9
Acked-by: Song Gao <gaosong@loongson.cn>
10
Message-Id: <20240105075804.1228596-2-zhaotianrui@loongson.cn>
11
Signed-off-by: Song Gao <gaosong@loongson.cn>
12
---
13
include/standard-headers/linux/fuse.h | 10 ++++++----
14
1 file changed, 6 insertions(+), 4 deletions(-)
15
16
diff --git a/include/standard-headers/linux/fuse.h b/include/standard-headers/linux/fuse.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/standard-headers/linux/fuse.h
19
+++ b/include/standard-headers/linux/fuse.h
20
@@ -XXX,XX +XXX,XX @@
21
* - add FUSE_HAS_EXPIRE_ONLY
22
*
23
* 7.39
24
- * - add FUSE_DIRECT_IO_RELAX
25
+ * - add FUSE_DIRECT_IO_ALLOW_MMAP
26
* - add FUSE_STATX and related structures
27
*/
28
29
@@ -XXX,XX +XXX,XX @@ struct fuse_file_lock {
30
* FUSE_CREATE_SUPP_GROUP: add supplementary group info to create, mkdir,
31
*            symlink and mknod (single group that matches parent)
32
* FUSE_HAS_EXPIRE_ONLY: kernel supports expiry-only entry invalidation
33
- * FUSE_DIRECT_IO_RELAX: relax restrictions in FOPEN_DIRECT_IO mode, for now
34
- * allow shared mmap
35
+ * FUSE_DIRECT_IO_ALLOW_MMAP: allow shared mmap in FOPEN_DIRECT_IO mode.
36
*/
37
#define FUSE_ASYNC_READ        (1 << 0)
38
#define FUSE_POSIX_LOCKS    (1 << 1)
39
@@ -XXX,XX +XXX,XX @@ struct fuse_file_lock {
40
#define FUSE_HAS_INODE_DAX    (1ULL << 33)
41
#define FUSE_CREATE_SUPP_GROUP    (1ULL << 34)
42
#define FUSE_HAS_EXPIRE_ONLY    (1ULL << 35)
43
-#define FUSE_DIRECT_IO_RELAX    (1ULL << 36)
44
+#define FUSE_DIRECT_IO_ALLOW_MMAP (1ULL << 36)
45
+
46
+/* Obsolete alias for FUSE_DIRECT_IO_ALLOW_MMAP */
47
+#define FUSE_DIRECT_IO_RELAX    FUSE_DIRECT_IO_ALLOW_MMAP
48
49
/**
50
* CUSE INIT request/reply flags
51
--
52
2.25.1
diff view generated by jsdifflib
Deleted patch
1
From: Tianrui Zhao <zhaotianrui@loongson.cn>
2
1
3
Define some functions in target/loongarch/kvm/kvm.c,
4
such as kvm_arch_put_registers, kvm_arch_get_registers
5
and kvm_arch_handle_exit, etc. which are needed by
6
kvm/kvm-all.c. Now the most functions has no content
7
and they will be implemented in the next patches.
8
9
Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn>
10
Signed-off-by: xianglai li <lixianglai@loongson.cn>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Song Gao <gaosong@loongson.cn>
13
Message-Id: <20240105075804.1228596-3-zhaotianrui@loongson.cn>
14
Signed-off-by: Song Gao <gaosong@loongson.cn>
15
---
16
target/loongarch/kvm/kvm.c | 131 +++++++++++++++++++++++++++++++++++++
17
1 file changed, 131 insertions(+)
18
create mode 100644 target/loongarch/kvm/kvm.c
19
20
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
21
new file mode 100644
22
index XXXXXXX..XXXXXXX
23
--- /dev/null
24
+++ b/target/loongarch/kvm/kvm.c
25
@@ -XXX,XX +XXX,XX @@
26
+/* SPDX-License-Identifier: GPL-2.0-or-later */
27
+/*
28
+ * QEMU LoongArch KVM
29
+ *
30
+ * Copyright (c) 2023 Loongson Technology Corporation Limited
31
+ */
32
+
33
+#include "qemu/osdep.h"
34
+#include <sys/ioctl.h>
35
+#include <linux/kvm.h>
36
+
37
+#include "qemu/timer.h"
38
+#include "qemu/error-report.h"
39
+#include "qemu/main-loop.h"
40
+#include "sysemu/sysemu.h"
41
+#include "sysemu/kvm.h"
42
+#include "sysemu/kvm_int.h"
43
+#include "hw/pci/pci.h"
44
+#include "exec/memattrs.h"
45
+#include "exec/address-spaces.h"
46
+#include "hw/boards.h"
47
+#include "hw/irq.h"
48
+#include "qemu/log.h"
49
+#include "hw/loader.h"
50
+#include "migration/migration.h"
51
+#include "sysemu/runstate.h"
52
+#include "cpu-csr.h"
53
+#include "kvm_loongarch.h"
54
+
55
+static bool cap_has_mp_state;
56
+const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
57
+ KVM_CAP_LAST_INFO
58
+};
59
+
60
+int kvm_arch_get_registers(CPUState *cs)
61
+{
62
+ return 0;
63
+}
64
+int kvm_arch_put_registers(CPUState *cs, int level)
65
+{
66
+ return 0;
67
+}
68
+
69
+int kvm_arch_init_vcpu(CPUState *cs)
70
+{
71
+ return 0;
72
+}
73
+
74
+int kvm_arch_destroy_vcpu(CPUState *cs)
75
+{
76
+ return 0;
77
+}
78
+
79
+unsigned long kvm_arch_vcpu_id(CPUState *cs)
80
+{
81
+ return cs->cpu_index;
82
+}
83
+
84
+int kvm_arch_release_virq_post(int virq)
85
+{
86
+ return 0;
87
+}
88
+
89
+int kvm_arch_msi_data_to_gsi(uint32_t data)
90
+{
91
+ abort();
92
+}
93
+
94
+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
95
+ uint64_t address, uint32_t data, PCIDevice *dev)
96
+{
97
+ return 0;
98
+}
99
+
100
+int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route,
101
+ int vector, PCIDevice *dev)
102
+{
103
+ return 0;
104
+}
105
+
106
+void kvm_arch_init_irq_routing(KVMState *s)
107
+{
108
+}
109
+
110
+int kvm_arch_get_default_type(MachineState *ms)
111
+{
112
+ return 0;
113
+}
114
+
115
+int kvm_arch_init(MachineState *ms, KVMState *s)
116
+{
117
+ return 0;
118
+}
119
+
120
+int kvm_arch_irqchip_create(KVMState *s)
121
+{
122
+ return 0;
123
+}
124
+
125
+void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run)
126
+{
127
+}
128
+
129
+MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run)
130
+{
131
+ return MEMTXATTRS_UNSPECIFIED;
132
+}
133
+
134
+int kvm_arch_process_async_events(CPUState *cs)
135
+{
136
+ return cs->halted;
137
+}
138
+
139
+bool kvm_arch_stop_on_emulation_error(CPUState *cs)
140
+{
141
+ return true;
142
+}
143
+
144
+bool kvm_arch_cpu_check_are_resettable(void)
145
+{
146
+ return true;
147
+}
148
+
149
+int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
150
+{
151
+ return 0;
152
+}
153
+
154
+void kvm_arch_accel_class_init(ObjectClass *oc)
155
+{
156
+}
157
--
158
2.25.1
diff view generated by jsdifflib
Deleted patch
1
From: Tianrui Zhao <zhaotianrui@loongson.cn>
2
1
3
Supplement vcpu env initial when vcpu reset, including
4
init vcpu CSR_CPUID,CSR_TID to cpu->cpu_index. The two
5
regs will be used in kvm_get/set_csr_ioctl.
6
7
Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn>
8
Signed-off-by: xianglai li <lixianglai@loongson.cn>
9
Reviewed-by: Song Gao <gaosong@loongson.cn>
10
Message-Id: <20240105075804.1228596-4-zhaotianrui@loongson.cn>
11
Signed-off-by: Song Gao <gaosong@loongson.cn>
12
---
13
target/loongarch/cpu.c | 2 ++
14
target/loongarch/cpu.h | 2 +-
15
2 files changed, 3 insertions(+), 1 deletion(-)
16
17
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/loongarch/cpu.c
20
+++ b/target/loongarch/cpu.c
21
@@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_reset_hold(Object *obj)
22
23
env->CSR_ESTAT = env->CSR_ESTAT & (~MAKE_64BIT_MASK(0, 2));
24
env->CSR_RVACFG = FIELD_DP64(env->CSR_RVACFG, CSR_RVACFG, RBITS, 0);
25
+ env->CSR_CPUID = cs->cpu_index;
26
env->CSR_TCFG = FIELD_DP64(env->CSR_TCFG, CSR_TCFG, EN, 0);
27
env->CSR_LLBCTL = FIELD_DP64(env->CSR_LLBCTL, CSR_LLBCTL, KLO, 0);
28
env->CSR_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR, 0);
29
env->CSR_MERRCTL = FIELD_DP64(env->CSR_MERRCTL, CSR_MERRCTL, ISMERR, 0);
30
+ env->CSR_TID = cs->cpu_index;
31
32
env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, TLB_TYPE, 2);
33
env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, MTLB_ENTRY, 63);
34
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/loongarch/cpu.h
37
+++ b/target/loongarch/cpu.h
38
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
39
uint64_t CSR_PWCH;
40
uint64_t CSR_STLBPS;
41
uint64_t CSR_RVACFG;
42
+ uint64_t CSR_CPUID;
43
uint64_t CSR_PRCFG1;
44
uint64_t CSR_PRCFG2;
45
uint64_t CSR_PRCFG3;
46
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
47
uint64_t CSR_DBG;
48
uint64_t CSR_DERA;
49
uint64_t CSR_DSAVE;
50
- uint64_t CSR_CPUID;
51
52
#ifndef CONFIG_USER_ONLY
53
LoongArchTLB tlb[LOONGARCH_TLB_MAX];
54
--
55
2.25.1
diff view generated by jsdifflib
1
From: Bibo Mao <maobibo@loongson.cn>
1
From: ghy <2247883756@qq.com>
2
2
3
There are elements sw_ipmap and sw_coremap, which is usd to speed
3
Refer to the link below for a description of the vldi instructions:
4
up irq injection flow. They are saved and restored in vmstate during
4
https://jia.je/unofficial-loongarch-intrinsics-guide/lsx/misc/#synopsis_88
5
migration, indeed they can calculated from hw registers. Here
5
Fixed errors in vldi instruction implementation.
6
post_load is added for get sw_ipmap and sw_coremap from extioi hw
7
state.
8
6
7
Signed-off-by: Guo Hongyu <guohongyu24@mails.ucas.ac.cn>
8
Tested-by: Xianglai Li <lixianglai@loongson.cn>
9
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
10
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
9
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
11
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
10
Reviewed-by: Song Gao <gaosong@loongson.cn>
11
Message-Id: <20231215100333.3933632-5-maobibo@loongson.cn>
12
Signed-off-by: Song Gao <gaosong@loongson.cn>
13
---
12
---
14
hw/intc/loongarch_extioi.c | 120 +++++++++++++++++++++++--------------
13
target/loongarch/tcg/insn_trans/trans_vec.c.inc | 2 +-
15
1 file changed, 76 insertions(+), 44 deletions(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
16
15
17
diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c
16
diff --git a/target/loongarch/tcg/insn_trans/trans_vec.c.inc b/target/loongarch/tcg/insn_trans/trans_vec.c.inc
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/intc/loongarch_extioi.c
18
--- a/target/loongarch/tcg/insn_trans/trans_vec.c.inc
20
+++ b/hw/intc/loongarch_extioi.c
19
+++ b/target/loongarch/tcg/insn_trans/trans_vec.c.inc
21
@@ -XXX,XX +XXX,XX @@ static inline void extioi_enable_irq(LoongArchExtIOI *s, int index,\
20
@@ -XXX,XX +XXX,XX @@ static uint64_t vldi_get_value(DisasContext *ctx, uint32_t imm)
22
}
23
}
24
25
+static inline void extioi_update_sw_coremap(LoongArchExtIOI *s, int irq,
26
+ uint64_t val, bool notify)
27
+{
28
+ int i, cpu;
29
+
30
+ /*
31
+ * loongarch only support little endian,
32
+ * so we paresd the value with little endian.
33
+ */
34
+ val = cpu_to_le64(val);
35
+
36
+ for (i = 0; i < 4; i++) {
37
+ cpu = val & 0xff;
38
+ cpu = ctz32(cpu);
39
+ cpu = (cpu >= 4) ? 0 : cpu;
40
+ val = val >> 8;
41
+
42
+ if (s->sw_coremap[irq + i] == cpu) {
43
+ continue;
44
+ }
45
+
46
+ if (notify && test_bit(irq, (unsigned long *)s->isr)) {
47
+ /*
48
+ * lower irq at old cpu and raise irq at new cpu
49
+ */
50
+ extioi_update_irq(s, irq + i, 0);
51
+ s->sw_coremap[irq + i] = cpu;
52
+ extioi_update_irq(s, irq + i, 1);
53
+ } else {
54
+ s->sw_coremap[irq + i] = cpu;
55
+ }
56
+ }
57
+}
58
+
59
+static inline void extioi_update_sw_ipmap(LoongArchExtIOI *s, int index,
60
+ uint64_t val)
61
+{
62
+ int i;
63
+ uint8_t ipnum;
64
+
65
+ /*
66
+ * loongarch only support little endian,
67
+ * so we paresd the value with little endian.
68
+ */
69
+ val = cpu_to_le64(val);
70
+ for (i = 0; i < 4; i++) {
71
+ ipnum = val & 0xff;
72
+ ipnum = ctz32(ipnum);
73
+ ipnum = (ipnum >= 4) ? 0 : ipnum;
74
+ s->sw_ipmap[index * 4 + i] = ipnum;
75
+ val = val >> 8;
76
+ }
77
+}
78
+
79
static MemTxResult extioi_writew(void *opaque, hwaddr addr,
80
uint64_t val, unsigned size,
81
MemTxAttrs attrs)
82
{
83
LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque);
84
- int i, cpu, index, old_data, irq;
85
+ int cpu, index, old_data, irq;
86
uint32_t offset;
87
88
trace_loongarch_extioi_writew(addr, val);
89
@@ -XXX,XX +XXX,XX @@ static MemTxResult extioi_writew(void *opaque, hwaddr addr,
90
*/
91
index = (offset - EXTIOI_IPMAP_START) >> 2;
92
s->ipmap[index] = val;
93
- /*
94
- * loongarch only support little endian,
95
- * so we paresd the value with little endian.
96
- */
97
- val = cpu_to_le64(val);
98
- for (i = 0; i < 4; i++) {
99
- uint8_t ipnum;
100
- ipnum = val & 0xff;
101
- ipnum = ctz32(ipnum);
102
- ipnum = (ipnum >= 4) ? 0 : ipnum;
103
- s->sw_ipmap[index * 4 + i] = ipnum;
104
- val = val >> 8;
105
- }
106
-
107
+ extioi_update_sw_ipmap(s, index, val);
108
break;
21
break;
109
case EXTIOI_ENABLE_START ... EXTIOI_ENABLE_END - 1:
22
case 1:
110
index = (offset - EXTIOI_ENABLE_START) >> 2;
23
/* data: {2{16'0, imm[7:0], 8'0}} */
111
@@ -XXX,XX +XXX,XX @@ static MemTxResult extioi_writew(void *opaque, hwaddr addr,
24
- data = (t << 24) | (t << 8);
112
irq = offset - EXTIOI_COREMAP_START;
25
+ data = (t << 40) | (t << 8);
113
index = irq / 4;
114
s->coremap[index] = val;
115
- /*
116
- * loongarch only support little endian,
117
- * so we paresd the value with little endian.
118
- */
119
- val = cpu_to_le64(val);
120
-
121
- for (i = 0; i < 4; i++) {
122
- cpu = val & 0xff;
123
- cpu = ctz32(cpu);
124
- cpu = (cpu >= 4) ? 0 : cpu;
125
- val = val >> 8;
126
-
127
- if (s->sw_coremap[irq + i] == cpu) {
128
- continue;
129
- }
130
-
131
- if (test_bit(irq, (unsigned long *)s->isr)) {
132
- /*
133
- * lower irq at old cpu and raise irq at new cpu
134
- */
135
- extioi_update_irq(s, irq + i, 0);
136
- s->sw_coremap[irq + i] = cpu;
137
- extioi_update_irq(s, irq + i, 1);
138
- } else {
139
- s->sw_coremap[irq + i] = cpu;
140
- }
141
- }
142
+
143
+ extioi_update_sw_coremap(s, irq, val, true);
144
break;
26
break;
145
default:
27
case 2:
146
break;
28
/* data: {2{8'0, imm[7:0], 16'0}} */
147
@@ -XXX,XX +XXX,XX @@ static void loongarch_extioi_finalize(Object *obj)
148
g_free(s->cpu);
149
}
150
151
+static int vmstate_extioi_post_load(void *opaque, int version_id)
152
+{
153
+ LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque);
154
+ int i, start_irq;
155
+
156
+ for (i = 0; i < (EXTIOI_IRQS / 4); i++) {
157
+ start_irq = i * 4;
158
+ extioi_update_sw_coremap(s, start_irq, s->coremap[i], false);
159
+ }
160
+
161
+ for (i = 0; i < (EXTIOI_IRQS_IPMAP_SIZE / 4); i++) {
162
+ extioi_update_sw_ipmap(s, i, s->ipmap[i]);
163
+ }
164
+
165
+ return 0;
166
+}
167
+
168
static const VMStateDescription vmstate_extioi_core = {
169
.name = "extioi-core",
170
.version_id = 1,
171
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_loongarch_extioi = {
172
.name = TYPE_LOONGARCH_EXTIOI,
173
.version_id = 2,
174
.minimum_version_id = 2,
175
+ .post_load = vmstate_extioi_post_load,
176
.fields = (const VMStateField[]) {
177
VMSTATE_UINT32_ARRAY(bounce, LoongArchExtIOI, EXTIOI_IRQS_GROUP_COUNT),
178
VMSTATE_UINT32_ARRAY(nodetype, LoongArchExtIOI,
179
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_loongarch_extioi = {
180
VMSTATE_UINT32_ARRAY(isr, LoongArchExtIOI, EXTIOI_IRQS / 32),
181
VMSTATE_UINT32_ARRAY(ipmap, LoongArchExtIOI, EXTIOI_IRQS_IPMAP_SIZE / 4),
182
VMSTATE_UINT32_ARRAY(coremap, LoongArchExtIOI, EXTIOI_IRQS / 4),
183
- VMSTATE_UINT8_ARRAY(sw_ipmap, LoongArchExtIOI, EXTIOI_IRQS_IPMAP_SIZE),
184
- VMSTATE_UINT8_ARRAY(sw_coremap, LoongArchExtIOI, EXTIOI_IRQS),
185
186
VMSTATE_STRUCT_VARRAY_POINTER_UINT32(cpu, LoongArchExtIOI, num_cpu,
187
vmstate_extioi_core, ExtIOICore),
188
--
29
--
189
2.25.1
30
2.43.5
diff view generated by jsdifflib
1
From: Tianrui Zhao <zhaotianrui@loongson.cn>
1
Hardcoded 32 bytes is used for vbsrl emulation check, there is
2
problem when options lsx=on,lasx=off is used for vbsrl.v instruction
3
in TCG mode. It injects LASX exception rather LSX exception.
2
4
3
Implement loongarch kvm set vcpu interrupt interface,
5
Here actual operand size is used.
4
when a irq is set in vcpu, we use the KVM_INTERRUPT
5
ioctl to set intr into kvm.
6
6
7
Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn>
7
Cc: qemu-stable@nongnu.org
8
Signed-off-by: xianglai li <lixianglai@loongson.cn>
8
Fixes: df97f338076 ("target/loongarch: Implement xvreplve xvinsve0 xvpickve")
9
Reviewed-by: Song Gao <gaosong@loongson.cn>
9
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
10
Message-ID: <20240105075804.1228596-9-zhaotianrui@loongson.cn>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
[PMD: Split from bigger patch, part 2]
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
13
Message-Id: <20240110094152.52138-2-philmd@linaro.org>
14
Signed-off-by: Song Gao <gaosong@loongson.cn>
15
---
12
---
16
target/loongarch/cpu.c | 9 ++++++++-
13
target/loongarch/tcg/insn_trans/trans_vec.c.inc | 2 +-
17
target/loongarch/kvm/kvm.c | 15 +++++++++++++++
14
1 file changed, 1 insertion(+), 1 deletion(-)
18
target/loongarch/kvm/kvm_loongarch.h | 16 ++++++++++++++++
19
target/loongarch/trace-events | 1 +
20
4 files changed, 40 insertions(+), 1 deletion(-)
21
create mode 100644 target/loongarch/kvm/kvm_loongarch.h
22
15
23
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
16
diff --git a/target/loongarch/tcg/insn_trans/trans_vec.c.inc b/target/loongarch/tcg/insn_trans/trans_vec.c.inc
24
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
25
--- a/target/loongarch/cpu.c
18
--- a/target/loongarch/tcg/insn_trans/trans_vec.c.inc
26
+++ b/target/loongarch/cpu.c
19
+++ b/target/loongarch/tcg/insn_trans/trans_vec.c.inc
27
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static bool do_vbsrl_v(DisasContext *ctx, arg_vv_i *a, uint32_t oprsz)
28
#include "qemu/module.h"
21
{
29
#include "sysemu/qtest.h"
22
int i, ofs;
30
#include "sysemu/tcg.h"
23
31
+#include "sysemu/kvm.h"
24
- if (!check_vec(ctx, 32)) {
32
+#include "kvm/kvm_loongarch.h"
25
+ if (!check_vec(ctx, oprsz)) {
33
#include "exec/exec-all.h"
26
return true;
34
#include "cpu.h"
35
#include "internals.h"
36
@@ -XXX,XX +XXX,XX @@
37
#include "sysemu/reset.h"
38
#endif
39
#include "vec.h"
40
+#ifdef CONFIG_KVM
41
+#include <linux/kvm.h>
42
+#endif
43
#ifdef CONFIG_TCG
44
#include "exec/cpu_ldst.h"
45
#include "tcg/tcg.h"
46
@@ -XXX,XX +XXX,XX @@ void loongarch_cpu_set_irq(void *opaque, int irq, int level)
47
return;
48
}
27
}
49
28
50
- if (tcg_enabled()) {
51
+ if (kvm_enabled()) {
52
+ kvm_loongarch_set_interrupt(cpu, irq, level);
53
+ } else if (tcg_enabled()) {
54
env->CSR_ESTAT = deposit64(env->CSR_ESTAT, irq, 1, level != 0);
55
if (FIELD_EX64(env->CSR_ESTAT, CSR_ESTAT, IS)) {
56
cpu_interrupt(cs, CPU_INTERRUPT_HARD);
57
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/target/loongarch/kvm/kvm.c
60
+++ b/target/loongarch/kvm/kvm.c
61
@@ -XXX,XX +XXX,XX @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
62
return ret;
63
}
64
65
+int kvm_loongarch_set_interrupt(LoongArchCPU *cpu, int irq, int level)
66
+{
67
+ struct kvm_interrupt intr;
68
+ CPUState *cs = CPU(cpu);
69
+
70
+ if (level) {
71
+ intr.irq = irq;
72
+ } else {
73
+ intr.irq = -irq;
74
+ }
75
+
76
+ trace_kvm_set_intr(irq, level);
77
+ return kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &intr);
78
+}
79
+
80
void kvm_arch_accel_class_init(ObjectClass *oc)
81
{
82
}
83
diff --git a/target/loongarch/kvm/kvm_loongarch.h b/target/loongarch/kvm/kvm_loongarch.h
84
new file mode 100644
85
index XXXXXXX..XXXXXXX
86
--- /dev/null
87
+++ b/target/loongarch/kvm/kvm_loongarch.h
88
@@ -XXX,XX +XXX,XX @@
89
+/* SPDX-License-Identifier: GPL-2.0-or-later */
90
+/*
91
+ * QEMU LoongArch kvm interface
92
+ *
93
+ * Copyright (c) 2023 Loongson Technology Corporation Limited
94
+ */
95
+
96
+#include "cpu.h"
97
+
98
+#ifndef QEMU_KVM_LOONGARCH_H
99
+#define QEMU_KVM_LOONGARCH_H
100
+
101
+int kvm_loongarch_set_interrupt(LoongArchCPU *cpu, int irq, int level);
102
+void kvm_arch_reset_vcpu(CPULoongArchState *env);
103
+
104
+#endif
105
diff --git a/target/loongarch/trace-events b/target/loongarch/trace-events
106
index XXXXXXX..XXXXXXX 100644
107
--- a/target/loongarch/trace-events
108
+++ b/target/loongarch/trace-events
109
@@ -XXX,XX +XXX,XX @@ kvm_failed_put_counter(const char *msg) "Failed to put counter into KVM: %s"
110
kvm_failed_get_cpucfg(const char *msg) "Failed to get cpucfg from KVM: %s"
111
kvm_failed_put_cpucfg(const char *msg) "Failed to put cpucfg into KVM: %s"
112
kvm_arch_handle_exit(int num) "kvm arch handle exit, the reason number: %d"
113
+kvm_set_intr(int irq, int level) "kvm set interrupt, irq num: %d, level: %d"
114
--
29
--
115
2.25.1
30
2.43.5
116
31
117
32
diff view generated by jsdifflib
1
From: Bibo Mao <maobibo@loongson.cn>
1
The same with ACPI table, fdt table is created on machine done
2
2
notification. Some objects like CPU objects can be created with cold-plug
3
LoongArch system has iocsr address space, most iocsr registers are
3
method with command such as -smp x, -device la464-loongarch-cpu, so all
4
per-board, however some iocsr register spaces banked for percpu such
4
objects finish to create when machine is done.
5
as ipi mailbox and extioi interrupt status. For banked iocsr space,
6
each cpu has the same iocsr space, but separate data.
7
8
This patch changes iocsr address space per-board rather percpu,
9
for iocsr registers specified for cpu, MemTxAttrs.requester_id
10
can be parsed for the cpu. With this patches, the total address space
11
on board will be simple, only iocsr address space and system memory,
12
rather than the number of cpu and system memory.
13
5
14
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
6
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
15
Reviewed-by: Song Gao <gaosong@loongson.cn>
7
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
16
Message-Id: <20231215100333.3933632-3-maobibo@loongson.cn>
17
Signed-off-by: Song Gao <gaosong@loongson.cn>
18
---
8
---
19
hw/intc/loongarch_extioi.c | 3 -
9
hw/loongarch/virt.c | 103 ++++++++++++++++++++++++--------------------
20
hw/intc/loongarch_ipi.c | 61 ++++++++++++++-----
10
1 file changed, 57 insertions(+), 46 deletions(-)
21
hw/loongarch/virt.c | 91 +++++++++++++++++++++--------
22
include/hw/intc/loongarch_extioi.h | 1 -
23
include/hw/intc/loongarch_ipi.h | 3 +-
24
include/hw/loongarch/virt.h | 3 +
25
target/loongarch/cpu.c | 48 ---------------
26
target/loongarch/cpu.h | 4 +-
27
target/loongarch/kvm/kvm.c | 2 +-
28
target/loongarch/tcg/iocsr_helper.c | 16 ++---
29
10 files changed, 128 insertions(+), 104 deletions(-)
30
11
31
diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/intc/loongarch_extioi.c
34
+++ b/hw/intc/loongarch_extioi.c
35
@@ -XXX,XX +XXX,XX @@ static void loongarch_extioi_instance_init(Object *obj)
36
qdev_init_gpio_in(DEVICE(obj), extioi_setirq, EXTIOI_IRQS);
37
38
for (cpu = 0; cpu < EXTIOI_CPUS; cpu++) {
39
- memory_region_init_io(&s->extioi_iocsr_mem[cpu], OBJECT(s), &extioi_ops,
40
- s, "extioi_iocsr", 0x900);
41
- sysbus_init_mmio(dev, &s->extioi_iocsr_mem[cpu]);
42
for (pin = 0; pin < LS3A_INTC_IP; pin++) {
43
qdev_init_gpio_out(DEVICE(obj), &s->parent_irq[cpu][pin], 1);
44
}
45
diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/hw/intc/loongarch_ipi.c
48
+++ b/hw/intc/loongarch_ipi.c
49
@@ -XXX,XX +XXX,XX @@
50
#include "hw/sysbus.h"
51
#include "hw/intc/loongarch_ipi.h"
52
#include "hw/irq.h"
53
+#include "hw/qdev-properties.h"
54
#include "qapi/error.h"
55
#include "qemu/log.h"
56
#include "exec/address-spaces.h"
57
@@ -XXX,XX +XXX,XX @@ static MemTxResult loongarch_ipi_readl(void *opaque, hwaddr addr,
58
uint64_t ret = 0;
59
int index = 0;
60
61
- s = &ipi->ipi_core;
62
+ s = &ipi->cpu[attrs.requester_id];
63
addr &= 0xff;
64
switch (addr) {
65
case CORE_STATUS_OFF:
66
@@ -XXX,XX +XXX,XX @@ static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr,
67
* if the mask is 0, we need not to do anything.
68
*/
69
if ((val >> 27) & 0xf) {
70
- data = address_space_ldl(&env->address_space_iocsr, addr,
71
+ data = address_space_ldl(env->address_space_iocsr, addr,
72
attrs, NULL);
73
for (i = 0; i < 4; i++) {
74
/* get mask for byte writing */
75
@@ -XXX,XX +XXX,XX @@ static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr,
76
77
data &= mask;
78
data |= (val >> 32) & ~mask;
79
- address_space_stl(&env->address_space_iocsr, addr,
80
+ address_space_stl(env->address_space_iocsr, addr,
81
data, attrs, NULL);
82
}
83
84
@@ -XXX,XX +XXX,XX @@ static MemTxResult loongarch_ipi_writel(void *opaque, hwaddr addr, uint64_t val,
85
uint8_t vector;
86
CPUState *cs;
87
88
- s = &ipi->ipi_core;
89
+ s = &ipi->cpu[attrs.requester_id];
90
addr &= 0xff;
91
trace_loongarch_ipi_write(size, (uint64_t)addr, val);
92
switch (addr) {
93
@@ -XXX,XX +XXX,XX @@ static MemTxResult loongarch_ipi_writel(void *opaque, hwaddr addr, uint64_t val,
94
95
/* override requester_id */
96
attrs.requester_id = cs->cpu_index;
97
- ipi = LOONGARCH_IPI(LOONGARCH_CPU(cs)->env.ipistate);
98
loongarch_ipi_writel(ipi, CORE_SET_OFF, BIT(vector), 4, attrs);
99
break;
100
default:
101
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps loongarch_ipi64_ops = {
102
.endianness = DEVICE_LITTLE_ENDIAN,
103
};
104
105
-static void loongarch_ipi_init(Object *obj)
106
+static void loongarch_ipi_realize(DeviceState *dev, Error **errp)
107
{
108
- LoongArchIPI *s = LOONGARCH_IPI(obj);
109
- SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
110
+ LoongArchIPI *s = LOONGARCH_IPI(dev);
111
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
112
+ int i;
113
+
114
+ if (s->num_cpu == 0) {
115
+ error_setg(errp, "num-cpu must be at least 1");
116
+ return;
117
+ }
118
119
- memory_region_init_io(&s->ipi_iocsr_mem, obj, &loongarch_ipi_ops,
120
+ memory_region_init_io(&s->ipi_iocsr_mem, OBJECT(dev), &loongarch_ipi_ops,
121
s, "loongarch_ipi_iocsr", 0x48);
122
123
/* loongarch_ipi_iocsr performs re-entrant IO through ipi_send */
124
@@ -XXX,XX +XXX,XX @@ static void loongarch_ipi_init(Object *obj)
125
126
sysbus_init_mmio(sbd, &s->ipi_iocsr_mem);
127
128
- memory_region_init_io(&s->ipi64_iocsr_mem, obj, &loongarch_ipi64_ops,
129
+ memory_region_init_io(&s->ipi64_iocsr_mem, OBJECT(dev),
130
+ &loongarch_ipi64_ops,
131
s, "loongarch_ipi64_iocsr", 0x118);
132
sysbus_init_mmio(sbd, &s->ipi64_iocsr_mem);
133
- qdev_init_gpio_out(DEVICE(obj), &s->ipi_core.irq, 1);
134
+
135
+ s->cpu = g_new0(IPICore, s->num_cpu);
136
+ if (s->cpu == NULL) {
137
+ error_setg(errp, "Memory allocation for ExtIOICore faile");
138
+ return;
139
+ }
140
+
141
+ for (i = 0; i < s->num_cpu; i++) {
142
+ qdev_init_gpio_out(dev, &s->cpu[i].irq, 1);
143
+ }
144
}
145
146
static const VMStateDescription vmstate_ipi_core = {
147
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_ipi_core = {
148
149
static const VMStateDescription vmstate_loongarch_ipi = {
150
.name = TYPE_LOONGARCH_IPI,
151
- .version_id = 1,
152
- .minimum_version_id = 1,
153
+ .version_id = 2,
154
+ .minimum_version_id = 2,
155
.fields = (const VMStateField[]) {
156
- VMSTATE_STRUCT(ipi_core, LoongArchIPI, 0, vmstate_ipi_core, IPICore),
157
+ VMSTATE_STRUCT_VARRAY_POINTER_UINT32(cpu, LoongArchIPI, num_cpu,
158
+ vmstate_ipi_core, IPICore),
159
VMSTATE_END_OF_LIST()
160
}
161
};
162
163
+static Property ipi_properties[] = {
164
+ DEFINE_PROP_UINT32("num-cpu", LoongArchIPI, num_cpu, 1),
165
+ DEFINE_PROP_END_OF_LIST(),
166
+};
167
+
168
static void loongarch_ipi_class_init(ObjectClass *klass, void *data)
169
{
170
DeviceClass *dc = DEVICE_CLASS(klass);
171
172
+ dc->realize = loongarch_ipi_realize;
173
+ device_class_set_props(dc, ipi_properties);
174
dc->vmsd = &vmstate_loongarch_ipi;
175
}
176
177
+static void loongarch_ipi_finalize(Object *obj)
178
+{
179
+ LoongArchIPI *s = LOONGARCH_IPI(obj);
180
+
181
+ g_free(s->cpu);
182
+}
183
+
184
static const TypeInfo loongarch_ipi_info = {
185
.name = TYPE_LOONGARCH_IPI,
186
.parent = TYPE_SYS_BUS_DEVICE,
187
.instance_size = sizeof(LoongArchIPI),
188
- .instance_init = loongarch_ipi_init,
189
.class_init = loongarch_ipi_class_init,
190
+ .instance_finalize = loongarch_ipi_finalize,
191
};
192
193
static void loongarch_ipi_register_types(void)
194
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
12
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
195
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
196
--- a/hw/loongarch/virt.c
14
--- a/hw/loongarch/virt.c
197
+++ b/hw/loongarch/virt.c
15
+++ b/hw/loongarch/virt.c
198
@@ -XXX,XX +XXX,XX @@ static void loongarch_irq_init(LoongArchMachineState *lams)
16
@@ -XXX,XX +XXX,XX @@ static void virt_build_smbios(LoongArchVirtMachineState *lvms)
17
}
18
}
19
20
+static void virt_fdt_setup(LoongArchVirtMachineState *lvms)
21
+{
22
+ MachineState *machine = MACHINE(lvms);
23
+ uint32_t cpuintc_phandle, eiointc_phandle, pch_pic_phandle, pch_msi_phandle;
24
+ int i;
25
+
26
+ create_fdt(lvms);
27
+ fdt_add_cpu_nodes(lvms);
28
+ fdt_add_memory_nodes(machine);
29
+ fdt_add_fw_cfg_node(lvms);
30
+ fdt_add_flash_node(lvms);
31
+
32
+ /* Add cpu interrupt-controller */
33
+ fdt_add_cpuic_node(lvms, &cpuintc_phandle);
34
+ /* Add Extend I/O Interrupt Controller node */
35
+ fdt_add_eiointc_node(lvms, &cpuintc_phandle, &eiointc_phandle);
36
+ /* Add PCH PIC node */
37
+ fdt_add_pch_pic_node(lvms, &eiointc_phandle, &pch_pic_phandle);
38
+ /* Add PCH MSI node */
39
+ fdt_add_pch_msi_node(lvms, &eiointc_phandle, &pch_msi_phandle);
40
+ /* Add pcie node */
41
+ fdt_add_pcie_node(lvms, &pch_pic_phandle, &pch_msi_phandle);
42
+
43
+ /*
44
+ * Create uart fdt node in reverse order so that they appear
45
+ * in the finished device tree lowest address first
46
+ */
47
+ for (i = VIRT_UART_COUNT; i-- > 0;) {
48
+ hwaddr base = VIRT_UART_BASE + i * VIRT_UART_SIZE;
49
+ int irq = VIRT_UART_IRQ + i - VIRT_GSI_BASE;
50
+ fdt_add_uart_node(lvms, &pch_pic_phandle, base, irq, i == 0);
51
+ }
52
+
53
+ fdt_add_rtc_node(lvms, &pch_pic_phandle);
54
+ fdt_add_ged_reset(lvms);
55
+ platform_bus_add_all_fdt_nodes(machine->fdt, "/platic",
56
+ VIRT_PLATFORM_BUS_BASEADDRESS,
57
+ VIRT_PLATFORM_BUS_SIZE,
58
+ VIRT_PLATFORM_BUS_IRQ);
59
+
60
+ /*
61
+ * Since lowmem region starts from 0 and Linux kernel legacy start address
62
+ * at 2 MiB, FDT base address is located at 1 MiB to avoid NULL pointer
63
+ * access. FDT size limit with 1 MiB.
64
+ * Put the FDT into the memory map as a ROM image: this will ensure
65
+ * the FDT is copied again upon reset, even if addr points into RAM.
66
+ */
67
+ qemu_fdt_dumpdtb(machine->fdt, lvms->fdt_size);
68
+ rom_add_blob_fixed_as("fdt", machine->fdt, lvms->fdt_size, FDT_BASE,
69
+ &address_space_memory);
70
+ qemu_register_reset_nosnapshotload(qemu_fdt_randomize_seeds,
71
+ rom_ptr_for_as(&address_space_memory, FDT_BASE, lvms->fdt_size));
72
+}
73
+
74
static void virt_done(Notifier *notifier, void *data)
75
{
76
LoongArchVirtMachineState *lvms = container_of(notifier,
77
LoongArchVirtMachineState, machine_done);
78
virt_build_smbios(lvms);
79
loongarch_acpi_setup(lvms);
80
+ virt_fdt_setup(lvms);
81
}
82
83
static void virt_powerdown_req(Notifier *notifier, void *opaque)
84
@@ -XXX,XX +XXX,XX @@ static DeviceState *create_platform_bus(DeviceState *pch_pic)
85
}
86
87
static void virt_devices_init(DeviceState *pch_pic,
88
- LoongArchVirtMachineState *lvms,
89
- uint32_t *pch_pic_phandle,
90
- uint32_t *pch_msi_phandle)
91
+ LoongArchVirtMachineState *lvms)
92
{
93
MachineClass *mc = MACHINE_GET_CLASS(lvms);
94
DeviceState *gpex_dev;
95
@@ -XXX,XX +XXX,XX @@ static void virt_devices_init(DeviceState *pch_pic,
96
gpex_set_irq_num(GPEX_HOST(gpex_dev), i, 16 + i);
97
}
98
99
- /* Add pcie node */
100
- fdt_add_pcie_node(lvms, pch_pic_phandle, pch_msi_phandle);
101
-
102
/*
103
* Create uart fdt node in reverse order so that they appear
104
* in the finished device tree lowest address first
105
@@ -XXX,XX +XXX,XX @@ static void virt_devices_init(DeviceState *pch_pic,
106
serial_mm_init(get_system_memory(), base, 0,
107
qdev_get_gpio_in(pch_pic, irq),
108
115200, serial_hd(i), DEVICE_LITTLE_ENDIAN);
109
- fdt_add_uart_node(lvms, pch_pic_phandle, base, irq, i == 0);
110
}
111
112
/* Network init */
113
@@ -XXX,XX +XXX,XX @@ static void virt_devices_init(DeviceState *pch_pic,
114
sysbus_create_simple("ls7a_rtc", VIRT_RTC_REG_BASE,
115
qdev_get_gpio_in(pch_pic,
116
VIRT_RTC_IRQ - VIRT_GSI_BASE));
117
- fdt_add_rtc_node(lvms, pch_pic_phandle);
118
- fdt_add_ged_reset(lvms);
119
120
/* acpi ged */
121
lvms->acpi_ged = create_acpi_ged(pch_pic, lvms);
122
@@ -XXX,XX +XXX,XX @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
123
CPULoongArchState *env;
199
CPUState *cpu_state;
124
CPUState *cpu_state;
200
int cpu, pin, i, start, num;
125
int cpu, pin, i, start, num;
201
126
- uint32_t cpuintc_phandle, eiointc_phandle, pch_pic_phandle, pch_msi_phandle;
202
- extioi = qdev_new(TYPE_LOONGARCH_EXTIOI);
127
203
- sysbus_realize_and_unref(SYS_BUS_DEVICE(extioi), &error_fatal);
204
-
205
/*
128
/*
206
* The connection of interrupts:
129
* Extended IRQ model.
207
* +-----+ +---------+ +-------+
130
@@ -XXX,XX +XXX,XX @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
208
@@ -XXX,XX +XXX,XX @@ static void loongarch_irq_init(LoongArchMachineState *lams)
131
memory_region_add_subregion(&lvms->system_iocsr, MAIL_SEND_ADDR,
209
* | UARTs | | Devices | | Devices |
132
sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 1));
210
* +--------+ +---------+ +---------+
133
211
*/
134
- /* Add cpu interrupt-controller */
212
+
135
- fdt_add_cpuic_node(lvms, &cpuintc_phandle);
213
+ /* Create IPI device */
136
-
214
+ ipi = qdev_new(TYPE_LOONGARCH_IPI);
215
+ qdev_prop_set_uint32(ipi, "num-cpu", ms->smp.cpus);
216
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal);
217
+
218
+ /* IPI iocsr memory region */
219
+ memory_region_add_subregion(&lams->system_iocsr, SMP_IPI_MAILBOX,
220
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 0));
221
+ memory_region_add_subregion(&lams->system_iocsr, MAIL_SEND_ADDR,
222
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 1));
223
+
224
for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
137
for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
225
cpu_state = qemu_get_cpu(cpu);
138
cpu_state = qemu_get_cpu(cpu);
226
cpudev = DEVICE(cpu_state);
139
cpudev = DEVICE(cpu_state);
227
lacpu = LOONGARCH_CPU(cpu_state);
140
@@ -XXX,XX +XXX,XX @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
228
env = &(lacpu->env);
141
}
229
-
142
}
230
- ipi = qdev_new(TYPE_LOONGARCH_IPI);
143
231
- sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal);
144
- /* Add Extend I/O Interrupt Controller node */
232
+ env->address_space_iocsr = &lams->as_iocsr;
145
- fdt_add_eiointc_node(lvms, &cpuintc_phandle, &eiointc_phandle);
233
146
-
234
/* connect ipi irq to cpu irq */
147
pch_pic = qdev_new(TYPE_LOONGARCH_PIC);
235
- qdev_connect_gpio_out(ipi, 0, qdev_get_gpio_in(cpudev, IRQ_IPI));
148
num = VIRT_PCH_PIC_IRQ_NUM;
236
- /* IPI iocsr memory region */
149
qdev_prop_set_uint32(pch_pic, "pch_pic_irq_num", num);
237
- memory_region_add_subregion(&env->system_iocsr, SMP_IPI_MAILBOX,
150
@@ -XXX,XX +XXX,XX @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
238
- sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi),
151
qdev_connect_gpio_out(DEVICE(d), i, qdev_get_gpio_in(extioi, i));
239
- 0));
152
}
240
- memory_region_add_subregion(&env->system_iocsr, MAIL_SEND_ADDR,
153
241
- sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi),
154
- /* Add PCH PIC node */
242
- 1));
155
- fdt_add_pch_pic_node(lvms, &eiointc_phandle, &pch_pic_phandle);
243
- /*
156
-
244
-     * extioi iocsr memory region
157
pch_msi = qdev_new(TYPE_LOONGARCH_PCH_MSI);
245
-     * only one extioi is added on loongarch virt machine
158
start = num;
246
-     * external device interrupt can only be routed to cpu 0-3
159
num = EXTIOI_IRQS - start;
247
-     */
160
@@ -XXX,XX +XXX,XX @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
248
-    if (cpu < EXTIOI_CPUS)
161
qdev_get_gpio_in(extioi, i + start));
249
- memory_region_add_subregion(&env->system_iocsr, APIC_BASE,
162
}
250
- sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi),
163
251
- cpu));
164
- /* Add PCH MSI node */
252
+ qdev_connect_gpio_out(ipi, cpu, qdev_get_gpio_in(cpudev, IRQ_IPI));
165
- fdt_add_pch_msi_node(lvms, &eiointc_phandle, &pch_msi_phandle);
253
env->ipistate = ipi;
166
-
254
}
167
- virt_devices_init(pch_pic, lvms, &pch_pic_phandle, &pch_msi_phandle);
255
168
+ virt_devices_init(pch_pic, lvms);
256
+ /* Create EXTIOI device */
169
}
257
+ extioi = qdev_new(TYPE_LOONGARCH_EXTIOI);
170
258
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(extioi), &error_fatal);
171
static void virt_firmware_init(LoongArchVirtMachineState *lvms)
259
+ memory_region_add_subregion(&lams->system_iocsr, APIC_BASE,
172
@@ -XXX,XX +XXX,XX @@ static void virt_init(MachineState *machine)
260
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 0));
173
cpu_model = LOONGARCH_CPU_TYPE_NAME("la464");
261
+
174
}
262
/*
175
263
* connect ext irq to the cpu irq
176
- create_fdt(lvms);
264
* cpu_pin[9:2] <= intc_pin[7:0]
177
-
265
@@ -XXX,XX +XXX,XX @@ static void loongarch_direct_kernel_boot(LoongArchMachineState *lams,
178
/* Create IOCSR space */
266
}
179
memory_region_init_io(&lvms->system_iocsr, OBJECT(machine), NULL,
267
}
180
machine, "iocsr", UINT64_MAX);
268
181
@@ -XXX,XX +XXX,XX @@ static void virt_init(MachineState *machine)
269
+static void loongarch_qemu_write(void *opaque, hwaddr addr,
182
lacpu = LOONGARCH_CPU(cpu);
270
+ uint64_t val, unsigned size)
183
lacpu->phy_id = machine->possible_cpus->cpus[i].arch_id;
271
+{
184
}
272
+}
185
- fdt_add_cpu_nodes(lvms);
273
+
186
- fdt_add_memory_nodes(machine);
274
+static uint64_t loongarch_qemu_read(void *opaque, hwaddr addr, unsigned size)
187
fw_cfg_add_memory(machine);
275
+{
188
276
+ switch (addr) {
189
/* Node0 memory */
277
+ case VERSION_REG:
190
@@ -XXX,XX +XXX,XX @@ static void virt_init(MachineState *machine)
278
+ return 0x11ULL;
191
memmap_table,
279
+ case FEATURE_REG:
192
sizeof(struct memmap_entry) * (memmap_entries));
280
+ return 1ULL << IOCSRF_MSI | 1ULL << IOCSRF_EXTIOI |
193
}
281
+ 1ULL << IOCSRF_CSRIPI;
194
- fdt_add_fw_cfg_node(lvms);
282
+ case VENDOR_REG:
195
- fdt_add_flash_node(lvms);
283
+ return 0x6e6f73676e6f6f4cULL; /* "Loongson" */
196
284
+ case CPUNAME_REG:
197
/* Initialize the IO interrupt subsystem */
285
+ return 0x303030354133ULL; /* "3A5000" */
198
virt_irq_init(lvms);
286
+ case MISC_FUNC_REG:
199
- platform_bus_add_all_fdt_nodes(machine->fdt, "/platic",
287
+ return 1ULL << IOCSRM_EXTIOI_EN;
200
- VIRT_PLATFORM_BUS_BASEADDRESS,
288
+ }
201
- VIRT_PLATFORM_BUS_SIZE,
289
+ return 0ULL;
202
- VIRT_PLATFORM_BUS_IRQ);
290
+}
203
lvms->machine_done.notify = virt_done;
291
+
204
qemu_add_machine_init_done_notifier(&lvms->machine_done);
292
+static const MemoryRegionOps loongarch_qemu_ops = {
205
/* connect powerdown request */
293
+ .read = loongarch_qemu_read,
206
lvms->powerdown_notifier.notify = virt_powerdown_req;
294
+ .write = loongarch_qemu_write,
207
qemu_register_powerdown_notifier(&lvms->powerdown_notifier);
295
+ .endianness = DEVICE_LITTLE_ENDIAN,
208
296
+ .valid = {
209
- /*
297
+ .min_access_size = 4,
210
- * Since lowmem region starts from 0 and Linux kernel legacy start address
298
+ .max_access_size = 8,
211
- * at 2 MiB, FDT base address is located at 1 MiB to avoid NULL pointer
299
+ },
212
- * access. FDT size limit with 1 MiB.
300
+ .impl = {
213
- * Put the FDT into the memory map as a ROM image: this will ensure
301
+ .min_access_size = 8,
214
- * the FDT is copied again upon reset, even if addr points into RAM.
302
+ .max_access_size = 8,
215
- */
303
+ },
216
- qemu_fdt_dumpdtb(machine->fdt, lvms->fdt_size);
304
+};
217
- rom_add_blob_fixed_as("fdt", machine->fdt, lvms->fdt_size, FDT_BASE,
305
+
218
- &address_space_memory);
306
static void loongarch_init(MachineState *machine)
219
- qemu_register_reset_nosnapshotload(qemu_fdt_randomize_seeds,
307
{
220
- rom_ptr_for_as(&address_space_memory, FDT_BASE, lvms->fdt_size));
308
LoongArchCPU *lacpu;
221
-
309
@@ -XXX,XX +XXX,XX @@ static void loongarch_init(MachineState *machine)
222
lvms->bootinfo.ram_size = ram_size;
310
exit(1);
223
loongarch_load_kernel(machine, &lvms->bootinfo);
311
}
312
create_fdt(lams);
313
- /* Init CPUs */
314
315
+ /* Create IOCSR space */
316
+ memory_region_init_io(&lams->system_iocsr, OBJECT(machine), NULL,
317
+ machine, "iocsr", UINT64_MAX);
318
+ address_space_init(&lams->as_iocsr, &lams->system_iocsr, "IOCSR");
319
+ memory_region_init_io(&lams->iocsr_mem, OBJECT(machine),
320
+ &loongarch_qemu_ops,
321
+ machine, "iocsr_misc", 0x428);
322
+ memory_region_add_subregion(&lams->system_iocsr, 0, &lams->iocsr_mem);
323
+
324
+ /* Init CPUs */
325
possible_cpus = mc->possible_cpu_arch_ids(machine);
326
for (i = 0; i < possible_cpus->len; i++) {
327
cpu = cpu_create(machine->cpu_type);
328
diff --git a/include/hw/intc/loongarch_extioi.h b/include/hw/intc/loongarch_extioi.h
329
index XXXXXXX..XXXXXXX 100644
330
--- a/include/hw/intc/loongarch_extioi.h
331
+++ b/include/hw/intc/loongarch_extioi.h
332
@@ -XXX,XX +XXX,XX @@ struct LoongArchExtIOI {
333
uint8_t sw_coremap[EXTIOI_IRQS];
334
qemu_irq parent_irq[EXTIOI_CPUS][LS3A_INTC_IP];
335
qemu_irq irq[EXTIOI_IRQS];
336
- MemoryRegion extioi_iocsr_mem[EXTIOI_CPUS];
337
MemoryRegion extioi_system_mem;
338
};
339
#endif /* LOONGARCH_EXTIOI_H */
340
diff --git a/include/hw/intc/loongarch_ipi.h b/include/hw/intc/loongarch_ipi.h
341
index XXXXXXX..XXXXXXX 100644
342
--- a/include/hw/intc/loongarch_ipi.h
343
+++ b/include/hw/intc/loongarch_ipi.h
344
@@ -XXX,XX +XXX,XX @@ struct LoongArchIPI {
345
SysBusDevice parent_obj;
346
MemoryRegion ipi_iocsr_mem;
347
MemoryRegion ipi64_iocsr_mem;
348
- IPICore ipi_core;
349
+ uint32_t num_cpu;
350
+ IPICore *cpu;
351
};
352
353
#endif
354
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
355
index XXXXXXX..XXXXXXX 100644
356
--- a/include/hw/loongarch/virt.h
357
+++ b/include/hw/loongarch/virt.h
358
@@ -XXX,XX +XXX,XX @@ struct LoongArchMachineState {
359
DeviceState *platform_bus_dev;
360
PCIBus *pci_bus;
361
PFlashCFI01 *flash;
362
+ MemoryRegion system_iocsr;
363
+ MemoryRegion iocsr_mem;
364
+ AddressSpace as_iocsr;
365
};
366
367
#define TYPE_LOONGARCH_MACHINE MACHINE_TYPE_NAME("virt")
368
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
369
index XXXXXXX..XXXXXXX 100644
370
--- a/target/loongarch/cpu.c
371
+++ b/target/loongarch/cpu.c
372
@@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_realizefn(DeviceState *dev, Error **errp)
373
lacc->parent_realize(dev, errp);
374
}
375
376
-#ifndef CONFIG_USER_ONLY
377
-static void loongarch_qemu_write(void *opaque, hwaddr addr,
378
- uint64_t val, unsigned size)
379
-{
380
- qemu_log_mask(LOG_UNIMP, "[%s]: Unimplemented reg 0x%" HWADDR_PRIx "\n",
381
- __func__, addr);
382
-}
383
-
384
-static uint64_t loongarch_qemu_read(void *opaque, hwaddr addr, unsigned size)
385
-{
386
- switch (addr) {
387
- case VERSION_REG:
388
- return 0x11ULL;
389
- case FEATURE_REG:
390
- return 1ULL << IOCSRF_MSI | 1ULL << IOCSRF_EXTIOI |
391
- 1ULL << IOCSRF_CSRIPI;
392
- case VENDOR_REG:
393
- return 0x6e6f73676e6f6f4cULL; /* "Loongson" */
394
- case CPUNAME_REG:
395
- return 0x303030354133ULL; /* "3A5000" */
396
- case MISC_FUNC_REG:
397
- return 1ULL << IOCSRM_EXTIOI_EN;
398
- }
399
- return 0ULL;
400
-}
401
-
402
-static const MemoryRegionOps loongarch_qemu_ops = {
403
- .read = loongarch_qemu_read,
404
- .write = loongarch_qemu_write,
405
- .endianness = DEVICE_LITTLE_ENDIAN,
406
- .valid = {
407
- .min_access_size = 4,
408
- .max_access_size = 8,
409
- },
410
- .impl = {
411
- .min_access_size = 8,
412
- .max_access_size = 8,
413
- },
414
-};
415
-#endif
416
-
417
static bool loongarch_get_lsx(Object *obj, Error **errp)
418
{
419
LoongArchCPU *cpu = LOONGARCH_CPU(obj);
420
@@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_init(Object *obj)
421
{
422
#ifndef CONFIG_USER_ONLY
423
LoongArchCPU *cpu = LOONGARCH_CPU(obj);
424
- CPULoongArchState *env = &cpu->env;
425
426
qdev_init_gpio_in(DEVICE(cpu), loongarch_cpu_set_irq, N_IRQS);
427
#ifdef CONFIG_TCG
428
timer_init_ns(&cpu->timer, QEMU_CLOCK_VIRTUAL,
429
&loongarch_constant_timer_cb, cpu);
430
#endif
431
- memory_region_init_io(&env->system_iocsr, OBJECT(cpu), NULL,
432
- env, "iocsr", UINT64_MAX);
433
- address_space_init(&env->address_space_iocsr, &env->system_iocsr, "IOCSR");
434
- memory_region_init_io(&env->iocsr_mem, OBJECT(cpu), &loongarch_qemu_ops,
435
- NULL, "iocsr_misc", 0x428);
436
- memory_region_add_subregion(&env->system_iocsr, 0, &env->iocsr_mem);
437
#endif
438
}
439
440
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
441
index XXXXXXX..XXXXXXX 100644
442
--- a/target/loongarch/cpu.h
443
+++ b/target/loongarch/cpu.h
444
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
445
#ifndef CONFIG_USER_ONLY
446
LoongArchTLB tlb[LOONGARCH_TLB_MAX];
447
448
- AddressSpace address_space_iocsr;
449
- MemoryRegion system_iocsr;
450
- MemoryRegion iocsr_mem;
451
+ AddressSpace *address_space_iocsr;
452
bool load_elf;
453
uint64_t elf_address;
454
uint32_t mp_state;
455
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
456
index XXXXXXX..XXXXXXX 100644
457
--- a/target/loongarch/kvm/kvm.c
458
+++ b/target/loongarch/kvm/kvm.c
459
@@ -XXX,XX +XXX,XX @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
460
trace_kvm_arch_handle_exit(run->exit_reason);
461
switch (run->exit_reason) {
462
case KVM_EXIT_LOONGARCH_IOCSR:
463
- address_space_rw(&env->address_space_iocsr,
464
+ address_space_rw(env->address_space_iocsr,
465
run->iocsr_io.phys_addr,
466
attrs,
467
run->iocsr_io.data,
468
diff --git a/target/loongarch/tcg/iocsr_helper.c b/target/loongarch/tcg/iocsr_helper.c
469
index XXXXXXX..XXXXXXX 100644
470
--- a/target/loongarch/tcg/iocsr_helper.c
471
+++ b/target/loongarch/tcg/iocsr_helper.c
472
@@ -XXX,XX +XXX,XX @@
473
474
uint64_t helper_iocsrrd_b(CPULoongArchState *env, target_ulong r_addr)
475
{
476
- return address_space_ldub(&env->address_space_iocsr, r_addr,
477
+ return address_space_ldub(env->address_space_iocsr, r_addr,
478
GET_MEMTXATTRS(env), NULL);
479
}
480
481
uint64_t helper_iocsrrd_h(CPULoongArchState *env, target_ulong r_addr)
482
{
483
- return address_space_lduw(&env->address_space_iocsr, r_addr,
484
+ return address_space_lduw(env->address_space_iocsr, r_addr,
485
GET_MEMTXATTRS(env), NULL);
486
}
487
488
uint64_t helper_iocsrrd_w(CPULoongArchState *env, target_ulong r_addr)
489
{
490
- return address_space_ldl(&env->address_space_iocsr, r_addr,
491
+ return address_space_ldl(env->address_space_iocsr, r_addr,
492
GET_MEMTXATTRS(env), NULL);
493
}
494
495
uint64_t helper_iocsrrd_d(CPULoongArchState *env, target_ulong r_addr)
496
{
497
- return address_space_ldq(&env->address_space_iocsr, r_addr,
498
+ return address_space_ldq(env->address_space_iocsr, r_addr,
499
GET_MEMTXATTRS(env), NULL);
500
}
501
502
void helper_iocsrwr_b(CPULoongArchState *env, target_ulong w_addr,
503
target_ulong val)
504
{
505
- address_space_stb(&env->address_space_iocsr, w_addr,
506
+ address_space_stb(env->address_space_iocsr, w_addr,
507
val, GET_MEMTXATTRS(env), NULL);
508
}
509
510
void helper_iocsrwr_h(CPULoongArchState *env, target_ulong w_addr,
511
target_ulong val)
512
{
513
- address_space_stw(&env->address_space_iocsr, w_addr,
514
+ address_space_stw(env->address_space_iocsr, w_addr,
515
val, GET_MEMTXATTRS(env), NULL);
516
}
517
518
void helper_iocsrwr_w(CPULoongArchState *env, target_ulong w_addr,
519
target_ulong val)
520
{
521
- address_space_stl(&env->address_space_iocsr, w_addr,
522
+ address_space_stl(env->address_space_iocsr, w_addr,
523
val, GET_MEMTXATTRS(env), NULL);
524
}
525
526
void helper_iocsrwr_d(CPULoongArchState *env, target_ulong w_addr,
527
target_ulong val)
528
{
529
- address_space_stq(&env->address_space_iocsr, w_addr,
530
+ address_space_stq(env->address_space_iocsr, w_addr,
531
val, GET_MEMTXATTRS(env), NULL);
532
}
224
}
533
--
225
--
534
2.25.1
226
2.43.5
diff view generated by jsdifflib
1
From: Bibo Mao <maobibo@loongson.cn>
1
For CPU object, possible_cpu_arch_ids() function is used rather than
2
2
smp.cpus. With command -smp x, -device la464-loongarch-cpu, smp.cpus
3
On LoongArch physical machine, one extioi interrupt controller only
3
is not accurate for all possible CPU objects, possible_cpu_arch_ids()
4
supports 4 cpus. With processor more than 4 cpus, there are multiple
4
is used here.
5
extioi interrupt controllers; if interrupts need to be routed to
6
other cpus, they are forwarded from extioi node0 to other extioi nodes.
7
8
On virt machine model, there is simple extioi interrupt device model.
9
All cpus can access register of extioi interrupt controller, however
10
interrupt can only be route to 4 vcpu for compatible with old kernel.
11
12
This patch adds dynamic cpu number support about extioi interrupt.
13
With old kernel legacy extioi model is used, however kernel can detect
14
and choose new route method in future, so that interrupt can be routed to
15
all vcpus.
16
5
17
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
6
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
18
Reviewed-by: Song Gao <gaosong@loongson.cn>
7
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
19
Message-Id: <20231215100333.3933632-4-maobibo@loongson.cn>
20
Signed-off-by: Song Gao <gaosong@loongson.cn>
21
---
8
---
22
hw/intc/loongarch_extioi.c | 107 +++++++++++++++++++----------
9
hw/loongarch/virt.c | 39 +++++++++++++++++++++++++--------------
23
hw/loongarch/virt.c | 3 +-
10
1 file changed, 25 insertions(+), 14 deletions(-)
24
include/hw/intc/loongarch_extioi.h | 11 ++-
25
3 files changed, 81 insertions(+), 40 deletions(-)
26
11
27
diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/intc/loongarch_extioi.c
30
+++ b/hw/intc/loongarch_extioi.c
31
@@ -XXX,XX +XXX,XX @@
32
#include "qemu/osdep.h"
33
#include "qemu/module.h"
34
#include "qemu/log.h"
35
+#include "qapi/error.h"
36
#include "hw/irq.h"
37
#include "hw/sysbus.h"
38
#include "hw/loongarch/virt.h"
39
@@ -XXX,XX +XXX,XX @@ static void extioi_update_irq(LoongArchExtIOI *s, int irq, int level)
40
if (((s->enable[irq_index]) & irq_mask) == 0) {
41
return;
42
}
43
- s->coreisr[cpu][irq_index] |= irq_mask;
44
- found = find_first_bit(s->sw_isr[cpu][ipnum], EXTIOI_IRQS);
45
- set_bit(irq, s->sw_isr[cpu][ipnum]);
46
+ s->cpu[cpu].coreisr[irq_index] |= irq_mask;
47
+ found = find_first_bit(s->cpu[cpu].sw_isr[ipnum], EXTIOI_IRQS);
48
+ set_bit(irq, s->cpu[cpu].sw_isr[ipnum]);
49
if (found < EXTIOI_IRQS) {
50
/* other irq is handling, need not update parent irq level */
51
return;
52
}
53
} else {
54
- s->coreisr[cpu][irq_index] &= ~irq_mask;
55
- clear_bit(irq, s->sw_isr[cpu][ipnum]);
56
- found = find_first_bit(s->sw_isr[cpu][ipnum], EXTIOI_IRQS);
57
+ s->cpu[cpu].coreisr[irq_index] &= ~irq_mask;
58
+ clear_bit(irq, s->cpu[cpu].sw_isr[ipnum]);
59
+ found = find_first_bit(s->cpu[cpu].sw_isr[ipnum], EXTIOI_IRQS);
60
if (found < EXTIOI_IRQS) {
61
/* other irq is handling, need not update parent irq level */
62
return;
63
}
64
}
65
- qemu_set_irq(s->parent_irq[cpu][ipnum], level);
66
+ qemu_set_irq(s->cpu[cpu].parent_irq[ipnum], level);
67
}
68
69
static void extioi_setirq(void *opaque, int irq, int level)
70
@@ -XXX,XX +XXX,XX @@ static MemTxResult extioi_readw(void *opaque, hwaddr addr, uint64_t *data,
71
index = (offset - EXTIOI_COREISR_START) >> 2;
72
/* using attrs to get current cpu index */
73
cpu = attrs.requester_id;
74
- *data = s->coreisr[cpu][index];
75
+ *data = s->cpu[cpu].coreisr[index];
76
break;
77
case EXTIOI_COREMAP_START ... EXTIOI_COREMAP_END - 1:
78
index = (offset - EXTIOI_COREMAP_START) >> 2;
79
@@ -XXX,XX +XXX,XX @@ static MemTxResult extioi_writew(void *opaque, hwaddr addr,
80
index = (offset - EXTIOI_COREISR_START) >> 2;
81
/* using attrs to get current cpu index */
82
cpu = attrs.requester_id;
83
- old_data = s->coreisr[cpu][index];
84
- s->coreisr[cpu][index] = old_data & ~val;
85
+ old_data = s->cpu[cpu].coreisr[index];
86
+ s->cpu[cpu].coreisr[index] = old_data & ~val;
87
/* write 1 to clear interrupt */
88
old_data &= val;
89
irq = ctz32(old_data);
90
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps extioi_ops = {
91
.endianness = DEVICE_LITTLE_ENDIAN,
92
};
93
94
-static const VMStateDescription vmstate_loongarch_extioi = {
95
- .name = TYPE_LOONGARCH_EXTIOI,
96
+static void loongarch_extioi_realize(DeviceState *dev, Error **errp)
97
+{
98
+ LoongArchExtIOI *s = LOONGARCH_EXTIOI(dev);
99
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
100
+ int i, pin;
101
+
102
+ if (s->num_cpu == 0) {
103
+ error_setg(errp, "num-cpu must be at least 1");
104
+ return;
105
+ }
106
+
107
+ for (i = 0; i < EXTIOI_IRQS; i++) {
108
+ sysbus_init_irq(sbd, &s->irq[i]);
109
+ }
110
+
111
+ qdev_init_gpio_in(dev, extioi_setirq, EXTIOI_IRQS);
112
+ memory_region_init_io(&s->extioi_system_mem, OBJECT(s), &extioi_ops,
113
+ s, "extioi_system_mem", 0x900);
114
+ sysbus_init_mmio(sbd, &s->extioi_system_mem);
115
+ s->cpu = g_new0(ExtIOICore, s->num_cpu);
116
+ if (s->cpu == NULL) {
117
+ error_setg(errp, "Memory allocation for ExtIOICore faile");
118
+ return;
119
+ }
120
+
121
+ for (i = 0; i < s->num_cpu; i++) {
122
+ for (pin = 0; pin < LS3A_INTC_IP; pin++) {
123
+ qdev_init_gpio_out(dev, &s->cpu[i].parent_irq[pin], 1);
124
+ }
125
+ }
126
+}
127
+
128
+static void loongarch_extioi_finalize(Object *obj)
129
+{
130
+ LoongArchExtIOI *s = LOONGARCH_EXTIOI(obj);
131
+
132
+ g_free(s->cpu);
133
+}
134
+
135
+static const VMStateDescription vmstate_extioi_core = {
136
+ .name = "extioi-core",
137
.version_id = 1,
138
.minimum_version_id = 1,
139
+ .fields = (const VMStateField[]) {
140
+ VMSTATE_UINT32_ARRAY(coreisr, ExtIOICore, EXTIOI_IRQS_GROUP_COUNT),
141
+ VMSTATE_END_OF_LIST()
142
+ }
143
+};
144
+
145
+static const VMStateDescription vmstate_loongarch_extioi = {
146
+ .name = TYPE_LOONGARCH_EXTIOI,
147
+ .version_id = 2,
148
+ .minimum_version_id = 2,
149
.fields = (const VMStateField[]) {
150
VMSTATE_UINT32_ARRAY(bounce, LoongArchExtIOI, EXTIOI_IRQS_GROUP_COUNT),
151
- VMSTATE_UINT32_2DARRAY(coreisr, LoongArchExtIOI, EXTIOI_CPUS,
152
- EXTIOI_IRQS_GROUP_COUNT),
153
VMSTATE_UINT32_ARRAY(nodetype, LoongArchExtIOI,
154
EXTIOI_IRQS_NODETYPE_COUNT / 2),
155
VMSTATE_UINT32_ARRAY(enable, LoongArchExtIOI, EXTIOI_IRQS / 32),
156
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_loongarch_extioi = {
157
VMSTATE_UINT8_ARRAY(sw_ipmap, LoongArchExtIOI, EXTIOI_IRQS_IPMAP_SIZE),
158
VMSTATE_UINT8_ARRAY(sw_coremap, LoongArchExtIOI, EXTIOI_IRQS),
159
160
+ VMSTATE_STRUCT_VARRAY_POINTER_UINT32(cpu, LoongArchExtIOI, num_cpu,
161
+ vmstate_extioi_core, ExtIOICore),
162
VMSTATE_END_OF_LIST()
163
}
164
};
165
166
-static void loongarch_extioi_instance_init(Object *obj)
167
-{
168
- SysBusDevice *dev = SYS_BUS_DEVICE(obj);
169
- LoongArchExtIOI *s = LOONGARCH_EXTIOI(obj);
170
- int i, cpu, pin;
171
-
172
- for (i = 0; i < EXTIOI_IRQS; i++) {
173
- sysbus_init_irq(dev, &s->irq[i]);
174
- }
175
-
176
- qdev_init_gpio_in(DEVICE(obj), extioi_setirq, EXTIOI_IRQS);
177
-
178
- for (cpu = 0; cpu < EXTIOI_CPUS; cpu++) {
179
- for (pin = 0; pin < LS3A_INTC_IP; pin++) {
180
- qdev_init_gpio_out(DEVICE(obj), &s->parent_irq[cpu][pin], 1);
181
- }
182
- }
183
- memory_region_init_io(&s->extioi_system_mem, OBJECT(s), &extioi_ops,
184
- s, "extioi_system_mem", 0x900);
185
- sysbus_init_mmio(dev, &s->extioi_system_mem);
186
-}
187
+static Property extioi_properties[] = {
188
+ DEFINE_PROP_UINT32("num-cpu", LoongArchExtIOI, num_cpu, 1),
189
+ DEFINE_PROP_END_OF_LIST(),
190
+};
191
192
static void loongarch_extioi_class_init(ObjectClass *klass, void *data)
193
{
194
DeviceClass *dc = DEVICE_CLASS(klass);
195
196
+ dc->realize = loongarch_extioi_realize;
197
+ device_class_set_props(dc, extioi_properties);
198
dc->vmsd = &vmstate_loongarch_extioi;
199
}
200
201
static const TypeInfo loongarch_extioi_info = {
202
.name = TYPE_LOONGARCH_EXTIOI,
203
.parent = TYPE_SYS_BUS_DEVICE,
204
- .instance_init = loongarch_extioi_instance_init,
205
.instance_size = sizeof(struct LoongArchExtIOI),
206
.class_init = loongarch_extioi_class_init,
207
+ .instance_finalize = loongarch_extioi_finalize,
208
};
209
210
static void loongarch_extioi_register_types(void)
211
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
12
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
212
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
213
--- a/hw/loongarch/virt.c
14
--- a/hw/loongarch/virt.c
214
+++ b/hw/loongarch/virt.c
15
+++ b/hw/loongarch/virt.c
215
@@ -XXX,XX +XXX,XX @@ static void loongarch_irq_init(LoongArchMachineState *lams)
16
@@ -XXX,XX +XXX,XX @@ static void create_fdt(LoongArchVirtMachineState *lvms)
216
17
static void fdt_add_cpu_nodes(const LoongArchVirtMachineState *lvms)
217
/* Create EXTIOI device */
18
{
218
extioi = qdev_new(TYPE_LOONGARCH_EXTIOI);
19
int num;
219
+ qdev_prop_set_uint32(extioi, "num-cpu", ms->smp.cpus);
20
- const MachineState *ms = MACHINE(lvms);
220
sysbus_realize_and_unref(SYS_BUS_DEVICE(extioi), &error_fatal);
21
- int smp_cpus = ms->smp.cpus;
221
memory_region_add_subregion(&lams->system_iocsr, APIC_BASE,
22
+ MachineState *ms = MACHINE(lvms);
222
sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 0));
23
+ MachineClass *mc = MACHINE_GET_CLASS(ms);
223
@@ -XXX,XX +XXX,XX @@ static void loongarch_irq_init(LoongArchMachineState *lams)
24
+ const CPUArchIdList *possible_cpus;
224
* connect ext irq to the cpu irq
25
+ LoongArchCPU *cpu;
225
* cpu_pin[9:2] <= intc_pin[7:0]
26
+ CPUState *cs;
226
*/
27
+ char *nodename, *map_path;
227
- for (cpu = 0; cpu < MIN(ms->smp.cpus, EXTIOI_CPUS); cpu++) {
28
228
+ for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
29
qemu_fdt_add_subnode(ms->fdt, "/cpus");
229
cpudev = DEVICE(qemu_get_cpu(cpu));
30
qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#address-cells", 0x1);
230
for (pin = 0; pin < LS3A_INTC_IP; pin++) {
31
qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#size-cells", 0x0);
231
qdev_connect_gpio_out(extioi, (cpu * 8 + pin),
32
232
diff --git a/include/hw/intc/loongarch_extioi.h b/include/hw/intc/loongarch_extioi.h
33
/* cpu nodes */
233
index XXXXXXX..XXXXXXX 100644
34
- for (num = smp_cpus - 1; num >= 0; num--) {
234
--- a/include/hw/intc/loongarch_extioi.h
35
- char *nodename = g_strdup_printf("/cpus/cpu@%d", num);
235
+++ b/include/hw/intc/loongarch_extioi.h
36
- LoongArchCPU *cpu = LOONGARCH_CPU(qemu_get_cpu(num));
236
@@ -XXX,XX +XXX,XX @@
37
- CPUState *cs = CPU(cpu);
237
#define EXTIOI_COREMAP_START (0xC00 - APIC_OFFSET)
38
+ possible_cpus = mc->possible_cpu_arch_ids(ms);
238
#define EXTIOI_COREMAP_END (0xD00 - APIC_OFFSET)
39
+ for (num = 0; num < possible_cpus->len; num++) {
239
40
+ cs = possible_cpus->cpus[num].cpu;
240
+typedef struct ExtIOICore {
41
+ if (cs == NULL) {
241
+ uint32_t coreisr[EXTIOI_IRQS_GROUP_COUNT];
42
+ continue;
242
+ DECLARE_BITMAP(sw_isr[LS3A_INTC_IP], EXTIOI_IRQS);
43
+ }
243
+ qemu_irq parent_irq[LS3A_INTC_IP];
244
+} ExtIOICore;
245
+
44
+
246
#define TYPE_LOONGARCH_EXTIOI "loongarch.extioi"
45
+ nodename = g_strdup_printf("/cpus/cpu@%d", num);
247
OBJECT_DECLARE_SIMPLE_TYPE(LoongArchExtIOI, LOONGARCH_EXTIOI)
46
+ cpu = LOONGARCH_CPU(cs);
248
struct LoongArchExtIOI {
47
249
SysBusDevice parent_obj;
48
qemu_fdt_add_subnode(ms->fdt, nodename);
250
+ uint32_t num_cpu;
49
qemu_fdt_setprop_string(ms->fdt, nodename, "device_type", "cpu");
251
/* hardware state */
50
qemu_fdt_setprop_string(ms->fdt, nodename, "compatible",
252
uint32_t nodetype[EXTIOI_IRQS_NODETYPE_COUNT / 2];
51
cpu->dtb_compatible);
253
uint32_t bounce[EXTIOI_IRQS_GROUP_COUNT];
52
- if (ms->possible_cpus->cpus[cs->cpu_index].props.has_node_id) {
254
uint32_t isr[EXTIOI_IRQS / 32];
53
+ if (possible_cpus->cpus[num].props.has_node_id) {
255
- uint32_t coreisr[EXTIOI_CPUS][EXTIOI_IRQS_GROUP_COUNT];
54
qemu_fdt_setprop_cell(ms->fdt, nodename, "numa-node-id",
256
uint32_t enable[EXTIOI_IRQS / 32];
55
- ms->possible_cpus->cpus[cs->cpu_index].props.node_id);
257
uint32_t ipmap[EXTIOI_IRQS_IPMAP_SIZE / 4];
56
+ possible_cpus->cpus[num].props.node_id);
258
uint32_t coremap[EXTIOI_IRQS / 4];
57
}
259
uint32_t sw_pending[EXTIOI_IRQS / 32];
58
qemu_fdt_setprop_cell(ms->fdt, nodename, "reg", num);
260
- DECLARE_BITMAP(sw_isr[EXTIOI_CPUS][LS3A_INTC_IP], EXTIOI_IRQS);
59
qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle",
261
uint8_t sw_ipmap[EXTIOI_IRQS_IPMAP_SIZE];
60
@@ -XXX,XX +XXX,XX @@ static void fdt_add_cpu_nodes(const LoongArchVirtMachineState *lvms)
262
uint8_t sw_coremap[EXTIOI_IRQS];
61
263
- qemu_irq parent_irq[EXTIOI_CPUS][LS3A_INTC_IP];
62
/*cpu map */
264
qemu_irq irq[EXTIOI_IRQS];
63
qemu_fdt_add_subnode(ms->fdt, "/cpus/cpu-map");
265
+ ExtIOICore *cpu;
64
+ for (num = 0; num < possible_cpus->len; num++) {
266
MemoryRegion extioi_system_mem;
65
+ cs = possible_cpus->cpus[num].cpu;
267
};
66
+ if (cs == NULL) {
268
#endif /* LOONGARCH_EXTIOI_H */
67
+ continue;
68
+ }
69
70
- for (num = smp_cpus - 1; num >= 0; num--) {
71
- char *cpu_path = g_strdup_printf("/cpus/cpu@%d", num);
72
- char *map_path;
73
-
74
+ nodename = g_strdup_printf("/cpus/cpu@%d", num);
75
if (ms->smp.threads > 1) {
76
map_path = g_strdup_printf(
77
"/cpus/cpu-map/socket%d/core%d/thread%d",
78
@@ -XXX,XX +XXX,XX @@ static void fdt_add_cpu_nodes(const LoongArchVirtMachineState *lvms)
79
num % ms->smp.cores);
80
}
81
qemu_fdt_add_path(ms->fdt, map_path);
82
- qemu_fdt_setprop_phandle(ms->fdt, map_path, "cpu", cpu_path);
83
+ qemu_fdt_setprop_phandle(ms->fdt, map_path, "cpu", nodename);
84
85
g_free(map_path);
86
- g_free(cpu_path);
87
+ g_free(nodename);
88
}
89
}
90
269
--
91
--
270
2.25.1
92
2.43.5
diff view generated by jsdifflib
1
From: Tianrui Zhao <zhaotianrui@loongson.cn>
1
Like LBT feature, add type OnOffAuto for LSX feature setting. Also
2
add LSX feature detection with new VM ioctl command, fallback to old
3
method if it is not supported.
2
4
3
Implement kvm_arch_init_vcpu interface for loongarch,
5
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
4
in this function, we register VM change state handler.
6
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
5
And when VM state changes to running, the counter value
7
---
6
should be put into kvm to keep consistent with kvm,
8
target/loongarch/cpu.c | 38 +++++++++++++++------------
7
and when state change to stop, counter value should be
9
target/loongarch/cpu.h | 2 ++
8
refreshed from kvm.
10
target/loongarch/kvm/kvm.c | 54 ++++++++++++++++++++++++++++++++++++++
11
3 files changed, 77 insertions(+), 17 deletions(-)
9
12
10
Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn>
13
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
11
Signed-off-by: xianglai li <lixianglai@loongson.cn>
14
index XXXXXXX..XXXXXXX 100644
12
Reviewed-by: Song Gao <gaosong@loongson.cn>
15
--- a/target/loongarch/cpu.c
13
Message-Id: <20240105075804.1228596-7-zhaotianrui@loongson.cn>
16
+++ b/target/loongarch/cpu.c
14
Signed-off-by: Song Gao <gaosong@loongson.cn>
17
@@ -XXX,XX +XXX,XX @@ static void loongarch_la464_initfn(Object *obj)
15
---
18
{
16
target/loongarch/cpu.h | 2 ++
19
LoongArchCPU *cpu = LOONGARCH_CPU(obj);
17
target/loongarch/kvm/kvm.c | 23 +++++++++++++++++++++++
20
CPULoongArchState *env = &cpu->env;
18
target/loongarch/trace-events | 2 ++
21
+ uint32_t data = 0;
19
3 files changed, 27 insertions(+)
22
int i;
20
23
24
for (i = 0; i < 21; i++) {
25
@@ -XXX,XX +XXX,XX @@ static void loongarch_la464_initfn(Object *obj)
26
cpu->dtb_compatible = "loongarch,Loongson-3A5000";
27
env->cpucfg[0] = 0x14c010; /* PRID */
28
29
- uint32_t data = 0;
30
data = FIELD_DP32(data, CPUCFG1, ARCH, 2);
31
data = FIELD_DP32(data, CPUCFG1, PGMMU, 1);
32
data = FIELD_DP32(data, CPUCFG1, IOCSR, 1);
33
@@ -XXX,XX +XXX,XX @@ static void loongarch_la132_initfn(Object *obj)
34
{
35
LoongArchCPU *cpu = LOONGARCH_CPU(obj);
36
CPULoongArchState *env = &cpu->env;
37
-
38
+ uint32_t data = 0;
39
int i;
40
41
for (i = 0; i < 21; i++) {
42
@@ -XXX,XX +XXX,XX @@ static void loongarch_la132_initfn(Object *obj)
43
cpu->dtb_compatible = "loongarch,Loongson-1C103";
44
env->cpucfg[0] = 0x148042; /* PRID */
45
46
- uint32_t data = 0;
47
data = FIELD_DP32(data, CPUCFG1, ARCH, 1); /* LA32 */
48
data = FIELD_DP32(data, CPUCFG1, PGMMU, 1);
49
data = FIELD_DP32(data, CPUCFG1, IOCSR, 1);
50
@@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_realizefn(DeviceState *dev, Error **errp)
51
52
static bool loongarch_get_lsx(Object *obj, Error **errp)
53
{
54
- LoongArchCPU *cpu = LOONGARCH_CPU(obj);
55
- bool ret;
56
-
57
- if (FIELD_EX32(cpu->env.cpucfg[2], CPUCFG2, LSX)) {
58
- ret = true;
59
- } else {
60
- ret = false;
61
- }
62
- return ret;
63
+ return LOONGARCH_CPU(obj)->lsx != ON_OFF_AUTO_OFF;
64
}
65
66
static void loongarch_set_lsx(Object *obj, bool value, Error **errp)
67
{
68
LoongArchCPU *cpu = LOONGARCH_CPU(obj);
69
+ uint32_t val;
70
71
- if (value) {
72
- cpu->env.cpucfg[2] = FIELD_DP32(cpu->env.cpucfg[2], CPUCFG2, LSX, 1);
73
- } else {
74
- cpu->env.cpucfg[2] = FIELD_DP32(cpu->env.cpucfg[2], CPUCFG2, LSX, 0);
75
- cpu->env.cpucfg[2] = FIELD_DP32(cpu->env.cpucfg[2], CPUCFG2, LASX, 0);
76
+ cpu->lsx = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
77
+ if (kvm_enabled()) {
78
+ /* kvm feature detection in function kvm_arch_init_vcpu */
79
+ return;
80
}
81
+
82
+ /* LSX feature detection in TCG mode */
83
+ val = cpu->env.cpucfg[2];
84
+ if (cpu->lsx == ON_OFF_AUTO_ON) {
85
+ if (FIELD_EX32(val, CPUCFG2, LSX) == 0) {
86
+ error_setg(errp, "Failed to enable LSX in TCG mode");
87
+ return;
88
+ }
89
+ }
90
+
91
+ cpu->env.cpucfg[2] = FIELD_DP32(val, CPUCFG2, LSX, value);
92
}
93
94
static bool loongarch_get_lasx(Object *obj, Error **errp)
95
@@ -XXX,XX +XXX,XX @@ void loongarch_cpu_post_init(Object *obj)
96
{
97
LoongArchCPU *cpu = LOONGARCH_CPU(obj);
98
99
+ cpu->lsx = ON_OFF_AUTO_AUTO;
100
object_property_add_bool(obj, "lsx", loongarch_get_lsx,
101
loongarch_set_lsx);
102
object_property_add_bool(obj, "lasx", loongarch_get_lasx,
103
@@ -XXX,XX +XXX,XX @@ void loongarch_cpu_post_init(Object *obj)
104
105
} else {
106
cpu->lbt = ON_OFF_AUTO_OFF;
107
+ cpu->pmu = ON_OFF_AUTO_OFF;
108
}
109
}
110
21
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
111
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
22
index XXXXXXX..XXXXXXX 100644
112
index XXXXXXX..XXXXXXX 100644
23
--- a/target/loongarch/cpu.h
113
--- a/target/loongarch/cpu.h
24
+++ b/target/loongarch/cpu.h
114
+++ b/target/loongarch/cpu.h
115
@@ -XXX,XX +XXX,XX @@ typedef struct LoongArchTLB LoongArchTLB;
116
#endif
117
118
enum loongarch_features {
119
+ LOONGARCH_FEATURE_LSX,
120
LOONGARCH_FEATURE_LBT, /* loongson binary translation extension */
121
LOONGARCH_FEATURE_PMU,
122
};
25
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
123
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
124
uint32_t phy_id;
125
OnOffAuto lbt;
126
OnOffAuto pmu;
127
+ OnOffAuto lsx;
26
128
27
/* 'compatible' string for this CPU for Linux device trees */
129
/* 'compatible' string for this CPU for Linux device trees */
28
const char *dtb_compatible;
130
const char *dtb_compatible;
29
+ /* used by KVM_REG_LOONGARCH_COUNTER ioctl to access guest time counters */
30
+ uint64_t kvm_state_counter;
31
};
32
33
/**
34
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
131
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
35
index XXXXXXX..XXXXXXX 100644
132
index XXXXXXX..XXXXXXX 100644
36
--- a/target/loongarch/kvm/kvm.c
133
--- a/target/loongarch/kvm/kvm.c
37
+++ b/target/loongarch/kvm/kvm.c
134
+++ b/target/loongarch/kvm/kvm.c
38
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
135
@@ -XXX,XX +XXX,XX @@ static bool kvm_feature_supported(CPUState *cs, enum loongarch_features feature)
39
return ret;
136
{
40
}
137
int ret;
41
138
struct kvm_device_attr attr;
42
+static void kvm_loongarch_vm_stage_change(void *opaque, bool running,
139
+ uint64_t val;
43
+ RunState state)
140
141
switch (feature) {
142
+ case LOONGARCH_FEATURE_LSX:
143
+ attr.group = KVM_LOONGARCH_VM_FEAT_CTRL;
144
+ attr.attr = KVM_LOONGARCH_VM_FEAT_LSX;
145
+ ret = kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr);
146
+ if (ret == 0) {
147
+ return true;
148
+ }
149
+
150
+ /* Fallback to old kernel detect interface */
151
+ val = 0;
152
+ attr.group = KVM_LOONGARCH_VCPU_CPUCFG;
153
+ /* Cpucfg2 */
154
+ attr.attr = 2;
155
+ attr.addr = (uint64_t)&val;
156
+ ret = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, &attr);
157
+ if (!ret) {
158
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_DEVICE_ATTR, &attr);
159
+ if (ret) {
160
+ return false;
161
+ }
162
+
163
+ ret = FIELD_EX32((uint32_t)val, CPUCFG2, LSX);
164
+ return (ret != 0);
165
+ }
166
+ return false;
167
+
168
case LOONGARCH_FEATURE_LBT:
169
/*
170
* Return all if all the LBT features are supported such as:
171
@@ -XXX,XX +XXX,XX @@ static bool kvm_feature_supported(CPUState *cs, enum loongarch_features feature)
172
return false;
173
}
174
175
+static int kvm_cpu_check_lsx(CPUState *cs, Error **errp)
44
+{
176
+{
45
+ int ret;
177
+ CPULoongArchState *env = cpu_env(cs);
46
+ CPUState *cs = opaque;
47
+ LoongArchCPU *cpu = LOONGARCH_CPU(cs);
178
+ LoongArchCPU *cpu = LOONGARCH_CPU(cs);
48
+
179
+ bool kvm_supported;
49
+ if (running) {
180
+
50
+ ret = kvm_set_one_reg(cs, KVM_REG_LOONGARCH_COUNTER,
181
+ kvm_supported = kvm_feature_supported(cs, LOONGARCH_FEATURE_LSX);
51
+ &cpu->kvm_state_counter);
182
+ env->cpucfg[2] = FIELD_DP32(env->cpucfg[2], CPUCFG2, LSX, 0);
52
+ if (ret < 0) {
183
+ if (cpu->lsx == ON_OFF_AUTO_ON) {
53
+ trace_kvm_failed_put_counter(strerror(errno));
184
+ if (kvm_supported) {
54
+ }
185
+ env->cpucfg[2] = FIELD_DP32(env->cpucfg[2], CPUCFG2, LSX, 1);
55
+ } else {
186
+ } else {
56
+ ret = kvm_get_one_reg(cs, KVM_REG_LOONGARCH_COUNTER,
187
+ error_setg(errp, "'lsx' feature not supported by KVM on this host");
57
+ &cpu->kvm_state_counter);
188
+ return -ENOTSUP;
58
+ if (ret < 0) {
189
+ }
59
+ trace_kvm_failed_get_counter(strerror(errno));
190
+ } else if ((cpu->lsx == ON_OFF_AUTO_AUTO) && kvm_supported) {
60
+ }
191
+ env->cpucfg[2] = FIELD_DP32(env->cpucfg[2], CPUCFG2, LSX, 1);
61
+ }
192
+ }
193
+
194
+ return 0;
62
+}
195
+}
63
+
196
+
64
int kvm_arch_init_vcpu(CPUState *cs)
197
static int kvm_cpu_check_lbt(CPUState *cs, Error **errp)
65
{
198
{
66
+ qemu_add_vm_change_state_handler(kvm_loongarch_vm_stage_change, cs);
199
CPULoongArchState *env = cpu_env(cs);
67
return 0;
200
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
68
}
201
brk_insn = val;
69
202
}
70
diff --git a/target/loongarch/trace-events b/target/loongarch/trace-events
203
71
index XXXXXXX..XXXXXXX 100644
204
+ ret = kvm_cpu_check_lsx(cs, &local_err);
72
--- a/target/loongarch/trace-events
205
+ if (ret < 0) {
73
+++ b/target/loongarch/trace-events
206
+ error_report_err(local_err);
74
@@ -XXX,XX +XXX,XX @@ kvm_failed_get_fpu(const char *msg) "Failed to get fpu from KVM: %s"
207
+ }
75
kvm_failed_put_fpu(const char *msg) "Failed to put fpu into KVM: %s"
208
+
76
kvm_failed_get_mpstate(const char *msg) "Failed to get mp_state from KVM: %s"
209
ret = kvm_cpu_check_lbt(cs, &local_err);
77
kvm_failed_put_mpstate(const char *msg) "Failed to put mp_state into KVM: %s"
210
if (ret < 0) {
78
+kvm_failed_get_counter(const char *msg) "Failed to get counter from KVM: %s"
211
error_report_err(local_err);
79
+kvm_failed_put_counter(const char *msg) "Failed to put counter into KVM: %s"
80
kvm_failed_get_cpucfg(const char *msg) "Failed to get cpucfg from KVM: %s"
81
kvm_failed_put_cpucfg(const char *msg) "Failed to put cpucfg into KVM: %s"
82
--
212
--
83
2.25.1
213
2.43.5
diff view generated by jsdifflib
1
From: Tianrui Zhao <zhaotianrui@loongson.cn>
1
Like LSX feature, add type OnOffAuto for LASX feature setting.
2
2
3
Implement kvm_arch_get/set_registers interfaces, many regs
3
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
4
can be get/set in the function, such as core regs, csr regs,
4
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
5
fpu regs, mp state, etc.
5
---
6
target/loongarch/cpu.c | 50 +++++++++++++++++++++++------------
7
target/loongarch/cpu.h | 2 ++
8
target/loongarch/kvm/kvm.c | 53 ++++++++++++++++++++++++++++++++++++++
9
3 files changed, 89 insertions(+), 16 deletions(-)
6
10
7
Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn>
8
Signed-off-by: xianglai li <lixianglai@loongson.cn>
9
Reviewed-by: Song Gao <gaosong@loongson.cn>
10
Change-Id: Ia8fc48fe08b1768853f7729e77d37cdf270031e4
11
Message-Id: <20240105075804.1228596-5-zhaotianrui@loongson.cn>
12
Signed-off-by: Song Gao <gaosong@loongson.cn>
13
---
14
meson.build | 1 +
15
target/loongarch/cpu.c | 3 +
16
target/loongarch/cpu.h | 1 +
17
target/loongarch/internals.h | 5 +-
18
target/loongarch/kvm/kvm.c | 580 +++++++++++++++++++++++++++++++++-
19
target/loongarch/trace-events | 11 +
20
target/loongarch/trace.h | 1 +
21
7 files changed, 599 insertions(+), 3 deletions(-)
22
create mode 100644 target/loongarch/trace-events
23
create mode 100644 target/loongarch/trace.h
24
25
diff --git a/meson.build b/meson.build
26
index XXXXXXX..XXXXXXX 100644
27
--- a/meson.build
28
+++ b/meson.build
29
@@ -XXX,XX +XXX,XX @@ if have_system or have_user
30
'target/hppa',
31
'target/i386',
32
'target/i386/kvm',
33
+ 'target/loongarch',
34
'target/mips/tcg',
35
'target/nios2',
36
'target/ppc',
37
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
11
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
38
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
39
--- a/target/loongarch/cpu.c
13
--- a/target/loongarch/cpu.c
40
+++ b/target/loongarch/cpu.c
14
+++ b/target/loongarch/cpu.c
41
@@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_reset_hold(Object *obj)
15
@@ -XXX,XX +XXX,XX @@ static void loongarch_set_lsx(Object *obj, bool value, Error **errp)
42
#ifndef CONFIG_USER_ONLY
16
uint32_t val;
43
env->pc = 0x1c000000;
17
44
memset(env->tlb, 0, sizeof(env->tlb));
18
cpu->lsx = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
19
+ if (cpu->lsx == ON_OFF_AUTO_OFF) {
20
+ cpu->lasx = ON_OFF_AUTO_OFF;
21
+ if (cpu->lasx == ON_OFF_AUTO_ON) {
22
+ error_setg(errp, "Failed to disable LSX since LASX is enabled");
23
+ return;
24
+ }
25
+ }
26
+
27
if (kvm_enabled()) {
28
/* kvm feature detection in function kvm_arch_init_vcpu */
29
return;
30
@@ -XXX,XX +XXX,XX @@ static void loongarch_set_lsx(Object *obj, bool value, Error **errp)
31
error_setg(errp, "Failed to enable LSX in TCG mode");
32
return;
33
}
34
+ } else {
35
+ cpu->env.cpucfg[2] = FIELD_DP32(val, CPUCFG2, LASX, 0);
36
+ val = cpu->env.cpucfg[2];
37
}
38
39
cpu->env.cpucfg[2] = FIELD_DP32(val, CPUCFG2, LSX, value);
40
@@ -XXX,XX +XXX,XX @@ static void loongarch_set_lsx(Object *obj, bool value, Error **errp)
41
42
static bool loongarch_get_lasx(Object *obj, Error **errp)
43
{
44
- LoongArchCPU *cpu = LOONGARCH_CPU(obj);
45
- bool ret;
46
-
47
- if (FIELD_EX32(cpu->env.cpucfg[2], CPUCFG2, LASX)) {
48
- ret = true;
49
- } else {
50
- ret = false;
51
- }
52
- return ret;
53
+ return LOONGARCH_CPU(obj)->lasx != ON_OFF_AUTO_OFF;
54
}
55
56
static void loongarch_set_lasx(Object *obj, bool value, Error **errp)
57
{
58
LoongArchCPU *cpu = LOONGARCH_CPU(obj);
59
+ uint32_t val;
60
61
- if (value) {
62
-    if (!FIELD_EX32(cpu->env.cpucfg[2], CPUCFG2, LSX)) {
63
- cpu->env.cpucfg[2] = FIELD_DP32(cpu->env.cpucfg[2], CPUCFG2, LSX, 1);
64
-    }
65
- cpu->env.cpucfg[2] = FIELD_DP32(cpu->env.cpucfg[2], CPUCFG2, LASX, 1);
66
- } else {
67
- cpu->env.cpucfg[2] = FIELD_DP32(cpu->env.cpucfg[2], CPUCFG2, LASX, 0);
68
+ cpu->lasx = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
69
+ if ((cpu->lsx == ON_OFF_AUTO_OFF) && (cpu->lasx == ON_OFF_AUTO_ON)) {
70
+ error_setg(errp, "Failed to enable LASX since lSX is disabled");
71
+ return;
72
+ }
73
+
45
+ if (kvm_enabled()) {
74
+ if (kvm_enabled()) {
46
+ kvm_arch_reset_vcpu(env);
75
+ /* kvm feature detection in function kvm_arch_init_vcpu */
76
+ return;
77
}
78
+
79
+ /* LASX feature detection in TCG mode */
80
+ val = cpu->env.cpucfg[2];
81
+ if (cpu->lasx == ON_OFF_AUTO_ON) {
82
+ if (FIELD_EX32(val, CPUCFG2, LASX) == 0) {
83
+ error_setg(errp, "Failed to enable LASX in TCG mode");
84
+ return;
85
+ }
47
+ }
86
+ }
48
#endif
87
+
49
88
+ cpu->env.cpucfg[2] = FIELD_DP32(val, CPUCFG2, LASX, value);
50
restore_fp_status(env);
89
}
90
91
static bool loongarch_get_lbt(Object *obj, Error **errp)
92
@@ -XXX,XX +XXX,XX @@ void loongarch_cpu_post_init(Object *obj)
93
LoongArchCPU *cpu = LOONGARCH_CPU(obj);
94
95
cpu->lsx = ON_OFF_AUTO_AUTO;
96
+ cpu->lasx = ON_OFF_AUTO_AUTO;
97
object_property_add_bool(obj, "lsx", loongarch_get_lsx,
98
loongarch_set_lsx);
99
object_property_add_bool(obj, "lasx", loongarch_get_lasx,
51
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
100
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
52
index XXXXXXX..XXXXXXX 100644
101
index XXXXXXX..XXXXXXX 100644
53
--- a/target/loongarch/cpu.h
102
--- a/target/loongarch/cpu.h
54
+++ b/target/loongarch/cpu.h
103
+++ b/target/loongarch/cpu.h
55
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
104
@@ -XXX,XX +XXX,XX @@ typedef struct LoongArchTLB LoongArchTLB;
56
MemoryRegion iocsr_mem;
105
57
bool load_elf;
106
enum loongarch_features {
58
uint64_t elf_address;
107
LOONGARCH_FEATURE_LSX,
59
+ uint32_t mp_state;
108
+ LOONGARCH_FEATURE_LASX,
60
/* Store ipistate to access from this struct */
109
LOONGARCH_FEATURE_LBT, /* loongson binary translation extension */
61
DeviceState *ipistate;
110
LOONGARCH_FEATURE_PMU,
62
#endif
111
};
63
diff --git a/target/loongarch/internals.h b/target/loongarch/internals.h
112
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
64
index XXXXXXX..XXXXXXX 100644
113
OnOffAuto lbt;
65
--- a/target/loongarch/internals.h
114
OnOffAuto pmu;
66
+++ b/target/loongarch/internals.h
115
OnOffAuto lsx;
67
@@ -XXX,XX +XXX,XX @@ void G_NORETURN do_raise_exception(CPULoongArchState *env,
116
+ OnOffAuto lasx;
68
117
69
const char *loongarch_exception_name(int32_t exception);
118
/* 'compatible' string for this CPU for Linux device trees */
70
119
const char *dtb_compatible;
71
+#ifdef CONFIG_TCG
72
int ieee_ex_to_loongarch(int xcpt);
73
void restore_fp_status(CPULoongArchState *env);
74
+#endif
75
76
#ifndef CONFIG_USER_ONLY
77
extern const VMStateDescription vmstate_loongarch_cpu;
78
@@ -XXX,XX +XXX,XX @@ uint64_t cpu_loongarch_get_constant_timer_counter(LoongArchCPU *cpu);
79
uint64_t cpu_loongarch_get_constant_timer_ticks(LoongArchCPU *cpu);
80
void cpu_loongarch_store_constant_timer_config(LoongArchCPU *cpu,
81
uint64_t value);
82
-
83
+#ifdef CONFIG_TCG
84
bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
85
MMUAccessType access_type, int mmu_idx,
86
bool probe, uintptr_t retaddr);
87
88
hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
89
+#endif
90
#endif /* !CONFIG_USER_ONLY */
91
92
uint64_t read_fcc(CPULoongArchState *env);
93
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
120
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
94
index XXXXXXX..XXXXXXX 100644
121
index XXXXXXX..XXXXXXX 100644
95
--- a/target/loongarch/kvm/kvm.c
122
--- a/target/loongarch/kvm/kvm.c
96
+++ b/target/loongarch/kvm/kvm.c
123
+++ b/target/loongarch/kvm/kvm.c
97
@@ -XXX,XX +XXX,XX @@
124
@@ -XXX,XX +XXX,XX @@ static bool kvm_feature_supported(CPUState *cs, enum loongarch_features feature)
98
#include "sysemu/runstate.h"
125
}
99
#include "cpu-csr.h"
126
return false;
100
#include "kvm_loongarch.h"
127
101
+#include "trace.h"
128
+ case LOONGARCH_FEATURE_LASX:
102
129
+ attr.group = KVM_LOONGARCH_VM_FEAT_CTRL;
103
static bool cap_has_mp_state;
130
+ attr.attr = KVM_LOONGARCH_VM_FEAT_LASX;
104
const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
131
+ ret = kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr);
105
KVM_CAP_LAST_INFO
132
+ if (ret == 0) {
106
};
133
+ return true;
107
134
+ }
108
+static int kvm_loongarch_get_regs_core(CPUState *cs)
135
+
136
+ /* Fallback to old kernel detect interface */
137
+ val = 0;
138
+ attr.group = KVM_LOONGARCH_VCPU_CPUCFG;
139
+ /* Cpucfg2 */
140
+ attr.attr = 2;
141
+ attr.addr = (uint64_t)&val;
142
+ ret = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, &attr);
143
+ if (!ret) {
144
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_DEVICE_ATTR, &attr);
145
+ if (ret) {
146
+ return false;
147
+ }
148
+
149
+ ret = FIELD_EX32((uint32_t)val, CPUCFG2, LASX);
150
+ return (ret != 0);
151
+ }
152
+ return false;
153
+
154
case LOONGARCH_FEATURE_LBT:
155
/*
156
* Return all if all the LBT features are supported such as:
157
@@ -XXX,XX +XXX,XX @@ static int kvm_cpu_check_lsx(CPUState *cs, Error **errp)
158
return 0;
159
}
160
161
+static int kvm_cpu_check_lasx(CPUState *cs, Error **errp)
109
+{
162
+{
110
+ int ret = 0;
163
+ CPULoongArchState *env = cpu_env(cs);
111
+ int i;
112
+ struct kvm_regs regs;
113
+ LoongArchCPU *cpu = LOONGARCH_CPU(cs);
164
+ LoongArchCPU *cpu = LOONGARCH_CPU(cs);
114
+ CPULoongArchState *env = &cpu->env;
165
+ bool kvm_supported;
115
+
166
+
116
+ /* Get the current register set as KVM seems it */
167
+ kvm_supported = kvm_feature_supported(cs, LOONGARCH_FEATURE_LASX);
117
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_REGS, &regs);
168
+ env->cpucfg[2] = FIELD_DP32(env->cpucfg[2], CPUCFG2, LASX, 0);
118
+ if (ret < 0) {
169
+ if (cpu->lasx == ON_OFF_AUTO_ON) {
119
+ trace_kvm_failed_get_regs_core(strerror(errno));
170
+ if (kvm_supported) {
120
+ return ret;
171
+ env->cpucfg[2] = FIELD_DP32(env->cpucfg[2], CPUCFG2, LASX, 1);
121
+ }
172
+ } else {
122
+ /* gpr[0] value is always 0 */
173
+ error_setg(errp, "'lasx' feature not supported by KVM on host");
123
+ env->gpr[0] = 0;
174
+ return -ENOTSUP;
124
+ for (i = 1; i < 32; i++) {
175
+ }
125
+ env->gpr[i] = regs.gpr[i];
176
+ } else if ((cpu->lasx == ON_OFF_AUTO_AUTO) && kvm_supported) {
177
+ env->cpucfg[2] = FIELD_DP32(env->cpucfg[2], CPUCFG2, LASX, 1);
126
+ }
178
+ }
127
+
179
+
128
+ env->pc = regs.pc;
180
+ return 0;
129
+ return ret;
130
+}
181
+}
131
+
182
+
132
+static int kvm_loongarch_put_regs_core(CPUState *cs)
183
static int kvm_cpu_check_lbt(CPUState *cs, Error **errp)
133
+{
184
{
134
+ int ret = 0;
185
CPULoongArchState *env = cpu_env(cs);
135
+ int i;
186
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
136
+ struct kvm_regs regs;
187
error_report_err(local_err);
137
+ LoongArchCPU *cpu = LOONGARCH_CPU(cs);
188
}
138
+ CPULoongArchState *env = &cpu->env;
189
139
+
190
+ ret = kvm_cpu_check_lasx(cs, &local_err);
140
+ /* Set the registers based on QEMU's view of things */
191
+ if (ret < 0) {
141
+ for (i = 0; i < 32; i++) {
192
+ error_report_err(local_err);
142
+ regs.gpr[i] = env->gpr[i];
143
+ }
193
+ }
144
+
194
+
145
+ regs.pc = env->pc;
195
ret = kvm_cpu_check_lbt(cs, &local_err);
146
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_REGS, &regs);
196
if (ret < 0) {
147
+ if (ret < 0) {
197
error_report_err(local_err);
148
+ trace_kvm_failed_put_regs_core(strerror(errno));
149
+ }
150
+
151
+ return ret;
152
+}
153
+
154
+static int kvm_loongarch_get_csr(CPUState *cs)
155
+{
156
+ int ret = 0;
157
+ LoongArchCPU *cpu = LOONGARCH_CPU(cs);
158
+ CPULoongArchState *env = &cpu->env;
159
+
160
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CRMD),
161
+ &env->CSR_CRMD);
162
+
163
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRMD),
164
+ &env->CSR_PRMD);
165
+
166
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EUEN),
167
+ &env->CSR_EUEN);
168
+
169
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_MISC),
170
+ &env->CSR_MISC);
171
+
172
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ECFG),
173
+ &env->CSR_ECFG);
174
+
175
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ESTAT),
176
+ &env->CSR_ESTAT);
177
+
178
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ERA),
179
+ &env->CSR_ERA);
180
+
181
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADV),
182
+ &env->CSR_BADV);
183
+
184
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADI),
185
+ &env->CSR_BADI);
186
+
187
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EENTRY),
188
+ &env->CSR_EENTRY);
189
+
190
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBIDX),
191
+ &env->CSR_TLBIDX);
192
+
193
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBEHI),
194
+ &env->CSR_TLBEHI);
195
+
196
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO0),
197
+ &env->CSR_TLBELO0);
198
+
199
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO1),
200
+ &env->CSR_TLBELO1);
201
+
202
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ASID),
203
+ &env->CSR_ASID);
204
+
205
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDL),
206
+ &env->CSR_PGDL);
207
+
208
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDH),
209
+ &env->CSR_PGDH);
210
+
211
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGD),
212
+ &env->CSR_PGD);
213
+
214
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCL),
215
+ &env->CSR_PWCL);
216
+
217
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCH),
218
+ &env->CSR_PWCH);
219
+
220
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_STLBPS),
221
+ &env->CSR_STLBPS);
222
+
223
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_RVACFG),
224
+ &env->CSR_RVACFG);
225
+
226
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CPUID),
227
+ &env->CSR_CPUID);
228
+
229
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG1),
230
+ &env->CSR_PRCFG1);
231
+
232
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG2),
233
+ &env->CSR_PRCFG2);
234
+
235
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG3),
236
+ &env->CSR_PRCFG3);
237
+
238
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(0)),
239
+ &env->CSR_SAVE[0]);
240
+
241
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(1)),
242
+ &env->CSR_SAVE[1]);
243
+
244
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(2)),
245
+ &env->CSR_SAVE[2]);
246
+
247
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(3)),
248
+ &env->CSR_SAVE[3]);
249
+
250
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(4)),
251
+ &env->CSR_SAVE[4]);
252
+
253
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(5)),
254
+ &env->CSR_SAVE[5]);
255
+
256
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(6)),
257
+ &env->CSR_SAVE[6]);
258
+
259
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(7)),
260
+ &env->CSR_SAVE[7]);
261
+
262
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TID),
263
+ &env->CSR_TID);
264
+
265
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CNTC),
266
+ &env->CSR_CNTC);
267
+
268
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TICLR),
269
+ &env->CSR_TICLR);
270
+
271
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_LLBCTL),
272
+ &env->CSR_LLBCTL);
273
+
274
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL1),
275
+ &env->CSR_IMPCTL1);
276
+
277
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL2),
278
+ &env->CSR_IMPCTL2);
279
+
280
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRENTRY),
281
+ &env->CSR_TLBRENTRY);
282
+
283
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRBADV),
284
+ &env->CSR_TLBRBADV);
285
+
286
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRERA),
287
+ &env->CSR_TLBRERA);
288
+
289
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRSAVE),
290
+ &env->CSR_TLBRSAVE);
291
+
292
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO0),
293
+ &env->CSR_TLBRELO0);
294
+
295
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO1),
296
+ &env->CSR_TLBRELO1);
297
+
298
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBREHI),
299
+ &env->CSR_TLBREHI);
300
+
301
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRPRMD),
302
+ &env->CSR_TLBRPRMD);
303
+
304
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(0)),
305
+ &env->CSR_DMW[0]);
306
+
307
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(1)),
308
+ &env->CSR_DMW[1]);
309
+
310
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(2)),
311
+ &env->CSR_DMW[2]);
312
+
313
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(3)),
314
+ &env->CSR_DMW[3]);
315
+
316
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TVAL),
317
+ &env->CSR_TVAL);
318
+
319
+ ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TCFG),
320
+ &env->CSR_TCFG);
321
+
322
+ return ret;
323
+}
324
+
325
+static int kvm_loongarch_put_csr(CPUState *cs)
326
+{
327
+ int ret = 0;
328
+ LoongArchCPU *cpu = LOONGARCH_CPU(cs);
329
+ CPULoongArchState *env = &cpu->env;
330
+
331
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CRMD),
332
+ &env->CSR_CRMD);
333
+
334
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRMD),
335
+ &env->CSR_PRMD);
336
+
337
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EUEN),
338
+ &env->CSR_EUEN);
339
+
340
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_MISC),
341
+ &env->CSR_MISC);
342
+
343
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ECFG),
344
+ &env->CSR_ECFG);
345
+
346
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ESTAT),
347
+ &env->CSR_ESTAT);
348
+
349
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ERA),
350
+ &env->CSR_ERA);
351
+
352
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADV),
353
+ &env->CSR_BADV);
354
+
355
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADI),
356
+ &env->CSR_BADI);
357
+
358
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EENTRY),
359
+ &env->CSR_EENTRY);
360
+
361
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBIDX),
362
+ &env->CSR_TLBIDX);
363
+
364
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBEHI),
365
+ &env->CSR_TLBEHI);
366
+
367
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO0),
368
+ &env->CSR_TLBELO0);
369
+
370
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO1),
371
+ &env->CSR_TLBELO1);
372
+
373
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ASID),
374
+ &env->CSR_ASID);
375
+
376
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDL),
377
+ &env->CSR_PGDL);
378
+
379
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDH),
380
+ &env->CSR_PGDH);
381
+
382
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGD),
383
+ &env->CSR_PGD);
384
+
385
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCL),
386
+ &env->CSR_PWCL);
387
+
388
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCH),
389
+ &env->CSR_PWCH);
390
+
391
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_STLBPS),
392
+ &env->CSR_STLBPS);
393
+
394
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_RVACFG),
395
+ &env->CSR_RVACFG);
396
+
397
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CPUID),
398
+ &env->CSR_CPUID);
399
+
400
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG1),
401
+ &env->CSR_PRCFG1);
402
+
403
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG2),
404
+ &env->CSR_PRCFG2);
405
+
406
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG3),
407
+ &env->CSR_PRCFG3);
408
+
409
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(0)),
410
+ &env->CSR_SAVE[0]);
411
+
412
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(1)),
413
+ &env->CSR_SAVE[1]);
414
+
415
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(2)),
416
+ &env->CSR_SAVE[2]);
417
+
418
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(3)),
419
+ &env->CSR_SAVE[3]);
420
+
421
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(4)),
422
+ &env->CSR_SAVE[4]);
423
+
424
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(5)),
425
+ &env->CSR_SAVE[5]);
426
+
427
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(6)),
428
+ &env->CSR_SAVE[6]);
429
+
430
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(7)),
431
+ &env->CSR_SAVE[7]);
432
+
433
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TID),
434
+ &env->CSR_TID);
435
+
436
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CNTC),
437
+ &env->CSR_CNTC);
438
+
439
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TICLR),
440
+ &env->CSR_TICLR);
441
+
442
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_LLBCTL),
443
+ &env->CSR_LLBCTL);
444
+
445
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL1),
446
+ &env->CSR_IMPCTL1);
447
+
448
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL2),
449
+ &env->CSR_IMPCTL2);
450
+
451
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRENTRY),
452
+ &env->CSR_TLBRENTRY);
453
+
454
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRBADV),
455
+ &env->CSR_TLBRBADV);
456
+
457
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRERA),
458
+ &env->CSR_TLBRERA);
459
+
460
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRSAVE),
461
+ &env->CSR_TLBRSAVE);
462
+
463
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO0),
464
+ &env->CSR_TLBRELO0);
465
+
466
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO1),
467
+ &env->CSR_TLBRELO1);
468
+
469
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBREHI),
470
+ &env->CSR_TLBREHI);
471
+
472
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRPRMD),
473
+ &env->CSR_TLBRPRMD);
474
+
475
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(0)),
476
+ &env->CSR_DMW[0]);
477
+
478
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(1)),
479
+ &env->CSR_DMW[1]);
480
+
481
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(2)),
482
+ &env->CSR_DMW[2]);
483
+
484
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(3)),
485
+ &env->CSR_DMW[3]);
486
+ /*
487
+ * timer cfg must be put at last since it is used to enable
488
+ * guest timer
489
+ */
490
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TVAL),
491
+ &env->CSR_TVAL);
492
+
493
+ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TCFG),
494
+ &env->CSR_TCFG);
495
+ return ret;
496
+}
497
+
498
+static int kvm_loongarch_get_regs_fp(CPUState *cs)
499
+{
500
+ int ret, i;
501
+ struct kvm_fpu fpu;
502
+
503
+ LoongArchCPU *cpu = LOONGARCH_CPU(cs);
504
+ CPULoongArchState *env = &cpu->env;
505
+
506
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_FPU, &fpu);
507
+ if (ret < 0) {
508
+ trace_kvm_failed_get_fpu(strerror(errno));
509
+ return ret;
510
+ }
511
+
512
+ env->fcsr0 = fpu.fcsr;
513
+ for (i = 0; i < 32; i++) {
514
+ env->fpr[i].vreg.UD[0] = fpu.fpr[i].val64[0];
515
+ }
516
+ for (i = 0; i < 8; i++) {
517
+ env->cf[i] = fpu.fcc & 0xFF;
518
+ fpu.fcc = fpu.fcc >> 8;
519
+ }
520
+
521
+ return ret;
522
+}
523
+
524
+static int kvm_loongarch_put_regs_fp(CPUState *cs)
525
+{
526
+ int ret, i;
527
+ struct kvm_fpu fpu;
528
+
529
+ LoongArchCPU *cpu = LOONGARCH_CPU(cs);
530
+ CPULoongArchState *env = &cpu->env;
531
+
532
+ fpu.fcsr = env->fcsr0;
533
+ fpu.fcc = 0;
534
+ for (i = 0; i < 32; i++) {
535
+ fpu.fpr[i].val64[0] = env->fpr[i].vreg.UD[0];
536
+ }
537
+
538
+ for (i = 0; i < 8; i++) {
539
+ fpu.fcc |= env->cf[i] << (8 * i);
540
+ }
541
+
542
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_FPU, &fpu);
543
+ if (ret < 0) {
544
+ trace_kvm_failed_put_fpu(strerror(errno));
545
+ }
546
+
547
+ return ret;
548
+}
549
+
550
+void kvm_arch_reset_vcpu(CPULoongArchState *env)
551
+{
552
+ env->mp_state = KVM_MP_STATE_RUNNABLE;
553
+}
554
+
555
+static int kvm_loongarch_get_mpstate(CPUState *cs)
556
+{
557
+ int ret = 0;
558
+ struct kvm_mp_state mp_state;
559
+ LoongArchCPU *cpu = LOONGARCH_CPU(cs);
560
+ CPULoongArchState *env = &cpu->env;
561
+
562
+ if (cap_has_mp_state) {
563
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_MP_STATE, &mp_state);
564
+ if (ret) {
565
+ trace_kvm_failed_get_mpstate(strerror(errno));
566
+ return ret;
567
+ }
568
+ env->mp_state = mp_state.mp_state;
569
+ }
570
+
571
+ return ret;
572
+}
573
+
574
+static int kvm_loongarch_put_mpstate(CPUState *cs)
575
+{
576
+ int ret = 0;
577
+
578
+ LoongArchCPU *cpu = LOONGARCH_CPU(cs);
579
+ CPULoongArchState *env = &cpu->env;
580
+
581
+ struct kvm_mp_state mp_state = {
582
+ .mp_state = env->mp_state
583
+ };
584
+
585
+ if (cap_has_mp_state) {
586
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_MP_STATE, &mp_state);
587
+ if (ret) {
588
+ trace_kvm_failed_put_mpstate(strerror(errno));
589
+ }
590
+ }
591
+
592
+ return ret;
593
+}
594
+
595
+static int kvm_loongarch_get_cpucfg(CPUState *cs)
596
+{
597
+ int i, ret = 0;
598
+ uint64_t val;
599
+ LoongArchCPU *cpu = LOONGARCH_CPU(cs);
600
+ CPULoongArchState *env = &cpu->env;
601
+
602
+ for (i = 0; i < 21; i++) {
603
+ ret = kvm_get_one_reg(cs, KVM_IOC_CPUCFG(i), &val);
604
+ if (ret < 0) {
605
+ trace_kvm_failed_get_cpucfg(strerror(errno));
606
+ }
607
+ env->cpucfg[i] = (uint32_t)val;
608
+ }
609
+ return ret;
610
+}
611
+
612
+static int kvm_loongarch_put_cpucfg(CPUState *cs)
613
+{
614
+ int i, ret = 0;
615
+ LoongArchCPU *cpu = LOONGARCH_CPU(cs);
616
+ CPULoongArchState *env = &cpu->env;
617
+ uint64_t val;
618
+
619
+ for (i = 0; i < 21; i++) {
620
+ val = env->cpucfg[i];
621
+ /* LSX and LASX and LBT are not supported in kvm now */
622
+ if (i == 2) {
623
+ val &= ~(BIT(R_CPUCFG2_LSX_SHIFT) | BIT(R_CPUCFG2_LASX_SHIFT));
624
+ val &= ~(BIT(R_CPUCFG2_LBT_X86_SHIFT) |
625
+ BIT(R_CPUCFG2_LBT_ARM_SHIFT) |
626
+ BIT(R_CPUCFG2_LBT_MIPS_SHIFT));
627
+ }
628
+ ret = kvm_set_one_reg(cs, KVM_IOC_CPUCFG(i), &val);
629
+ if (ret < 0) {
630
+ trace_kvm_failed_put_cpucfg(strerror(errno));
631
+ }
632
+ }
633
+ return ret;
634
+}
635
+
636
int kvm_arch_get_registers(CPUState *cs)
637
{
638
- return 0;
639
+ int ret;
640
+
641
+ ret = kvm_loongarch_get_regs_core(cs);
642
+ if (ret) {
643
+ return ret;
644
+ }
645
+
646
+ ret = kvm_loongarch_get_csr(cs);
647
+ if (ret) {
648
+ return ret;
649
+ }
650
+
651
+ ret = kvm_loongarch_get_regs_fp(cs);
652
+ if (ret) {
653
+ return ret;
654
+ }
655
+
656
+ ret = kvm_loongarch_get_mpstate(cs);
657
+ if (ret) {
658
+ return ret;
659
+ }
660
+
661
+ ret = kvm_loongarch_get_cpucfg(cs);
662
+ return ret;
663
}
664
+
665
int kvm_arch_put_registers(CPUState *cs, int level)
666
{
667
- return 0;
668
+ int ret;
669
+
670
+ ret = kvm_loongarch_put_regs_core(cs);
671
+ if (ret) {
672
+ return ret;
673
+ }
674
+
675
+ ret = kvm_loongarch_put_csr(cs);
676
+ if (ret) {
677
+ return ret;
678
+ }
679
+
680
+ ret = kvm_loongarch_put_regs_fp(cs);
681
+ if (ret) {
682
+ return ret;
683
+ }
684
+
685
+ ret = kvm_loongarch_put_mpstate(cs);
686
+ if (ret) {
687
+ return ret;
688
+ }
689
+
690
+ ret = kvm_loongarch_put_cpucfg(cs);
691
+ return ret;
692
}
693
694
int kvm_arch_init_vcpu(CPUState *cs)
695
diff --git a/target/loongarch/trace-events b/target/loongarch/trace-events
696
new file mode 100644
697
index XXXXXXX..XXXXXXX
698
--- /dev/null
699
+++ b/target/loongarch/trace-events
700
@@ -XXX,XX +XXX,XX @@
701
+# See docs/devel/tracing.rst for syntax documentation.
702
+
703
+#kvm.c
704
+kvm_failed_get_regs_core(const char *msg) "Failed to get core regs from KVM: %s"
705
+kvm_failed_put_regs_core(const char *msg) "Failed to put core regs into KVM: %s"
706
+kvm_failed_get_fpu(const char *msg) "Failed to get fpu from KVM: %s"
707
+kvm_failed_put_fpu(const char *msg) "Failed to put fpu into KVM: %s"
708
+kvm_failed_get_mpstate(const char *msg) "Failed to get mp_state from KVM: %s"
709
+kvm_failed_put_mpstate(const char *msg) "Failed to put mp_state into KVM: %s"
710
+kvm_failed_get_cpucfg(const char *msg) "Failed to get cpucfg from KVM: %s"
711
+kvm_failed_put_cpucfg(const char *msg) "Failed to put cpucfg into KVM: %s"
712
diff --git a/target/loongarch/trace.h b/target/loongarch/trace.h
713
new file mode 100644
714
index XXXXXXX..XXXXXXX
715
--- /dev/null
716
+++ b/target/loongarch/trace.h
717
@@ -0,0 +1 @@
718
+#include "trace/trace-target_loongarch.h"
719
--
198
--
720
2.25.1
199
2.43.5
diff view generated by jsdifflib
Deleted patch
1
From: Tianrui Zhao <zhaotianrui@loongson.cn>
2
1
3
Implement the kvm_arch_init of loongarch, in the function, the
4
KVM_CAP_MP_STATE cap is checked by kvm ioctl.
5
6
Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn>
7
Signed-off-by: xianglai li <lixianglai@loongson.cn>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Song Gao <gaosong@loongson.cn>
10
Message-Id: <20240105075804.1228596-6-zhaotianrui@loongson.cn>
11
Signed-off-by: Song Gao <gaosong@loongson.cn>
12
---
13
target/loongarch/kvm/kvm.c | 1 +
14
1 file changed, 1 insertion(+)
15
16
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/loongarch/kvm/kvm.c
19
+++ b/target/loongarch/kvm/kvm.c
20
@@ -XXX,XX +XXX,XX @@ int kvm_arch_get_default_type(MachineState *ms)
21
22
int kvm_arch_init(MachineState *ms, KVMState *s)
23
{
24
+ cap_has_mp_state = kvm_check_extension(s, KVM_CAP_MP_STATE);
25
return 0;
26
}
27
28
--
29
2.25.1
diff view generated by jsdifflib
Deleted patch
1
From: Tianrui Zhao <zhaotianrui@loongson.cn>
2
1
3
Implement kvm_arch_handle_exit for loongarch. In this
4
function, the KVM_EXIT_LOONGARCH_IOCSR is handled,
5
we read or write the iocsr address space by the addr,
6
length and is_write argument in kvm_run.
7
8
Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn>
9
Signed-off-by: xianglai li <lixianglai@loongson.cn>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Song Gao <gaosong@loongson.cn>
12
Message-Id: <20240105075804.1228596-8-zhaotianrui@loongson.cn>
13
Signed-off-by: Song Gao <gaosong@loongson.cn>
14
---
15
target/loongarch/kvm/kvm.c | 24 +++++++++++++++++++++++-
16
target/loongarch/trace-events | 1 +
17
2 files changed, 24 insertions(+), 1 deletion(-)
18
19
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/loongarch/kvm/kvm.c
22
+++ b/target/loongarch/kvm/kvm.c
23
@@ -XXX,XX +XXX,XX @@ bool kvm_arch_cpu_check_are_resettable(void)
24
25
int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
26
{
27
- return 0;
28
+ int ret = 0;
29
+ LoongArchCPU *cpu = LOONGARCH_CPU(cs);
30
+ CPULoongArchState *env = &cpu->env;
31
+ MemTxAttrs attrs = {};
32
+
33
+ attrs.requester_id = env_cpu(env)->cpu_index;
34
+
35
+ trace_kvm_arch_handle_exit(run->exit_reason);
36
+ switch (run->exit_reason) {
37
+ case KVM_EXIT_LOONGARCH_IOCSR:
38
+ address_space_rw(&env->address_space_iocsr,
39
+ run->iocsr_io.phys_addr,
40
+ attrs,
41
+ run->iocsr_io.data,
42
+ run->iocsr_io.len,
43
+ run->iocsr_io.is_write);
44
+ break;
45
+ default:
46
+ ret = -1;
47
+ warn_report("KVM: unknown exit reason %d", run->exit_reason);
48
+ break;
49
+ }
50
+ return ret;
51
}
52
53
void kvm_arch_accel_class_init(ObjectClass *oc)
54
diff --git a/target/loongarch/trace-events b/target/loongarch/trace-events
55
index XXXXXXX..XXXXXXX 100644
56
--- a/target/loongarch/trace-events
57
+++ b/target/loongarch/trace-events
58
@@ -XXX,XX +XXX,XX @@ kvm_failed_get_counter(const char *msg) "Failed to get counter from KVM: %s"
59
kvm_failed_put_counter(const char *msg) "Failed to put counter into KVM: %s"
60
kvm_failed_get_cpucfg(const char *msg) "Failed to get cpucfg from KVM: %s"
61
kvm_failed_put_cpucfg(const char *msg) "Failed to put cpucfg into KVM: %s"
62
+kvm_arch_handle_exit(int num) "kvm arch handle exit, the reason number: %d"
63
--
64
2.25.1
diff view generated by jsdifflib
Deleted patch
1
From: Tianrui Zhao <zhaotianrui@loongson.cn>
2
1
3
In preparation of supporting KVM in the next commit.
4
5
Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn>
6
Signed-off-by: xianglai li <lixianglai@loongson.cn>
7
Reviewed-by: Song Gao <gaosong@loongson.cn>
8
Message-ID: <20240105075804.1228596-9-zhaotianrui@loongson.cn>
9
[PMD: Split from bigger patch, part 1]
10
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Message-Id: <20240110094152.52138-1-philmd@linaro.org>
12
Signed-off-by: Song Gao <gaosong@loongson.cn>
13
---
14
target/loongarch/cpu.c | 30 +++++++++++++++++++++---------
15
1 file changed, 21 insertions(+), 9 deletions(-)
16
17
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/loongarch/cpu.c
20
+++ b/target/loongarch/cpu.c
21
@@ -XXX,XX +XXX,XX @@
22
#include "qapi/error.h"
23
#include "qemu/module.h"
24
#include "sysemu/qtest.h"
25
-#include "exec/cpu_ldst.h"
26
+#include "sysemu/tcg.h"
27
#include "exec/exec-all.h"
28
#include "cpu.h"
29
#include "internals.h"
30
@@ -XXX,XX +XXX,XX @@
31
#ifndef CONFIG_USER_ONLY
32
#include "sysemu/reset.h"
33
#endif
34
-#include "tcg/tcg.h"
35
#include "vec.h"
36
+#ifdef CONFIG_TCG
37
+#include "exec/cpu_ldst.h"
38
+#include "tcg/tcg.h"
39
+#endif
40
41
const char * const regnames[32] = {
42
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
43
@@ -XXX,XX +XXX,XX @@ void loongarch_cpu_set_irq(void *opaque, int irq, int level)
44
return;
45
}
46
47
- env->CSR_ESTAT = deposit64(env->CSR_ESTAT, irq, 1, level != 0);
48
-
49
- if (FIELD_EX64(env->CSR_ESTAT, CSR_ESTAT, IS)) {
50
- cpu_interrupt(cs, CPU_INTERRUPT_HARD);
51
- } else {
52
- cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
53
+ if (tcg_enabled()) {
54
+ env->CSR_ESTAT = deposit64(env->CSR_ESTAT, irq, 1, level != 0);
55
+ if (FIELD_EX64(env->CSR_ESTAT, CSR_ESTAT, IS)) {
56
+ cpu_interrupt(cs, CPU_INTERRUPT_HARD);
57
+ } else {
58
+ cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
59
+ }
60
}
61
}
62
63
@@ -XXX,XX +XXX,XX @@ static inline bool cpu_loongarch_hw_interrupts_pending(CPULoongArchState *env)
64
65
return (pending & status) != 0;
66
}
67
+#endif
68
69
+#ifdef CONFIG_TCG
70
+#ifndef CONFIG_USER_ONLY
71
static void loongarch_cpu_do_interrupt(CPUState *cs)
72
{
73
LoongArchCPU *cpu = LOONGARCH_CPU(cs);
74
@@ -XXX,XX +XXX,XX @@ static bool loongarch_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
75
}
76
#endif
77
78
-#ifdef CONFIG_TCG
79
static void loongarch_cpu_synchronize_from_tb(CPUState *cs,
80
const TranslationBlock *tb)
81
{
82
@@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_reset_hold(Object *obj)
83
}
84
#endif
85
86
+#ifdef CONFIG_TCG
87
restore_fp_status(env);
88
+#endif
89
cs->exception_index = -1;
90
}
91
92
@@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_init(Object *obj)
93
CPULoongArchState *env = &cpu->env;
94
95
qdev_init_gpio_in(DEVICE(cpu), loongarch_cpu_set_irq, N_IRQS);
96
+#ifdef CONFIG_TCG
97
timer_init_ns(&cpu->timer, QEMU_CLOCK_VIRTUAL,
98
&loongarch_constant_timer_cb, cpu);
99
+#endif
100
memory_region_init_io(&env->system_iocsr, OBJECT(cpu), NULL,
101
env, "iocsr", UINT64_MAX);
102
address_space_init(&env->address_space_iocsr, &env->system_iocsr, "IOCSR");
103
@@ -XXX,XX +XXX,XX @@ static struct TCGCPUOps loongarch_tcg_ops = {
104
#include "hw/core/sysemu-cpu-ops.h"
105
106
static const struct SysemuCPUOps loongarch_sysemu_ops = {
107
+#ifdef CONFIG_TCG
108
.get_phys_page_debug = loongarch_cpu_get_phys_page_debug,
109
+#endif
110
};
111
112
static int64_t loongarch_cpu_get_arch_id(CPUState *cs)
113
--
114
2.25.1
115
116
diff view generated by jsdifflib
Deleted patch
1
From: Tianrui Zhao <zhaotianrui@loongson.cn>
2
1
3
Add kvm.c into meson.build to compile it when kvm
4
is configed. Meanwhile in meson.build, we set the
5
kvm_targets to loongarch64-softmmu when the cpu is
6
loongarch. And fix the compiling error when config
7
is enable-kvm,disable-tcg.
8
9
Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn>
10
Signed-off-by: xianglai li <lixianglai@loongson.cn>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Song Gao <gaosong@loongson.cn>
13
Message-Id: <20240105075804.1228596-10-zhaotianrui@loongson.cn>
14
Signed-off-by: Song Gao <gaosong@loongson.cn>
15
---
16
meson.build | 2 ++
17
target/loongarch/kvm/meson.build | 1 +
18
target/loongarch/meson.build | 1 +
19
3 files changed, 4 insertions(+)
20
create mode 100644 target/loongarch/kvm/meson.build
21
22
diff --git a/meson.build b/meson.build
23
index XXXXXXX..XXXXXXX 100644
24
--- a/meson.build
25
+++ b/meson.build
26
@@ -XXX,XX +XXX,XX @@ elif cpu in ['riscv32']
27
kvm_targets = ['riscv32-softmmu']
28
elif cpu in ['riscv64']
29
kvm_targets = ['riscv64-softmmu']
30
+elif cpu in ['loongarch64']
31
+ kvm_targets = ['loongarch64-softmmu']
32
else
33
kvm_targets = []
34
endif
35
diff --git a/target/loongarch/kvm/meson.build b/target/loongarch/kvm/meson.build
36
new file mode 100644
37
index XXXXXXX..XXXXXXX
38
--- /dev/null
39
+++ b/target/loongarch/kvm/meson.build
40
@@ -0,0 +1 @@
41
+loongarch_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'))
42
diff --git a/target/loongarch/meson.build b/target/loongarch/meson.build
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/loongarch/meson.build
45
+++ b/target/loongarch/meson.build
46
@@ -XXX,XX +XXX,XX @@ subdir('tcg')
47
48
target_arch += {'loongarch': loongarch_ss}
49
target_system_arch += {'loongarch': loongarch_system_ss}
50
+subdir('kvm')
51
--
52
2.25.1
diff view generated by jsdifflib
Deleted patch
1
From: Bibo Mao <maobibo@loongson.cn>
2
1
3
There are two interface pairs for MemoryRegionOps, read/write and
4
read_with_attrs/write_with_attrs. The later is better for ipi device
5
emulation since initial cpu can be parsed from attrs.requester_id.
6
7
And requester_id can be overrided for IOCSR_IPI_SEND and mail_send
8
function when it is to forward message to another vcpu.
9
10
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
11
Reviewed-by: Song Gao <gaosong@loongson.cn>
12
Message-Id: <20231215100333.3933632-2-maobibo@loongson.cn>
13
Signed-off-by: Song Gao <gaosong@loongson.cn>
14
---
15
hw/intc/loongarch_ipi.c | 136 +++++++++++++++++++++++-----------------
16
1 file changed, 77 insertions(+), 59 deletions(-)
17
18
diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/intc/loongarch_ipi.c
21
+++ b/hw/intc/loongarch_ipi.c
22
@@ -XXX,XX +XXX,XX @@
23
#include "target/loongarch/internals.h"
24
#include "trace.h"
25
26
-static void loongarch_ipi_writel(void *, hwaddr, uint64_t, unsigned);
27
-
28
-static uint64_t loongarch_ipi_readl(void *opaque, hwaddr addr, unsigned size)
29
+static MemTxResult loongarch_ipi_readl(void *opaque, hwaddr addr,
30
+ uint64_t *data,
31
+ unsigned size, MemTxAttrs attrs)
32
{
33
- IPICore *s = opaque;
34
+ IPICore *s;
35
+ LoongArchIPI *ipi = opaque;
36
uint64_t ret = 0;
37
int index = 0;
38
39
+ s = &ipi->ipi_core;
40
addr &= 0xff;
41
switch (addr) {
42
case CORE_STATUS_OFF:
43
@@ -XXX,XX +XXX,XX @@ static uint64_t loongarch_ipi_readl(void *opaque, hwaddr addr, unsigned size)
44
}
45
46
trace_loongarch_ipi_read(size, (uint64_t)addr, ret);
47
- return ret;
48
+ *data = ret;
49
+ return MEMTX_OK;
50
}
51
52
-static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr)
53
+static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr,
54
+ MemTxAttrs attrs)
55
{
56
int i, mask = 0, data = 0;
57
58
@@ -XXX,XX +XXX,XX @@ static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr)
59
*/
60
if ((val >> 27) & 0xf) {
61
data = address_space_ldl(&env->address_space_iocsr, addr,
62
- MEMTXATTRS_UNSPECIFIED, NULL);
63
+ attrs, NULL);
64
for (i = 0; i < 4; i++) {
65
/* get mask for byte writing */
66
if (val & (0x1 << (27 + i))) {
67
@@ -XXX,XX +XXX,XX @@ static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr)
68
data &= mask;
69
data |= (val >> 32) & ~mask;
70
address_space_stl(&env->address_space_iocsr, addr,
71
- data, MEMTXATTRS_UNSPECIFIED, NULL);
72
+ data, attrs, NULL);
73
}
74
75
static int archid_cmp(const void *a, const void *b)
76
@@ -XXX,XX +XXX,XX @@ static CPUState *ipi_getcpu(int arch_id)
77
CPUArchId *archid;
78
79
archid = find_cpu_by_archid(machine, arch_id);
80
- return CPU(archid->cpu);
81
-}
82
-
83
-static void ipi_send(uint64_t val)
84
-{
85
- uint32_t cpuid;
86
- uint8_t vector;
87
- CPUState *cs;
88
- LoongArchCPU *cpu;
89
- LoongArchIPI *s;
90
-
91
- cpuid = extract32(val, 16, 10);
92
- if (cpuid >= LOONGARCH_MAX_CPUS) {
93
- trace_loongarch_ipi_unsupported_cpuid("IOCSR_IPI_SEND", cpuid);
94
- return;
95
+ if (archid) {
96
+ return CPU(archid->cpu);
97
}
98
99
- /* IPI status vector */
100
- vector = extract8(val, 0, 5);
101
-
102
- cs = ipi_getcpu(cpuid);
103
- cpu = LOONGARCH_CPU(cs);
104
- s = LOONGARCH_IPI(cpu->env.ipistate);
105
- loongarch_ipi_writel(&s->ipi_core, CORE_SET_OFF, BIT(vector), 4);
106
+ return NULL;
107
}
108
109
-static void mail_send(uint64_t val)
110
+static MemTxResult mail_send(uint64_t val, MemTxAttrs attrs)
111
{
112
uint32_t cpuid;
113
hwaddr addr;
114
- CPULoongArchState *env;
115
CPUState *cs;
116
- LoongArchCPU *cpu;
117
118
cpuid = extract32(val, 16, 10);
119
if (cpuid >= LOONGARCH_MAX_CPUS) {
120
trace_loongarch_ipi_unsupported_cpuid("IOCSR_MAIL_SEND", cpuid);
121
- return;
122
+ return MEMTX_DECODE_ERROR;
123
}
124
125
- addr = 0x1020 + (val & 0x1c);
126
cs = ipi_getcpu(cpuid);
127
- cpu = LOONGARCH_CPU(cs);
128
- env = &cpu->env;
129
- send_ipi_data(env, val, addr);
130
+ if (cs == NULL) {
131
+ return MEMTX_DECODE_ERROR;
132
+ }
133
+
134
+ /* override requester_id */
135
+ addr = SMP_IPI_MAILBOX + CORE_BUF_20 + (val & 0x1c);
136
+ attrs.requester_id = cs->cpu_index;
137
+ send_ipi_data(&LOONGARCH_CPU(cs)->env, val, addr, attrs);
138
+ return MEMTX_OK;
139
}
140
141
-static void any_send(uint64_t val)
142
+static MemTxResult any_send(uint64_t val, MemTxAttrs attrs)
143
{
144
uint32_t cpuid;
145
hwaddr addr;
146
- CPULoongArchState *env;
147
CPUState *cs;
148
- LoongArchCPU *cpu;
149
150
cpuid = extract32(val, 16, 10);
151
if (cpuid >= LOONGARCH_MAX_CPUS) {
152
trace_loongarch_ipi_unsupported_cpuid("IOCSR_ANY_SEND", cpuid);
153
- return;
154
+ return MEMTX_DECODE_ERROR;
155
}
156
157
- addr = val & 0xffff;
158
cs = ipi_getcpu(cpuid);
159
- cpu = LOONGARCH_CPU(cs);
160
- env = &cpu->env;
161
- send_ipi_data(env, val, addr);
162
+ if (cs == NULL) {
163
+ return MEMTX_DECODE_ERROR;
164
+ }
165
+
166
+ /* override requester_id */
167
+ addr = val & 0xffff;
168
+ attrs.requester_id = cs->cpu_index;
169
+ send_ipi_data(&LOONGARCH_CPU(cs)->env, val, addr, attrs);
170
+ return MEMTX_OK;
171
}
172
173
-static void loongarch_ipi_writel(void *opaque, hwaddr addr, uint64_t val,
174
- unsigned size)
175
+static MemTxResult loongarch_ipi_writel(void *opaque, hwaddr addr, uint64_t val,
176
+ unsigned size, MemTxAttrs attrs)
177
{
178
- IPICore *s = opaque;
179
+ LoongArchIPI *ipi = opaque;
180
+ IPICore *s;
181
int index = 0;
182
+ uint32_t cpuid;
183
+ uint8_t vector;
184
+ CPUState *cs;
185
186
+ s = &ipi->ipi_core;
187
addr &= 0xff;
188
trace_loongarch_ipi_write(size, (uint64_t)addr, val);
189
switch (addr) {
190
@@ -XXX,XX +XXX,XX @@ static void loongarch_ipi_writel(void *opaque, hwaddr addr, uint64_t val,
191
s->buf[index] = val;
192
break;
193
case IOCSR_IPI_SEND:
194
- ipi_send(val);
195
+ cpuid = extract32(val, 16, 10);
196
+ if (cpuid >= LOONGARCH_MAX_CPUS) {
197
+ trace_loongarch_ipi_unsupported_cpuid("IOCSR_IPI_SEND", cpuid);
198
+ return MEMTX_DECODE_ERROR;
199
+ }
200
+
201
+ /* IPI status vector */
202
+ vector = extract8(val, 0, 5);
203
+ cs = ipi_getcpu(cpuid);
204
+ if (cs == NULL) {
205
+ return MEMTX_DECODE_ERROR;
206
+ }
207
+
208
+ /* override requester_id */
209
+ attrs.requester_id = cs->cpu_index;
210
+ ipi = LOONGARCH_IPI(LOONGARCH_CPU(cs)->env.ipistate);
211
+ loongarch_ipi_writel(ipi, CORE_SET_OFF, BIT(vector), 4, attrs);
212
break;
213
default:
214
qemu_log_mask(LOG_UNIMP, "invalid write: %x", (uint32_t)addr);
215
break;
216
}
217
+
218
+ return MEMTX_OK;
219
}
220
221
static const MemoryRegionOps loongarch_ipi_ops = {
222
- .read = loongarch_ipi_readl,
223
- .write = loongarch_ipi_writel,
224
+ .read_with_attrs = loongarch_ipi_readl,
225
+ .write_with_attrs = loongarch_ipi_writel,
226
.impl.min_access_size = 4,
227
.impl.max_access_size = 4,
228
.valid.min_access_size = 4,
229
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps loongarch_ipi_ops = {
230
};
231
232
/* mail send and any send only support writeq */
233
-static void loongarch_ipi_writeq(void *opaque, hwaddr addr, uint64_t val,
234
- unsigned size)
235
+static MemTxResult loongarch_ipi_writeq(void *opaque, hwaddr addr, uint64_t val,
236
+ unsigned size, MemTxAttrs attrs)
237
{
238
+ MemTxResult ret = MEMTX_OK;
239
+
240
addr &= 0xfff;
241
switch (addr) {
242
case MAIL_SEND_OFFSET:
243
- mail_send(val);
244
+ ret = mail_send(val, attrs);
245
break;
246
case ANY_SEND_OFFSET:
247
- any_send(val);
248
+ ret = any_send(val, attrs);
249
break;
250
default:
251
break;
252
}
253
+
254
+ return ret;
255
}
256
257
static const MemoryRegionOps loongarch_ipi64_ops = {
258
- .write = loongarch_ipi_writeq,
259
+ .write_with_attrs = loongarch_ipi_writeq,
260
.impl.min_access_size = 8,
261
.impl.max_access_size = 8,
262
.valid.min_access_size = 8,
263
@@ -XXX,XX +XXX,XX @@ static void loongarch_ipi_init(Object *obj)
264
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
265
266
memory_region_init_io(&s->ipi_iocsr_mem, obj, &loongarch_ipi_ops,
267
- &s->ipi_core, "loongarch_ipi_iocsr", 0x48);
268
+ s, "loongarch_ipi_iocsr", 0x48);
269
270
/* loongarch_ipi_iocsr performs re-entrant IO through ipi_send */
271
s->ipi_iocsr_mem.disable_reentrancy_guard = true;
272
@@ -XXX,XX +XXX,XX @@ static void loongarch_ipi_init(Object *obj)
273
sysbus_init_mmio(sbd, &s->ipi_iocsr_mem);
274
275
memory_region_init_io(&s->ipi64_iocsr_mem, obj, &loongarch_ipi64_ops,
276
- &s->ipi_core, "loongarch_ipi64_iocsr", 0x118);
277
+ s, "loongarch_ipi64_iocsr", 0x118);
278
sysbus_init_mmio(sbd, &s->ipi64_iocsr_mem);
279
qdev_init_gpio_out(DEVICE(obj), &s->ipi_core.irq, 1);
280
}
281
--
282
2.25.1
diff view generated by jsdifflib