1
The following changes since commit 848a6caa88b9f082c89c9b41afa975761262981d:
1
The following changes since commit 661c2e1ab29cd9c4d268ae3f44712e8d421c0e56:
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
scripts/checkpatch: Fix a typo (2025-03-04 09:30:26 +0800)
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/bibo-mao/qemu.git tags/pull-loongarch-20250305
8
8
9
for you to fetch changes up to 8555ddc671203969b0e6eb651e538d02a9a79b3a:
9
for you to fetch changes up to 0a629c827300d514cc1f61806414d214fcf75051:
10
10
11
hw/intc/loongarch_ipi: Bring back all 4 IPI mailboxes (2023-06-05 11:08:55 +0800)
11
target/loongarch: Adjust the cpu reset action to a proper position (2025-03-05 09:45:52 +0800)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Fixes Coverity CID: 1512452, 1512453
14
pull-loongarch-20250305 queue
15
Fixes: 78464f023b54 ("hw/loongarch/virt: Modify ipi as percpu device")
16
15
17
----------------------------------------------------------------
16
----------------------------------------------------------------
18
Jiaxun Yang (1):
17
Bibo Mao (14):
19
hw/intc/loongarch_ipi: Bring back all 4 IPI mailboxes
18
hw/intc/loongarch_ipi: Add basic hotplug framework
19
hw/intc/loongarch_ipi: Implment cpu hotplug interface
20
hw/intc/loongarch_ipi: Notify ipi object when cpu is plugged
21
hw/intc/loongarch_extioi: Move gpio irq initial to common code
22
hw/intc/loongarch_extioi: Add basic hotplug framework
23
hw/intc/loongarch_extioi: Implment cpu hotplug interface
24
hw/intc/loongarch_extioi: Use cpu plug notification
25
hw/loongarch/virt: Add CPU topology support
26
hw/loongarch/virt: Add topo properties on CPU object
27
hw/loongarch/virt: Add basic cpu plug interface framework
28
hw/loongarch/virt: Implement cpu unplug interface
29
hw/loongarch/virt: Implement cpu plug interface
30
hw/loongarch/virt: Update the ACPI table for hotplug cpu
31
hw/loongarch/virt: Enable cpu hotplug feature on virt machine
20
32
21
hw/intc/loongarch_ipi.c | 6 +++---
33
Xianglai Li (1):
22
include/hw/intc/loongarch_ipi.h | 4 +++-
34
target/loongarch: Adjust the cpu reset action to a proper position
23
2 files changed, 6 insertions(+), 4 deletions(-)
35
36
hw/intc/loongarch_extioi.c | 8 +-
37
hw/intc/loongarch_extioi_common.c | 84 ++++++++++-
38
hw/intc/loongarch_ipi.c | 71 +++++++++
39
hw/loongarch/Kconfig | 1 +
40
hw/loongarch/virt-acpi-build.c | 35 ++++-
41
hw/loongarch/virt.c | 301 ++++++++++++++++++++++++++++++++++----
42
include/hw/loongarch/virt.h | 1 +
43
target/loongarch/cpu.c | 25 +++-
44
target/loongarch/cpu.h | 11 ++
45
9 files changed, 493 insertions(+), 44 deletions(-)
diff view generated by jsdifflib
1
From: Jiaxun Yang <jiaxun.yang@flygoat.com>
1
LoongArch ipi can send interrupt to multiple CPUs, interrupt routing
2
to CPU comes from destination physical cpu id. Here hotplug interface
3
is added for IPI object, so that parent irq line can be connected, and
4
routing table can be added for new created cpu.
2
5
3
As per "Loongson 3A5000/3B5000 Processor Reference Manual",
6
Here only basic hotplug framework is added, it is stub function.
4
Loongson 3A5000's IPI implementation have 4 mailboxes per
5
core.
6
7
7
However, in 78464f023b54 ("hw/loongarch/virt: Modify ipi as
8
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
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>
19
Message-Id: <20230521102307.87081-2-jiaxun.yang@flygoat.com>
20
Signed-off-by: Song Gao <gaosong@loongson.cn>
21
---
9
---
22
hw/intc/loongarch_ipi.c | 6 +++---
10
hw/intc/loongarch_ipi.c | 32 ++++++++++++++++++++++++++++++++
23
include/hw/intc/loongarch_ipi.h | 4 +++-
11
1 file changed, 32 insertions(+)
24
2 files changed, 6 insertions(+), 4 deletions(-)
25
12
26
diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c
13
diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c
27
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/intc/loongarch_ipi.c
15
--- a/hw/intc/loongarch_ipi.c
29
+++ b/hw/intc/loongarch_ipi.c
16
+++ b/hw/intc/loongarch_ipi.c
30
@@ -XXX,XX +XXX,XX @@ static void loongarch_ipi_init(Object *obj)
17
@@ -XXX,XX +XXX,XX @@
31
18
*/
32
static const VMStateDescription vmstate_ipi_core = {
19
33
.name = "ipi-single",
20
#include "qemu/osdep.h"
34
- .version_id = 1,
21
+#include "qemu/error-report.h"
35
- .minimum_version_id = 1,
22
#include "hw/boards.h"
36
+ .version_id = 2,
23
#include "qapi/error.h"
37
+ .minimum_version_id = 2,
24
#include "hw/intc/loongarch_ipi.h"
38
.fields = (VMStateField[]) {
25
@@ -XXX,XX +XXX,XX @@ static void loongarch_ipi_realize(DeviceState *dev, Error **errp)
39
VMSTATE_UINT32(status, IPICore),
26
}
40
VMSTATE_UINT32(en, IPICore),
27
}
41
VMSTATE_UINT32(set, IPICore),
28
42
VMSTATE_UINT32(clear, IPICore),
29
+static void loongarch_ipi_cpu_plug(HotplugHandler *hotplug_dev,
43
- VMSTATE_UINT32_ARRAY(buf, IPICore, 2),
30
+ DeviceState *dev, Error **errp)
44
+ VMSTATE_UINT32_ARRAY(buf, IPICore, IPI_MBX_NUM * 2),
31
+{
45
VMSTATE_END_OF_LIST()
32
+ Object *obj = OBJECT(dev);
33
+
34
+ if (!object_dynamic_cast(obj, TYPE_LOONGARCH_CPU)) {
35
+ warn_report("LoongArch extioi: Invalid %s device type",
36
+ object_get_typename(obj));
37
+ return;
38
+ }
39
+}
40
+
41
+static void loongarch_ipi_cpu_unplug(HotplugHandler *hotplug_dev,
42
+ DeviceState *dev, Error **errp)
43
+{
44
+ Object *obj = OBJECT(dev);
45
+
46
+ if (!object_dynamic_cast(obj, TYPE_LOONGARCH_CPU)) {
47
+ warn_report("LoongArch extioi: Invalid %s device type",
48
+ object_get_typename(obj));
49
+ return;
50
+ }
51
+}
52
+
53
static void loongarch_ipi_class_init(ObjectClass *klass, void *data)
54
{
55
LoongsonIPICommonClass *licc = LOONGSON_IPI_COMMON_CLASS(klass);
56
+ HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
57
LoongarchIPIClass *lic = LOONGARCH_IPI_CLASS(klass);
58
DeviceClass *dc = DEVICE_CLASS(klass);
59
60
@@ -XXX,XX +XXX,XX @@ static void loongarch_ipi_class_init(ObjectClass *klass, void *data)
61
&lic->parent_realize);
62
licc->get_iocsr_as = get_iocsr_as;
63
licc->cpu_by_arch_id = loongarch_cpu_by_arch_id;
64
+ hc->plug = loongarch_ipi_cpu_plug;
65
+ hc->unplug = loongarch_ipi_cpu_unplug;
66
}
67
68
static const TypeInfo loongarch_ipi_types[] = {
69
@@ -XXX,XX +XXX,XX @@ static const TypeInfo loongarch_ipi_types[] = {
70
.instance_size = sizeof(LoongarchIPIState),
71
.class_size = sizeof(LoongarchIPIClass),
72
.class_init = loongarch_ipi_class_init,
73
+ .interfaces = (InterfaceInfo[]) {
74
+ { TYPE_HOTPLUG_HANDLER },
75
+ { }
76
+ },
46
}
77
}
47
};
78
};
48
diff --git a/include/hw/intc/loongarch_ipi.h b/include/hw/intc/loongarch_ipi.h
49
index XXXXXXX..XXXXXXX 100644
50
--- a/include/hw/intc/loongarch_ipi.h
51
+++ b/include/hw/intc/loongarch_ipi.h
52
@@ -XXX,XX +XXX,XX @@
53
#define MAIL_SEND_OFFSET 0
54
#define ANY_SEND_OFFSET (IOCSR_ANY_SEND - IOCSR_MAIL_SEND)
55
56
+#define IPI_MBX_NUM 4
57
+
58
#define TYPE_LOONGARCH_IPI "loongarch_ipi"
59
OBJECT_DECLARE_SIMPLE_TYPE(LoongArchIPI, LOONGARCH_IPI)
60
61
@@ -XXX,XX +XXX,XX @@ typedef struct IPICore {
62
uint32_t set;
63
uint32_t clear;
64
/* 64bit buf divide into 2 32bit buf */
65
- uint32_t buf[2];
66
+ uint32_t buf[IPI_MBX_NUM * 2];
67
qemu_irq irq;
68
} IPICore;
69
79
70
--
80
--
71
2.39.1
81
2.43.5
diff view generated by jsdifflib
New patch
1
Add logic cpu allocation and cpu mapping with cpu hotplug interface.
2
When cpu is added, connect ipi gpio irq to CPU IRQ_IPI irq pin.
1
3
4
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
5
---
6
hw/intc/loongarch_ipi.c | 39 +++++++++++++++++++++++++++++++++++++++
7
1 file changed, 39 insertions(+)
8
9
diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/hw/intc/loongarch_ipi.c
12
+++ b/hw/intc/loongarch_ipi.c
13
@@ -XXX,XX +XXX,XX @@ static int loongarch_cpu_by_arch_id(LoongsonIPICommonState *lics,
14
return MEMTX_ERROR;
15
}
16
17
+static IPICore *loongarch_ipi_get_cpu(LoongsonIPICommonState *lics,
18
+ DeviceState *dev)
19
+{
20
+ CPUClass *k = CPU_GET_CLASS(dev);
21
+ uint64_t arch_id = k->get_arch_id(CPU(dev));
22
+ int i;
23
+
24
+ for (i = 0; i < lics->num_cpu; i++) {
25
+ if (lics->cpu[i].arch_id == arch_id) {
26
+ return &lics->cpu[i];
27
+ }
28
+ }
29
+
30
+ return NULL;
31
+}
32
+
33
static void loongarch_ipi_realize(DeviceState *dev, Error **errp)
34
{
35
LoongsonIPICommonState *lics = LOONGSON_IPI_COMMON(dev);
36
@@ -XXX,XX +XXX,XX @@ static void loongarch_ipi_realize(DeviceState *dev, Error **errp)
37
static void loongarch_ipi_cpu_plug(HotplugHandler *hotplug_dev,
38
DeviceState *dev, Error **errp)
39
{
40
+ LoongsonIPICommonState *lics = LOONGSON_IPI_COMMON(hotplug_dev);
41
Object *obj = OBJECT(dev);
42
+ IPICore *core;
43
+ int index;
44
45
if (!object_dynamic_cast(obj, TYPE_LOONGARCH_CPU)) {
46
warn_report("LoongArch extioi: Invalid %s device type",
47
object_get_typename(obj));
48
return;
49
}
50
+
51
+ core = loongarch_ipi_get_cpu(lics, dev);
52
+ if (!core) {
53
+ return;
54
+ }
55
+
56
+ core->cpu = CPU(dev);
57
+ index = core - lics->cpu;
58
+
59
+ /* connect ipi irq to cpu irq */
60
+ qdev_connect_gpio_out(DEVICE(lics), index, qdev_get_gpio_in(dev, IRQ_IPI));
61
}
62
63
static void loongarch_ipi_cpu_unplug(HotplugHandler *hotplug_dev,
64
DeviceState *dev, Error **errp)
65
{
66
+ LoongsonIPICommonState *lics = LOONGSON_IPI_COMMON(hotplug_dev);
67
Object *obj = OBJECT(dev);
68
+ IPICore *core;
69
70
if (!object_dynamic_cast(obj, TYPE_LOONGARCH_CPU)) {
71
warn_report("LoongArch extioi: Invalid %s device type",
72
object_get_typename(obj));
73
return;
74
}
75
+
76
+ core = loongarch_ipi_get_cpu(lics, dev);
77
+ if (!core) {
78
+ return;
79
+ }
80
+
81
+ core->cpu = NULL;
82
}
83
84
static void loongarch_ipi_class_init(ObjectClass *klass, void *data)
85
--
86
2.43.5
diff view generated by jsdifflib
New patch
1
Use hotplug_handler_plug() to nofity ipi object when cold-plug
2
cpu is created, so that ipi can set and configure irq routing
3
to new cpu.
1
4
5
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
6
---
7
hw/loongarch/virt.c | 5 ++---
8
1 file changed, 2 insertions(+), 3 deletions(-)
9
10
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/hw/loongarch/virt.c
13
+++ b/hw/loongarch/virt.c
14
@@ -XXX,XX +XXX,XX @@ static void virt_cpu_irq_init(LoongArchVirtMachineState *lvms)
15
MachineClass *mc = MACHINE_GET_CLASS(ms);
16
const CPUArchIdList *possible_cpus;
17
CPUState *cs;
18
+ Error *err = NULL;
19
20
/* cpu nodes */
21
possible_cpus = mc->possible_cpu_arch_ids(ms);
22
@@ -XXX,XX +XXX,XX @@ static void virt_cpu_irq_init(LoongArchVirtMachineState *lvms)
23
continue;
24
}
25
26
- /* connect ipi irq to cpu irq */
27
- qdev_connect_gpio_out(lvms->ipi, num,
28
- qdev_get_gpio_in(DEVICE(cs), IRQ_IPI));
29
+ hotplug_handler_plug(HOTPLUG_HANDLER(lvms->ipi), DEVICE(cs), &err);
30
31
/*
32
* connect ext irq to the cpu irq
33
--
34
2.43.5
diff view generated by jsdifflib
New patch
1
When cpu is added, it will connect gpio irq line to cpu irq.
2
And cpu hot-add is put in common code, move gpio irq initial
3
part into common code.
1
4
5
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
6
---
7
hw/intc/loongarch_extioi.c | 8 +-------
8
hw/intc/loongarch_extioi_common.c | 6 +++++-
9
2 files changed, 6 insertions(+), 8 deletions(-)
10
11
diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/intc/loongarch_extioi.c
14
+++ b/hw/intc/loongarch_extioi.c
15
@@ -XXX,XX +XXX,XX @@ static void loongarch_extioi_realize(DeviceState *dev, Error **errp)
16
LoongArchExtIOIClass *lec = LOONGARCH_EXTIOI_GET_CLASS(dev);
17
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
18
Error *local_err = NULL;
19
- int i, pin;
20
+ int i;
21
22
lec->parent_realize(dev, &local_err);
23
if (local_err) {
24
@@ -XXX,XX +XXX,XX @@ static void loongarch_extioi_realize(DeviceState *dev, Error **errp)
25
} else {
26
s->status |= BIT(EXTIOI_ENABLE);
27
}
28
-
29
- for (i = 0; i < s->num_cpu; i++) {
30
- for (pin = 0; pin < LS3A_INTC_IP; pin++) {
31
- qdev_init_gpio_out(dev, &s->cpu[i].parent_irq[pin], 1);
32
- }
33
- }
34
}
35
36
static void loongarch_extioi_unrealize(DeviceState *dev)
37
diff --git a/hw/intc/loongarch_extioi_common.c b/hw/intc/loongarch_extioi_common.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/hw/intc/loongarch_extioi_common.c
40
+++ b/hw/intc/loongarch_extioi_common.c
41
@@ -XXX,XX +XXX,XX @@ static void loongarch_extioi_common_realize(DeviceState *dev, Error **errp)
42
MachineState *machine = MACHINE(qdev_get_machine());
43
MachineClass *mc = MACHINE_GET_CLASS(machine);
44
const CPUArchIdList *id_list;
45
- int i;
46
+ int i, pin;
47
48
assert(mc->possible_cpu_arch_ids);
49
id_list = mc->possible_cpu_arch_ids(machine);
50
@@ -XXX,XX +XXX,XX @@ static void loongarch_extioi_common_realize(DeviceState *dev, Error **errp)
51
for (i = 0; i < s->num_cpu; i++) {
52
s->cpu[i].arch_id = id_list->cpus[i].arch_id;
53
s->cpu[i].cpu = CPU(id_list->cpus[i].cpu);
54
+
55
+ for (pin = 0; pin < LS3A_INTC_IP; pin++) {
56
+ qdev_init_gpio_out(dev, &s->cpu[i].parent_irq[pin], 1);
57
+ }
58
}
59
}
60
61
--
62
2.43.5
diff view generated by jsdifflib
New patch
1
LoongArch extioi interrupt controller routes peripheral interrupt
2
to multiple CPUs, physical cpu id is used in interrupt routing table.
3
Here hotplug interface is added for extioi object, so that parent irq
4
line can be connected, and routing table can be added for new created
5
cpu.
1
6
7
Here only basic hotplug framework is added, it is stub function.
8
9
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
10
---
11
hw/intc/loongarch_extioi_common.c | 33 +++++++++++++++++++++++++++++++
12
1 file changed, 33 insertions(+)
13
14
diff --git a/hw/intc/loongarch_extioi_common.c b/hw/intc/loongarch_extioi_common.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/intc/loongarch_extioi_common.c
17
+++ b/hw/intc/loongarch_extioi_common.c
18
@@ -XXX,XX +XXX,XX @@
19
* Copyright (C) 2024 Loongson Technology Corporation Limited
20
*/
21
#include "qemu/osdep.h"
22
+#include "qemu/error-report.h"
23
#include "qemu/module.h"
24
#include "qapi/error.h"
25
#include "hw/qdev-properties.h"
26
#include "hw/intc/loongarch_extioi_common.h"
27
#include "migration/vmstate.h"
28
+#include "target/loongarch/cpu.h"
29
+
30
+static void loongarch_extioi_cpu_plug(HotplugHandler *hotplug_dev,
31
+ DeviceState *dev, Error **errp)
32
+{
33
+ Object *obj = OBJECT(dev);
34
+
35
+ if (!object_dynamic_cast(obj, TYPE_LOONGARCH_CPU)) {
36
+ warn_report("LoongArch extioi: Invalid %s device type",
37
+ object_get_typename(obj));
38
+ return;
39
+ }
40
+}
41
+
42
+static void loongarch_extioi_cpu_unplug(HotplugHandler *hotplug_dev,
43
+ DeviceState *dev, Error **errp)
44
+{
45
+ Object *obj = OBJECT(dev);
46
+
47
+ if (!object_dynamic_cast(obj, TYPE_LOONGARCH_CPU)) {
48
+ warn_report("LoongArch extioi: Invalid %s device type",
49
+ object_get_typename(obj));
50
+ return;
51
+ }
52
+}
53
54
static void loongarch_extioi_common_realize(DeviceState *dev, Error **errp)
55
{
56
@@ -XXX,XX +XXX,XX @@ static void loongarch_extioi_common_class_init(ObjectClass *klass, void *data)
57
{
58
DeviceClass *dc = DEVICE_CLASS(klass);
59
LoongArchExtIOICommonClass *lecc = LOONGARCH_EXTIOI_COMMON_CLASS(klass);
60
+ HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
61
62
device_class_set_parent_realize(dc, loongarch_extioi_common_realize,
63
&lecc->parent_realize);
64
device_class_set_props(dc, extioi_properties);
65
dc->vmsd = &vmstate_loongarch_extioi;
66
+ hc->plug = loongarch_extioi_cpu_plug;
67
+ hc->unplug = loongarch_extioi_cpu_unplug;
68
}
69
70
static const TypeInfo loongarch_extioi_common_types[] = {
71
@@ -XXX,XX +XXX,XX @@ static const TypeInfo loongarch_extioi_common_types[] = {
72
.instance_size = sizeof(LoongArchExtIOICommonState),
73
.class_size = sizeof(LoongArchExtIOICommonClass),
74
.class_init = loongarch_extioi_common_class_init,
75
+ .interfaces = (InterfaceInfo[]) {
76
+ { TYPE_HOTPLUG_HANDLER },
77
+ { }
78
+ },
79
.abstract = true,
80
}
81
};
82
--
83
2.43.5
diff view generated by jsdifflib
New patch
1
When cpu is added, connect extioi gpio irq to CPU irq pin.
1
2
3
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
4
---
5
hw/intc/loongarch_extioi_common.c | 45 +++++++++++++++++++++++++++++++
6
1 file changed, 45 insertions(+)
7
8
diff --git a/hw/intc/loongarch_extioi_common.c b/hw/intc/loongarch_extioi_common.c
9
index XXXXXXX..XXXXXXX 100644
10
--- a/hw/intc/loongarch_extioi_common.c
11
+++ b/hw/intc/loongarch_extioi_common.c
12
@@ -XXX,XX +XXX,XX @@
13
#include "migration/vmstate.h"
14
#include "target/loongarch/cpu.h"
15
16
+static ExtIOICore *loongarch_extioi_get_cpu(LoongArchExtIOICommonState *s,
17
+ DeviceState *dev)
18
+{
19
+ CPUClass *k = CPU_GET_CLASS(dev);
20
+ uint64_t arch_id = k->get_arch_id(CPU(dev));
21
+ int i;
22
+
23
+ for (i = 0; i < s->num_cpu; i++) {
24
+ if (s->cpu[i].arch_id == arch_id) {
25
+ return &s->cpu[i];
26
+ }
27
+ }
28
+
29
+ return NULL;
30
+}
31
+
32
static void loongarch_extioi_cpu_plug(HotplugHandler *hotplug_dev,
33
DeviceState *dev, Error **errp)
34
{
35
+ LoongArchExtIOICommonState *s = LOONGARCH_EXTIOI_COMMON(hotplug_dev);
36
Object *obj = OBJECT(dev);
37
+ ExtIOICore *core;
38
+ int pin, index;
39
40
if (!object_dynamic_cast(obj, TYPE_LOONGARCH_CPU)) {
41
warn_report("LoongArch extioi: Invalid %s device type",
42
object_get_typename(obj));
43
return;
44
}
45
+
46
+ core = loongarch_extioi_get_cpu(s, dev);
47
+ if (!core) {
48
+ return;
49
+ }
50
+
51
+ core->cpu = CPU(dev);
52
+ index = core - s->cpu;
53
+
54
+ /*
55
+ * connect extioi irq to the cpu irq
56
+ * cpu_pin[LS3A_INTC_IP + 2 : 2] <= intc_pin[LS3A_INTC_IP : 0]
57
+ */
58
+ for (pin = 0; pin < LS3A_INTC_IP; pin++) {
59
+ qdev_connect_gpio_out(DEVICE(s), index * LS3A_INTC_IP + pin,
60
+ qdev_get_gpio_in(dev, pin + 2));
61
+ }
62
}
63
64
static void loongarch_extioi_cpu_unplug(HotplugHandler *hotplug_dev,
65
DeviceState *dev, Error **errp)
66
{
67
+ LoongArchExtIOICommonState *s = LOONGARCH_EXTIOI_COMMON(hotplug_dev);
68
Object *obj = OBJECT(dev);
69
+ ExtIOICore *core;
70
71
if (!object_dynamic_cast(obj, TYPE_LOONGARCH_CPU)) {
72
warn_report("LoongArch extioi: Invalid %s device type",
73
object_get_typename(obj));
74
return;
75
}
76
+
77
+ core = loongarch_extioi_get_cpu(s, dev);
78
+ if (!core) {
79
+ return;
80
+ }
81
+
82
+ core->cpu = NULL;
83
}
84
85
static void loongarch_extioi_common_realize(DeviceState *dev, Error **errp)
86
--
87
2.43.5
diff view generated by jsdifflib
New patch
1
Use hotplug_handler_plug() to nofity extioi object when cold-plug
2
cpu is created, so that extioi can set and configure irq routing
3
to new cpu.
1
4
5
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
6
---
7
hw/loongarch/virt.c | 12 ++----------
8
1 file changed, 2 insertions(+), 10 deletions(-)
9
10
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/hw/loongarch/virt.c
13
+++ b/hw/loongarch/virt.c
14
@@ -XXX,XX +XXX,XX @@ static void virt_devices_init(DeviceState *pch_pic,
15
16
static void virt_cpu_irq_init(LoongArchVirtMachineState *lvms)
17
{
18
- int num, pin;
19
+ int num;
20
MachineState *ms = MACHINE(lvms);
21
MachineClass *mc = MACHINE_GET_CLASS(ms);
22
const CPUArchIdList *possible_cpus;
23
@@ -XXX,XX +XXX,XX @@ static void virt_cpu_irq_init(LoongArchVirtMachineState *lvms)
24
}
25
26
hotplug_handler_plug(HOTPLUG_HANDLER(lvms->ipi), DEVICE(cs), &err);
27
-
28
- /*
29
- * connect ext irq to the cpu irq
30
- * cpu_pin[9:2] <= intc_pin[7:0]
31
- */
32
- for (pin = 0; pin < LS3A_INTC_IP; pin++) {
33
- qdev_connect_gpio_out(lvms->extioi, (num * LS3A_INTC_IP + pin),
34
- qdev_get_gpio_in(DEVICE(cs), pin + 2));
35
- }
36
+ hotplug_handler_plug(HOTPLUG_HANDLER(lvms->extioi), DEVICE(cs), &err);
37
}
38
}
39
40
--
41
2.43.5
diff view generated by jsdifflib
New patch
1
Add topological relationships for Loongarch VCPU and initialize
2
topology member variables.
1
3
4
On LoongArch system there is socket/core/thread topo information,
5
physical CPU id is calculated from CPU topo, every topo sub-field is
6
aligned by power of 2. So it is different from logical cpu index.
7
8
Co-developed-by: Xianglai Li <lixianglai@loongson.cn>
9
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
10
---
11
hw/loongarch/virt.c | 59 ++++++++++++++++++++++++++++++++++++------
12
target/loongarch/cpu.h | 6 +++++
13
2 files changed, 57 insertions(+), 8 deletions(-)
14
15
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/loongarch/virt.c
18
+++ b/hw/loongarch/virt.c
19
@@ -XXX,XX +XXX,XX @@ static void virt_initfn(Object *obj)
20
virt_flash_create(lvms);
21
}
22
23
+static void virt_get_topo_from_index(MachineState *ms,
24
+ LoongArchCPUTopo *topo, int index)
25
+{
26
+ topo->socket_id = index / (ms->smp.cores * ms->smp.threads);
27
+ topo->core_id = index / ms->smp.threads % ms->smp.cores;
28
+ topo->thread_id = index % ms->smp.threads;
29
+}
30
+
31
+static unsigned int topo_align_up(unsigned int count)
32
+{
33
+ g_assert(count >= 1);
34
+ count -= 1;
35
+ return BIT(count ? 32 - clz32(count) : 0);
36
+}
37
+
38
+/*
39
+ * LoongArch Reference Manual Vol1, Chapter 7.4.12 CPU Identity
40
+ * For CPU architecture, bit0 .. bit8 is valid for CPU id, max cpuid is 512
41
+ * However for IPI/Eiointc interrupt controller, max supported cpu id for
42
+ * irq routingis 256
43
+ *
44
+ * Here max cpu id is 256 for virt machine
45
+ */
46
+static int virt_get_arch_id_from_topo(MachineState *ms, LoongArchCPUTopo *topo)
47
+{
48
+ int arch_id, threads, cores, sockets;
49
+
50
+ threads = topo_align_up(ms->smp.threads);
51
+ cores = topo_align_up(ms->smp.cores);
52
+ sockets = topo_align_up(ms->smp.sockets);
53
+ if ((threads * cores * sockets) > 256) {
54
+ error_report("Exceeding max cpuid 256 with sockets[%d] cores[%d]"
55
+ " threads[%d]", ms->smp.sockets, ms->smp.cores,
56
+ ms->smp.threads);
57
+ exit(1);
58
+ }
59
+
60
+ arch_id = topo->thread_id + topo->core_id * threads;
61
+ arch_id += topo->socket_id * threads * cores;
62
+ return arch_id;
63
+}
64
+
65
static bool memhp_type_supported(DeviceState *dev)
66
{
67
/* we only support pc dimm now */
68
@@ -XXX,XX +XXX,XX @@ static HotplugHandler *virt_get_hotplug_handler(MachineState *machine,
69
70
static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
71
{
72
- int n;
73
+ int n, arch_id;
74
unsigned int max_cpus = ms->smp.max_cpus;
75
+ LoongArchCPUTopo topo;
76
77
if (ms->possible_cpus) {
78
assert(ms->possible_cpus->len == max_cpus);
79
@@ -XXX,XX +XXX,XX @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
80
sizeof(CPUArchId) * max_cpus);
81
ms->possible_cpus->len = max_cpus;
82
for (n = 0; n < ms->possible_cpus->len; n++) {
83
+ virt_get_topo_from_index(ms, &topo, n);
84
+ arch_id = virt_get_arch_id_from_topo(ms, &topo);
85
ms->possible_cpus->cpus[n].type = ms->cpu_type;
86
- ms->possible_cpus->cpus[n].arch_id = n;
87
-
88
+ ms->possible_cpus->cpus[n].arch_id = arch_id;
89
+ ms->possible_cpus->cpus[n].vcpus_count = 1;
90
ms->possible_cpus->cpus[n].props.has_socket_id = true;
91
- ms->possible_cpus->cpus[n].props.socket_id =
92
- n / (ms->smp.cores * ms->smp.threads);
93
+ ms->possible_cpus->cpus[n].props.socket_id = topo.socket_id;
94
ms->possible_cpus->cpus[n].props.has_core_id = true;
95
- ms->possible_cpus->cpus[n].props.core_id =
96
- n / ms->smp.threads % ms->smp.cores;
97
+ ms->possible_cpus->cpus[n].props.core_id = topo.core_id;
98
ms->possible_cpus->cpus[n].props.has_thread_id = true;
99
- ms->possible_cpus->cpus[n].props.thread_id = n % ms->smp.threads;
100
+ ms->possible_cpus->cpus[n].props.thread_id = topo.thread_id;
101
}
102
return ms->possible_cpus;
103
}
104
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
105
index XXXXXXX..XXXXXXX 100644
106
--- a/target/loongarch/cpu.h
107
+++ b/target/loongarch/cpu.h
108
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
109
#endif
110
} CPULoongArchState;
111
112
+typedef struct LoongArchCPUTopo {
113
+ int32_t socket_id; /* socket-id of this VCPU */
114
+ int32_t core_id; /* core-id of this VCPU */
115
+ int32_t thread_id; /* thread-id of this VCPU */
116
+} LoongArchCPUTopo;
117
+
118
/**
119
* LoongArchCPU:
120
* @env: #CPULoongArchState
121
--
122
2.43.5
diff view generated by jsdifflib
New patch
1
Add some properties such as socket_id, core_id, thread_id and node_id
2
on LoongArch CPU object.
1
3
4
Co-developed-by: Xianglai Li <lixianglai@loongson.cn>
5
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
6
---
7
target/loongarch/cpu.c | 9 +++++++++
8
target/loongarch/cpu.h | 4 ++++
9
2 files changed, 13 insertions(+)
10
11
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/loongarch/cpu.c
14
+++ b/target/loongarch/cpu.c
15
@@ -XXX,XX +XXX,XX @@
16
#include "system/tcg.h"
17
#include "system/kvm.h"
18
#include "kvm/kvm_loongarch.h"
19
+#include "hw/qdev-properties.h"
20
#include "exec/exec-all.h"
21
#include "exec/translation-block.h"
22
#include "cpu.h"
23
@@ -XXX,XX +XXX,XX @@ static int64_t loongarch_cpu_get_arch_id(CPUState *cs)
24
}
25
#endif
26
27
+static const Property loongarch_cpu_properties[] = {
28
+ DEFINE_PROP_INT32("socket-id", LoongArchCPU, socket_id, 0),
29
+ DEFINE_PROP_INT32("core-id", LoongArchCPU, core_id, 0),
30
+ DEFINE_PROP_INT32("thread-id", LoongArchCPU, thread_id, 0),
31
+ DEFINE_PROP_INT32("node-id", LoongArchCPU, node_id, CPU_UNSET_NUMA_NODE_ID),
32
+};
33
+
34
static void loongarch_cpu_class_init(ObjectClass *c, void *data)
35
{
36
LoongArchCPUClass *lacc = LOONGARCH_CPU_CLASS(c);
37
@@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_class_init(ObjectClass *c, void *data)
38
DeviceClass *dc = DEVICE_CLASS(c);
39
ResettableClass *rc = RESETTABLE_CLASS(c);
40
41
+ device_class_set_props(dc, loongarch_cpu_properties);
42
device_class_set_parent_realize(dc, loongarch_cpu_realizefn,
43
&lacc->parent_realize);
44
resettable_class_set_parent_phases(rc, NULL, loongarch_cpu_reset_hold, NULL,
45
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
46
index XXXXXXX..XXXXXXX 100644
47
--- a/target/loongarch/cpu.h
48
+++ b/target/loongarch/cpu.h
49
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
50
OnOffAuto lasx;
51
OnOffAuto kvm_pv_ipi;
52
OnOffAuto kvm_steal_time;
53
+ int32_t socket_id; /* socket-id of this CPU */
54
+ int32_t core_id; /* core-id of this CPU */
55
+ int32_t thread_id; /* thread-id of this CPU */
56
+ int32_t node_id; /* NUMA node of this CPU */
57
58
/* 'compatible' string for this CPU for Linux device trees */
59
const char *dtb_compatible;
60
--
61
2.43.5
diff view generated by jsdifflib
New patch
1
Add basic cpu hotplug interface framework, cpu hotplug interface is
2
stub function and only framework is added here.
1
3
4
Co-developed-by: Xianglai Li <lixianglai@loongson.cn>
5
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
6
---
7
hw/loongarch/virt.c | 29 +++++++++++++++++++++++++++++
8
target/loongarch/cpu.c | 13 +++++++++++++
9
target/loongarch/cpu.h | 1 +
10
3 files changed, 43 insertions(+)
11
12
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/loongarch/virt.c
15
+++ b/hw/loongarch/virt.c
16
@@ -XXX,XX +XXX,XX @@ static int virt_get_arch_id_from_topo(MachineState *ms, LoongArchCPUTopo *topo)
17
return arch_id;
18
}
19
20
+static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev,
21
+ DeviceState *dev, Error **errp)
22
+{
23
+}
24
+
25
+static void virt_cpu_unplug_request(HotplugHandler *hotplug_dev,
26
+ DeviceState *dev, Error **errp)
27
+{
28
+}
29
+
30
+static void virt_cpu_unplug(HotplugHandler *hotplug_dev,
31
+ DeviceState *dev, Error **errp)
32
+{
33
+}
34
+
35
+static void virt_cpu_plug(HotplugHandler *hotplug_dev,
36
+ DeviceState *dev, Error **errp)
37
+{
38
+}
39
+
40
static bool memhp_type_supported(DeviceState *dev)
41
{
42
/* we only support pc dimm now */
43
@@ -XXX,XX +XXX,XX @@ static void virt_device_pre_plug(HotplugHandler *hotplug_dev,
44
{
45
if (memhp_type_supported(dev)) {
46
virt_mem_pre_plug(hotplug_dev, dev, errp);
47
+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) {
48
+ virt_cpu_pre_plug(hotplug_dev, dev, errp);
49
}
50
}
51
52
@@ -XXX,XX +XXX,XX @@ static void virt_device_unplug_request(HotplugHandler *hotplug_dev,
53
{
54
if (memhp_type_supported(dev)) {
55
virt_mem_unplug_request(hotplug_dev, dev, errp);
56
+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) {
57
+ virt_cpu_unplug_request(hotplug_dev, dev, errp);
58
}
59
}
60
61
@@ -XXX,XX +XXX,XX @@ static void virt_device_unplug(HotplugHandler *hotplug_dev,
62
{
63
if (memhp_type_supported(dev)) {
64
virt_mem_unplug(hotplug_dev, dev, errp);
65
+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) {
66
+ virt_cpu_unplug(hotplug_dev, dev, errp);
67
}
68
}
69
70
@@ -XXX,XX +XXX,XX @@ static void virt_device_plug_cb(HotplugHandler *hotplug_dev,
71
}
72
} else if (memhp_type_supported(dev)) {
73
virt_mem_plug(hotplug_dev, dev, errp);
74
+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) {
75
+ virt_cpu_plug(hotplug_dev, dev, errp);
76
}
77
}
78
79
@@ -XXX,XX +XXX,XX @@ static HotplugHandler *virt_get_hotplug_handler(MachineState *machine,
80
MachineClass *mc = MACHINE_GET_CLASS(machine);
81
82
if (device_is_dynamic_sysbus(mc, dev) ||
83
+ object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU) ||
84
object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI) ||
85
memhp_type_supported(dev)) {
86
return HOTPLUG_HANDLER(machine);
87
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/target/loongarch/cpu.c
90
+++ b/target/loongarch/cpu.c
91
@@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_realizefn(DeviceState *dev, Error **errp)
92
lacc->parent_realize(dev, errp);
93
}
94
95
+static void loongarch_cpu_unrealizefn(DeviceState *dev)
96
+{
97
+ LoongArchCPUClass *lacc = LOONGARCH_CPU_GET_CLASS(dev);
98
+
99
+#ifndef CONFIG_USER_ONLY
100
+ cpu_remove_sync(CPU(dev));
101
+#endif
102
+
103
+ lacc->parent_unrealize(dev);
104
+}
105
+
106
static bool loongarch_get_lsx(Object *obj, Error **errp)
107
{
108
return LOONGARCH_CPU(obj)->lsx != ON_OFF_AUTO_OFF;
109
@@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_class_init(ObjectClass *c, void *data)
110
device_class_set_props(dc, loongarch_cpu_properties);
111
device_class_set_parent_realize(dc, loongarch_cpu_realizefn,
112
&lacc->parent_realize);
113
+ device_class_set_parent_unrealize(dc, loongarch_cpu_unrealizefn,
114
+ &lacc->parent_unrealize);
115
resettable_class_set_parent_phases(rc, NULL, loongarch_cpu_reset_hold, NULL,
116
&lacc->parent_phases);
117
118
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
119
index XXXXXXX..XXXXXXX 100644
120
--- a/target/loongarch/cpu.h
121
+++ b/target/loongarch/cpu.h
122
@@ -XXX,XX +XXX,XX @@ struct LoongArchCPUClass {
123
CPUClass parent_class;
124
125
DeviceRealize parent_realize;
126
+ DeviceUnrealize parent_unrealize;
127
ResettablePhases parent_phases;
128
};
129
130
--
131
2.43.5
diff view generated by jsdifflib
New patch
1
Implement cpu unplug interfaces including virt_cpu_unplug_request()
2
and virt_cpu_unplug().
1
3
4
Co-developed-by: Xianglai Li <lixianglai@loongson.cn>
5
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
6
---
7
hw/loongarch/virt.c | 58 +++++++++++++++++++++++++++++++++++++++++++++
8
1 file changed, 58 insertions(+)
9
10
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/hw/loongarch/virt.c
13
+++ b/hw/loongarch/virt.c
14
@@ -XXX,XX +XXX,XX @@ static int virt_get_arch_id_from_topo(MachineState *ms, LoongArchCPUTopo *topo)
15
return arch_id;
16
}
17
18
+/* Find cpu slot in machine->possible_cpus by arch_id */
19
+static CPUArchId *virt_find_cpu_slot(MachineState *ms, int arch_id)
20
+{
21
+ int n;
22
+ for (n = 0; n < ms->possible_cpus->len; n++) {
23
+ if (ms->possible_cpus->cpus[n].arch_id == arch_id) {
24
+ return &ms->possible_cpus->cpus[n];
25
+ }
26
+ }
27
+
28
+ return NULL;
29
+}
30
+
31
static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev,
32
DeviceState *dev, Error **errp)
33
{
34
@@ -XXX,XX +XXX,XX @@ static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev,
35
static void virt_cpu_unplug_request(HotplugHandler *hotplug_dev,
36
DeviceState *dev, Error **errp)
37
{
38
+ LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev);
39
+ Error *err = NULL;
40
+ LoongArchCPU *cpu = LOONGARCH_CPU(dev);
41
+ CPUState *cs = CPU(dev);
42
+
43
+ if (cs->cpu_index == 0) {
44
+ error_setg(&err, "hot-unplug of boot cpu(id%d=%d:%d:%d) not supported",
45
+ cs->cpu_index, cpu->socket_id,
46
+ cpu->core_id, cpu->thread_id);
47
+ error_propagate(errp, err);
48
+ return;
49
+ }
50
+
51
+ hotplug_handler_unplug_request(HOTPLUG_HANDLER(lvms->acpi_ged), dev, &err);
52
+ if (err) {
53
+ error_propagate(errp, err);
54
+ }
55
}
56
57
static void virt_cpu_unplug(HotplugHandler *hotplug_dev,
58
DeviceState *dev, Error **errp)
59
{
60
+ CPUArchId *cpu_slot;
61
+ Error *err = NULL;
62
+ LoongArchCPU *cpu = LOONGARCH_CPU(dev);
63
+ LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev);
64
+
65
+ /* Notify ipi and extioi irqchip to remove interrupt routing to CPU */
66
+ hotplug_handler_unplug(HOTPLUG_HANDLER(lvms->ipi), dev, &err);
67
+ if (err) {
68
+ error_propagate(errp, err);
69
+ return;
70
+ }
71
+
72
+ hotplug_handler_unplug(HOTPLUG_HANDLER(lvms->extioi), dev, &err);
73
+ if (err) {
74
+ error_propagate(errp, err);
75
+ return;
76
+ }
77
+
78
+ /* Notify acpi ged CPU removed */
79
+ hotplug_handler_unplug(HOTPLUG_HANDLER(lvms->acpi_ged), dev, &err);
80
+ if (err) {
81
+ error_propagate(errp, err);
82
+ return;
83
+ }
84
+
85
+ cpu_slot = virt_find_cpu_slot(MACHINE(lvms), cpu->phy_id);
86
+ cpu_slot->cpu = NULL;
87
+ return;
88
}
89
90
static void virt_cpu_plug(HotplugHandler *hotplug_dev,
91
--
92
2.43.5
diff view generated by jsdifflib
New patch
1
Implement cpu plug interface, and cold-plug cpu uses plug interface
2
when cpu object is created.
1
3
4
Co-developed-by: Xianglai Li <lixianglai@loongson.cn>
5
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
6
---
7
hw/loongarch/virt.c | 88 ++++++++++++++++++++++++++++++++++++------
8
target/loongarch/cpu.c | 1 +
9
2 files changed, 78 insertions(+), 11 deletions(-)
10
11
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/loongarch/virt.c
14
+++ b/hw/loongarch/virt.c
15
@@ -XXX,XX +XXX,XX @@ static void fw_cfg_add_memory(MachineState *ms)
16
17
static void virt_init(MachineState *machine)
18
{
19
- LoongArchCPU *lacpu;
20
const char *cpu_model = machine->cpu_type;
21
MemoryRegion *address_space_mem = get_system_memory();
22
LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine);
23
int i;
24
hwaddr base, size, ram_size = machine->ram_size;
25
- const CPUArchIdList *possible_cpus;
26
MachineClass *mc = MACHINE_GET_CLASS(machine);
27
- CPUState *cpu;
28
+ Object *cpuobj;
29
30
if (!cpu_model) {
31
cpu_model = LOONGARCH_CPU_TYPE_NAME("la464");
32
@@ -XXX,XX +XXX,XX @@ static void virt_init(MachineState *machine)
33
memory_region_add_subregion(&lvms->system_iocsr, 0, &lvms->iocsr_mem);
34
35
/* Init CPUs */
36
- possible_cpus = mc->possible_cpu_arch_ids(machine);
37
- for (i = 0; i < possible_cpus->len; i++) {
38
- cpu = cpu_create(machine->cpu_type);
39
- cpu->cpu_index = i;
40
- machine->possible_cpus->cpus[i].cpu = cpu;
41
- lacpu = LOONGARCH_CPU(cpu);
42
- lacpu->phy_id = machine->possible_cpus->cpus[i].arch_id;
43
- lacpu->env.address_space_iocsr = &lvms->as_iocsr;
44
+ mc->possible_cpu_arch_ids(machine);
45
+ for (i = 0; i < machine->smp.cpus; i++) {
46
+ cpuobj = object_new(machine->cpu_type);
47
+ if (cpuobj == NULL) {
48
+ error_report("Fail to create object with type %s ",
49
+ machine->cpu_type);
50
+ exit(EXIT_FAILURE);
51
+ }
52
+ qdev_realize_and_unref(DEVICE(cpuobj), NULL, &error_fatal);
53
}
54
fw_cfg_add_memory(machine);
55
56
@@ -XXX,XX +XXX,XX @@ static CPUArchId *virt_find_cpu_slot(MachineState *ms, int arch_id)
57
return NULL;
58
}
59
60
+/* Find cpu slot for cold-plut CPU object where cpu is NULL */
61
+static CPUArchId *virt_find_empty_cpu_slot(MachineState *ms)
62
+{
63
+ int n;
64
+ for (n = 0; n < ms->possible_cpus->len; n++) {
65
+ if (ms->possible_cpus->cpus[n].cpu == NULL) {
66
+ return &ms->possible_cpus->cpus[n];
67
+ }
68
+ }
69
+
70
+ return NULL;
71
+}
72
+
73
static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev,
74
DeviceState *dev, Error **errp)
75
{
76
+ LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev);
77
+ MachineState *ms = MACHINE(OBJECT(hotplug_dev));
78
+ LoongArchCPU *cpu = LOONGARCH_CPU(dev);
79
+ CPUState *cs = CPU(dev);
80
+ CPUArchId *cpu_slot;
81
+ Error *err = NULL;
82
+ LoongArchCPUTopo topo;
83
+
84
+ if (lvms->acpi_ged) {
85
+ error_setg(&err, "CPU hotplug not supported");
86
+ goto out;
87
+ } else {
88
+ /* For cold-add cpu, find empty cpu slot */
89
+ cpu_slot = virt_find_empty_cpu_slot(ms);
90
+ topo.socket_id = cpu_slot->props.socket_id;
91
+ topo.core_id = cpu_slot->props.core_id;
92
+ topo.thread_id = cpu_slot->props.thread_id;
93
+ object_property_set_int(OBJECT(dev), "socket-id", topo.socket_id, NULL);
94
+ object_property_set_int(OBJECT(dev), "core-id", topo.core_id, NULL);
95
+ object_property_set_int(OBJECT(dev), "thread-id", topo.thread_id, NULL);
96
+ }
97
+
98
+ cpu->env.address_space_iocsr = &lvms->as_iocsr;
99
+ cpu->phy_id = cpu_slot->arch_id;
100
+ cs->cpu_index = cpu_slot - ms->possible_cpus->cpus;
101
+ numa_cpu_pre_plug(cpu_slot, dev, &err);
102
+out:
103
+ if (err) {
104
+ error_propagate(errp, err);
105
+ }
106
}
107
108
static void virt_cpu_unplug_request(HotplugHandler *hotplug_dev,
109
@@ -XXX,XX +XXX,XX @@ static void virt_cpu_unplug(HotplugHandler *hotplug_dev,
110
static void virt_cpu_plug(HotplugHandler *hotplug_dev,
111
DeviceState *dev, Error **errp)
112
{
113
+ CPUArchId *cpu_slot;
114
+ LoongArchCPU *cpu = LOONGARCH_CPU(dev);
115
+ LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev);
116
+ Error *err = NULL;
117
+
118
+ cpu_slot = virt_find_cpu_slot(MACHINE(lvms), cpu->phy_id);
119
+ cpu_slot->cpu = CPU(dev);
120
+ if (lvms->ipi) {
121
+ hotplug_handler_plug(HOTPLUG_HANDLER(lvms->ipi), dev, &err);
122
+ if (err) {
123
+ error_propagate(errp, err);
124
+ return;
125
+ }
126
+ }
127
+
128
+ if (lvms->extioi) {
129
+ hotplug_handler_plug(HOTPLUG_HANDLER(lvms->extioi), dev, &err);
130
+ if (err) {
131
+ error_propagate(errp, err);
132
+ return;
133
+ }
134
+ }
135
+
136
+ return;
137
}
138
139
static bool memhp_type_supported(DeviceState *dev)
140
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
141
index XXXXXXX..XXXXXXX 100644
142
--- a/target/loongarch/cpu.c
143
+++ b/target/loongarch/cpu.c
144
@@ -XXX,XX +XXX,XX @@ static void loongarch_cpu_class_init(ObjectClass *c, void *data)
145
#ifdef CONFIG_TCG
146
cc->tcg_ops = &loongarch_tcg_ops;
147
#endif
148
+ dc->user_creatable = true;
149
}
150
151
static const gchar *loongarch32_gdb_arch_name(CPUState *cs)
152
--
153
2.43.5
diff view generated by jsdifflib
New patch
1
On LoongArch virt machine, ACPI GED hardware is used for CPU hotplug
2
handler, here CPU hotplug support feature is added based on GED handler,
3
also CPU scan and reject method is added about CPU device in DSDT table.
1
4
5
Co-developed-by: Xianglai Li <lixianglai@loongson.cn>
6
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
7
---
8
hw/loongarch/Kconfig | 1 +
9
hw/loongarch/virt-acpi-build.c | 35 +++++++++++++++++++++++++++++++---
10
hw/loongarch/virt.c | 10 ++++++++++
11
include/hw/loongarch/virt.h | 1 +
12
4 files changed, 44 insertions(+), 3 deletions(-)
13
14
diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/loongarch/Kconfig
17
+++ b/hw/loongarch/Kconfig
18
@@ -XXX,XX +XXX,XX @@ config LOONGARCH_VIRT
19
select LOONGARCH_EXTIOI
20
select LS7A_RTC
21
select SMBIOS
22
+ select ACPI_CPU_HOTPLUG
23
select ACPI_PCI
24
select ACPI_HW_REDUCED
25
select FW_CFG_DMA
26
diff --git a/hw/loongarch/virt-acpi-build.c b/hw/loongarch/virt-acpi-build.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/loongarch/virt-acpi-build.c
29
+++ b/hw/loongarch/virt-acpi-build.c
30
@@ -XXX,XX +XXX,XX @@
31
#define ACPI_BUILD_DPRINTF(fmt, ...)
32
#endif
33
34
+static void virt_madt_cpu_entry(int uid,
35
+ const CPUArchIdList *apic_ids,
36
+ GArray *entry, bool force_enabled)
37
+{
38
+ uint32_t flags, apic_id = apic_ids->cpus[uid].arch_id;
39
+
40
+ flags = apic_ids->cpus[uid].cpu || force_enabled ? 1 /* Enabled */ : 0;
41
+
42
+ /* Rev 1.0b, Table 5-13 Processor Local APIC Structure */
43
+ build_append_int_noprefix(entry, 0, 1); /* Type */
44
+ build_append_int_noprefix(entry, 8, 1); /* Length */
45
+ build_append_int_noprefix(entry, uid, 1); /* ACPI Processor ID */
46
+ build_append_int_noprefix(entry, apic_id, 1); /* APIC ID */
47
+ build_append_int_noprefix(entry, flags, 4); /* Flags */
48
+}
49
+
50
/* build FADT */
51
static void init_common_fadt_data(AcpiFadtData *data)
52
{
53
@@ -XXX,XX +XXX,XX @@ build_madt(GArray *table_data, BIOSLinker *linker,
54
MachineState *ms = MACHINE(lvms);
55
MachineClass *mc = MACHINE_GET_CLASS(ms);
56
const CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(ms);
57
- int i, arch_id;
58
+ int i, arch_id, flags;
59
AcpiTable table = { .sig = "APIC", .rev = 1, .oem_id = lvms->oem_id,
60
.oem_table_id = lvms->oem_table_id };
61
62
@@ -XXX,XX +XXX,XX @@ build_madt(GArray *table_data, BIOSLinker *linker,
63
for (i = 0; i < arch_ids->len; i++) {
64
/* Processor Core Interrupt Controller Structure */
65
arch_id = arch_ids->cpus[i].arch_id;
66
-
67
+ flags = arch_ids->cpus[i].cpu ? 1 : 0;
68
build_append_int_noprefix(table_data, 17, 1); /* Type */
69
build_append_int_noprefix(table_data, 15, 1); /* Length */
70
build_append_int_noprefix(table_data, 1, 1); /* Version */
71
build_append_int_noprefix(table_data, i, 4); /* ACPI Processor ID */
72
build_append_int_noprefix(table_data, arch_id, 4); /* Core ID */
73
- build_append_int_noprefix(table_data, 1, 4); /* Flags */
74
+ build_append_int_noprefix(table_data, flags, 4); /* Flags */
75
}
76
77
/* Extend I/O Interrupt Controller Structure */
78
@@ -XXX,XX +XXX,XX @@ build_la_ged_aml(Aml *dsdt, MachineState *machine)
79
{
80
uint32_t event;
81
LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine);
82
+ CPUHotplugFeatures opts;
83
84
build_ged_aml(dsdt, "\\_SB."GED_DEVICE,
85
HOTPLUG_HANDLER(lvms->acpi_ged),
86
@@ -XXX,XX +XXX,XX @@ build_la_ged_aml(Aml *dsdt, MachineState *machine)
87
AML_SYSTEM_MEMORY,
88
VIRT_GED_MEM_ADDR);
89
}
90
+
91
+ if (event & ACPI_GED_CPU_HOTPLUG_EVT) {
92
+ opts.acpi_1_compatible = false;
93
+ opts.has_legacy_cphp = false;
94
+ opts.fw_unplugs_cpu = false;
95
+ opts.smi_path = NULL;
96
+
97
+ build_cpus_aml(dsdt, machine, opts, virt_madt_cpu_entry,
98
+ VIRT_GED_CPUHP_ADDR, "\\_SB",
99
+ AML_GED_EVT_CPU_SCAN_METHOD, AML_SYSTEM_MEMORY);
100
+ }
101
+
102
acpi_dsdt_add_power_button(dsdt);
103
}
104
105
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
106
index XXXXXXX..XXXXXXX 100644
107
--- a/hw/loongarch/virt.c
108
+++ b/hw/loongarch/virt.c
109
@@ -XXX,XX +XXX,XX @@ static DeviceState *create_acpi_ged(DeviceState *pch_pic,
110
{
111
DeviceState *dev;
112
MachineState *ms = MACHINE(lvms);
113
+ MachineClass *mc = MACHINE_GET_CLASS(lvms);
114
uint32_t event = ACPI_GED_PWR_DOWN_EVT;
115
116
if (ms->ram_slots) {
117
event |= ACPI_GED_MEM_HOTPLUG_EVT;
118
}
119
+
120
+ if (mc->has_hotpluggable_cpus) {
121
+ event |= ACPI_GED_CPU_HOTPLUG_EVT;
122
+ }
123
+
124
dev = qdev_new(TYPE_ACPI_GED);
125
qdev_prop_set_uint32(dev, "ged-event", event);
126
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
127
@@ -XXX,XX +XXX,XX @@ static DeviceState *create_acpi_ged(DeviceState *pch_pic,
128
/* ged regs used for reset and power down */
129
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, VIRT_GED_REG_ADDR);
130
131
+ if (mc->has_hotpluggable_cpus) {
132
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 3, VIRT_GED_CPUHP_ADDR);
133
+ }
134
+
135
sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
136
qdev_get_gpio_in(pch_pic, VIRT_SCI_IRQ - VIRT_GSI_BASE));
137
return dev;
138
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
139
index XXXXXXX..XXXXXXX 100644
140
--- a/include/hw/loongarch/virt.h
141
+++ b/include/hw/loongarch/virt.h
142
@@ -XXX,XX +XXX,XX @@
143
#define VIRT_GED_EVT_ADDR 0x100e0000
144
#define VIRT_GED_MEM_ADDR (VIRT_GED_EVT_ADDR + ACPI_GED_EVT_SEL_LEN)
145
#define VIRT_GED_REG_ADDR (VIRT_GED_MEM_ADDR + MEMORY_HOTPLUG_IO_LEN)
146
+#define VIRT_GED_CPUHP_ADDR (VIRT_GED_REG_ADDR + ACPI_GED_REG_COUNT)
147
148
#define COMMAND_LINE_SIZE 512
149
150
--
151
2.43.5
diff view generated by jsdifflib