|
@@ -647,15 +647,13 @@ static void fw_cfg_add_memory(MachineState *ms)
|
|
|
|
|
|
static void virt_init(MachineState *machine)
|
|
static void virt_init(MachineState *machine)
|
|
{
|
|
{
|
|
- LoongArchCPU *lacpu;
|
|
|
|
const char *cpu_model = machine->cpu_type;
|
|
const char *cpu_model = machine->cpu_type;
|
|
MemoryRegion *address_space_mem = get_system_memory();
|
|
MemoryRegion *address_space_mem = get_system_memory();
|
|
LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine);
|
|
LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine);
|
|
int i;
|
|
int i;
|
|
hwaddr base, size, ram_size = machine->ram_size;
|
|
hwaddr base, size, ram_size = machine->ram_size;
|
|
- const CPUArchIdList *possible_cpus;
|
|
|
|
MachineClass *mc = MACHINE_GET_CLASS(machine);
|
|
MachineClass *mc = MACHINE_GET_CLASS(machine);
|
|
- CPUState *cpu;
|
|
|
|
|
|
+ Object *cpuobj;
|
|
|
|
|
|
if (!cpu_model) {
|
|
if (!cpu_model) {
|
|
cpu_model = LOONGARCH_CPU_TYPE_NAME("la464");
|
|
cpu_model = LOONGARCH_CPU_TYPE_NAME("la464");
|
|
@@ -671,14 +669,15 @@ static void virt_init(MachineState *machine)
|
|
memory_region_add_subregion(&lvms->system_iocsr, 0, &lvms->iocsr_mem);
|
|
memory_region_add_subregion(&lvms->system_iocsr, 0, &lvms->iocsr_mem);
|
|
|
|
|
|
/* Init CPUs */
|
|
/* Init CPUs */
|
|
- possible_cpus = mc->possible_cpu_arch_ids(machine);
|
|
|
|
- for (i = 0; i < possible_cpus->len; i++) {
|
|
|
|
- cpu = cpu_create(machine->cpu_type);
|
|
|
|
- cpu->cpu_index = i;
|
|
|
|
- machine->possible_cpus->cpus[i].cpu = cpu;
|
|
|
|
- lacpu = LOONGARCH_CPU(cpu);
|
|
|
|
- lacpu->phy_id = machine->possible_cpus->cpus[i].arch_id;
|
|
|
|
- lacpu->env.address_space_iocsr = &lvms->as_iocsr;
|
|
|
|
|
|
+ mc->possible_cpu_arch_ids(machine);
|
|
|
|
+ for (i = 0; i < machine->smp.cpus; i++) {
|
|
|
|
+ cpuobj = object_new(machine->cpu_type);
|
|
|
|
+ if (cpuobj == NULL) {
|
|
|
|
+ error_report("Fail to create object with type %s ",
|
|
|
|
+ machine->cpu_type);
|
|
|
|
+ exit(EXIT_FAILURE);
|
|
|
|
+ }
|
|
|
|
+ qdev_realize_and_unref(DEVICE(cpuobj), NULL, &error_fatal);
|
|
}
|
|
}
|
|
fw_cfg_add_memory(machine);
|
|
fw_cfg_add_memory(machine);
|
|
|
|
|
|
@@ -829,9 +828,52 @@ static CPUArchId *virt_find_cpu_slot(MachineState *ms, int arch_id)
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/* Find cpu slot for cold-plut CPU object where cpu is NULL */
|
|
|
|
+static CPUArchId *virt_find_empty_cpu_slot(MachineState *ms)
|
|
|
|
+{
|
|
|
|
+ int n;
|
|
|
|
+ for (n = 0; n < ms->possible_cpus->len; n++) {
|
|
|
|
+ if (ms->possible_cpus->cpus[n].cpu == NULL) {
|
|
|
|
+ return &ms->possible_cpus->cpus[n];
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return NULL;
|
|
|
|
+}
|
|
|
|
+
|
|
static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev,
|
|
static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev,
|
|
DeviceState *dev, Error **errp)
|
|
DeviceState *dev, Error **errp)
|
|
{
|
|
{
|
|
|
|
+ LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev);
|
|
|
|
+ MachineState *ms = MACHINE(OBJECT(hotplug_dev));
|
|
|
|
+ LoongArchCPU *cpu = LOONGARCH_CPU(dev);
|
|
|
|
+ CPUState *cs = CPU(dev);
|
|
|
|
+ CPUArchId *cpu_slot;
|
|
|
|
+ Error *err = NULL;
|
|
|
|
+ LoongArchCPUTopo topo;
|
|
|
|
+
|
|
|
|
+ if (lvms->acpi_ged) {
|
|
|
|
+ error_setg(&err, "CPU hotplug not supported");
|
|
|
|
+ goto out;
|
|
|
|
+ } else {
|
|
|
|
+ /* For cold-add cpu, find empty cpu slot */
|
|
|
|
+ cpu_slot = virt_find_empty_cpu_slot(ms);
|
|
|
|
+ topo.socket_id = cpu_slot->props.socket_id;
|
|
|
|
+ topo.core_id = cpu_slot->props.core_id;
|
|
|
|
+ topo.thread_id = cpu_slot->props.thread_id;
|
|
|
|
+ object_property_set_int(OBJECT(dev), "socket-id", topo.socket_id, NULL);
|
|
|
|
+ object_property_set_int(OBJECT(dev), "core-id", topo.core_id, NULL);
|
|
|
|
+ object_property_set_int(OBJECT(dev), "thread-id", topo.thread_id, NULL);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ cpu->env.address_space_iocsr = &lvms->as_iocsr;
|
|
|
|
+ cpu->phy_id = cpu_slot->arch_id;
|
|
|
|
+ cs->cpu_index = cpu_slot - ms->possible_cpus->cpus;
|
|
|
|
+ numa_cpu_pre_plug(cpu_slot, dev, &err);
|
|
|
|
+out:
|
|
|
|
+ if (err) {
|
|
|
|
+ error_propagate(errp, err);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
static void virt_cpu_unplug_request(HotplugHandler *hotplug_dev,
|
|
static void virt_cpu_unplug_request(HotplugHandler *hotplug_dev,
|
|
@@ -892,6 +934,30 @@ static void virt_cpu_unplug(HotplugHandler *hotplug_dev,
|
|
static void virt_cpu_plug(HotplugHandler *hotplug_dev,
|
|
static void virt_cpu_plug(HotplugHandler *hotplug_dev,
|
|
DeviceState *dev, Error **errp)
|
|
DeviceState *dev, Error **errp)
|
|
{
|
|
{
|
|
|
|
+ CPUArchId *cpu_slot;
|
|
|
|
+ LoongArchCPU *cpu = LOONGARCH_CPU(dev);
|
|
|
|
+ LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev);
|
|
|
|
+ Error *err = NULL;
|
|
|
|
+
|
|
|
|
+ cpu_slot = virt_find_cpu_slot(MACHINE(lvms), cpu->phy_id);
|
|
|
|
+ cpu_slot->cpu = CPU(dev);
|
|
|
|
+ if (lvms->ipi) {
|
|
|
|
+ hotplug_handler_plug(HOTPLUG_HANDLER(lvms->ipi), dev, &err);
|
|
|
|
+ if (err) {
|
|
|
|
+ error_propagate(errp, err);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (lvms->extioi) {
|
|
|
|
+ hotplug_handler_plug(HOTPLUG_HANDLER(lvms->extioi), dev, &err);
|
|
|
|
+ if (err) {
|
|
|
|
+ error_propagate(errp, err);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return;
|
|
}
|
|
}
|
|
|
|
|
|
static bool memhp_type_supported(DeviceState *dev)
|
|
static bool memhp_type_supported(DeviceState *dev)
|