1 | The following changes since commit 848a6caa88b9f082c89c9b41afa975761262981d: | 1 | The following changes since commit 7efd65423ab22e6f5890ca08ae40c84d6660242f: |
---|---|---|---|
2 | 2 | ||
3 | Merge tag 'migration-20230602-pull-request' of https://gitlab.com/juan.quintela/qemu into staging (2023-06-02 17:33:29 -0700) | 3 | Merge tag 'pull-riscv-to-apply-20230614' of https://github.com/alistair23/qemu into staging (2023-06-14 05:28:51 +0200) |
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-20230605 | 7 | https://gitlab.com/gaosong/qemu.git tags/pull-loongarch-20230616 |
8 | 8 | ||
9 | for you to fetch changes up to 8555ddc671203969b0e6eb651e538d02a9a79b3a: | 9 | for you to fetch changes up to 505aa8d8f29b79fcef77563bb4124208badbd8d4: |
10 | 10 | ||
11 | hw/intc/loongarch_ipi: Bring back all 4 IPI mailboxes (2023-06-05 11:08:55 +0800) | 11 | target/loongarch: Fix CSR.DMW0-3.VSEG check (2023-06-16 17:58:46 +0800) |
12 | 12 | ||
13 | ---------------------------------------------------------------- | 13 | ---------------------------------------------------------------- |
14 | Fixes Coverity CID: 1512452, 1512453 | 14 | pull-loongarch-20230616 |
15 | Fixes: 78464f023b54 ("hw/loongarch/virt: Modify ipi as percpu device") | 15 | |
16 | * Fix CSR.DMW0-3.VSEG check | ||
17 | * Add cpu arch_id support | ||
18 | * Set physical cpuid route for LoongArch ipi device | ||
19 | * Add numa support | ||
20 | * Supplement cpu topology arguments | ||
16 | 21 | ||
17 | ---------------------------------------------------------------- | 22 | ---------------------------------------------------------------- |
18 | Jiaxun Yang (1): | 23 | Jiajie Chen (1): |
19 | hw/intc/loongarch_ipi: Bring back all 4 IPI mailboxes | 24 | target/loongarch: Fix CSR.DMW0-3.VSEG check |
20 | 25 | ||
21 | hw/intc/loongarch_ipi.c | 6 +++--- | 26 | Tianrui Zhao (4): |
22 | include/hw/intc/loongarch_ipi.h | 4 +++- | 27 | hw/loongarch/virt: Add cpu arch_id support |
23 | 2 files changed, 6 insertions(+), 4 deletions(-) | 28 | hw/intc: Set physical cpuid route for LoongArch ipi device |
29 | hw/loongarch: Add numa support | ||
30 | hw/loongarch: Supplement cpu topology arguments | ||
31 | |||
32 | hw/intc/loongarch_ipi.c | 44 +++++++++++-- | ||
33 | hw/loongarch/Kconfig | 1 + | ||
34 | hw/loongarch/acpi-build.c | 78 ++++++++++++++++++----- | ||
35 | hw/loongarch/virt.c | 144 ++++++++++++++++++++++++++++++++++++++---- | ||
36 | target/loongarch/cpu.h | 2 + | ||
37 | target/loongarch/tlb_helper.c | 4 +- | ||
38 | 6 files changed, 235 insertions(+), 38 deletions(-) | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Tianrui Zhao <zhaotianrui@loongson.cn> | ||
1 | 2 | ||
3 | With acpi madt table, there is cpu physical coreid, which may | ||
4 | be different with logical id in qemu. This patch adds cpu arch_id | ||
5 | support, and fill madt table with arch_id. For the present cpu | ||
6 | arch_id is still equal to logical id. | ||
7 | |||
8 | Reviewed-by: Song Gao <gaosong@loongson.cn> | ||
9 | Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn> | ||
10 | Signed-off-by: Song Gao <gaosong@loongson.cn> | ||
11 | Message-Id: <20230613120552.2471420-2-zhaotianrui@loongson.cn> | ||
12 | --- | ||
13 | hw/loongarch/acpi-build.c | 20 ++++++++++++++------ | ||
14 | hw/loongarch/virt.c | 34 ++++++++++++++++++++++++++++++++-- | ||
15 | 2 files changed, 46 insertions(+), 8 deletions(-) | ||
16 | |||
17 | diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/hw/loongarch/acpi-build.c | ||
20 | +++ b/hw/loongarch/acpi-build.c | ||
21 | @@ -XXX,XX +XXX,XX @@ static void | ||
22 | build_madt(GArray *table_data, BIOSLinker *linker, LoongArchMachineState *lams) | ||
23 | { | ||
24 | MachineState *ms = MACHINE(lams); | ||
25 | - int i; | ||
26 | + MachineClass *mc = MACHINE_GET_CLASS(ms); | ||
27 | + const CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(ms); | ||
28 | + int i, arch_id; | ||
29 | AcpiTable table = { .sig = "APIC", .rev = 1, .oem_id = lams->oem_id, | ||
30 | .oem_table_id = lams->oem_table_id }; | ||
31 | |||
32 | @@ -XXX,XX +XXX,XX @@ build_madt(GArray *table_data, BIOSLinker *linker, LoongArchMachineState *lams) | ||
33 | build_append_int_noprefix(table_data, 0, 4); | ||
34 | build_append_int_noprefix(table_data, 1 /* PCAT_COMPAT */, 4); /* Flags */ | ||
35 | |||
36 | - for (i = 0; i < ms->smp.cpus; i++) { | ||
37 | + for (i = 0; i < arch_ids->len; i++) { | ||
38 | /* Processor Core Interrupt Controller Structure */ | ||
39 | + arch_id = arch_ids->cpus[i].arch_id; | ||
40 | + | ||
41 | build_append_int_noprefix(table_data, 17, 1); /* Type */ | ||
42 | build_append_int_noprefix(table_data, 15, 1); /* Length */ | ||
43 | build_append_int_noprefix(table_data, 1, 1); /* Version */ | ||
44 | build_append_int_noprefix(table_data, i + 1, 4); /* ACPI Processor ID */ | ||
45 | - build_append_int_noprefix(table_data, i, 4); /* Core ID */ | ||
46 | + build_append_int_noprefix(table_data, arch_id, 4); /* Core ID */ | ||
47 | build_append_int_noprefix(table_data, 1, 4); /* Flags */ | ||
48 | } | ||
49 | |||
50 | @@ -XXX,XX +XXX,XX @@ build_madt(GArray *table_data, BIOSLinker *linker, LoongArchMachineState *lams) | ||
51 | static void | ||
52 | build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine) | ||
53 | { | ||
54 | - uint64_t i; | ||
55 | + int i, arch_id; | ||
56 | LoongArchMachineState *lams = LOONGARCH_MACHINE(machine); | ||
57 | MachineState *ms = MACHINE(lams); | ||
58 | + MachineClass *mc = MACHINE_GET_CLASS(ms); | ||
59 | + const CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(ms); | ||
60 | AcpiTable table = { .sig = "SRAT", .rev = 1, .oem_id = lams->oem_id, | ||
61 | .oem_table_id = lams->oem_table_id }; | ||
62 | |||
63 | @@ -XXX,XX +XXX,XX @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine) | ||
64 | build_append_int_noprefix(table_data, 1, 4); /* Reserved */ | ||
65 | build_append_int_noprefix(table_data, 0, 8); /* Reserved */ | ||
66 | |||
67 | - for (i = 0; i < ms->smp.cpus; ++i) { | ||
68 | + for (i = 0; i < arch_ids->len; ++i) { | ||
69 | + arch_id = arch_ids->cpus[i].arch_id; | ||
70 | + | ||
71 | /* Processor Local APIC/SAPIC Affinity Structure */ | ||
72 | build_append_int_noprefix(table_data, 0, 1); /* Type */ | ||
73 | build_append_int_noprefix(table_data, 16, 1); /* Length */ | ||
74 | /* Proximity Domain [7:0] */ | ||
75 | build_append_int_noprefix(table_data, 0, 1); | ||
76 | - build_append_int_noprefix(table_data, i, 1); /* APIC ID */ | ||
77 | + build_append_int_noprefix(table_data, arch_id, 1); /* APIC ID */ | ||
78 | /* Flags, Table 5-36 */ | ||
79 | build_append_int_noprefix(table_data, 1, 4); | ||
80 | build_append_int_noprefix(table_data, 0, 1); /* Local SAPIC EID */ | ||
81 | diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c | ||
82 | index XXXXXXX..XXXXXXX 100644 | ||
83 | --- a/hw/loongarch/virt.c | ||
84 | +++ b/hw/loongarch/virt.c | ||
85 | @@ -XXX,XX +XXX,XX @@ static void loongarch_init(MachineState *machine) | ||
86 | LoongArchMachineState *lams = LOONGARCH_MACHINE(machine); | ||
87 | int i; | ||
88 | hwaddr fdt_base; | ||
89 | + const CPUArchIdList *possible_cpus; | ||
90 | + MachineClass *mc = MACHINE_GET_CLASS(machine); | ||
91 | + CPUState *cpu; | ||
92 | |||
93 | if (!cpu_model) { | ||
94 | cpu_model = LOONGARCH_CPU_TYPE_NAME("la464"); | ||
95 | @@ -XXX,XX +XXX,XX @@ static void loongarch_init(MachineState *machine) | ||
96 | } | ||
97 | create_fdt(lams); | ||
98 | /* Init CPUs */ | ||
99 | - for (i = 0; i < machine->smp.cpus; i++) { | ||
100 | - cpu_create(machine->cpu_type); | ||
101 | + | ||
102 | + possible_cpus = mc->possible_cpu_arch_ids(machine); | ||
103 | + for (i = 0; i < possible_cpus->len; i++) { | ||
104 | + cpu = cpu_create(machine->cpu_type); | ||
105 | + cpu->cpu_index = i; | ||
106 | + machine->possible_cpus->cpus[i].cpu = OBJECT(cpu); | ||
107 | } | ||
108 | fdt_add_cpu_nodes(lams); | ||
109 | /* Add memory region */ | ||
110 | @@ -XXX,XX +XXX,XX @@ static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine, | ||
111 | return NULL; | ||
112 | } | ||
113 | |||
114 | +static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms) | ||
115 | +{ | ||
116 | + int n; | ||
117 | + unsigned int max_cpus = ms->smp.max_cpus; | ||
118 | + | ||
119 | + if (ms->possible_cpus) { | ||
120 | + assert(ms->possible_cpus->len == max_cpus); | ||
121 | + return ms->possible_cpus; | ||
122 | + } | ||
123 | + | ||
124 | + ms->possible_cpus = g_malloc0(sizeof(CPUArchIdList) + | ||
125 | + sizeof(CPUArchId) * max_cpus); | ||
126 | + ms->possible_cpus->len = max_cpus; | ||
127 | + for (n = 0; n < ms->possible_cpus->len; n++) { | ||
128 | + ms->possible_cpus->cpus[n].type = ms->cpu_type; | ||
129 | + ms->possible_cpus->cpus[n].arch_id = n; | ||
130 | + ms->possible_cpus->cpus[n].props.has_core_id = true; | ||
131 | + ms->possible_cpus->cpus[n].props.core_id = n % ms->smp.cores; | ||
132 | + } | ||
133 | + return ms->possible_cpus; | ||
134 | +} | ||
135 | + | ||
136 | static void loongarch_class_init(ObjectClass *oc, void *data) | ||
137 | { | ||
138 | MachineClass *mc = MACHINE_CLASS(oc); | ||
139 | @@ -XXX,XX +XXX,XX @@ static void loongarch_class_init(ObjectClass *oc, void *data) | ||
140 | mc->block_default_type = IF_VIRTIO; | ||
141 | mc->default_boot_order = "c"; | ||
142 | mc->no_cdrom = 1; | ||
143 | + mc->possible_cpu_arch_ids = virt_possible_cpu_arch_ids; | ||
144 | mc->get_hotplug_handler = virt_machine_get_hotplug_handler; | ||
145 | mc->default_nic = "virtio-net-pci"; | ||
146 | hc->plug = loongarch_machine_device_plug_cb; | ||
147 | -- | ||
148 | 2.39.1 | diff view generated by jsdifflib |
1 | From: Jiaxun Yang <jiaxun.yang@flygoat.com> | 1 | From: Tianrui Zhao <zhaotianrui@loongson.cn> |
---|---|---|---|
2 | 2 | ||
3 | As per "Loongson 3A5000/3B5000 Processor Reference Manual", | 3 | LoongArch ipi device uses physical cpuid to route to different |
4 | Loongson 3A5000's IPI implementation have 4 mailboxes per | 4 | vcpus rather logical cpuid, and the physical cpuid is the same |
5 | core. | 5 | with cpuid in acpi dsdt and srat table. |
6 | 6 | ||
7 | However, in 78464f023b54 ("hw/loongarch/virt: Modify ipi as | ||
8 | percpu device"), the number of IPI mailboxes was reduced to | ||
9 | one, which mismatches actual hardware. | ||
10 | |||
11 | It won't affect LoongArch based system as LoongArch boot code | ||
12 | only uses the first mailbox, however MIPS based Loongson boot | ||
13 | code uses all 4 mailboxes. | ||
14 | |||
15 | Fixes Coverity CID: 1512452, 1512453 | ||
16 | Fixes: 78464f023b54 ("hw/loongarch/virt: Modify ipi as percpu device") | ||
17 | Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com> | ||
18 | Reviewed-by: Song Gao <gaosong@loongson.cn> | 7 | Reviewed-by: Song Gao <gaosong@loongson.cn> |
19 | Message-Id: <20230521102307.87081-2-jiaxun.yang@flygoat.com> | 8 | Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn> |
20 | Signed-off-by: Song Gao <gaosong@loongson.cn> | 9 | Signed-off-by: Song Gao <gaosong@loongson.cn> |
10 | Message-Id: <20230613120552.2471420-3-zhaotianrui@loongson.cn> | ||
21 | --- | 11 | --- |
22 | hw/intc/loongarch_ipi.c | 6 +++--- | 12 | hw/intc/loongarch_ipi.c | 44 ++++++++++++++++++++++++++++++++++------- |
23 | include/hw/intc/loongarch_ipi.h | 4 +++- | 13 | hw/loongarch/virt.c | 1 + |
24 | 2 files changed, 6 insertions(+), 4 deletions(-) | 14 | target/loongarch/cpu.h | 2 ++ |
15 | 3 files changed, 40 insertions(+), 7 deletions(-) | ||
25 | 16 | ||
26 | diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c | 17 | diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c |
27 | index XXXXXXX..XXXXXXX 100644 | 18 | index XXXXXXX..XXXXXXX 100644 |
28 | --- a/hw/intc/loongarch_ipi.c | 19 | --- a/hw/intc/loongarch_ipi.c |
29 | +++ b/hw/intc/loongarch_ipi.c | 20 | +++ b/hw/intc/loongarch_ipi.c |
30 | @@ -XXX,XX +XXX,XX @@ static void loongarch_ipi_init(Object *obj) | 21 | @@ -XXX,XX +XXX,XX @@ |
31 | 22 | #include "target/loongarch/internals.h" | |
32 | static const VMStateDescription vmstate_ipi_core = { | 23 | #include "trace.h" |
33 | .name = "ipi-single", | 24 | |
34 | - .version_id = 1, | 25 | +static void loongarch_ipi_writel(void *, hwaddr, uint64_t, unsigned); |
35 | - .minimum_version_id = 1, | 26 | + |
36 | + .version_id = 2, | 27 | static uint64_t loongarch_ipi_readl(void *opaque, hwaddr addr, unsigned size) |
37 | + .minimum_version_id = 2, | 28 | { |
38 | .fields = (VMStateField[]) { | 29 | IPICore *s = opaque; |
39 | VMSTATE_UINT32(status, IPICore), | 30 | @@ -XXX,XX +XXX,XX @@ static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr) |
40 | VMSTATE_UINT32(en, IPICore), | 31 | data, MEMTXATTRS_UNSPECIFIED, NULL); |
41 | VMSTATE_UINT32(set, IPICore), | 32 | } |
42 | VMSTATE_UINT32(clear, IPICore), | 33 | |
43 | - VMSTATE_UINT32_ARRAY(buf, IPICore, 2), | 34 | +static int archid_cmp(const void *a, const void *b) |
44 | + VMSTATE_UINT32_ARRAY(buf, IPICore, IPI_MBX_NUM * 2), | 35 | +{ |
45 | VMSTATE_END_OF_LIST() | 36 | + CPUArchId *archid_a = (CPUArchId *)a; |
37 | + CPUArchId *archid_b = (CPUArchId *)b; | ||
38 | + | ||
39 | + return archid_a->arch_id - archid_b->arch_id; | ||
40 | +} | ||
41 | + | ||
42 | +static CPUArchId *find_cpu_by_archid(MachineState *ms, uint32_t id) | ||
43 | +{ | ||
44 | + CPUArchId apic_id, *found_cpu; | ||
45 | + | ||
46 | + apic_id.arch_id = id; | ||
47 | + found_cpu = bsearch(&apic_id, ms->possible_cpus->cpus, | ||
48 | + ms->possible_cpus->len, sizeof(*ms->possible_cpus->cpus), | ||
49 | + archid_cmp); | ||
50 | + | ||
51 | + return found_cpu; | ||
52 | +} | ||
53 | + | ||
54 | +static CPUState *ipi_getcpu(int arch_id) | ||
55 | +{ | ||
56 | + MachineState *machine = MACHINE(qdev_get_machine()); | ||
57 | + CPUArchId *archid; | ||
58 | + | ||
59 | + archid = find_cpu_by_archid(machine, arch_id); | ||
60 | + return CPU(archid->cpu); | ||
61 | +} | ||
62 | + | ||
63 | static void ipi_send(uint64_t val) | ||
64 | { | ||
65 | uint32_t cpuid; | ||
66 | uint8_t vector; | ||
67 | - CPULoongArchState *env; | ||
68 | CPUState *cs; | ||
69 | LoongArchCPU *cpu; | ||
70 | + LoongArchIPI *s; | ||
71 | |||
72 | cpuid = extract32(val, 16, 10); | ||
73 | if (cpuid >= LOONGARCH_MAX_CPUS) { | ||
74 | @@ -XXX,XX +XXX,XX @@ static void ipi_send(uint64_t val) | ||
75 | /* IPI status vector */ | ||
76 | vector = extract8(val, 0, 5); | ||
77 | |||
78 | - cs = qemu_get_cpu(cpuid); | ||
79 | + cs = ipi_getcpu(cpuid); | ||
80 | cpu = LOONGARCH_CPU(cs); | ||
81 | - env = &cpu->env; | ||
82 | - address_space_stl(&env->address_space_iocsr, 0x1008, | ||
83 | - BIT(vector), MEMTXATTRS_UNSPECIFIED, NULL); | ||
84 | + s = LOONGARCH_IPI(cpu->env.ipistate); | ||
85 | + loongarch_ipi_writel(&s->ipi_core, CORE_SET_OFF, BIT(vector), 4); | ||
86 | } | ||
87 | |||
88 | static void mail_send(uint64_t val) | ||
89 | @@ -XXX,XX +XXX,XX @@ static void mail_send(uint64_t val) | ||
46 | } | 90 | } |
47 | }; | 91 | |
48 | diff --git a/include/hw/intc/loongarch_ipi.h b/include/hw/intc/loongarch_ipi.h | 92 | addr = 0x1020 + (val & 0x1c); |
93 | - cs = qemu_get_cpu(cpuid); | ||
94 | + cs = ipi_getcpu(cpuid); | ||
95 | cpu = LOONGARCH_CPU(cs); | ||
96 | env = &cpu->env; | ||
97 | send_ipi_data(env, val, addr); | ||
98 | @@ -XXX,XX +XXX,XX @@ static void any_send(uint64_t val) | ||
99 | } | ||
100 | |||
101 | addr = val & 0xffff; | ||
102 | - cs = qemu_get_cpu(cpuid); | ||
103 | + cs = ipi_getcpu(cpuid); | ||
104 | cpu = LOONGARCH_CPU(cs); | ||
105 | env = &cpu->env; | ||
106 | send_ipi_data(env, val, addr); | ||
107 | diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c | ||
49 | index XXXXXXX..XXXXXXX 100644 | 108 | index XXXXXXX..XXXXXXX 100644 |
50 | --- a/include/hw/intc/loongarch_ipi.h | 109 | --- a/hw/loongarch/virt.c |
51 | +++ b/include/hw/intc/loongarch_ipi.h | 110 | +++ b/hw/loongarch/virt.c |
52 | @@ -XXX,XX +XXX,XX @@ | 111 | @@ -XXX,XX +XXX,XX @@ static void loongarch_irq_init(LoongArchMachineState *lams) |
53 | #define MAIL_SEND_OFFSET 0 | 112 | memory_region_add_subregion(&env->system_iocsr, APIC_BASE, |
54 | #define ANY_SEND_OFFSET (IOCSR_ANY_SEND - IOCSR_MAIL_SEND) | 113 | sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), |
55 | 114 | cpu)); | |
56 | +#define IPI_MBX_NUM 4 | 115 | + env->ipistate = ipi; |
57 | + | 116 | } |
58 | #define TYPE_LOONGARCH_IPI "loongarch_ipi" | 117 | |
59 | OBJECT_DECLARE_SIMPLE_TYPE(LoongArchIPI, LOONGARCH_IPI) | 118 | /* |
60 | 119 | diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h | |
61 | @@ -XXX,XX +XXX,XX @@ typedef struct IPICore { | 120 | index XXXXXXX..XXXXXXX 100644 |
62 | uint32_t set; | 121 | --- a/target/loongarch/cpu.h |
63 | uint32_t clear; | 122 | +++ b/target/loongarch/cpu.h |
64 | /* 64bit buf divide into 2 32bit buf */ | 123 | @@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState { |
65 | - uint32_t buf[2]; | 124 | MemoryRegion iocsr_mem; |
66 | + uint32_t buf[IPI_MBX_NUM * 2]; | 125 | bool load_elf; |
67 | qemu_irq irq; | 126 | uint64_t elf_address; |
68 | } IPICore; | 127 | + /* Store ipistate to access from this struct */ |
128 | + DeviceState *ipistate; | ||
129 | #endif | ||
130 | } CPULoongArchState; | ||
69 | 131 | ||
70 | -- | 132 | -- |
71 | 2.39.1 | 133 | 2.39.1 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Tianrui Zhao <zhaotianrui@loongson.cn> | ||
1 | 2 | ||
3 | 1. Implement some functions for LoongArch numa support; | ||
4 | 2. Implement fdt_add_memory_node() for fdt; | ||
5 | 3. build_srat() fills node_id and adds build numa memory. | ||
6 | |||
7 | Reviewed-by: Song Gao <gaosong@loongson.cn> | ||
8 | Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn> | ||
9 | Signed-off-by: Song Gao <gaosong@loongson.cn> | ||
10 | Message-Id: <20230613122613.2471743-1-zhaotianrui@loongson.cn> | ||
11 | --- | ||
12 | hw/loongarch/Kconfig | 1 + | ||
13 | hw/loongarch/acpi-build.c | 60 +++++++++++++++++----- | ||
14 | hw/loongarch/virt.c | 102 +++++++++++++++++++++++++++++++++----- | ||
15 | 3 files changed, 139 insertions(+), 24 deletions(-) | ||
16 | |||
17 | diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/hw/loongarch/Kconfig | ||
20 | +++ b/hw/loongarch/Kconfig | ||
21 | @@ -XXX,XX +XXX,XX @@ config LOONGARCH_VIRT | ||
22 | select FW_CFG_DMA | ||
23 | select DIMM | ||
24 | select PFLASH_CFI01 | ||
25 | + select ACPI_HMAT | ||
26 | diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c | ||
27 | index XXXXXXX..XXXXXXX 100644 | ||
28 | --- a/hw/loongarch/acpi-build.c | ||
29 | +++ b/hw/loongarch/acpi-build.c | ||
30 | @@ -XXX,XX +XXX,XX @@ | ||
31 | #include "sysemu/tpm.h" | ||
32 | #include "hw/platform-bus.h" | ||
33 | #include "hw/acpi/aml-build.h" | ||
34 | +#include "hw/acpi/hmat.h" | ||
35 | |||
36 | #define ACPI_BUILD_ALIGN_SIZE 0x1000 | ||
37 | #define ACPI_BUILD_TABLE_SIZE 0x20000 | ||
38 | @@ -XXX,XX +XXX,XX @@ build_madt(GArray *table_data, BIOSLinker *linker, LoongArchMachineState *lams) | ||
39 | static void | ||
40 | build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine) | ||
41 | { | ||
42 | - int i, arch_id; | ||
43 | + int i, arch_id, node_id; | ||
44 | + uint64_t mem_len, mem_base; | ||
45 | + int nb_numa_nodes = machine->numa_state->num_nodes; | ||
46 | LoongArchMachineState *lams = LOONGARCH_MACHINE(machine); | ||
47 | - MachineState *ms = MACHINE(lams); | ||
48 | - MachineClass *mc = MACHINE_GET_CLASS(ms); | ||
49 | - const CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(ms); | ||
50 | + MachineClass *mc = MACHINE_GET_CLASS(lams); | ||
51 | + const CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(machine); | ||
52 | AcpiTable table = { .sig = "SRAT", .rev = 1, .oem_id = lams->oem_id, | ||
53 | .oem_table_id = lams->oem_table_id }; | ||
54 | |||
55 | @@ -XXX,XX +XXX,XX @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine) | ||
56 | |||
57 | for (i = 0; i < arch_ids->len; ++i) { | ||
58 | arch_id = arch_ids->cpus[i].arch_id; | ||
59 | + node_id = arch_ids->cpus[i].props.node_id; | ||
60 | |||
61 | /* Processor Local APIC/SAPIC Affinity Structure */ | ||
62 | build_append_int_noprefix(table_data, 0, 1); /* Type */ | ||
63 | build_append_int_noprefix(table_data, 16, 1); /* Length */ | ||
64 | /* Proximity Domain [7:0] */ | ||
65 | - build_append_int_noprefix(table_data, 0, 1); | ||
66 | + build_append_int_noprefix(table_data, node_id, 1); | ||
67 | build_append_int_noprefix(table_data, arch_id, 1); /* APIC ID */ | ||
68 | /* Flags, Table 5-36 */ | ||
69 | build_append_int_noprefix(table_data, 1, 4); | ||
70 | @@ -XXX,XX +XXX,XX @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine) | ||
71 | build_append_int_noprefix(table_data, 0, 4); /* Reserved */ | ||
72 | } | ||
73 | |||
74 | + /* Node0 */ | ||
75 | build_srat_memory(table_data, VIRT_LOWMEM_BASE, VIRT_LOWMEM_SIZE, | ||
76 | 0, MEM_AFFINITY_ENABLED); | ||
77 | + mem_base = VIRT_HIGHMEM_BASE; | ||
78 | + if (!nb_numa_nodes) { | ||
79 | + mem_len = machine->ram_size - VIRT_LOWMEM_SIZE; | ||
80 | + } else { | ||
81 | + mem_len = machine->numa_state->nodes[0].node_mem - VIRT_LOWMEM_SIZE; | ||
82 | + } | ||
83 | + if (mem_len) | ||
84 | + build_srat_memory(table_data, mem_base, mem_len, 0, MEM_AFFINITY_ENABLED); | ||
85 | + | ||
86 | + /* Node1 - Nodemax */ | ||
87 | + if (nb_numa_nodes) { | ||
88 | + mem_base += mem_len; | ||
89 | + for (i = 1; i < nb_numa_nodes; ++i) { | ||
90 | + if (machine->numa_state->nodes[i].node_mem > 0) { | ||
91 | + build_srat_memory(table_data, mem_base, | ||
92 | + machine->numa_state->nodes[i].node_mem, i, | ||
93 | + MEM_AFFINITY_ENABLED); | ||
94 | + mem_base += machine->numa_state->nodes[i].node_mem; | ||
95 | + } | ||
96 | + } | ||
97 | + } | ||
98 | |||
99 | - build_srat_memory(table_data, VIRT_HIGHMEM_BASE, machine->ram_size - VIRT_LOWMEM_SIZE, | ||
100 | - 0, MEM_AFFINITY_ENABLED); | ||
101 | - | ||
102 | - if (ms->device_memory) { | ||
103 | - build_srat_memory(table_data, ms->device_memory->base, | ||
104 | - memory_region_size(&ms->device_memory->mr), | ||
105 | - 0, MEM_AFFINITY_HOTPLUGGABLE | MEM_AFFINITY_ENABLED); | ||
106 | + if (machine->device_memory) { | ||
107 | + build_srat_memory(table_data, machine->device_memory->base, | ||
108 | + memory_region_size(&machine->device_memory->mr), | ||
109 | + nb_numa_nodes - 1, | ||
110 | + MEM_AFFINITY_HOTPLUGGABLE | MEM_AFFINITY_ENABLED); | ||
111 | } | ||
112 | |||
113 | acpi_table_end(linker, &table); | ||
114 | @@ -XXX,XX +XXX,XX @@ static void acpi_build(AcpiBuildTables *tables, MachineState *machine) | ||
115 | acpi_add_table(table_offsets, tables_blob); | ||
116 | build_srat(tables_blob, tables->linker, machine); | ||
117 | |||
118 | + if (machine->numa_state->num_nodes) { | ||
119 | + if (machine->numa_state->have_numa_distance) { | ||
120 | + acpi_add_table(table_offsets, tables_blob); | ||
121 | + build_slit(tables_blob, tables->linker, machine, lams->oem_id, | ||
122 | + lams->oem_table_id); | ||
123 | + } | ||
124 | + if (machine->numa_state->hmat_enabled) { | ||
125 | + acpi_add_table(table_offsets, tables_blob); | ||
126 | + build_hmat(tables_blob, tables->linker, machine->numa_state, | ||
127 | + lams->oem_id, lams->oem_table_id); | ||
128 | + } | ||
129 | + } | ||
130 | + | ||
131 | acpi_add_table(table_offsets, tables_blob); | ||
132 | { | ||
133 | AcpiMcfgInfo mcfg = { | ||
134 | diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c | ||
135 | index XXXXXXX..XXXXXXX 100644 | ||
136 | --- a/hw/loongarch/virt.c | ||
137 | +++ b/hw/loongarch/virt.c | ||
138 | @@ -XXX,XX +XXX,XX @@ static void fdt_add_cpu_nodes(const LoongArchMachineState *lams) | ||
139 | for (num = smp_cpus - 1; num >= 0; num--) { | ||
140 | char *nodename = g_strdup_printf("/cpus/cpu@%d", num); | ||
141 | LoongArchCPU *cpu = LOONGARCH_CPU(qemu_get_cpu(num)); | ||
142 | + CPUState *cs = CPU(cpu); | ||
143 | |||
144 | qemu_fdt_add_subnode(ms->fdt, nodename); | ||
145 | qemu_fdt_setprop_string(ms->fdt, nodename, "device_type", "cpu"); | ||
146 | qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", | ||
147 | cpu->dtb_compatible); | ||
148 | + if (ms->possible_cpus->cpus[cs->cpu_index].props.has_node_id) { | ||
149 | + qemu_fdt_setprop_cell(ms->fdt, nodename, "numa-node-id", | ||
150 | + ms->possible_cpus->cpus[cs->cpu_index].props.node_id); | ||
151 | + } | ||
152 | qemu_fdt_setprop_cell(ms->fdt, nodename, "reg", num); | ||
153 | qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle", | ||
154 | qemu_fdt_alloc_phandle(ms->fdt)); | ||
155 | @@ -XXX,XX +XXX,XX @@ static void fdt_add_irqchip_node(LoongArchMachineState *lams) | ||
156 | g_free(nodename); | ||
157 | } | ||
158 | |||
159 | +static void fdt_add_memory_node(MachineState *ms, | ||
160 | + uint64_t base, uint64_t size, int node_id) | ||
161 | +{ | ||
162 | + char *nodename = g_strdup_printf("/memory@%" PRIx64, base); | ||
163 | + | ||
164 | + qemu_fdt_add_subnode(ms->fdt, nodename); | ||
165 | + qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", 2, base, 2, size); | ||
166 | + qemu_fdt_setprop_string(ms->fdt, nodename, "device_type", "memory"); | ||
167 | + | ||
168 | + if (ms->numa_state && ms->numa_state->num_nodes) { | ||
169 | + qemu_fdt_setprop_cell(ms->fdt, nodename, "numa-node-id", node_id); | ||
170 | + } | ||
171 | + | ||
172 | + g_free(nodename); | ||
173 | +} | ||
174 | + | ||
175 | #define PM_BASE 0x10080000 | ||
176 | #define PM_SIZE 0x100 | ||
177 | #define PM_CTRL 0x10 | ||
178 | @@ -XXX,XX +XXX,XX @@ static void loongarch_init(MachineState *machine) | ||
179 | const char *cpu_model = machine->cpu_type; | ||
180 | ram_addr_t offset = 0; | ||
181 | ram_addr_t ram_size = machine->ram_size; | ||
182 | - uint64_t highram_size = 0; | ||
183 | + uint64_t highram_size = 0, phyAddr = 0; | ||
184 | MemoryRegion *address_space_mem = get_system_memory(); | ||
185 | LoongArchMachineState *lams = LOONGARCH_MACHINE(machine); | ||
186 | + int nb_numa_nodes = machine->numa_state->num_nodes; | ||
187 | + NodeInfo *numa_info = machine->numa_state->nodes; | ||
188 | int i; | ||
189 | hwaddr fdt_base; | ||
190 | const CPUArchIdList *possible_cpus; | ||
191 | MachineClass *mc = MACHINE_GET_CLASS(machine); | ||
192 | CPUState *cpu; | ||
193 | + char *ramName = NULL; | ||
194 | |||
195 | if (!cpu_model) { | ||
196 | cpu_model = LOONGARCH_CPU_TYPE_NAME("la464"); | ||
197 | @@ -XXX,XX +XXX,XX @@ static void loongarch_init(MachineState *machine) | ||
198 | machine->possible_cpus->cpus[i].cpu = OBJECT(cpu); | ||
199 | } | ||
200 | fdt_add_cpu_nodes(lams); | ||
201 | - /* Add memory region */ | ||
202 | - memory_region_init_alias(&lams->lowmem, NULL, "loongarch.lowram", | ||
203 | - machine->ram, 0, 256 * MiB); | ||
204 | - memory_region_add_subregion(address_space_mem, offset, &lams->lowmem); | ||
205 | - offset += 256 * MiB; | ||
206 | - memmap_add_entry(0, 256 * MiB, 1); | ||
207 | - highram_size = ram_size - 256 * MiB; | ||
208 | - memory_region_init_alias(&lams->highmem, NULL, "loongarch.highmem", | ||
209 | - machine->ram, offset, highram_size); | ||
210 | - memory_region_add_subregion(address_space_mem, 0x90000000, &lams->highmem); | ||
211 | - memmap_add_entry(0x90000000, highram_size, 1); | ||
212 | + | ||
213 | + /* Node0 memory */ | ||
214 | + memmap_add_entry(VIRT_LOWMEM_BASE, VIRT_LOWMEM_SIZE, 1); | ||
215 | + fdt_add_memory_node(machine, VIRT_LOWMEM_BASE, VIRT_LOWMEM_SIZE, 0); | ||
216 | + memory_region_init_alias(&lams->lowmem, NULL, "loongarch.node0.lowram", | ||
217 | + machine->ram, offset, VIRT_LOWMEM_SIZE); | ||
218 | + memory_region_add_subregion(address_space_mem, phyAddr, &lams->lowmem); | ||
219 | + | ||
220 | + offset += VIRT_LOWMEM_SIZE; | ||
221 | + if (nb_numa_nodes > 0) { | ||
222 | + assert(numa_info[0].node_mem > VIRT_LOWMEM_SIZE); | ||
223 | + highram_size = numa_info[0].node_mem - VIRT_LOWMEM_SIZE; | ||
224 | + } else { | ||
225 | + highram_size = ram_size - VIRT_LOWMEM_SIZE; | ||
226 | + } | ||
227 | + phyAddr = VIRT_HIGHMEM_BASE; | ||
228 | + memmap_add_entry(phyAddr, highram_size, 1); | ||
229 | + fdt_add_memory_node(machine, phyAddr, highram_size, 0); | ||
230 | + memory_region_init_alias(&lams->highmem, NULL, "loongarch.node0.highram", | ||
231 | + machine->ram, offset, highram_size); | ||
232 | + memory_region_add_subregion(address_space_mem, phyAddr, &lams->highmem); | ||
233 | + | ||
234 | + /* Node1 - Nodemax memory */ | ||
235 | + offset += highram_size; | ||
236 | + phyAddr += highram_size; | ||
237 | + | ||
238 | + for (i = 1; i < nb_numa_nodes; i++) { | ||
239 | + MemoryRegion *nodemem = g_new(MemoryRegion, 1); | ||
240 | + ramName = g_strdup_printf("loongarch.node%d.ram", i); | ||
241 | + memory_region_init_alias(nodemem, NULL, ramName, machine->ram, | ||
242 | + offset, numa_info[i].node_mem); | ||
243 | + memory_region_add_subregion(address_space_mem, phyAddr, nodemem); | ||
244 | + memmap_add_entry(phyAddr, numa_info[i].node_mem, 1); | ||
245 | + fdt_add_memory_node(machine, phyAddr, numa_info[i].node_mem, i); | ||
246 | + offset += numa_info[i].node_mem; | ||
247 | + phyAddr += numa_info[i].node_mem; | ||
248 | + } | ||
249 | |||
250 | /* initialize device memory address space */ | ||
251 | if (machine->ram_size < machine->maxram_size) { | ||
252 | @@ -XXX,XX +XXX,XX @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms) | ||
253 | return ms->possible_cpus; | ||
254 | } | ||
255 | |||
256 | +static CpuInstanceProperties | ||
257 | +virt_cpu_index_to_props(MachineState *ms, unsigned cpu_index) | ||
258 | +{ | ||
259 | + MachineClass *mc = MACHINE_GET_CLASS(ms); | ||
260 | + const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms); | ||
261 | + | ||
262 | + assert(cpu_index < possible_cpus->len); | ||
263 | + return possible_cpus->cpus[cpu_index].props; | ||
264 | +} | ||
265 | + | ||
266 | +static int64_t virt_get_default_cpu_node_id(const MachineState *ms, int idx) | ||
267 | +{ | ||
268 | + int64_t nidx = 0; | ||
269 | + | ||
270 | + if (ms->numa_state->num_nodes) { | ||
271 | + nidx = idx / (ms->smp.cpus / ms->numa_state->num_nodes); | ||
272 | + if (ms->numa_state->num_nodes <= nidx) { | ||
273 | + nidx = ms->numa_state->num_nodes - 1; | ||
274 | + } | ||
275 | + } | ||
276 | + return nidx; | ||
277 | +} | ||
278 | + | ||
279 | static void loongarch_class_init(ObjectClass *oc, void *data) | ||
280 | { | ||
281 | MachineClass *mc = MACHINE_CLASS(oc); | ||
282 | @@ -XXX,XX +XXX,XX @@ static void loongarch_class_init(ObjectClass *oc, void *data) | ||
283 | mc->default_boot_order = "c"; | ||
284 | mc->no_cdrom = 1; | ||
285 | mc->possible_cpu_arch_ids = virt_possible_cpu_arch_ids; | ||
286 | + mc->cpu_index_to_instance_props = virt_cpu_index_to_props; | ||
287 | + mc->get_default_cpu_node_id = virt_get_default_cpu_node_id; | ||
288 | + mc->numa_mem_supported = true; | ||
289 | + mc->auto_enable_numa_with_memhp = true; | ||
290 | + mc->auto_enable_numa_with_memdev = true; | ||
291 | mc->get_hotplug_handler = virt_machine_get_hotplug_handler; | ||
292 | mc->default_nic = "virtio-net-pci"; | ||
293 | hc->plug = loongarch_machine_device_plug_cb; | ||
294 | -- | ||
295 | 2.39.1 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Tianrui Zhao <zhaotianrui@loongson.cn> | ||
1 | 2 | ||
3 | Supplement LoongArch cpu topology arguments, including support socket | ||
4 | and threads per core. | ||
5 | |||
6 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
7 | Reviewed-by: Song Gao <gaosong@loongson.cn> | ||
8 | Signed-off-by: Tianrui Zhao <zhaotianrui@loongson.cn> | ||
9 | Signed-off-by: Song Gao <gaosong@loongson.cn> | ||
10 | Message-Id: <20230613123251.2471878-1-zhaotianrui@loongson.cn> | ||
11 | --- | ||
12 | hw/loongarch/acpi-build.c | 4 ++++ | ||
13 | hw/loongarch/virt.c | 9 ++++++++- | ||
14 | 2 files changed, 12 insertions(+), 1 deletion(-) | ||
15 | |||
16 | diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/hw/loongarch/acpi-build.c | ||
19 | +++ b/hw/loongarch/acpi-build.c | ||
20 | @@ -XXX,XX +XXX,XX @@ static void acpi_build(AcpiBuildTables *tables, MachineState *machine) | ||
21 | acpi_add_table(table_offsets, tables_blob); | ||
22 | build_madt(tables_blob, tables->linker, lams); | ||
23 | |||
24 | + acpi_add_table(table_offsets, tables_blob); | ||
25 | + build_pptt(tables_blob, tables->linker, machine, | ||
26 | + lams->oem_id, lams->oem_table_id); | ||
27 | + | ||
28 | acpi_add_table(table_offsets, tables_blob); | ||
29 | build_srat(tables_blob, tables->linker, machine); | ||
30 | |||
31 | diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c | ||
32 | index XXXXXXX..XXXXXXX 100644 | ||
33 | --- a/hw/loongarch/virt.c | ||
34 | +++ b/hw/loongarch/virt.c | ||
35 | @@ -XXX,XX +XXX,XX @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms) | ||
36 | for (n = 0; n < ms->possible_cpus->len; n++) { | ||
37 | ms->possible_cpus->cpus[n].type = ms->cpu_type; | ||
38 | ms->possible_cpus->cpus[n].arch_id = n; | ||
39 | + | ||
40 | + ms->possible_cpus->cpus[n].props.has_socket_id = true; | ||
41 | + ms->possible_cpus->cpus[n].props.socket_id = | ||
42 | + n / (ms->smp.cores * ms->smp.threads); | ||
43 | ms->possible_cpus->cpus[n].props.has_core_id = true; | ||
44 | - ms->possible_cpus->cpus[n].props.core_id = n % ms->smp.cores; | ||
45 | + ms->possible_cpus->cpus[n].props.core_id = | ||
46 | + n / ms->smp.threads % ms->smp.cores; | ||
47 | + ms->possible_cpus->cpus[n].props.has_thread_id = true; | ||
48 | + ms->possible_cpus->cpus[n].props.thread_id = n % ms->smp.threads; | ||
49 | } | ||
50 | return ms->possible_cpus; | ||
51 | } | ||
52 | -- | ||
53 | 2.39.1 | ||
54 | |||
55 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Jiajie Chen <c@jia.je> | ||
1 | 2 | ||
3 | The previous code checks whether the highest 16 bits of virtual address | ||
4 | equal to that of CSR.DMW0-3. This is incorrect according to the spec, | ||
5 | and is corrected to compare only the highest four bits instead. | ||
6 | |||
7 | Signed-off-by: Jiajie Chen <c@jia.je> | ||
8 | Reviewed-by: Song Gao <gaosong@loongson.cn> | ||
9 | Message-Id: <20230614065556.2397513-1-c@jia.je> | ||
10 | Signed-off-by: Song Gao <gaosong@loongson.cn> | ||
11 | --- | ||
12 | target/loongarch/tlb_helper.c | 4 ++-- | ||
13 | 1 file changed, 2 insertions(+), 2 deletions(-) | ||
14 | |||
15 | diff --git a/target/loongarch/tlb_helper.c b/target/loongarch/tlb_helper.c | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/target/loongarch/tlb_helper.c | ||
18 | +++ b/target/loongarch/tlb_helper.c | ||
19 | @@ -XXX,XX +XXX,XX @@ static int get_physical_address(CPULoongArchState *env, hwaddr *physical, | ||
20 | } | ||
21 | |||
22 | plv = kernel_mode | (user_mode << R_CSR_DMW_PLV3_SHIFT); | ||
23 | - base_v = address >> TARGET_VIRT_ADDR_SPACE_BITS; | ||
24 | + base_v = address >> R_CSR_DMW_VSEG_SHIFT; | ||
25 | /* Check direct map window */ | ||
26 | for (int i = 0; i < 4; i++) { | ||
27 | - base_c = env->CSR_DMW[i] >> TARGET_VIRT_ADDR_SPACE_BITS; | ||
28 | + base_c = FIELD_EX64(env->CSR_DMW[i], CSR_DMW, VSEG); | ||
29 | if ((plv & env->CSR_DMW[i]) && (base_c == base_v)) { | ||
30 | *physical = dmw_va2pa(address); | ||
31 | *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; | ||
32 | -- | ||
33 | 2.39.1 | diff view generated by jsdifflib |