1
The following changes since commit 4b7ea33074450bc6148c8e1545d78f179e64adb4:
1
The following changes since commit 38d0939b86e2eef6f6a622c6f1f7befda0146595:
2
2
3
Merge tag 'pull-request-2024-09-11' of https://gitlab.com/thuth/qemu into staging (2024-09-11 19:28:23 +0100)
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-20240912
7
https://gitlab.com/bibo-mao/qemu.git tags/pull-loongarch-20241227
8
8
9
for you to fetch changes up to 45d1fe46e5a6fe2b22b034e2b2bc0d941acd4b9e:
9
for you to fetch changes up to 5e360dabedb1ab1f15cce27a134ccbe4b8e18424:
10
10
11
hw/loongarch: Add acpi SPCR table support (2024-09-12 20:57:54 +0800)
11
target/loongarch: Use auto method with LASX feature (2024-12-27 11:33:06 +0800)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
pull-loongarch-20240912
14
pull-loongarch-20241227
15
v1 ... v2
16
1. Modify patch auther inconsistent with SOB
15
17
16
----------------------------------------------------------------
18
----------------------------------------------------------------
17
Bibo Mao (5):
19
Bibo Mao (5):
18
target/loongarch: Add compatible support about VM reboot
20
target/loongarch: Use actual operand size with vbsrl check
19
hw/loongarch: Remove default enable with VIRTIO_VGA device
21
hw/loongarch/virt: Create fdt table on machine creation done notification
20
target/loongarch/kvm: Add vCPU reset function
22
hw/loongarch/virt: Improve fdt table creation for CPU object
21
target/loongarch: Support QMP dump-guest-memory
23
target/loongarch: Use auto method with LSX feature
22
hw/loongarch: Add acpi SPCR table support
24
target/loongarch: Use auto method with LASX feature
23
25
24
Jason A. Donenfeld (2):
26
Guo Hongyu (1):
25
hw/loongarch: virt: support up to 4 serial ports
27
target/loongarch: Fix vldi inst
26
hw/loongarch: virt: pass random seed to fdt
27
28
28
hw/loongarch/Kconfig | 1 -
29
hw/loongarch/virt.c | 142 ++++++++++++++----------
29
hw/loongarch/acpi-build.c | 63 +++++++++++--
30
target/loongarch/cpu.c | 86 ++++++++------
30
hw/loongarch/virt.c | 33 ++++---
31
target/loongarch/cpu.h | 4 +
31
include/hw/pci-host/ls7a.h | 9 +-
32
target/loongarch/kvm/kvm.c | 107 ++++++++++++++++++
32
target/loongarch/arch_dump.c | 167 +++++++++++++++++++++++++++++++++++
33
target/loongarch/tcg/insn_trans/trans_vec.c.inc | 4 +-
33
target/loongarch/cpu.c | 17 +++-
34
5 files changed, 249 insertions(+), 94 deletions(-)
34
target/loongarch/internals.h | 2 +
35
target/loongarch/kvm/kvm.c | 5 +-
36
target/loongarch/kvm/kvm_loongarch.h | 2 +-
37
target/loongarch/meson.build | 1 +
38
10 files changed, 274 insertions(+), 26 deletions(-)
39
create mode 100644 target/loongarch/arch_dump.c
diff view generated by jsdifflib
Deleted patch
1
From: Bibo Mao <maobibo@loongson.cn>
2
1
3
With edk2-stable202408 LoongArch UEFI bios, CSR PGD register is set only
4
if its value is equal to zero for boot cpu, it causes reboot issue. Since
5
CSR PGD register is changed with linux kernel, UEFI BIOS cannot use it.
6
7
Add workaround to clear CSR registers relative with TLB in function
8
loongarch_cpu_reset_hold(), so that VM can reboot with edk2-stable202408
9
UEFI bios.
10
11
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
12
Reviewed-by: Song Gao <gaosong@loongson.cn>
13
Message-Id: <20240827035807.3326293-1-maobibo@loongson.cn>
14
Signed-off-by: Song Gao <gaosong@loongson.cn>
15
---
16
target/loongarch/cpu.c | 14 ++++++++++++++
17
1 file changed, 14 insertions(+)
18
19
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/loongarch/cpu.c
22
+++ b/target/loongarch/cpu.c
23
@@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_reset_hold(Object *obj, ResetType type)
24
env->CSR_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR, 0);
25
env->CSR_MERRCTL = FIELD_DP64(env->CSR_MERRCTL, CSR_MERRCTL, ISMERR, 0);
26
env->CSR_TID = cs->cpu_index;
27
+ /*
28
+ * Workaround for edk2-stable202408, CSR PGD register is set only if
29
+ * its value is equal to zero for boot cpu, it causes reboot issue.
30
+ *
31
+ * Here clear CSR registers relative with TLB.
32
+ */
33
+ env->CSR_PGDH = 0;
34
+ env->CSR_PGDL = 0;
35
+ env->CSR_PWCL = 0;
36
+ env->CSR_PWCH = 0;
37
+ env->CSR_STLBPS = 0;
38
+ env->CSR_EENTRY = 0;
39
+ env->CSR_TLBRENTRY = 0;
40
+ env->CSR_MERRENTRY = 0;
41
42
for (n = 0; n < 4; n++) {
43
env->CSR_DMW[n] = FIELD_DP64(env->CSR_DMW[n], CSR_DMW, PLV0, 0);
44
--
45
2.34.1
diff view generated by jsdifflib
1
From: Bibo Mao <maobibo@loongson.cn>
1
From: Guo Hongyu <guohongyu24@mails.ucas.ac.cn>
2
2
3
Serial port console redirection table can be used for default serial
3
Refer to the link below for a description of the vldi instructions:
4
port selection, like chosen stdout-path selection with FDT method.
4
https://jia.je/unofficial-loongarch-intrinsics-guide/lsx/misc/#synopsis_88
5
Fixed errors in vldi instruction implementation.
5
6
6
With acpi SPCR table added, early debug console can be parsed from
7
Signed-off-by: Guo Hongyu <guohongyu24@mails.ucas.ac.cn>
7
SPCR table with simple kernel parameter earlycon rather than
8
Tested-by: Xianglai Li <lixianglai@loongson.cn>
8
earlycon=uart,mmio,0x1fe001e0
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>
12
---
13
target/loongarch/tcg/insn_trans/trans_vec.c.inc | 2 +-
14
1 file changed, 1 insertion(+), 1 deletion(-)
9
15
10
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
16
diff --git a/target/loongarch/tcg/insn_trans/trans_vec.c.inc b/target/loongarch/tcg/insn_trans/trans_vec.c.inc
11
Reviewed-by: Song Gao <gaosong@loongson.cn>
12
Message-Id: <20240907073037.243353-1-maobibo@loongson.cn>
13
Signed-off-by: Song Gao <gaosong@loongson.cn>
14
---
15
hw/loongarch/acpi-build.c | 40 +++++++++++++++++++++++++++++++++++++++
16
1 file changed, 40 insertions(+)
17
18
diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c
19
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/loongarch/acpi-build.c
18
--- a/target/loongarch/tcg/insn_trans/trans_vec.c.inc
21
+++ b/hw/loongarch/acpi-build.c
19
+++ b/target/loongarch/tcg/insn_trans/trans_vec.c.inc
22
@@ -XXX,XX +XXX,XX @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
20
@@ -XXX,XX +XXX,XX @@ static uint64_t vldi_get_value(DisasContext *ctx, uint32_t imm)
23
acpi_table_end(linker, &table);
21
break;
24
}
22
case 1:
25
23
/* data: {2{16'0, imm[7:0], 8'0}} */
26
+/*
24
- data = (t << 24) | (t << 8);
27
+ * Serial Port Console Redirection Table (SPCR)
25
+ data = (t << 40) | (t << 8);
28
+ * https://learn.microsoft.com/en-us/windows-hardware/drivers/serports/serial-port-console-redirection-table
26
break;
29
+ */
27
case 2:
30
+static void
28
/* data: {2{8'0, imm[7:0], 16'0}} */
31
+spcr_setup(GArray *table_data, BIOSLinker *linker, MachineState *machine)
32
+{
33
+ LoongArchVirtMachineState *lvms;
34
+ AcpiSpcrData serial = {
35
+ .interface_type = 0, /* 16550 compatible */
36
+ .base_addr.id = AML_AS_SYSTEM_MEMORY,
37
+ .base_addr.width = 32,
38
+ .base_addr.offset = 0,
39
+ .base_addr.size = 1,
40
+ .base_addr.addr = VIRT_UART_BASE,
41
+ .interrupt_type = 0, /* Interrupt not supported */
42
+ .pc_interrupt = 0,
43
+ .interrupt = VIRT_UART_IRQ,
44
+ .baud_rate = 7, /* 115200 */
45
+ .parity = 0,
46
+ .stop_bits = 1,
47
+ .flow_control = 0,
48
+ .terminal_type = 3, /* ANSI */
49
+ .language = 0, /* Language */
50
+ .pci_device_id = 0xffff, /* not a PCI device*/
51
+ .pci_vendor_id = 0xffff, /* not a PCI device*/
52
+ .pci_bus = 0,
53
+ .pci_device = 0,
54
+ .pci_function = 0,
55
+ .pci_flags = 0,
56
+ .pci_segment = 0,
57
+ };
58
+
59
+ lvms = LOONGARCH_VIRT_MACHINE(machine);
60
+ build_spcr(table_data, linker, &serial, 2, lvms->oem_id,
61
+ lvms->oem_table_id);
62
+}
63
+
64
typedef
65
struct AcpiBuildState {
66
/* Copy of table in RAM (for patching). */
67
@@ -XXX,XX +XXX,XX @@ static void acpi_build(AcpiBuildTables *tables, MachineState *machine)
68
69
acpi_add_table(table_offsets, tables_blob);
70
build_srat(tables_blob, tables->linker, machine);
71
+ acpi_add_table(table_offsets, tables_blob);
72
+ spcr_setup(tables_blob, tables->linker, machine);
73
74
if (machine->numa_state->num_nodes) {
75
if (machine->numa_state->have_numa_distance) {
76
--
29
--
77
2.34.1
30
2.43.5
diff view generated by jsdifflib
1
From: Bibo Mao <maobibo@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
For virtio VGA deivce libvirt will select VIRTIO_VGA firstly rather than
5
Here actual operand size is used.
4
VIRTIO_GPU, VIRTIO_VGA device supports frame buffer however it requires
5
legacy VGA compatible support. Frame buffer area 0xa0000 -- 0xc0000
6
conflicts with low memory area 0 -- 0x10000000.
7
6
8
Here remove default support for VIRTIO_VGA device, VIRTIO_GPU is prefered
7
Cc: qemu-stable@nongnu.org
9
on LoongArch system. For frame buffer video card support, standard VGA can
8
Fixes: df97f338076 ("target/loongarch: Implement xvreplve xvinsve0 xvpickve")
10
be used.
9
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
---
13
target/loongarch/tcg/insn_trans/trans_vec.c.inc | 2 +-
14
1 file changed, 1 insertion(+), 1 deletion(-)
11
15
12
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
16
diff --git a/target/loongarch/tcg/insn_trans/trans_vec.c.inc b/target/loongarch/tcg/insn_trans/trans_vec.c.inc
13
Reviewed-by: Song Gao <gaosong@loongson.cn>
17
index XXXXXXX..XXXXXXX 100644
14
Message-Id: <20240823073050.2619484-1-maobibo@loongson.cn>
18
--- a/target/loongarch/tcg/insn_trans/trans_vec.c.inc
15
Signed-off-by: Song Gao <gaosong@loongson.cn>
19
+++ b/target/loongarch/tcg/insn_trans/trans_vec.c.inc
16
---
20
@@ -XXX,XX +XXX,XX @@ static bool do_vbsrl_v(DisasContext *ctx, arg_vv_i *a, uint32_t oprsz)
17
hw/loongarch/Kconfig | 1 -
21
{
18
1 file changed, 1 deletion(-)
22
int i, ofs;
23
24
- if (!check_vec(ctx, 32)) {
25
+ if (!check_vec(ctx, oprsz)) {
26
return true;
27
}
28
29
--
30
2.43.5
19
31
20
diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig
32
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/loongarch/Kconfig
23
+++ b/hw/loongarch/Kconfig
24
@@ -XXX,XX +XXX,XX @@ config LOONGARCH_VIRT
25
select DEVICE_TREE
26
select PCI
27
select PCI_EXPRESS_GENERIC_BRIDGE
28
- imply VIRTIO_VGA
29
imply PCI_DEVICES
30
imply NVDIMM
31
imply TPM_TIS_SYSBUS
32
--
33
2.34.1
diff view generated by jsdifflib
1
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
1
The same with ACPI table, fdt table is created on machine done
2
notification. Some objects like CPU objects can be created with cold-plug
3
method with command such as -smp x, -device la464-loongarch-cpu, so all
4
objects finish to create when machine is done.
2
5
3
In order to support additional channels of communication using
6
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
4
`-serial`, add several serial ports, up to the standard 4 generally
7
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
5
supported by the 8250 driver.
8
---
9
hw/loongarch/virt.c | 103 ++++++++++++++++++++++++--------------------
10
1 file changed, 57 insertions(+), 46 deletions(-)
6
11
7
Fixed: https://lore.kernel.org/all/20240907143439.2792924-1-Jason@zx2c4.com/
8
9
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
10
Tested-by: Bibo Mao <maobibo@loongson.cn>
11
[gaosong: ACPI uart need't reverse order]
12
Signed-off-by: Song Gao <gaosong@loongson.cn>
13
Message-Id: <20240907143439.2792924-1-Jason@zx2c4.com>
14
---
15
hw/loongarch/acpi-build.c | 23 +++++++++++++++--------
16
hw/loongarch/virt.c | 27 +++++++++++++++++----------
17
include/hw/pci-host/ls7a.h | 9 +++++----
18
3 files changed, 37 insertions(+), 22 deletions(-)
19
20
diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/loongarch/acpi-build.c
23
+++ b/hw/loongarch/acpi-build.c
24
@@ -XXX,XX +XXX,XX @@
25
26
#include "hw/acpi/generic_event_device.h"
27
#include "hw/pci-host/gpex.h"
28
+#include "sysemu/sysemu.h"
29
#include "sysemu/tpm.h"
30
#include "hw/platform-bus.h"
31
#include "hw/acpi/aml-build.h"
32
@@ -XXX,XX +XXX,XX @@ struct AcpiBuildState {
33
MemoryRegion *linker_mr;
34
} AcpiBuildState;
35
36
-static void build_uart_device_aml(Aml *table)
37
+static void build_uart_device_aml(Aml *table, int index)
38
{
39
Aml *dev;
40
Aml *crs;
41
Aml *pkg0, *pkg1, *pkg2;
42
- uint32_t uart_irq = VIRT_UART_IRQ;
43
-
44
- Aml *scope = aml_scope("_SB");
45
- dev = aml_device("COMA");
46
+ Aml *scope;
47
+ uint32_t uart_irq;
48
+ uint64_t base;
49
+
50
+ uart_irq = VIRT_UART_IRQ + index;
51
+ base = VIRT_UART_BASE + index * VIRT_UART_SIZE;
52
+ scope = aml_scope("_SB");
53
+ dev = aml_device("COM%d", index);
54
aml_append(dev, aml_name_decl("_HID", aml_string("PNP0501")));
55
- aml_append(dev, aml_name_decl("_UID", aml_int(0)));
56
+ aml_append(dev, aml_name_decl("_UID", aml_int(index)));
57
aml_append(dev, aml_name_decl("_CCA", aml_int(1)));
58
crs = aml_resource_template();
59
aml_append(crs,
60
aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,
61
AML_NON_CACHEABLE, AML_READ_WRITE,
62
- 0, VIRT_UART_BASE, VIRT_UART_BASE + VIRT_UART_SIZE - 1,
63
+ 0, base, base + VIRT_UART_SIZE - 1,
64
0, VIRT_UART_SIZE));
65
aml_append(crs, aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH,
66
AML_SHARED, &uart_irq, 1));
67
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_tpm(Aml *scope, LoongArchVirtMachineState *vms)
68
static void
69
build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine)
70
{
71
+ int i;
72
Aml *dsdt, *scope, *pkg;
73
LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine);
74
AcpiTable table = { .sig = "DSDT", .rev = 1, .oem_id = lvms->oem_id,
75
@@ -XXX,XX +XXX,XX @@ build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine)
76
77
acpi_table_begin(&table, table_data);
78
dsdt = init_aml_allocator();
79
- build_uart_device_aml(dsdt);
80
+ for (i = 0; i < VIRT_UART_COUNT; i++)
81
+ build_uart_device_aml(dsdt, i);
82
build_pci_device_aml(dsdt, lvms);
83
build_la_ged_aml(dsdt, machine);
84
build_flash_aml(dsdt, lvms);
85
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
86
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
87
--- a/hw/loongarch/virt.c
14
--- a/hw/loongarch/virt.c
88
+++ b/hw/loongarch/virt.c
15
+++ b/hw/loongarch/virt.c
89
@@ -XXX,XX +XXX,XX @@ static void fdt_add_rtc_node(LoongArchVirtMachineState *lvms,
16
@@ -XXX,XX +XXX,XX @@ static void virt_build_smbios(LoongArchVirtMachineState *lvms)
90
}
17
}
91
18
}
92
static void fdt_add_uart_node(LoongArchVirtMachineState *lvms,
19
93
- uint32_t *pch_pic_phandle)
20
+static void virt_fdt_setup(LoongArchVirtMachineState *lvms)
94
+ uint32_t *pch_pic_phandle, hwaddr base,
21
+{
95
+ int irq, bool chosen)
22
+ MachineState *machine = MACHINE(lvms);
96
{
23
+ uint32_t cpuintc_phandle, eiointc_phandle, pch_pic_phandle, pch_msi_phandle;
97
char *nodename;
24
+ int i;
98
- hwaddr base = VIRT_UART_BASE;
25
+
99
hwaddr size = VIRT_UART_SIZE;
26
+ create_fdt(lvms);
100
MachineState *ms = MACHINE(lvms);
27
+ fdt_add_cpu_nodes(lvms);
101
28
+ fdt_add_memory_nodes(machine);
102
@@ -XXX,XX +XXX,XX @@ static void fdt_add_uart_node(LoongArchVirtMachineState *lvms,
29
+ fdt_add_fw_cfg_node(lvms);
103
qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "ns16550a");
30
+ fdt_add_flash_node(lvms);
104
qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", 0x0, base, 0x0, size);
31
+
105
qemu_fdt_setprop_cell(ms->fdt, nodename, "clock-frequency", 100000000);
32
+ /* Add cpu interrupt-controller */
106
- qemu_fdt_setprop_string(ms->fdt, "/chosen", "stdout-path", nodename);
33
+ fdt_add_cpuic_node(lvms, &cpuintc_phandle);
107
- qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts",
34
+ /* Add Extend I/O Interrupt Controller node */
108
- VIRT_UART_IRQ - VIRT_GSI_BASE, 0x4);
35
+ fdt_add_eiointc_node(lvms, &cpuintc_phandle, &eiointc_phandle);
109
+ if (chosen)
36
+ /* Add PCH PIC node */
110
+ qemu_fdt_setprop_string(ms->fdt, "/chosen", "stdout-path", nodename);
37
+ fdt_add_pch_pic_node(lvms, &eiointc_phandle, &pch_pic_phandle);
111
+ qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", irq, 0x4);
38
+ /* Add PCH MSI node */
112
qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent",
39
+ fdt_add_pch_msi_node(lvms, &eiointc_phandle, &pch_msi_phandle);
113
*pch_pic_phandle);
40
+ /* Add pcie node */
114
g_free(nodename);
41
+ fdt_add_pcie_node(lvms, &pch_pic_phandle, &pch_msi_phandle);
115
@@ -XXX,XX +XXX,XX @@ static void virt_devices_init(DeviceState *pch_pic,
42
+
116
/* Add pcie node */
117
fdt_add_pcie_node(lvms, pch_pic_phandle, pch_msi_phandle);
118
119
- serial_mm_init(get_system_memory(), VIRT_UART_BASE, 0,
120
- qdev_get_gpio_in(pch_pic,
121
- VIRT_UART_IRQ - VIRT_GSI_BASE),
122
- 115200, serial_hd(0), DEVICE_LITTLE_ENDIAN);
123
- fdt_add_uart_node(lvms, pch_pic_phandle);
124
+ /*
43
+ /*
125
+ * Create uart fdt node in reverse order so that they appear
44
+ * Create uart fdt node in reverse order so that they appear
126
+ * in the finished device tree lowest address first
45
+ * in the finished device tree lowest address first
127
+ */
46
+ */
128
+ for (i = VIRT_UART_COUNT; i --> 0;) {
47
+ for (i = VIRT_UART_COUNT; i-- > 0;) {
129
+ hwaddr base = VIRT_UART_BASE + i * VIRT_UART_SIZE;
48
+ hwaddr base = VIRT_UART_BASE + i * VIRT_UART_SIZE;
130
+ int irq = VIRT_UART_IRQ + i - VIRT_GSI_BASE;
49
+ int irq = VIRT_UART_IRQ + i - VIRT_GSI_BASE;
131
+ serial_mm_init(get_system_memory(), base, 0,
50
+ fdt_add_uart_node(lvms, &pch_pic_phandle, base, irq, i == 0);
132
+ qdev_get_gpio_in(pch_pic, irq),
133
+ 115200, serial_hd(i), DEVICE_LITTLE_ENDIAN);
134
+ fdt_add_uart_node(lvms, pch_pic_phandle, base, irq, i == 0);
135
+ }
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
}
136
111
137
/* Network init */
112
/* Network init */
138
pci_init_nic_devices(pci_bus, mc->default_nic);
113
@@ -XXX,XX +XXX,XX @@ static void virt_devices_init(DeviceState *pch_pic,
139
diff --git a/include/hw/pci-host/ls7a.h b/include/hw/pci-host/ls7a.h
114
sysbus_create_simple("ls7a_rtc", VIRT_RTC_REG_BASE,
140
index XXXXXXX..XXXXXXX 100644
115
qdev_get_gpio_in(pch_pic,
141
--- a/include/hw/pci-host/ls7a.h
116
VIRT_RTC_IRQ - VIRT_GSI_BASE));
142
+++ b/include/hw/pci-host/ls7a.h
117
- fdt_add_rtc_node(lvms, pch_pic_phandle);
143
@@ -XXX,XX +XXX,XX @@
118
- fdt_add_ged_reset(lvms);
144
#define VIRT_PCH_PIC_IRQ_NUM 32
119
145
#define VIRT_GSI_BASE 64
120
/* acpi ged */
146
#define VIRT_DEVICE_IRQS 16
121
lvms->acpi_ged = create_acpi_ged(pch_pic, lvms);
147
+#define VIRT_UART_COUNT 4
122
@@ -XXX,XX +XXX,XX @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
148
#define VIRT_UART_IRQ (VIRT_GSI_BASE + 2)
123
CPULoongArchState *env;
149
#define VIRT_UART_BASE 0x1fe001e0
124
CPUState *cpu_state;
150
-#define VIRT_UART_SIZE 0X100
125
int cpu, pin, i, start, num;
151
-#define VIRT_RTC_IRQ (VIRT_GSI_BASE + 3)
126
- uint32_t cpuintc_phandle, eiointc_phandle, pch_pic_phandle, pch_msi_phandle;
152
+#define VIRT_UART_SIZE 0x100
127
153
+#define VIRT_RTC_IRQ (VIRT_GSI_BASE + 6)
128
/*
154
#define VIRT_MISC_REG_BASE (VIRT_PCH_REG_BASE + 0x00080000)
129
* Extended IRQ model.
155
#define VIRT_RTC_REG_BASE (VIRT_MISC_REG_BASE + 0x00050100)
130
@@ -XXX,XX +XXX,XX @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
156
#define VIRT_RTC_LEN 0x100
131
memory_region_add_subregion(&lvms->system_iocsr, MAIL_SEND_ADDR,
157
-#define VIRT_SCI_IRQ (VIRT_GSI_BASE + 4)
132
sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 1));
158
+#define VIRT_SCI_IRQ (VIRT_GSI_BASE + 7)
133
159
134
- /* Add cpu interrupt-controller */
160
#define VIRT_PLATFORM_BUS_BASEADDRESS 0x16000000
135
- fdt_add_cpuic_node(lvms, &cpuintc_phandle);
161
#define VIRT_PLATFORM_BUS_SIZE 0x2000000
136
-
162
#define VIRT_PLATFORM_BUS_NUM_IRQS 2
137
for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
163
-#define VIRT_PLATFORM_BUS_IRQ (VIRT_GSI_BASE + 5)
138
cpu_state = qemu_get_cpu(cpu);
164
+#define VIRT_PLATFORM_BUS_IRQ (VIRT_GSI_BASE + 8)
139
cpudev = DEVICE(cpu_state);
165
#endif
140
@@ -XXX,XX +XXX,XX @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
141
}
142
}
143
144
- /* Add Extend I/O Interrupt Controller node */
145
- fdt_add_eiointc_node(lvms, &cpuintc_phandle, &eiointc_phandle);
146
-
147
pch_pic = qdev_new(TYPE_LOONGARCH_PIC);
148
num = VIRT_PCH_PIC_IRQ_NUM;
149
qdev_prop_set_uint32(pch_pic, "pch_pic_irq_num", num);
150
@@ -XXX,XX +XXX,XX @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
151
qdev_connect_gpio_out(DEVICE(d), i, qdev_get_gpio_in(extioi, i));
152
}
153
154
- /* Add PCH PIC node */
155
- fdt_add_pch_pic_node(lvms, &eiointc_phandle, &pch_pic_phandle);
156
-
157
pch_msi = qdev_new(TYPE_LOONGARCH_PCH_MSI);
158
start = num;
159
num = EXTIOI_IRQS - start;
160
@@ -XXX,XX +XXX,XX @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
161
qdev_get_gpio_in(extioi, i + start));
162
}
163
164
- /* Add PCH MSI node */
165
- fdt_add_pch_msi_node(lvms, &eiointc_phandle, &pch_msi_phandle);
166
-
167
- virt_devices_init(pch_pic, lvms, &pch_pic_phandle, &pch_msi_phandle);
168
+ virt_devices_init(pch_pic, lvms);
169
}
170
171
static void virt_firmware_init(LoongArchVirtMachineState *lvms)
172
@@ -XXX,XX +XXX,XX @@ static void virt_init(MachineState *machine)
173
cpu_model = LOONGARCH_CPU_TYPE_NAME("la464");
174
}
175
176
- create_fdt(lvms);
177
-
178
/* Create IOCSR space */
179
memory_region_init_io(&lvms->system_iocsr, OBJECT(machine), NULL,
180
machine, "iocsr", UINT64_MAX);
181
@@ -XXX,XX +XXX,XX @@ static void virt_init(MachineState *machine)
182
lacpu = LOONGARCH_CPU(cpu);
183
lacpu->phy_id = machine->possible_cpus->cpus[i].arch_id;
184
}
185
- fdt_add_cpu_nodes(lvms);
186
- fdt_add_memory_nodes(machine);
187
fw_cfg_add_memory(machine);
188
189
/* Node0 memory */
190
@@ -XXX,XX +XXX,XX @@ static void virt_init(MachineState *machine)
191
memmap_table,
192
sizeof(struct memmap_entry) * (memmap_entries));
193
}
194
- fdt_add_fw_cfg_node(lvms);
195
- fdt_add_flash_node(lvms);
196
197
/* Initialize the IO interrupt subsystem */
198
virt_irq_init(lvms);
199
- platform_bus_add_all_fdt_nodes(machine->fdt, "/platic",
200
- VIRT_PLATFORM_BUS_BASEADDRESS,
201
- VIRT_PLATFORM_BUS_SIZE,
202
- VIRT_PLATFORM_BUS_IRQ);
203
lvms->machine_done.notify = virt_done;
204
qemu_add_machine_init_done_notifier(&lvms->machine_done);
205
/* connect powerdown request */
206
lvms->powerdown_notifier.notify = virt_powerdown_req;
207
qemu_register_powerdown_notifier(&lvms->powerdown_notifier);
208
209
- /*
210
- * Since lowmem region starts from 0 and Linux kernel legacy start address
211
- * at 2 MiB, FDT base address is located at 1 MiB to avoid NULL pointer
212
- * access. FDT size limit with 1 MiB.
213
- * Put the FDT into the memory map as a ROM image: this will ensure
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
}
166
--
225
--
167
2.34.1
226
2.43.5
diff view generated by jsdifflib
1
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
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
If the FDT contains /chosen/rng-seed, then the Linux RNG will use it to
6
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
4
initialize early. Set this using the usual guest random number
7
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
5
generation function.
6
7
This is the same procedure that's done in b91b6b5a2c ("hw/microblaze:
8
pass random seed to fdt"), e4b4f0b71c ("hw/riscv: virt: pass random seed
9
to fdt"), c6fe3e6b4c ("hw/openrisc: virt: pass random seed to fdt"),
10
67f7e426e5 ("hw/i386: pass RNG seed via setup_data entry"), c287941a4d
11
("hw/rx: pass random seed to fdt"), 5e19cc68fb ("hw/mips: boston: pass
12
random seed to fdt"), 6b23a67916 ("hw/nios2: virt: pass random seed to fdt")
13
c4b075318e ("hw/ppc: pass random seed to fdt"), and 5242876f37
14
("hw/arm/virt: dt: add rng-seed property").
15
16
These earlier commits later were amended to rerandomize the RNG seed on
17
snapshot load, but the LoongArch code somehow already does that, despite
18
not having this patch here, presumably due to some lucky copy and
19
pasting.
20
21
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
22
Reviewed-by: Song Gao <gaosong@loongson.cn>
23
Message-Id: <20240905153316.2038769-1-Jason@zx2c4.com>
24
Signed-off-by: Song Gao <gaosong@loongson.cn>
25
---
8
---
26
hw/loongarch/virt.c | 6 ++++++
9
hw/loongarch/virt.c | 39 +++++++++++++++++++++++++--------------
27
1 file changed, 6 insertions(+)
10
1 file changed, 25 insertions(+), 14 deletions(-)
28
11
29
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
30
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/loongarch/virt.c
14
--- a/hw/loongarch/virt.c
32
+++ b/hw/loongarch/virt.c
15
+++ b/hw/loongarch/virt.c
33
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ static void create_fdt(LoongArchVirtMachineState *lvms)
34
#include "hw/block/flash.h"
17
static void fdt_add_cpu_nodes(const LoongArchVirtMachineState *lvms)
35
#include "hw/virtio/virtio-iommu.h"
36
#include "qemu/error-report.h"
37
+#include "qemu/guest-random.h"
38
39
static bool virt_is_veiointc_enabled(LoongArchVirtMachineState *lvms)
40
{
18
{
41
@@ -XXX,XX +XXX,XX @@ static void fdt_add_uart_node(LoongArchVirtMachineState *lvms,
19
int num;
42
static void create_fdt(LoongArchVirtMachineState *lvms)
20
- const MachineState *ms = MACHINE(lvms);
43
{
21
- int smp_cpus = ms->smp.cpus;
44
MachineState *ms = MACHINE(lvms);
22
+ MachineState *ms = MACHINE(lvms);
45
+ uint8_t rng_seed[32];
23
+ MachineClass *mc = MACHINE_GET_CLASS(ms);
46
24
+ const CPUArchIdList *possible_cpus;
47
ms->fdt = create_device_tree(&lvms->fdt_size);
25
+ LoongArchCPU *cpu;
48
if (!ms->fdt) {
26
+ CPUState *cs;
49
@@ -XXX,XX +XXX,XX @@ static void create_fdt(LoongArchVirtMachineState *lvms)
27
+ char *nodename, *map_path;
50
qemu_fdt_setprop_cell(ms->fdt, "/", "#address-cells", 0x2);
28
51
qemu_fdt_setprop_cell(ms->fdt, "/", "#size-cells", 0x2);
29
qemu_fdt_add_subnode(ms->fdt, "/cpus");
52
qemu_fdt_add_subnode(ms->fdt, "/chosen");
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
+ }
53
+
44
+
54
+ /* Pass seed to RNG */
45
+ nodename = g_strdup_printf("/cpus/cpu@%d", num);
55
+ qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed));
46
+ cpu = LOONGARCH_CPU(cs);
56
+ qemu_fdt_setprop(ms->fdt, "/chosen", "rng-seed", rng_seed, sizeof(rng_seed));
47
48
qemu_fdt_add_subnode(ms->fdt, nodename);
49
qemu_fdt_setprop_string(ms->fdt, nodename, "device_type", "cpu");
50
qemu_fdt_setprop_string(ms->fdt, nodename, "compatible",
51
cpu->dtb_compatible);
52
- if (ms->possible_cpus->cpus[cs->cpu_index].props.has_node_id) {
53
+ if (possible_cpus->cpus[num].props.has_node_id) {
54
qemu_fdt_setprop_cell(ms->fdt, nodename, "numa-node-id",
55
- ms->possible_cpus->cpus[cs->cpu_index].props.node_id);
56
+ possible_cpus->cpus[num].props.node_id);
57
}
58
qemu_fdt_setprop_cell(ms->fdt, nodename, "reg", num);
59
qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle",
60
@@ -XXX,XX +XXX,XX @@ static void fdt_add_cpu_nodes(const LoongArchVirtMachineState *lvms)
61
62
/*cpu map */
63
qemu_fdt_add_subnode(ms->fdt, "/cpus/cpu-map");
64
+ for (num = 0; num < possible_cpus->len; num++) {
65
+ cs = possible_cpus->cpus[num].cpu;
66
+ if (cs == NULL) {
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
}
57
}
89
}
58
90
59
static void fdt_add_cpu_nodes(const LoongArchVirtMachineState *lvms)
60
--
91
--
61
2.34.1
92
2.43.5
diff view generated by jsdifflib
1
From: Bibo Mao <maobibo@loongson.cn>
1
Like LBT feature, add type OnOffAuto for LSX feature setting. Also
2
2
add LSX feature detection with new VM ioctl command, fallback to old
3
KVM provides interface KVM_REG_LOONGARCH_VCPU_RESET to reset vCPU,
3
method if it is not supported.
4
it can be used to clear internal state about kvm kernel. vCPU reset
5
function is added here for kvm mode.
6
4
7
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
5
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
8
Reviewed-by: Song Gao <gaosong@loongson.cn>
6
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
9
Message-Id: <20240822022827.2273534-1-maobibo@loongson.cn>
10
Signed-off-by: Song Gao <gaosong@loongson.cn>
11
---
7
---
12
target/loongarch/cpu.c | 2 +-
8
target/loongarch/cpu.c | 38 +++++++++++++++------------
13
target/loongarch/kvm/kvm.c | 5 ++++-
9
target/loongarch/cpu.h | 2 ++
14
target/loongarch/kvm/kvm_loongarch.h | 2 +-
10
target/loongarch/kvm/kvm.c | 54 ++++++++++++++++++++++++++++++++++++++
15
3 files changed, 6 insertions(+), 3 deletions(-)
11
3 files changed, 77 insertions(+), 17 deletions(-)
16
12
17
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
18
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
19
--- a/target/loongarch/cpu.c
15
--- a/target/loongarch/cpu.c
20
+++ b/target/loongarch/cpu.c
16
+++ b/target/loongarch/cpu.c
21
@@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_reset_hold(Object *obj, ResetType type)
17
@@ -XXX,XX +XXX,XX @@ static void loongarch_la464_initfn(Object *obj)
22
memset(env->tlb, 0, sizeof(env->tlb));
18
{
19
LoongArchCPU *cpu = LOONGARCH_CPU(obj);
20
CPULoongArchState *env = &cpu->env;
21
+ uint32_t data = 0;
22
int i;
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
111
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
112
index XXXXXXX..XXXXXXX 100644
113
--- a/target/loongarch/cpu.h
114
+++ b/target/loongarch/cpu.h
115
@@ -XXX,XX +XXX,XX @@ typedef struct LoongArchTLB LoongArchTLB;
23
#endif
116
#endif
24
if (kvm_enabled()) {
117
25
- kvm_arch_reset_vcpu(env);
118
enum loongarch_features {
26
+ kvm_arch_reset_vcpu(cs);
119
+ LOONGARCH_FEATURE_LSX,
27
}
120
LOONGARCH_FEATURE_LBT, /* loongson binary translation extension */
28
#endif
121
LOONGARCH_FEATURE_PMU,
29
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;
30
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
31
index XXXXXXX..XXXXXXX 100644
132
index XXXXXXX..XXXXXXX 100644
32
--- a/target/loongarch/kvm/kvm.c
133
--- a/target/loongarch/kvm/kvm.c
33
+++ b/target/loongarch/kvm/kvm.c
134
+++ b/target/loongarch/kvm/kvm.c
34
@@ -XXX,XX +XXX,XX @@ static int kvm_loongarch_put_regs_fp(CPUState *cs)
135
@@ -XXX,XX +XXX,XX @@ static bool kvm_feature_supported(CPUState *cs, enum loongarch_features feature)
35
return ret;
136
{
36
}
137
int ret;
37
138
struct kvm_device_attr attr;
38
-void kvm_arch_reset_vcpu(CPULoongArchState *env)
139
+ uint64_t val;
39
+void kvm_arch_reset_vcpu(CPUState *cs)
140
40
{
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
+{
41
+ CPULoongArchState *env = cpu_env(cs);
177
+ CPULoongArchState *env = cpu_env(cs);
42
+
178
+ LoongArchCPU *cpu = LOONGARCH_CPU(cs);
43
env->mp_state = KVM_MP_STATE_RUNNABLE;
179
+ bool kvm_supported;
44
+ kvm_set_one_reg(cs, KVM_REG_LOONGARCH_VCPU_RESET, 0);
180
+
45
}
181
+ kvm_supported = kvm_feature_supported(cs, LOONGARCH_FEATURE_LSX);
46
182
+ env->cpucfg[2] = FIELD_DP32(env->cpucfg[2], CPUCFG2, LSX, 0);
47
static int kvm_loongarch_get_mpstate(CPUState *cs)
183
+ if (cpu->lsx == ON_OFF_AUTO_ON) {
48
diff --git a/target/loongarch/kvm/kvm_loongarch.h b/target/loongarch/kvm/kvm_loongarch.h
184
+ if (kvm_supported) {
49
index XXXXXXX..XXXXXXX 100644
185
+ env->cpucfg[2] = FIELD_DP32(env->cpucfg[2], CPUCFG2, LSX, 1);
50
--- a/target/loongarch/kvm/kvm_loongarch.h
186
+ } else {
51
+++ b/target/loongarch/kvm/kvm_loongarch.h
187
+ error_setg(errp, "'lsx' feature not supported by KVM on this host");
52
@@ -XXX,XX +XXX,XX @@
188
+ return -ENOTSUP;
53
#define QEMU_KVM_LOONGARCH_H
189
+ }
54
190
+ } else if ((cpu->lsx == ON_OFF_AUTO_AUTO) && kvm_supported) {
55
int kvm_loongarch_set_interrupt(LoongArchCPU *cpu, int irq, int level);
191
+ env->cpucfg[2] = FIELD_DP32(env->cpucfg[2], CPUCFG2, LSX, 1);
56
-void kvm_arch_reset_vcpu(CPULoongArchState *env);
192
+ }
57
+void kvm_arch_reset_vcpu(CPUState *cs);
193
+
58
194
+ return 0;
59
#endif
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);
60
--
212
--
61
2.34.1
213
2.43.5
diff view generated by jsdifflib
1
From: Bibo Mao <maobibo@loongson.cn>
1
Like LSX feature, add type OnOffAuto for LASX feature setting.
2
3
Add the support needed for creating prstatus elf notes. This allows
4
us to use QMP dump-guest-memory.
5
6
Now ELF notes of LoongArch only supports general elf notes, LSX and
7
LASX is not supported, since it is mainly used to dump guest memory.
8
2
9
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
3
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
10
Reviewed-by: Song Gao <gaosong@loongson.cn>
4
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
11
Tested-by: Song Gao <gaosong@loongson.cn>
12
Message-Id: <20240822065245.2286214-1-maobibo@loongson.cn>
13
Signed-off-by: Song Gao <gaosong@loongson.cn>
14
---
5
---
15
target/loongarch/arch_dump.c | 167 +++++++++++++++++++++++++++++++++++
6
target/loongarch/cpu.c | 50 +++++++++++++++++++++++------------
16
target/loongarch/cpu.c | 1 +
7
target/loongarch/cpu.h | 2 ++
17
target/loongarch/internals.h | 2 +
8
target/loongarch/kvm/kvm.c | 53 ++++++++++++++++++++++++++++++++++++++
18
target/loongarch/meson.build | 1 +
9
3 files changed, 89 insertions(+), 16 deletions(-)
19
4 files changed, 171 insertions(+)
20
create mode 100644 target/loongarch/arch_dump.c
21
10
22
diff --git a/target/loongarch/arch_dump.c b/target/loongarch/arch_dump.c
11
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
23
new file mode 100644
12
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX
13
--- a/target/loongarch/cpu.c
25
--- /dev/null
14
+++ b/target/loongarch/cpu.c
26
+++ b/target/loongarch/arch_dump.c
15
@@ -XXX,XX +XXX,XX @@ static void loongarch_set_lsx(Object *obj, bool value, Error **errp)
27
@@ -XXX,XX +XXX,XX @@
16
uint32_t val;
28
+/*
17
29
+ * Support for writing ELF notes for LoongArch architectures
18
cpu->lsx = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
30
+ *
19
+ if (cpu->lsx == ON_OFF_AUTO_OFF) {
31
+ * Copyright (c) 2023 Loongarch Technology
20
+ cpu->lasx = ON_OFF_AUTO_OFF;
32
+ *
21
+ if (cpu->lasx == ON_OFF_AUTO_ON) {
33
+ * This program is free software; you can redistribute it and/or modify it
22
+ error_setg(errp, "Failed to disable LSX since LASX is enabled");
34
+ * under the terms and conditions of the GNU General Public License,
23
+ return;
35
+ * version 2 or later, as published by the Free Software Foundation.
24
+ }
36
+ *
37
+ * This program is distributed in the hope it will be useful, but WITHOUT
38
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
39
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
40
+ * more details.
41
+ *
42
+ * You should have received a copy of the GNU General Public License along with
43
+ * this program. If not, see <http://www.gnu.org/licenses/>.
44
+ *
45
+ */
46
+
47
+#include "qemu/osdep.h"
48
+#include "cpu.h"
49
+#include "elf.h"
50
+#include "sysemu/dump.h"
51
+#include "internals.h"
52
+
53
+/* struct user_pt_regs from arch/loongarch/include/uapi/asm/ptrace.h */
54
+struct loongarch_user_regs {
55
+ uint64_t gpr[32];
56
+ uint64_t pad1[1];
57
+ /* Special CSR registers. */
58
+ uint64_t csr_era;
59
+ uint64_t csr_badv;
60
+ uint64_t pad2[10];
61
+} QEMU_PACKED;
62
+
63
+QEMU_BUILD_BUG_ON(sizeof(struct loongarch_user_regs) != 360);
64
+
65
+/* struct elf_prstatus from include/uapi/linux/elfcore.h */
66
+struct loongarch_elf_prstatus {
67
+ char pad1[32]; /* 32 == offsetof(struct elf_prstatus, pr_pid) */
68
+ uint32_t pr_pid;
69
+ /*
70
+ * 76 == offsetof(struct elf_prstatus, pr_reg) -
71
+ * offsetof(struct elf_prstatus, pr_ppid)
72
+ */
73
+ char pad2[76];
74
+ struct loongarch_user_regs pr_reg;
75
+ uint32_t pr_fpvalid;
76
+ char pad3[4];
77
+} QEMU_PACKED;
78
+
79
+QEMU_BUILD_BUG_ON(sizeof(struct loongarch_elf_prstatus) != 480);
80
+
81
+/* struct user_fp_state from arch/loongarch/include/uapi/asm/ptrace.h */
82
+struct loongarch_fpu_struct {
83
+ uint64_t fpr[32];
84
+ uint64_t fcc;
85
+ unsigned int fcsr;
86
+} QEMU_PACKED;
87
+
88
+QEMU_BUILD_BUG_ON(sizeof(struct loongarch_fpu_struct) != 268);
89
+
90
+struct loongarch_note {
91
+ Elf64_Nhdr hdr;
92
+ char name[8]; /* align_up(sizeof("CORE"), 4) */
93
+ union {
94
+ struct loongarch_elf_prstatus prstatus;
95
+ struct loongarch_fpu_struct fpu;
96
+ };
97
+} QEMU_PACKED;
98
+
99
+#define LOONGARCH_NOTE_HEADER_SIZE offsetof(struct loongarch_note, prstatus)
100
+#define LOONGARCH_PRSTATUS_NOTE_SIZE \
101
+ (LOONGARCH_NOTE_HEADER_SIZE + sizeof(struct loongarch_elf_prstatus))
102
+#define LOONGARCH_PRFPREG_NOTE_SIZE \
103
+ (LOONGARCH_NOTE_HEADER_SIZE + sizeof(struct loongarch_fpu_struct))
104
+
105
+static void loongarch_note_init(struct loongarch_note *note, DumpState *s,
106
+ const char *name, Elf64_Word namesz,
107
+ Elf64_Word type, Elf64_Word descsz)
108
+{
109
+ memset(note, 0, sizeof(*note));
110
+
111
+ note->hdr.n_namesz = cpu_to_dump32(s, namesz);
112
+ note->hdr.n_descsz = cpu_to_dump32(s, descsz);
113
+ note->hdr.n_type = cpu_to_dump32(s, type);
114
+
115
+ memcpy(note->name, name, namesz);
116
+}
117
+
118
+static int loongarch_write_elf64_fprpreg(WriteCoreDumpFunction f,
119
+ CPULoongArchState *env, int cpuid,
120
+ DumpState *s)
121
+{
122
+ struct loongarch_note note;
123
+ int ret, i;
124
+
125
+ loongarch_note_init(&note, s, "CORE", 5, NT_PRFPREG, sizeof(note.fpu));
126
+ note.fpu.fcsr = cpu_to_dump64(s, env->fcsr0);
127
+
128
+ for (i = 0; i < 8; i++) {
129
+ note.fpu.fcc |= env->cf[i] << (8 * i);
130
+ }
131
+ note.fpu.fcc = cpu_to_dump64(s, note.fpu.fcc);
132
+
133
+ for (i = 0; i < 32; ++i) {
134
+ note.fpu.fpr[i] = cpu_to_dump64(s, env->fpr[i].vreg.UD[0]);
135
+ }
25
+ }
136
+
26
+
137
+ ret = f(&note, LOONGARCH_PRFPREG_NOTE_SIZE, s);
27
if (kvm_enabled()) {
138
+ if (ret < 0) {
28
/* kvm feature detection in function kvm_arch_init_vcpu */
139
+ return -1;
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
+
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)
162
+{
163
+ CPULoongArchState *env = cpu_env(cs);
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);
140
+ }
178
+ }
141
+
179
+
142
+ return 0;
180
+ return 0;
143
+}
181
+}
144
+
182
+
145
+int loongarch_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
183
static int kvm_cpu_check_lbt(CPUState *cs, Error **errp)
146
+ int cpuid, DumpState *s)
184
{
147
+{
185
CPULoongArchState *env = cpu_env(cs);
148
+ struct loongarch_note note;
186
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
149
+ CPULoongArchState *env = &LOONGARCH_CPU(cs)->env;
187
error_report_err(local_err);
150
+ int ret, i;
188
}
151
+
189
152
+ loongarch_note_init(&note, s, "CORE", 5, NT_PRSTATUS,
190
+ ret = kvm_cpu_check_lasx(cs, &local_err);
153
+ sizeof(note.prstatus));
154
+ note.prstatus.pr_pid = cpu_to_dump32(s, cpuid);
155
+ note.prstatus.pr_fpvalid = cpu_to_dump32(s, 1);
156
+
157
+ for (i = 0; i < 32; ++i) {
158
+ note.prstatus.pr_reg.gpr[i] = cpu_to_dump64(s, env->gpr[i]);
159
+ }
160
+ note.prstatus.pr_reg.csr_era = cpu_to_dump64(s, env->CSR_ERA);
161
+ note.prstatus.pr_reg.csr_badv = cpu_to_dump64(s, env->CSR_BADV);
162
+ ret = f(&note, LOONGARCH_PRSTATUS_NOTE_SIZE, s);
163
+ if (ret < 0) {
191
+ if (ret < 0) {
164
+ return -1;
192
+ error_report_err(local_err);
165
+ }
193
+ }
166
+
194
+
167
+ ret = loongarch_write_elf64_fprpreg(f, env, cpuid, s);
195
ret = kvm_cpu_check_lbt(cs, &local_err);
168
+ if (ret < 0) {
196
if (ret < 0) {
169
+ return -1;
197
error_report_err(local_err);
170
+ }
171
+
172
+ return ret;
173
+}
174
+
175
+int cpu_get_dump_info(ArchDumpInfo *info,
176
+ const GuestPhysBlockList *guest_phys_blocks)
177
+{
178
+ info->d_machine = EM_LOONGARCH;
179
+ info->d_endian = ELFDATA2LSB;
180
+ info->d_class = ELFCLASS64;
181
+
182
+ return 0;
183
+}
184
+
185
+ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
186
+{
187
+ size_t note_size = 0;
188
+
189
+ if (class == ELFCLASS64) {
190
+ note_size = LOONGARCH_PRSTATUS_NOTE_SIZE + LOONGARCH_PRFPREG_NOTE_SIZE;
191
+ }
192
+
193
+ return note_size * nr_cpus;
194
+}
195
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
196
index XXXXXXX..XXXXXXX 100644
197
--- a/target/loongarch/cpu.c
198
+++ b/target/loongarch/cpu.c
199
@@ -XXX,XX +XXX,XX @@ static const TCGCPUOps loongarch_tcg_ops = {
200
#include "hw/core/sysemu-cpu-ops.h"
201
202
static const struct SysemuCPUOps loongarch_sysemu_ops = {
203
+ .write_elf64_note = loongarch_cpu_write_elf64_note,
204
.get_phys_page_debug = loongarch_cpu_get_phys_page_debug,
205
};
206
207
diff --git a/target/loongarch/internals.h b/target/loongarch/internals.h
208
index XXXXXXX..XXXXXXX 100644
209
--- a/target/loongarch/internals.h
210
+++ b/target/loongarch/internals.h
211
@@ -XXX,XX +XXX,XX @@ void write_fcc(CPULoongArchState *env, uint64_t val);
212
int loongarch_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n);
213
int loongarch_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n);
214
void loongarch_cpu_register_gdb_regs_for_features(CPUState *cs);
215
+int loongarch_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cpu,
216
+ int cpuid, DumpState *s);
217
218
#endif
219
diff --git a/target/loongarch/meson.build b/target/loongarch/meson.build
220
index XXXXXXX..XXXXXXX 100644
221
--- a/target/loongarch/meson.build
222
+++ b/target/loongarch/meson.build
223
@@ -XXX,XX +XXX,XX @@ loongarch_ss.add(files(
224
225
loongarch_system_ss = ss.source_set()
226
loongarch_system_ss.add(files(
227
+ 'arch_dump.c',
228
'cpu_helper.c',
229
'loongarch-qmp-cmds.c',
230
'machine.c',
231
--
198
--
232
2.34.1
199
2.43.5
diff view generated by jsdifflib