1
The following changes since commit d762bf97931b58839316b68a570eecc6143c9e3e:
1
The following changes since commit 38d0939b86e2eef6f6a622c6f1f7befda0146595:
2
2
3
Merge tag 'pull-target-arm-20231102' of https://git.linaro.org/people/pmaydell/qemu-arm into staging (2023-11-03 10:04:12 +0800)
3
Merge tag 'pull-vfio-20241226' of https://github.com/legoater/qemu into staging (2024-12-26 04:38:38 -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-20231103
7
https://gitlab.com/bibo-mao/qemu.git tags/pull-loongarch-20241227
8
8
9
for you to fetch changes up to f7077737531b40aa879d4644837aeda0f7fc6aa8:
9
for you to fetch changes up to 5e360dabedb1ab1f15cce27a134ccbe4b8e18424:
10
10
11
linux-user/loongarch64: Add LASX sigcontext save/restore (2023-11-03 14:13:46 +0800)
11
target/loongarch: Use auto method with LASX feature (2024-12-27 11:33:06 +0800)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
pull-loongarch-20231103
14
pull-loongarch-20241227
15
v1 ... v2
16
1. Modify patch auther inconsistent with SOB
15
17
16
----------------------------------------------------------------
18
----------------------------------------------------------------
17
Richard Henderson (1):
19
Bibo Mao (5):
18
linux-user/loongarch64: Use traps to track LSX/LASX usage
20
target/loongarch: Use actual operand size with vbsrl check
21
hw/loongarch/virt: Create fdt table on machine creation done notification
22
hw/loongarch/virt: Improve fdt table creation for CPU object
23
target/loongarch: Use auto method with LSX feature
24
target/loongarch: Use auto method with LASX feature
19
25
20
Song Gao (9):
26
Guo Hongyu (1):
21
target/loongarch: Add cpu model 'max'
27
target/loongarch: Fix vldi inst
22
target/loongarch: Allow user enable/disable LSX/LASX features
23
target/loongarch: Implement query-cpu-model-expansion
24
target/loongarch: Support 4K page size
25
linux-user/loongarch64: Fix setup_extcontext alloc wrong fpu_context size
26
linux-user/loongarch64: setup_sigframe() set 'end' context size 0
27
linux-user/loongarch64: Use abi_{ulong,uint} types
28
linux-user/loongarch64: Add LSX sigcontext save/restore
29
linux-user/loongarch64: Add LASX sigcontext save/restore
30
28
31
linux-user/loongarch64/cpu_loop.c | 13 ++
29
hw/loongarch/virt.c | 142 ++++++++++++++----------
32
linux-user/loongarch64/signal.c | 189 +++++++++++++++++++++++-----
30
target/loongarch/cpu.c | 86 ++++++++------
33
qapi/machine-target.json | 6 +-
31
target/loongarch/cpu.h | 4 +
34
target/loongarch/cpu-param.h | 2 +-
32
target/loongarch/kvm/kvm.c | 107 ++++++++++++++++++
35
target/loongarch/cpu.c | 74 +++++++++++
33
target/loongarch/tcg/insn_trans/trans_vec.c.inc | 4 +-
36
target/loongarch/cpu.h | 2 +
34
5 files changed, 249 insertions(+), 94 deletions(-)
37
target/loongarch/insn_trans/trans_vec.c.inc | 11 --
38
target/loongarch/loongarch-qmp-cmds.c | 64 ++++++++++
39
target/loongarch/tlb_helper.c | 9 +-
40
9 files changed, 318 insertions(+), 52 deletions(-)
diff view generated by jsdifflib
1
See:
1
From: Guo Hongyu <guohongyu24@mails.ucas.ac.cn>
2
https://github.com/torvalds/linux/blob/master/arch/loongarch/kernel/signal.c
3
2
4
The kernel setup_sigcontext() set end context size 0.
3
Refer to the link below for a description of the vldi instructions:
4
https://jia.je/unofficial-loongarch-intrinsics-guide/lsx/misc/#synopsis_88
5
Fixed errors in vldi instruction implementation.
5
6
6
Signed-off-by: Song Gao <gaosong@loongson.cn>
7
Signed-off-by: Guo Hongyu <guohongyu24@mails.ucas.ac.cn>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Tested-by: Xianglai Li <lixianglai@loongson.cn>
8
Message-Id: <20231101030816.2353416-4-gaosong@loongson.cn>
9
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
10
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
11
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
9
---
12
---
10
linux-user/loongarch64/signal.c | 2 +-
13
target/loongarch/tcg/insn_trans/trans_vec.c.inc | 2 +-
11
1 file changed, 1 insertion(+), 1 deletion(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
12
15
13
diff --git a/linux-user/loongarch64/signal.c b/linux-user/loongarch64/signal.c
16
diff --git a/target/loongarch/tcg/insn_trans/trans_vec.c.inc b/target/loongarch/tcg/insn_trans/trans_vec.c.inc
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/linux-user/loongarch64/signal.c
18
--- a/target/loongarch/tcg/insn_trans/trans_vec.c.inc
16
+++ b/linux-user/loongarch64/signal.c
19
+++ b/target/loongarch/tcg/insn_trans/trans_vec.c.inc
17
@@ -XXX,XX +XXX,XX @@ static void setup_sigframe(CPULoongArchState *env,
20
@@ -XXX,XX +XXX,XX @@ static uint64_t vldi_get_value(DisasContext *ctx, uint32_t imm)
18
*/
21
break;
19
info = extctx->end.haddr;
22
case 1:
20
__put_user(0, &info->magic);
23
/* data: {2{16'0, imm[7:0], 8'0}} */
21
- __put_user(extctx->end.size, &info->size);
24
- data = (t << 24) | (t << 8);
22
+ __put_user(0, &info->size);
25
+ data = (t << 40) | (t << 8);
23
}
26
break;
24
27
case 2:
25
static bool parse_extcontext(struct extctx_layout *extctx, abi_ptr frame)
28
/* data: {2{8'0, imm[7:0], 16'0}} */
26
--
29
--
27
2.25.1
30
2.43.5
diff view generated by jsdifflib
1
Signed-off-by: Song Gao <gaosong@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.
4
5
Here actual operand size is used.
6
7
Cc: qemu-stable@nongnu.org
8
Fixes: df97f338076 ("target/loongarch: Implement xvreplve xvinsve0 xvpickve")
9
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
2
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
3
Message-Id: <20231101030816.2353416-7-gaosong@loongson.cn>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
---
12
---
5
linux-user/loongarch64/signal.c | 68 ++++++++++++++++++++++++++++++---
13
target/loongarch/tcg/insn_trans/trans_vec.c.inc | 2 +-
6
1 file changed, 62 insertions(+), 6 deletions(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
7
15
8
diff --git a/linux-user/loongarch64/signal.c b/linux-user/loongarch64/signal.c
16
diff --git a/target/loongarch/tcg/insn_trans/trans_vec.c.inc b/target/loongarch/tcg/insn_trans/trans_vec.c.inc
9
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
10
--- a/linux-user/loongarch64/signal.c
18
--- a/target/loongarch/tcg/insn_trans/trans_vec.c.inc
11
+++ b/linux-user/loongarch64/signal.c
19
+++ b/target/loongarch/tcg/insn_trans/trans_vec.c.inc
12
@@ -XXX,XX +XXX,XX @@ struct target_lsx_context {
20
@@ -XXX,XX +XXX,XX @@ static bool do_vbsrl_v(DisasContext *ctx, arg_vv_i *a, uint32_t oprsz)
13
abi_uint fcsr;
21
{
14
} QEMU_ALIGNED(LSX_CTX_ALIGN);
22
int i, ofs;
15
23
16
+#define LASX_CTX_MAGIC 0x41535801
24
- if (!check_vec(ctx, 32)) {
17
+#define LASX_CTX_ALIGN 32
25
+ if (!check_vec(ctx, oprsz)) {
18
+struct target_lasx_context {
26
return true;
19
+ abi_ulong regs[4 * 32];
20
+ abi_ulong fcc;
21
+ abi_uint fcsr;
22
+} QEMU_ALIGNED(LASX_CTX_ALIGN);
23
+
24
#define CONTEXT_INFO_ALIGN 16
25
struct target_sctx_info {
26
abi_uint magic;
27
@@ -XXX,XX +XXX,XX @@ struct extctx_layout {
28
unsigned int flags;
29
struct ctx_layout fpu;
30
struct ctx_layout lsx;
31
+ struct ctx_layout lasx;
32
struct ctx_layout end;
33
};
34
35
@@ -XXX,XX +XXX,XX @@ static abi_ptr setup_extcontext(CPULoongArchState *env,
36
/* For qemu, there is no lazy fp context switch, so fp always present. */
37
extctx->flags = SC_USED_FP;
38
39
- if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE)) {
40
+ if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, ASXE)) {
41
+ sp = extframe_alloc(extctx, &extctx->lasx,
42
+ sizeof(struct target_lasx_context), LASX_CTX_ALIGN, sp);
43
+ } else if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE)) {
44
sp = extframe_alloc(extctx, &extctx->lsx,
45
sizeof(struct target_lsx_context), LSX_CTX_ALIGN, sp);
46
-
47
} else {
48
sp = extframe_alloc(extctx, &extctx->fpu,
49
sizeof(struct target_fpu_context), FPU_CTX_ALIGN, sp);
50
@@ -XXX,XX +XXX,XX @@ static void setup_sigframe(CPULoongArchState *env,
51
* Set extension context
52
*/
53
54
- if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE)) {
55
+ if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, ASXE)) {
56
+ struct target_lasx_context *lasx_ctx;
57
+ info = extctx->lasx.haddr;
58
+
59
+ __put_user(LASX_CTX_MAGIC, &info->magic);
60
+ __put_user(extctx->lasx.size, &info->size);
61
+
62
+ lasx_ctx = (struct target_lasx_context *)(info + 1);
63
+
64
+ for (i = 0; i < 32; ++i) {
65
+ __put_user(env->fpr[i].vreg.UD(0), &lasx_ctx->regs[4 * i]);
66
+ __put_user(env->fpr[i].vreg.UD(1), &lasx_ctx->regs[4 * i + 1]);
67
+ __put_user(env->fpr[i].vreg.UD(2), &lasx_ctx->regs[4 * i + 2]);
68
+ __put_user(env->fpr[i].vreg.UD(3), &lasx_ctx->regs[4 * i + 3]);
69
+ }
70
+ __put_user(read_fcc(env), &lasx_ctx->fcc);
71
+ __put_user(env->fcsr0, &lasx_ctx->fcsr);
72
+ } else if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE)) {
73
struct target_lsx_context *lsx_ctx;
74
info = extctx->lsx.haddr;
75
76
@@ -XXX,XX +XXX,XX @@ static bool parse_extcontext(struct extctx_layout *extctx, abi_ptr frame)
77
extctx->lsx.size = size;
78
extctx->size += size;
79
break;
80
+ case LASX_CTX_MAGIC:
81
+ if (size < (sizeof(struct target_sctx_info) +
82
+ sizeof(struct target_lasx_context))) {
83
+ return false;
84
+ }
85
+ extctx->lasx.gaddr = frame;
86
+ extctx->lasx.size = size;
87
+ extctx->size += size;
88
+ break;
89
default:
90
return false;
91
}
92
@@ -XXX,XX +XXX,XX @@ static void restore_sigframe(CPULoongArchState *env,
93
__get_user(env->gpr[i], &sc->sc_regs[i]);
94
}
27
}
95
28
96
- if (extctx->lsx.haddr) {
97
+ if (extctx->lasx.haddr) {
98
+ struct target_lasx_context *lasx_ctx =
99
+ extctx->lasx.haddr + sizeof(struct target_sctx_info);
100
+
101
+ for (i = 0; i < 32; ++i) {
102
+ __get_user(env->fpr[i].vreg.UD(0), &lasx_ctx->regs[4 * i]);
103
+ __get_user(env->fpr[i].vreg.UD(1), &lasx_ctx->regs[4 * i + 1]);
104
+ __get_user(env->fpr[i].vreg.UD(2), &lasx_ctx->regs[4 * i + 2]);
105
+ __get_user(env->fpr[i].vreg.UD(3), &lasx_ctx->regs[4 * i + 3]);
106
+ }
107
+ __get_user(fcc, &lasx_ctx->fcc);
108
+ write_fcc(env, fcc);
109
+ __get_user(env->fcsr0, &lasx_ctx->fcsr);
110
+ restore_fp_status(env);
111
+ } else if (extctx->lsx.haddr) {
112
struct target_lsx_context *lsx_ctx =
113
extctx->lsx.haddr + sizeof(struct target_sctx_info);
114
115
@@ -XXX,XX +XXX,XX @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
116
return;
117
}
118
119
- if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE)) {
120
+ if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, ASXE)) {
121
+ extctx.lasx.haddr = (void *)frame + (extctx.lasx.gaddr - frame_addr);
122
+ extctx.end.haddr = (void *)frame + (extctx.end.gaddr - frame_addr);
123
+ } else if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE)) {
124
extctx.lsx.haddr = (void *)frame + (extctx.lsx.gaddr - frame_addr);
125
extctx.end.haddr = (void *)frame + (extctx.end.gaddr - frame_addr);
126
} else {
127
@@ -XXX,XX +XXX,XX @@ long do_rt_sigreturn(CPULoongArchState *env)
128
goto badframe;
129
}
130
131
- if (extctx.lsx.gaddr) {
132
+ if (extctx.lasx.gaddr) {
133
+ extctx.lasx.haddr = (void *)frame + (extctx.lasx.gaddr - frame_addr);
134
+ } else if (extctx.lsx.gaddr) {
135
extctx.lsx.haddr = (void *)frame + (extctx.lsx.gaddr - frame_addr);
136
} else if (extctx.fpu.gaddr) {
137
extctx.fpu.haddr = (void *)frame + (extctx.fpu.gaddr - frame_addr);
138
--
29
--
139
2.25.1
30
2.43.5
31
32
diff view generated by jsdifflib
1
Signed-off-by: Song Gao <gaosong@loongson.cn>
1
The same with ACPI table, fdt table is created on machine done
2
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2
notification. Some objects like CPU objects can be created with cold-plug
3
Message-Id: <20231101030816.2353416-6-gaosong@loongson.cn>
3
method with command such as -smp x, -device la464-loongarch-cpu, so all
4
objects finish to create when machine is done.
5
6
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
7
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
4
---
8
---
5
linux-user/loongarch64/signal.c | 107 ++++++++++++++++++++++++++------
9
hw/loongarch/virt.c | 103 ++++++++++++++++++++++++--------------------
6
1 file changed, 87 insertions(+), 20 deletions(-)
10
1 file changed, 57 insertions(+), 46 deletions(-)
7
11
8
diff --git a/linux-user/loongarch64/signal.c b/linux-user/loongarch64/signal.c
12
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
9
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
10
--- a/linux-user/loongarch64/signal.c
14
--- a/hw/loongarch/virt.c
11
+++ b/linux-user/loongarch64/signal.c
15
+++ b/hw/loongarch/virt.c
12
@@ -XXX,XX +XXX,XX @@ struct target_fpu_context {
16
@@ -XXX,XX +XXX,XX @@ static void virt_build_smbios(LoongArchVirtMachineState *lvms)
13
QEMU_BUILD_BUG_ON(offsetof(struct target_fpu_context, regs)
17
}
14
!= offsetof_fpucontext_fr);
18
}
15
19
16
+#define LSX_CTX_MAGIC 0x53580001
20
+static void virt_fdt_setup(LoongArchVirtMachineState *lvms)
17
+#define LSX_CTX_ALIGN 16
21
+{
18
+struct target_lsx_context {
22
+ MachineState *machine = MACHINE(lvms);
19
+ abi_ulong regs[2 * 32];
23
+ uint32_t cpuintc_phandle, eiointc_phandle, pch_pic_phandle, pch_msi_phandle;
20
+ abi_ulong fcc;
24
+ int i;
21
+ abi_uint fcsr;
25
+
22
+} QEMU_ALIGNED(LSX_CTX_ALIGN);
26
+ create_fdt(lvms);
23
+
27
+ fdt_add_cpu_nodes(lvms);
24
#define CONTEXT_INFO_ALIGN 16
28
+ fdt_add_memory_nodes(machine);
25
struct target_sctx_info {
29
+ fdt_add_fw_cfg_node(lvms);
26
abi_uint magic;
30
+ fdt_add_flash_node(lvms);
27
@@ -XXX,XX +XXX,XX @@ struct ctx_layout {
31
+
28
};
32
+ /* Add cpu interrupt-controller */
29
33
+ fdt_add_cpuic_node(lvms, &cpuintc_phandle);
30
struct extctx_layout {
34
+ /* Add Extend I/O Interrupt Controller node */
31
- unsigned int size;
35
+ fdt_add_eiointc_node(lvms, &cpuintc_phandle, &eiointc_phandle);
32
+ unsigned long size;
36
+ /* Add PCH PIC node */
33
unsigned int flags;
37
+ fdt_add_pch_pic_node(lvms, &eiointc_phandle, &pch_pic_phandle);
34
struct ctx_layout fpu;
38
+ /* Add PCH MSI node */
35
+ struct ctx_layout lsx;
39
+ fdt_add_pch_msi_node(lvms, &eiointc_phandle, &pch_msi_phandle);
36
struct ctx_layout end;
40
+ /* Add pcie node */
37
};
41
+ fdt_add_pcie_node(lvms, &pch_pic_phandle, &pch_msi_phandle);
38
42
+
39
@@ -XXX,XX +XXX,XX @@ static abi_ptr extframe_alloc(struct extctx_layout *extctx,
43
+ /*
40
return sp;
44
+ * Create uart fdt node in reverse order so that they appear
41
}
45
+ * in the finished device tree lowest address first
42
46
+ */
43
-static abi_ptr setup_extcontext(struct extctx_layout *extctx, abi_ptr sp)
47
+ for (i = VIRT_UART_COUNT; i-- > 0;) {
44
+static abi_ptr setup_extcontext(CPULoongArchState *env,
48
+ hwaddr base = VIRT_UART_BASE + i * VIRT_UART_SIZE;
45
+ struct extctx_layout *extctx, abi_ptr sp)
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)
46
{
75
{
47
memset(extctx, 0, sizeof(struct extctx_layout));
76
LoongArchVirtMachineState *lvms = container_of(notifier,
48
77
LoongArchVirtMachineState, machine_done);
49
@@ -XXX,XX +XXX,XX @@ static abi_ptr setup_extcontext(struct extctx_layout *extctx, abi_ptr sp)
78
virt_build_smbios(lvms);
50
79
loongarch_acpi_setup(lvms);
51
/* For qemu, there is no lazy fp context switch, so fp always present. */
80
+ virt_fdt_setup(lvms);
52
extctx->flags = SC_USED_FP;
81
}
53
- sp = extframe_alloc(extctx, &extctx->fpu,
82
54
+
83
static void virt_powerdown_req(Notifier *notifier, void *opaque)
55
+ if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE)) {
84
@@ -XXX,XX +XXX,XX @@ static DeviceState *create_platform_bus(DeviceState *pch_pic)
56
+ sp = extframe_alloc(extctx, &extctx->lsx,
85
}
57
+ sizeof(struct target_lsx_context), LSX_CTX_ALIGN, sp);
86
58
+
87
static void virt_devices_init(DeviceState *pch_pic,
59
+ } else {
88
- LoongArchVirtMachineState *lvms,
60
+ sp = extframe_alloc(extctx, &extctx->fpu,
89
- uint32_t *pch_pic_phandle,
61
sizeof(struct target_fpu_context), FPU_CTX_ALIGN, sp);
90
- uint32_t *pch_msi_phandle)
62
+ }
91
+ LoongArchVirtMachineState *lvms)
63
64
return sp;
65
}
66
@@ -XXX,XX +XXX,XX @@ static void setup_sigframe(CPULoongArchState *env,
67
struct extctx_layout *extctx)
68
{
92
{
69
struct target_sctx_info *info;
93
MachineClass *mc = MACHINE_GET_CLASS(lvms);
70
- struct target_fpu_context *fpu_ctx;
94
DeviceState *gpex_dev;
71
int i;
95
@@ -XXX,XX +XXX,XX @@ static void virt_devices_init(DeviceState *pch_pic,
72
96
gpex_set_irq_num(GPEX_HOST(gpex_dev), i, 16 + i);
73
__put_user(extctx->flags, &sc->sc_flags);
97
}
74
@@ -XXX,XX +XXX,XX @@ static void setup_sigframe(CPULoongArchState *env,
98
75
}
99
- /* Add pcie node */
76
100
- fdt_add_pcie_node(lvms, pch_pic_phandle, pch_msi_phandle);
101
-
77
/*
102
/*
78
- * Set fpu context
103
* Create uart fdt node in reverse order so that they appear
79
+ * Set extension context
104
* in the finished device tree lowest address first
80
*/
105
@@ -XXX,XX +XXX,XX @@ static void virt_devices_init(DeviceState *pch_pic,
81
- info = extctx->fpu.haddr;
106
serial_mm_init(get_system_memory(), base, 0,
82
- __put_user(FPU_CTX_MAGIC, &info->magic);
107
qdev_get_gpio_in(pch_pic, irq),
83
- __put_user(extctx->fpu.size, &info->size);
108
115200, serial_hd(i), DEVICE_LITTLE_ENDIAN);
84
109
- fdt_add_uart_node(lvms, pch_pic_phandle, base, irq, i == 0);
85
- fpu_ctx = (struct target_fpu_context *)(info + 1);
110
}
86
- for (i = 0; i < 32; ++i) {
111
87
- __put_user(env->fpr[i].vreg.D(0), &fpu_ctx->regs[i]);
112
/* Network init */
88
+ if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE)) {
113
@@ -XXX,XX +XXX,XX @@ static void virt_devices_init(DeviceState *pch_pic,
89
+ struct target_lsx_context *lsx_ctx;
114
sysbus_create_simple("ls7a_rtc", VIRT_RTC_REG_BASE,
90
+ info = extctx->lsx.haddr;
115
qdev_get_gpio_in(pch_pic,
91
+
116
VIRT_RTC_IRQ - VIRT_GSI_BASE));
92
+ __put_user(LSX_CTX_MAGIC, &info->magic);
117
- fdt_add_rtc_node(lvms, pch_pic_phandle);
93
+ __put_user(extctx->lsx.size, &info->size);
118
- fdt_add_ged_reset(lvms);
94
+
119
95
+ lsx_ctx = (struct target_lsx_context *)(info + 1);
120
/* acpi ged */
96
+
121
lvms->acpi_ged = create_acpi_ged(pch_pic, lvms);
97
+ for (i = 0; i < 32; ++i) {
122
@@ -XXX,XX +XXX,XX @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
98
+ __put_user(env->fpr[i].vreg.UD(0), &lsx_ctx->regs[2 * i]);
123
CPULoongArchState *env;
99
+ __put_user(env->fpr[i].vreg.UD(1), &lsx_ctx->regs[2 * i + 1]);
124
CPUState *cpu_state;
100
+ }
125
int cpu, pin, i, start, num;
101
+ __put_user(read_fcc(env), &lsx_ctx->fcc);
126
- uint32_t cpuintc_phandle, eiointc_phandle, pch_pic_phandle, pch_msi_phandle;
102
+ __put_user(env->fcsr0, &lsx_ctx->fcsr);
103
+ } else {
104
+ struct target_fpu_context *fpu_ctx;
105
+ info = extctx->fpu.haddr;
106
+
107
+ __put_user(FPU_CTX_MAGIC, &info->magic);
108
+ __put_user(extctx->fpu.size, &info->size);
109
+
110
+ fpu_ctx = (struct target_fpu_context *)(info + 1);
111
+
112
+ for (i = 0; i < 32; ++i) {
113
+ __put_user(env->fpr[i].vreg.UD(0), &fpu_ctx->regs[i]);
114
+ }
115
+ __put_user(read_fcc(env), &fpu_ctx->fcc);
116
+ __put_user(env->fcsr0, &fpu_ctx->fcsr);
117
}
118
- __put_user(read_fcc(env), &fpu_ctx->fcc);
119
- __put_user(env->fcsr0, &fpu_ctx->fcsr);
120
127
121
/*
128
/*
122
* Set end context
129
* Extended IRQ model.
123
@@ -XXX,XX +XXX,XX @@ static bool parse_extcontext(struct extctx_layout *extctx, abi_ptr frame)
130
@@ -XXX,XX +XXX,XX @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
124
extctx->fpu.size = size;
131
memory_region_add_subregion(&lvms->system_iocsr, MAIL_SEND_ADDR,
125
extctx->size += size;
132
sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 1));
126
break;
133
127
+ case LSX_CTX_MAGIC:
134
- /* Add cpu interrupt-controller */
128
+ if (size < (sizeof(struct target_sctx_info) +
135
- fdt_add_cpuic_node(lvms, &cpuintc_phandle);
129
+ sizeof(struct target_lsx_context))) {
136
-
130
+ return false;
137
for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
131
+ }
138
cpu_state = qemu_get_cpu(cpu);
132
+ extctx->lsx.gaddr = frame;
139
cpudev = DEVICE(cpu_state);
133
+ extctx->lsx.size = size;
140
@@ -XXX,XX +XXX,XX @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
134
+ extctx->size += size;
135
+ break;
136
default:
137
return false;
138
}
141
}
139
@@ -XXX,XX +XXX,XX @@ static void restore_sigframe(CPULoongArchState *env,
142
}
140
struct extctx_layout *extctx)
143
141
{
144
- /* Add Extend I/O Interrupt Controller node */
142
int i;
145
- fdt_add_eiointc_node(lvms, &cpuintc_phandle, &eiointc_phandle);
143
+ abi_ulong fcc;
146
-
144
147
pch_pic = qdev_new(TYPE_LOONGARCH_PIC);
145
__get_user(env->pc, &sc->sc_pc);
148
num = VIRT_PCH_PIC_IRQ_NUM;
146
for (i = 1; i < 32; ++i) {
149
qdev_prop_set_uint32(pch_pic, "pch_pic_irq_num", num);
147
__get_user(env->gpr[i], &sc->sc_regs[i]);
150
@@ -XXX,XX +XXX,XX @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
148
}
151
qdev_connect_gpio_out(DEVICE(d), i, qdev_get_gpio_in(extioi, i));
149
152
}
150
- if (extctx->fpu.haddr) {
153
151
+ if (extctx->lsx.haddr) {
154
- /* Add PCH PIC node */
152
+ struct target_lsx_context *lsx_ctx =
155
- fdt_add_pch_pic_node(lvms, &eiointc_phandle, &pch_pic_phandle);
153
+ extctx->lsx.haddr + sizeof(struct target_sctx_info);
156
-
154
+
157
pch_msi = qdev_new(TYPE_LOONGARCH_PCH_MSI);
155
+ for (i = 0; i < 32; ++i) {
158
start = num;
156
+ __get_user(env->fpr[i].vreg.UD(0), &lsx_ctx->regs[2 * i]);
159
num = EXTIOI_IRQS - start;
157
+ __get_user(env->fpr[i].vreg.UD(1), &lsx_ctx->regs[2 * i + 1]);
160
@@ -XXX,XX +XXX,XX @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
158
+ }
161
qdev_get_gpio_in(extioi, i + start));
159
+ __get_user(fcc, &lsx_ctx->fcc);
162
}
160
+ write_fcc(env, fcc);
163
161
+ __get_user(env->fcsr0, &lsx_ctx->fcsr);
164
- /* Add PCH MSI node */
162
+ restore_fp_status(env);
165
- fdt_add_pch_msi_node(lvms, &eiointc_phandle, &pch_msi_phandle);
163
+ } else if (extctx->fpu.haddr) {
166
-
164
struct target_fpu_context *fpu_ctx =
167
- virt_devices_init(pch_pic, lvms, &pch_pic_phandle, &pch_msi_phandle);
165
extctx->fpu.haddr + sizeof(struct target_sctx_info);
168
+ virt_devices_init(pch_pic, lvms);
166
- abi_ulong fcc;
169
}
167
170
168
for (i = 0; i < 32; ++i) {
171
static void virt_firmware_init(LoongArchVirtMachineState *lvms)
169
- __get_user(env->fpr[i].vreg.D(0), &fpu_ctx->regs[i]);
172
@@ -XXX,XX +XXX,XX @@ static void virt_init(MachineState *machine)
170
+ __get_user(env->fpr[i].vreg.UD(0), &fpu_ctx->regs[i]);
173
cpu_model = LOONGARCH_CPU_TYPE_NAME("la464");
171
}
174
}
172
__get_user(fcc, &fpu_ctx->fcc);
175
173
write_fcc(env, fcc);
176
- create_fdt(lvms);
174
@@ -XXX,XX +XXX,XX @@ static abi_ptr get_sigframe(struct target_sigaction *ka,
177
-
175
178
/* Create IOCSR space */
176
sp = target_sigsp(get_sp_from_cpustate(env), ka);
179
memory_region_init_io(&lvms->system_iocsr, OBJECT(machine), NULL,
177
sp = ROUND_DOWN(sp, 16);
180
machine, "iocsr", UINT64_MAX);
178
- sp = setup_extcontext(extctx, sp);
181
@@ -XXX,XX +XXX,XX @@ static void virt_init(MachineState *machine)
179
+ sp = setup_extcontext(env, extctx, sp);
182
lacpu = LOONGARCH_CPU(cpu);
180
sp -= sizeof(struct target_rt_sigframe);
183
lacpu->phy_id = machine->possible_cpus->cpus[i].arch_id;
181
184
}
182
assert(QEMU_IS_ALIGNED(sp, 16));
185
- fdt_add_cpu_nodes(lvms);
183
@@ -XXX,XX +XXX,XX @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
186
- fdt_add_memory_nodes(machine);
184
force_sigsegv(sig);
187
fw_cfg_add_memory(machine);
185
return;
188
186
}
189
/* Node0 memory */
187
- extctx.fpu.haddr = (void *)frame + (extctx.fpu.gaddr - frame_addr);
190
@@ -XXX,XX +XXX,XX @@ static void virt_init(MachineState *machine)
188
- extctx.end.haddr = (void *)frame + (extctx.end.gaddr - frame_addr);
191
memmap_table,
189
+
192
sizeof(struct memmap_entry) * (memmap_entries));
190
+ if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE)) {
193
}
191
+ extctx.lsx.haddr = (void *)frame + (extctx.lsx.gaddr - frame_addr);
194
- fdt_add_fw_cfg_node(lvms);
192
+ extctx.end.haddr = (void *)frame + (extctx.end.gaddr - frame_addr);
195
- fdt_add_flash_node(lvms);
193
+ } else {
196
194
+ extctx.fpu.haddr = (void *)frame + (extctx.fpu.gaddr - frame_addr);
197
/* Initialize the IO interrupt subsystem */
195
+ extctx.end.haddr = (void *)frame + (extctx.end.gaddr - frame_addr);
198
virt_irq_init(lvms);
196
+ }
199
- platform_bus_add_all_fdt_nodes(machine->fdt, "/platic",
197
200
- VIRT_PLATFORM_BUS_BASEADDRESS,
198
tswap_siginfo(&frame->rs_info, info);
201
- VIRT_PLATFORM_BUS_SIZE,
199
202
- VIRT_PLATFORM_BUS_IRQ);
200
@@ -XXX,XX +XXX,XX @@ long do_rt_sigreturn(CPULoongArchState *env)
203
lvms->machine_done.notify = virt_done;
201
if (!frame) {
204
qemu_add_machine_init_done_notifier(&lvms->machine_done);
202
goto badframe;
205
/* connect powerdown request */
203
}
206
lvms->powerdown_notifier.notify = virt_powerdown_req;
204
- if (extctx.fpu.gaddr) {
207
qemu_register_powerdown_notifier(&lvms->powerdown_notifier);
205
+
208
206
+ if (extctx.lsx.gaddr) {
209
- /*
207
+ extctx.lsx.haddr = (void *)frame + (extctx.lsx.gaddr - frame_addr);
210
- * Since lowmem region starts from 0 and Linux kernel legacy start address
208
+ } else if (extctx.fpu.gaddr) {
211
- * at 2 MiB, FDT base address is located at 1 MiB to avoid NULL pointer
209
extctx.fpu.haddr = (void *)frame + (extctx.fpu.gaddr - frame_addr);
212
- * access. FDT size limit with 1 MiB.
210
}
213
- * Put the FDT into the memory map as a ROM image: this will ensure
211
214
- * the FDT is copied again upon reset, even if addr points into RAM.
215
- */
216
- qemu_fdt_dumpdtb(machine->fdt, lvms->fdt_size);
217
- rom_add_blob_fixed_as("fdt", machine->fdt, lvms->fdt_size, FDT_BASE,
218
- &address_space_memory);
219
- qemu_register_reset_nosnapshotload(qemu_fdt_randomize_seeds,
220
- rom_ptr_for_as(&address_space_memory, FDT_BASE, lvms->fdt_size));
221
-
222
lvms->bootinfo.ram_size = ram_size;
223
loongarch_load_kernel(machine, &lvms->bootinfo);
224
}
212
--
225
--
213
2.25.1
226
2.43.5
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
For CPU object, possible_cpu_arch_ids() function is used rather than
2
smp.cpus. With command -smp x, -device la464-loongarch-cpu, smp.cpus
3
is not accurate for all possible CPU objects, possible_cpu_arch_ids()
4
is used here.
2
5
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
4
Message-Id: <20231101030816.2353416-2-gaosong@loongson.cn>
7
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
5
Signed-off-by: Song Gao <gaosong@loongson.cn>
6
---
8
---
7
linux-user/loongarch64/cpu_loop.c | 13 +++++++++++++
9
hw/loongarch/virt.c | 39 +++++++++++++++++++++++++--------------
8
target/loongarch/insn_trans/trans_vec.c.inc | 11 -----------
10
1 file changed, 25 insertions(+), 14 deletions(-)
9
2 files changed, 13 insertions(+), 11 deletions(-)
10
11
11
diff --git a/linux-user/loongarch64/cpu_loop.c b/linux-user/loongarch64/cpu_loop.c
12
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
12
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
13
--- a/linux-user/loongarch64/cpu_loop.c
14
--- a/hw/loongarch/virt.c
14
+++ b/linux-user/loongarch64/cpu_loop.c
15
+++ b/hw/loongarch/virt.c
15
@@ -XXX,XX +XXX,XX @@ void cpu_loop(CPULoongArchState *env)
16
@@ -XXX,XX +XXX,XX @@ static void create_fdt(LoongArchVirtMachineState *lvms)
16
case EXCCODE_BCE:
17
static void fdt_add_cpu_nodes(const LoongArchVirtMachineState *lvms)
17
force_sig_fault(TARGET_SIGSYS, TARGET_SI_KERNEL, env->pc);
18
{
18
break;
19
int num;
20
- const MachineState *ms = MACHINE(lvms);
21
- int smp_cpus = ms->smp.cpus;
22
+ MachineState *ms = MACHINE(lvms);
23
+ MachineClass *mc = MACHINE_GET_CLASS(ms);
24
+ const CPUArchIdList *possible_cpus;
25
+ LoongArchCPU *cpu;
26
+ CPUState *cs;
27
+ char *nodename, *map_path;
28
29
qemu_fdt_add_subnode(ms->fdt, "/cpus");
30
qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#address-cells", 0x1);
31
qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#size-cells", 0x0);
32
33
/* cpu nodes */
34
- for (num = smp_cpus - 1; num >= 0; num--) {
35
- char *nodename = g_strdup_printf("/cpus/cpu@%d", num);
36
- LoongArchCPU *cpu = LOONGARCH_CPU(qemu_get_cpu(num));
37
- CPUState *cs = CPU(cpu);
38
+ possible_cpus = mc->possible_cpu_arch_ids(ms);
39
+ for (num = 0; num < possible_cpus->len; num++) {
40
+ cs = possible_cpus->cpus[num].cpu;
41
+ if (cs == NULL) {
42
+ continue;
43
+ }
19
+
44
+
20
+ /*
45
+ nodename = g_strdup_printf("/cpus/cpu@%d", num);
21
+ * Begin with LSX and LASX disabled, then enable on the first trap.
46
+ cpu = LOONGARCH_CPU(cs);
22
+ * In this way we can tell if the unit is in use. This is used to
47
23
+ * choose the layout of any signal frame.
48
qemu_fdt_add_subnode(ms->fdt, nodename);
24
+ */
49
qemu_fdt_setprop_string(ms->fdt, nodename, "device_type", "cpu");
25
+ case EXCCODE_SXD:
50
qemu_fdt_setprop_string(ms->fdt, nodename, "compatible",
26
+ env->CSR_EUEN |= R_CSR_EUEN_SXE_MASK;
51
cpu->dtb_compatible);
27
+ break;
52
- if (ms->possible_cpus->cpus[cs->cpu_index].props.has_node_id) {
28
+ case EXCCODE_ASXD:
53
+ if (possible_cpus->cpus[num].props.has_node_id) {
29
+ env->CSR_EUEN |= R_CSR_EUEN_ASXE_MASK;
54
qemu_fdt_setprop_cell(ms->fdt, nodename, "numa-node-id",
30
+ break;
55
- ms->possible_cpus->cpus[cs->cpu_index].props.node_id);
31
+
56
+ possible_cpus->cpus[num].props.node_id);
32
case EXCP_ATOMIC:
57
}
33
cpu_exec_step_atomic(cs);
58
qemu_fdt_setprop_cell(ms->fdt, nodename, "reg", num);
34
break;
59
qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle",
35
diff --git a/target/loongarch/insn_trans/trans_vec.c.inc b/target/loongarch/insn_trans/trans_vec.c.inc
60
@@ -XXX,XX +XXX,XX @@ static void fdt_add_cpu_nodes(const LoongArchVirtMachineState *lvms)
36
index XXXXXXX..XXXXXXX 100644
61
37
--- a/target/loongarch/insn_trans/trans_vec.c.inc
62
/*cpu map */
38
+++ b/target/loongarch/insn_trans/trans_vec.c.inc
63
qemu_fdt_add_subnode(ms->fdt, "/cpus/cpu-map");
39
@@ -XXX,XX +XXX,XX @@
64
+ for (num = 0; num < possible_cpus->len; num++) {
40
* Copyright (c) 2022-2023 Loongson Technology Corporation Limited
65
+ cs = possible_cpus->cpus[num].cpu;
41
*/
66
+ if (cs == NULL) {
42
67
+ continue;
43
-#ifndef CONFIG_USER_ONLY
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;
44
-
73
-
45
static bool check_vec(DisasContext *ctx, uint32_t oprsz)
74
+ nodename = g_strdup_printf("/cpus/cpu@%d", num);
46
{
75
if (ms->smp.threads > 1) {
47
if ((oprsz == 16) && ((ctx->base.tb->flags & HW_FLAGS_EUEN_SXE) == 0)) {
76
map_path = g_strdup_printf(
48
@@ -XXX,XX +XXX,XX @@ static bool check_vec(DisasContext *ctx, uint32_t oprsz)
77
"/cpus/cpu-map/socket%d/core%d/thread%d",
49
return true;
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
}
50
}
89
}
51
90
52
-#else
53
-
54
-static bool check_vec(DisasContext *ctx, uint32_t oprsz)
55
-{
56
- return true;
57
-}
58
-
59
-#endif
60
-
61
static bool gen_vvvv_ptr_vl(DisasContext *ctx, arg_vvvv *a, uint32_t oprsz,
62
gen_helper_gvec_4_ptr *fn)
63
{
64
--
91
--
65
2.25.1
92
2.43.5
diff view generated by jsdifflib
1
Some users may not need LSX/LASX, this patch allows the user
1
Like LBT feature, add type OnOffAuto for LSX feature setting. Also
2
enable/disable LSX/LASX features.
2
add LSX feature detection with new VM ioctl command, fallback to old
3
method if it is not supported.
3
4
4
e.g
5
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
5
'-cpu max,lsx=on,lasx=on' (default);
6
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
6
'-cpu max,lsx=on,lasx=off' (enabled LSX);
7
'-cpu max,lsx=off,lasx=on' (enabled LASX, LSX);
8
'-cpu max,lsx=off' (disable LSX and LASX).
9
10
Signed-off-by: Song Gao <gaosong@loongson.cn>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-Id: <20231020084925.3457084-3-gaosong@loongson.cn>
13
---
7
---
14
target/loongarch/cpu.c | 67 ++++++++++++++++++++++++++++++++++++++++++
8
target/loongarch/cpu.c | 38 +++++++++++++++------------
15
target/loongarch/cpu.h | 2 ++
9
target/loongarch/cpu.h | 2 ++
16
2 files changed, 69 insertions(+)
10
target/loongarch/kvm/kvm.c | 54 ++++++++++++++++++++++++++++++++++++++
11
3 files changed, 77 insertions(+), 17 deletions(-)
17
12
18
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
13
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
19
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
20
--- a/target/loongarch/cpu.c
15
--- a/target/loongarch/cpu.c
21
+++ b/target/loongarch/cpu.c
16
+++ b/target/loongarch/cpu.c
22
@@ -XXX,XX +XXX,XX @@ static void loongarch_la464_initfn(Object *obj)
17
@@ -XXX,XX +XXX,XX @@ static void loongarch_la464_initfn(Object *obj)
23
env->cpucfg[20] = data;
18
{
24
19
LoongArchCPU *cpu = LOONGARCH_CPU(obj);
25
env->CSR_ASID = FIELD_DP64(0, CSR_ASID, ASIDBITS, 0xa);
20
CPULoongArchState *env = &cpu->env;
26
+ loongarch_cpu_post_init(obj);
21
+ uint32_t data = 0;
27
}
22
int i;
28
23
29
static void loongarch_la132_initfn(Object *obj)
24
for (i = 0; i < 21; i++) {
30
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps loongarch_qemu_ops = {
25
@@ -XXX,XX +XXX,XX @@ static void loongarch_la464_initfn(Object *obj)
31
};
26
cpu->dtb_compatible = "loongarch,Loongson-3A5000";
32
#endif
27
env->cpucfg[0] = 0x14c010; /* PRID */
33
28
34
+static bool loongarch_get_lsx(Object *obj, Error **errp)
29
- uint32_t data = 0;
35
+{
30
data = FIELD_DP32(data, CPUCFG1, ARCH, 2);
36
+ LoongArchCPU *cpu = LOONGARCH_CPU(obj);
31
data = FIELD_DP32(data, CPUCFG1, PGMMU, 1);
37
+ bool ret;
32
data = FIELD_DP32(data, CPUCFG1, IOCSR, 1);
38
+
33
@@ -XXX,XX +XXX,XX @@ static void loongarch_la132_initfn(Object *obj)
39
+ if (FIELD_EX32(cpu->env.cpucfg[2], CPUCFG2, LSX)) {
34
{
40
+ ret = true;
35
LoongArchCPU *cpu = LOONGARCH_CPU(obj);
41
+ } else {
36
CPULoongArchState *env = &cpu->env;
42
+ ret = false;
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
+ }
43
+ }
89
+ }
44
+ return ret;
90
+
45
+}
91
+ cpu->env.cpucfg[2] = FIELD_DP32(val, CPUCFG2, LSX, value);
46
+
92
}
47
+static void loongarch_set_lsx(Object *obj, bool value, Error **errp)
93
48
+{
94
static bool loongarch_get_lasx(Object *obj, Error **errp)
49
+ LoongArchCPU *cpu = LOONGARCH_CPU(obj);
95
@@ -XXX,XX +XXX,XX @@ void loongarch_cpu_post_init(Object *obj)
50
+
96
{
51
+ if (value) {
97
LoongArchCPU *cpu = LOONGARCH_CPU(obj);
52
+ cpu->env.cpucfg[2] = FIELD_DP32(cpu->env.cpucfg[2], CPUCFG2, LSX, 1);
98
53
+ } else {
99
+ cpu->lsx = ON_OFF_AUTO_AUTO;
54
+ cpu->env.cpucfg[2] = FIELD_DP32(cpu->env.cpucfg[2], CPUCFG2, LSX, 0);
100
object_property_add_bool(obj, "lsx", loongarch_get_lsx,
55
+ cpu->env.cpucfg[2] = FIELD_DP32(cpu->env.cpucfg[2], CPUCFG2, LASX, 0);
101
loongarch_set_lsx);
56
+ }
102
object_property_add_bool(obj, "lasx", loongarch_get_lasx,
57
+}
103
@@ -XXX,XX +XXX,XX @@ void loongarch_cpu_post_init(Object *obj)
58
+
104
59
+static bool loongarch_get_lasx(Object *obj, Error **errp)
105
} else {
60
+{
106
cpu->lbt = ON_OFF_AUTO_OFF;
61
+ LoongArchCPU *cpu = LOONGARCH_CPU(obj);
107
+ cpu->pmu = ON_OFF_AUTO_OFF;
62
+ bool ret;
108
}
63
+
109
}
64
+ if (FIELD_EX32(cpu->env.cpucfg[2], CPUCFG2, LASX)) {
110
65
+ ret = true;
66
+ } else {
67
+ ret = false;
68
+ }
69
+ return ret;
70
+}
71
+
72
+static void loongarch_set_lasx(Object *obj, bool value, Error **errp)
73
+{
74
+ LoongArchCPU *cpu = LOONGARCH_CPU(obj);
75
+
76
+ if (value) {
77
+    if (!FIELD_EX32(cpu->env.cpucfg[2], CPUCFG2, LSX)) {
78
+ cpu->env.cpucfg[2] = FIELD_DP32(cpu->env.cpucfg[2], CPUCFG2, LSX, 1);
79
+    }
80
+ cpu->env.cpucfg[2] = FIELD_DP32(cpu->env.cpucfg[2], CPUCFG2, LASX, 1);
81
+ } else {
82
+ cpu->env.cpucfg[2] = FIELD_DP32(cpu->env.cpucfg[2], CPUCFG2, LASX, 0);
83
+ }
84
+}
85
+
86
+void loongarch_cpu_post_init(Object *obj)
87
+{
88
+ LoongArchCPU *cpu = LOONGARCH_CPU(obj);
89
+
90
+ if (FIELD_EX32(cpu->env.cpucfg[2], CPUCFG2, LSX)) {
91
+ object_property_add_bool(obj, "lsx", loongarch_get_lsx,
92
+ loongarch_set_lsx);
93
+ }
94
+ if (FIELD_EX32(cpu->env.cpucfg[2], CPUCFG2, LASX)) {
95
+ object_property_add_bool(obj, "lasx", loongarch_get_lasx,
96
+ loongarch_set_lasx);
97
+ }
98
+}
99
+
100
static void loongarch_cpu_init(Object *obj)
101
{
102
#ifndef CONFIG_USER_ONLY
103
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
104
index XXXXXXX..XXXXXXX 100644
112
index XXXXXXX..XXXXXXX 100644
105
--- a/target/loongarch/cpu.h
113
--- a/target/loongarch/cpu.h
106
+++ b/target/loongarch/cpu.h
114
+++ b/target/loongarch/cpu.h
107
@@ -XXX,XX +XXX,XX @@ void loongarch_cpu_list(void);
115
@@ -XXX,XX +XXX,XX @@ typedef struct LoongArchTLB LoongArchTLB;
108
#define LOONGARCH_CPU_TYPE_NAME(model) model LOONGARCH_CPU_TYPE_SUFFIX
116
#endif
109
#define CPU_RESOLVING_TYPE TYPE_LOONGARCH_CPU
117
110
118
enum loongarch_features {
111
+void loongarch_cpu_post_init(Object *obj);
119
+ LOONGARCH_FEATURE_LSX,
112
+
120
LOONGARCH_FEATURE_LBT, /* loongson binary translation extension */
113
#endif /* LOONGARCH_CPU_H */
121
LOONGARCH_FEATURE_PMU,
122
};
123
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
124
uint32_t phy_id;
125
OnOffAuto lbt;
126
OnOffAuto pmu;
127
+ OnOffAuto lsx;
128
129
/* 'compatible' string for this CPU for Linux device trees */
130
const char *dtb_compatible;
131
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
132
index XXXXXXX..XXXXXXX 100644
133
--- a/target/loongarch/kvm/kvm.c
134
+++ b/target/loongarch/kvm/kvm.c
135
@@ -XXX,XX +XXX,XX @@ static bool kvm_feature_supported(CPUState *cs, enum loongarch_features feature)
136
{
137
int ret;
138
struct kvm_device_attr attr;
139
+ uint64_t val;
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)
176
+{
177
+ CPULoongArchState *env = cpu_env(cs);
178
+ LoongArchCPU *cpu = LOONGARCH_CPU(cs);
179
+ bool kvm_supported;
180
+
181
+ kvm_supported = kvm_feature_supported(cs, LOONGARCH_FEATURE_LSX);
182
+ env->cpucfg[2] = FIELD_DP32(env->cpucfg[2], CPUCFG2, LSX, 0);
183
+ if (cpu->lsx == ON_OFF_AUTO_ON) {
184
+ if (kvm_supported) {
185
+ env->cpucfg[2] = FIELD_DP32(env->cpucfg[2], CPUCFG2, LSX, 1);
186
+ } else {
187
+ error_setg(errp, "'lsx' feature not supported by KVM on this host");
188
+ return -ENOTSUP;
189
+ }
190
+ } else if ((cpu->lsx == ON_OFF_AUTO_AUTO) && kvm_supported) {
191
+ env->cpucfg[2] = FIELD_DP32(env->cpucfg[2], CPUCFG2, LSX, 1);
192
+ }
193
+
194
+ return 0;
195
+}
196
+
197
static int kvm_cpu_check_lbt(CPUState *cs, Error **errp)
198
{
199
CPULoongArchState *env = cpu_env(cs);
200
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
201
brk_insn = val;
202
}
203
204
+ ret = kvm_cpu_check_lsx(cs, &local_err);
205
+ if (ret < 0) {
206
+ error_report_err(local_err);
207
+ }
208
+
209
ret = kvm_cpu_check_lbt(cs, &local_err);
210
if (ret < 0) {
211
error_report_err(local_err);
114
--
212
--
115
2.25.1
213
2.43.5
diff view generated by jsdifflib
1
We use cpu la464 for the 'max' cpu.
1
Like LSX feature, add type OnOffAuto for LASX feature setting.
2
2
3
Signed-off-by: Song Gao <gaosong@loongson.cn>
3
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
5
Message-Id: <20231020084925.3457084-2-gaosong@loongson.cn>
6
---
5
---
7
target/loongarch/cpu.c | 7 +++++++
6
target/loongarch/cpu.c | 50 +++++++++++++++++++++++------------
8
1 file changed, 7 insertions(+)
7
target/loongarch/cpu.h | 2 ++
8
target/loongarch/kvm/kvm.c | 53 ++++++++++++++++++++++++++++++++++++++
9
3 files changed, 89 insertions(+), 16 deletions(-)
9
10
10
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
11
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
12
--- a/target/loongarch/cpu.c
13
--- a/target/loongarch/cpu.c
13
+++ b/target/loongarch/cpu.c
14
+++ b/target/loongarch/cpu.c
14
@@ -XXX,XX +XXX,XX @@ static void loongarch_la132_initfn(Object *obj)
15
@@ -XXX,XX +XXX,XX @@ static void loongarch_set_lsx(Object *obj, bool value, Error **errp)
15
env->cpucfg[1] = data;
16
uint32_t val;
17
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;
16
}
54
}
17
55
18
+static void loongarch_max_initfn(Object *obj)
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
+
74
+ if (kvm_enabled()) {
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
+ }
86
+ }
87
+
88
+ cpu->env.cpucfg[2] = FIELD_DP32(val, CPUCFG2, LASX, value);
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,
100
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
101
index XXXXXXX..XXXXXXX 100644
102
--- a/target/loongarch/cpu.h
103
+++ b/target/loongarch/cpu.h
104
@@ -XXX,XX +XXX,XX @@ typedef struct LoongArchTLB LoongArchTLB;
105
106
enum loongarch_features {
107
LOONGARCH_FEATURE_LSX,
108
+ LOONGARCH_FEATURE_LASX,
109
LOONGARCH_FEATURE_LBT, /* loongson binary translation extension */
110
LOONGARCH_FEATURE_PMU,
111
};
112
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
113
OnOffAuto lbt;
114
OnOffAuto pmu;
115
OnOffAuto lsx;
116
+ OnOffAuto lasx;
117
118
/* 'compatible' string for this CPU for Linux device trees */
119
const char *dtb_compatible;
120
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
121
index XXXXXXX..XXXXXXX 100644
122
--- a/target/loongarch/kvm/kvm.c
123
+++ b/target/loongarch/kvm/kvm.c
124
@@ -XXX,XX +XXX,XX @@ static bool kvm_feature_supported(CPUState *cs, enum loongarch_features feature)
125
}
126
return false;
127
128
+ case LOONGARCH_FEATURE_LASX:
129
+ attr.group = KVM_LOONGARCH_VM_FEAT_CTRL;
130
+ attr.attr = KVM_LOONGARCH_VM_FEAT_LASX;
131
+ ret = kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr);
132
+ if (ret == 0) {
133
+ return true;
134
+ }
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)
19
+{
162
+{
20
+ /* '-cpu max' for TCG: we use cpu la464. */
163
+ CPULoongArchState *env = cpu_env(cs);
21
+ loongarch_la464_initfn(obj);
164
+ LoongArchCPU *cpu = LOONGARCH_CPU(cs);
165
+ bool kvm_supported;
166
+
167
+ kvm_supported = kvm_feature_supported(cs, LOONGARCH_FEATURE_LASX);
168
+ env->cpucfg[2] = FIELD_DP32(env->cpucfg[2], CPUCFG2, LASX, 0);
169
+ if (cpu->lasx == ON_OFF_AUTO_ON) {
170
+ if (kvm_supported) {
171
+ env->cpucfg[2] = FIELD_DP32(env->cpucfg[2], CPUCFG2, LASX, 1);
172
+ } else {
173
+ error_setg(errp, "'lasx' feature not supported by KVM on host");
174
+ return -ENOTSUP;
175
+ }
176
+ } else if ((cpu->lasx == ON_OFF_AUTO_AUTO) && kvm_supported) {
177
+ env->cpucfg[2] = FIELD_DP32(env->cpucfg[2], CPUCFG2, LASX, 1);
178
+ }
179
+
180
+ return 0;
22
+}
181
+}
23
+
182
+
24
static void loongarch_cpu_list_entry(gpointer data, gpointer user_data)
183
static int kvm_cpu_check_lbt(CPUState *cs, Error **errp)
25
{
184
{
26
const char *typename = object_class_get_name(OBJECT_CLASS(data));
185
CPULoongArchState *env = cpu_env(cs);
27
@@ -XXX,XX +XXX,XX @@ static const TypeInfo loongarch_cpu_type_infos[] = {
186
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
28
},
187
error_report_err(local_err);
29
DEFINE_LOONGARCH_CPU_TYPE(64, "la464", loongarch_la464_initfn),
188
}
30
DEFINE_LOONGARCH_CPU_TYPE(32, "la132", loongarch_la132_initfn),
189
31
+ DEFINE_LOONGARCH_CPU_TYPE(64, "max", loongarch_max_initfn),
190
+ ret = kvm_cpu_check_lasx(cs, &local_err);
32
};
191
+ if (ret < 0) {
33
192
+ error_report_err(local_err);
34
DEFINE_TYPES(loongarch_cpu_type_infos)
193
+ }
194
+
195
ret = kvm_cpu_check_lbt(cs, &local_err);
196
if (ret < 0) {
197
error_report_err(local_err);
35
--
198
--
36
2.25.1
199
2.43.5
diff view generated by jsdifflib
Deleted patch
1
Add support for the query-cpu-model-expansion QMP command to LoongArch.
2
We support query the cpu features.
3
1
4
e.g
5
la464 and max cpu support LSX/LASX, default enable,
6
la132 not support LSX/LASX.
7
8
1. start with '-cpu max,lasx=off'
9
10
(QEMU) query-cpu-model-expansion type=static model={"name":"max"}
11
{"return": {"model": {"name": "max", "props": {"lasx": false, "lsx": true}}}}
12
13
2. start with '-cpu la464,lasx=off'
14
(QEMU) query-cpu-model-expansion type=static model={"name":"la464"}
15
{"return": {"model": {"name": "max", "props": {"lasx": false, "lsx": true}}}
16
17
3. start with '-cpu la132,lasx=off'
18
qemu-system-loongarch64: can't apply global la132-loongarch-cpu.lasx=off: Property 'la132-loongarch-cpu.lasx' not found
19
20
4. start with '-cpu max,lasx=off' or start with '-cpu la464,lasx=off' query cpu model la132
21
(QEMU) query-cpu-model-expansion type=static model={"name":"la132"}
22
{"return": {"model": {"name": "la132"}}}
23
24
Acked-by: Markus Armbruster <armbru@redhat.com>
25
Signed-off-by: Song Gao <gaosong@loongson.cn>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
27
Message-Id: <20231020084925.3457084-4-gaosong@loongson.cn>
28
---
29
qapi/machine-target.json | 6 ++-
30
target/loongarch/loongarch-qmp-cmds.c | 64 +++++++++++++++++++++++++++
31
2 files changed, 68 insertions(+), 2 deletions(-)
32
33
diff --git a/qapi/machine-target.json b/qapi/machine-target.json
34
index XXXXXXX..XXXXXXX 100644
35
--- a/qapi/machine-target.json
36
+++ b/qapi/machine-target.json
37
@@ -XXX,XX +XXX,XX @@
38
'data': { 'model': 'CpuModelInfo' },
39
'if': { 'any': [ 'TARGET_S390X',
40
'TARGET_I386',
41
- 'TARGET_ARM' ] } }
42
+ 'TARGET_ARM',
43
+ 'TARGET_LOONGARCH64' ] } }
44
45
##
46
# @query-cpu-model-expansion:
47
@@ -XXX,XX +XXX,XX @@
48
'returns': 'CpuModelExpansionInfo',
49
'if': { 'any': [ 'TARGET_S390X',
50
'TARGET_I386',
51
- 'TARGET_ARM' ] } }
52
+ 'TARGET_ARM',
53
+ 'TARGET_LOONGARCH64' ] } }
54
55
##
56
# @CpuDefinitionInfo:
57
diff --git a/target/loongarch/loongarch-qmp-cmds.c b/target/loongarch/loongarch-qmp-cmds.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/target/loongarch/loongarch-qmp-cmds.c
60
+++ b/target/loongarch/loongarch-qmp-cmds.c
61
@@ -XXX,XX +XXX,XX @@
62
*/
63
64
#include "qemu/osdep.h"
65
+#include "qapi/error.h"
66
#include "qapi/qapi-commands-machine-target.h"
67
#include "cpu.h"
68
+#include "qapi/qmp/qerror.h"
69
+#include "qapi/qmp/qdict.h"
70
+#include "qapi/qobject-input-visitor.h"
71
+#include "qom/qom-qobject.h"
72
73
static void loongarch_cpu_add_definition(gpointer data, gpointer user_data)
74
{
75
@@ -XXX,XX +XXX,XX @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
76
77
return cpu_list;
78
}
79
+
80
+static const char *cpu_model_advertised_features[] = {
81
+ "lsx", "lasx", NULL
82
+};
83
+
84
+CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
85
+ CpuModelInfo *model,
86
+ Error **errp)
87
+{
88
+ CpuModelExpansionInfo *expansion_info;
89
+ QDict *qdict_out;
90
+ ObjectClass *oc;
91
+ Object *obj;
92
+ const char *name;
93
+ int i;
94
+
95
+ if (type != CPU_MODEL_EXPANSION_TYPE_STATIC) {
96
+ error_setg(errp, "The requested expansion type is not supported");
97
+ return NULL;
98
+ }
99
+
100
+ oc = cpu_class_by_name(TYPE_LOONGARCH_CPU, model->name);
101
+ if (!oc) {
102
+ error_setg(errp, "The CPU type '%s' is not a recognized LoongArch CPU type",
103
+ model->name);
104
+ return NULL;
105
+ }
106
+
107
+ obj = object_new(object_class_get_name(oc));
108
+
109
+ expansion_info = g_new0(CpuModelExpansionInfo, 1);
110
+ expansion_info->model = g_malloc0(sizeof(*expansion_info->model));
111
+ expansion_info->model->name = g_strdup(model->name);
112
+
113
+ qdict_out = qdict_new();
114
+
115
+ i = 0;
116
+ while ((name = cpu_model_advertised_features[i++]) != NULL) {
117
+ ObjectProperty *prop = object_property_find(obj, name);
118
+ if (prop) {
119
+ QObject *value;
120
+
121
+ assert(prop->get);
122
+ value = object_property_get_qobject(obj, name, &error_abort);
123
+
124
+ qdict_put_obj(qdict_out, name, value);
125
+ }
126
+ }
127
+
128
+ if (!qdict_size(qdict_out)) {
129
+ qobject_unref(qdict_out);
130
+ } else {
131
+ expansion_info->model->props = QOBJECT(qdict_out);
132
+ }
133
+
134
+ object_unref(obj);
135
+
136
+ return expansion_info;
137
+}
138
--
139
2.25.1
diff view generated by jsdifflib
Deleted patch
1
The LoongArch kernel supports 4K page size.
2
Change TARGET_PAGE_BITS to 12.
3
1
4
Signed-off-by: Song Gao <gaosong@loongson.cn>
5
Message-Id: <20231023024059.3858349-1-gaosong@loongson.cn>
6
---
7
target/loongarch/cpu-param.h | 2 +-
8
target/loongarch/tlb_helper.c | 9 ++++-----
9
2 files changed, 5 insertions(+), 6 deletions(-)
10
11
diff --git a/target/loongarch/cpu-param.h b/target/loongarch/cpu-param.h
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/loongarch/cpu-param.h
14
+++ b/target/loongarch/cpu-param.h
15
@@ -XXX,XX +XXX,XX @@
16
#define TARGET_PHYS_ADDR_SPACE_BITS 48
17
#define TARGET_VIRT_ADDR_SPACE_BITS 48
18
19
-#define TARGET_PAGE_BITS 14
20
+#define TARGET_PAGE_BITS 12
21
22
#endif
23
diff --git a/target/loongarch/tlb_helper.c b/target/loongarch/tlb_helper.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/target/loongarch/tlb_helper.c
26
+++ b/target/loongarch/tlb_helper.c
27
@@ -XXX,XX +XXX,XX @@ static int loongarch_map_tlb_entry(CPULoongArchState *env, hwaddr *physical,
28
tlb_rplv = 0;
29
}
30
31
+ /* Remove sw bit between bit12 -- bit PS*/
32
+ tlb_ppn = tlb_ppn & ~(((0x1UL << (tlb_ps - 12)) -1));
33
+
34
/* Check access rights */
35
if (!tlb_v) {
36
return TLBRET_INVALID;
37
@@ -XXX,XX +XXX,XX @@ static int loongarch_map_tlb_entry(CPULoongArchState *env, hwaddr *physical,
38
return TLBRET_DIRTY;
39
}
40
41
- /*
42
- * tlb_entry contains ppn[47:12] while 16KiB ppn is [47:15]
43
- * need adjust.
44
- */
45
*physical = (tlb_ppn << R_TLBENTRY_64_PPN_SHIFT) |
46
(address & MAKE_64BIT_MASK(0, tlb_ps));
47
*prot = PAGE_READ;
48
@@ -XXX,XX +XXX,XX @@ void helper_ldpte(CPULoongArchState *env, target_ulong base, target_ulong odd,
49
/* Move Global bit */
50
tmp0 = ((tmp0 & (1 << LOONGARCH_HGLOBAL_SHIFT)) >>
51
LOONGARCH_HGLOBAL_SHIFT) << R_TLBENTRY_G_SHIFT |
52
- (tmp0 & (~(1 << R_TLBENTRY_G_SHIFT)));
53
+ (tmp0 & (~(1 << LOONGARCH_HGLOBAL_SHIFT)));
54
ps = ptbase + ptwidth - 1;
55
if (odd) {
56
tmp0 += MAKE_64BIT_MASK(ps, 1);
57
--
58
2.25.1
diff view generated by jsdifflib
Deleted patch
1
See:
2
https://github.com/torvalds/linux/blob/master/arch/loongarch/kernel/signal.c
3
1
4
The alloc size is sizeof(struct target_fpu_context).
5
6
Signed-off-by: Song Gao <gaosong@loongson.cn>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-Id: <20231101030816.2353416-3-gaosong@loongson.cn>
9
---
10
linux-user/loongarch64/signal.c | 2 +-
11
1 file changed, 1 insertion(+), 1 deletion(-)
12
13
diff --git a/linux-user/loongarch64/signal.c b/linux-user/loongarch64/signal.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/linux-user/loongarch64/signal.c
16
+++ b/linux-user/loongarch64/signal.c
17
@@ -XXX,XX +XXX,XX @@ static abi_ptr setup_extcontext(struct extctx_layout *extctx, abi_ptr sp)
18
/* For qemu, there is no lazy fp context switch, so fp always present. */
19
extctx->flags = SC_USED_FP;
20
sp = extframe_alloc(extctx, &extctx->fpu,
21
- sizeof(struct target_rt_sigframe), FPU_CTX_ALIGN, sp);
22
+ sizeof(struct target_fpu_context), FPU_CTX_ALIGN, sp);
23
24
return sp;
25
}
26
--
27
2.25.1
diff view generated by jsdifflib
Deleted patch
1
Signed-off-by: Song Gao <gaosong@loongson.cn>
2
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
3
Message-Id: <20231101030816.2353416-5-gaosong@loongson.cn>
4
---
5
linux-user/loongarch64/signal.c | 24 ++++++++++++------------
6
1 file changed, 12 insertions(+), 12 deletions(-)
7
1
8
diff --git a/linux-user/loongarch64/signal.c b/linux-user/loongarch64/signal.c
9
index XXXXXXX..XXXXXXX 100644
10
--- a/linux-user/loongarch64/signal.c
11
+++ b/linux-user/loongarch64/signal.c
12
@@ -XXX,XX +XXX,XX @@
13
#define SC_USED_FP (1 << 0)
14
15
struct target_sigcontext {
16
- uint64_t sc_pc;
17
- uint64_t sc_regs[32];
18
- uint32_t sc_flags;
19
- uint64_t sc_extcontext[0] QEMU_ALIGNED(16);
20
+ abi_ulong sc_pc;
21
+ abi_ulong sc_regs[32];
22
+ abi_uint sc_flags;
23
+ abi_ulong sc_extcontext[0] QEMU_ALIGNED(16);
24
};
25
26
QEMU_BUILD_BUG_ON(sizeof(struct target_sigcontext) != sizeof_sigcontext);
27
@@ -XXX,XX +XXX,XX @@ QEMU_BUILD_BUG_ON(offsetof(struct target_sigcontext, sc_regs)
28
#define FPU_CTX_MAGIC 0x46505501
29
#define FPU_CTX_ALIGN 8
30
struct target_fpu_context {
31
- uint64_t regs[32];
32
- uint64_t fcc;
33
- uint32_t fcsr;
34
+ abi_ulong regs[32];
35
+ abi_ulong fcc;
36
+ abi_uint fcsr;
37
} QEMU_ALIGNED(FPU_CTX_ALIGN);
38
39
QEMU_BUILD_BUG_ON(offsetof(struct target_fpu_context, regs)
40
@@ -XXX,XX +XXX,XX @@ QEMU_BUILD_BUG_ON(offsetof(struct target_fpu_context, regs)
41
42
#define CONTEXT_INFO_ALIGN 16
43
struct target_sctx_info {
44
- uint32_t magic;
45
- uint32_t size;
46
- uint64_t padding;
47
+ abi_uint magic;
48
+ abi_uint size;
49
+ abi_ulong padding;
50
} QEMU_ALIGNED(CONTEXT_INFO_ALIGN);
51
52
QEMU_BUILD_BUG_ON(sizeof(struct target_sctx_info) != sizeof_sctx_info);
53
@@ -XXX,XX +XXX,XX @@ static bool parse_extcontext(struct extctx_layout *extctx, abi_ptr frame)
54
memset(extctx, 0, sizeof(*extctx));
55
56
while (1) {
57
- uint32_t magic, size;
58
+ abi_uint magic, size;
59
60
if (get_user_u32(magic, frame) || get_user_u32(size, frame + 4)) {
61
return false;
62
@@ -XXX,XX +XXX,XX @@ static void restore_sigframe(CPULoongArchState *env,
63
if (extctx->fpu.haddr) {
64
struct target_fpu_context *fpu_ctx =
65
extctx->fpu.haddr + sizeof(struct target_sctx_info);
66
- uint64_t fcc;
67
+ abi_ulong fcc;
68
69
for (i = 0; i < 32; ++i) {
70
__get_user(env->fpr[i].vreg.D(0), &fpu_ctx->regs[i]);
71
--
72
2.25.1
diff view generated by jsdifflib