Skip to content

Commit

Permalink
pc: acpi: consolidate CPU hotplug AML
Browse files Browse the repository at this point in the history
move the former SSDT part of CPU hoplug close to DSDT part.
AML is only moved but there isn't any functional change.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
  • Loading branch information
Igor Mammedov authored and mstsirkin committed Jun 7, 2016
1 parent 86958d2 commit 7c2991f
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 113 deletions.
104 changes: 103 additions & 1 deletion hw/acpi/cpu_hotplug_acpi_table.c
Expand Up @@ -15,12 +15,19 @@

#include "qemu/osdep.h"
#include "hw/acpi/cpu_hotplug.h"
#include "hw/i386/pc.h"

void build_cpu_hotplug_aml(Aml *ctx)
void build_cpu_hotplug_aml(Aml *ctx, MachineState *machine,
uint16_t io_base, uint16_t io_len)
{
Aml *dev;
Aml *crs;
Aml *pkg;
Aml *field;
Aml *method;
Aml *if_ctx;
Aml *else_ctx;
int i, apic_idx;
Aml *sb_scope = aml_scope("_SB");
uint8_t madt_tmpl[8] = {0x00, 0x08, 0x00, 0x00, 0x00, 0, 0, 0};
Aml *cpu_id = aml_arg(0);
Expand All @@ -29,6 +36,9 @@ void build_cpu_hotplug_aml(Aml *ctx)
Aml *cpus_map = aml_name(CPU_ON_BITMAP);
Aml *zero = aml_int(0);
Aml *one = aml_int(1);
MachineClass *mc = MACHINE_GET_CLASS(machine);
CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(machine);
PCMachineState *pcms = PC_MACHINE(machine);

/*
* _MAT method - creates an madt apic buffer
Expand Down Expand Up @@ -132,5 +142,97 @@ void build_cpu_hotplug_aml(Aml *ctx)
}
aml_append(sb_scope, method);

/* The current AML generator can cover the APIC ID range [0..255],
* inclusive, for VCPU hotplug. */
QEMU_BUILD_BUG_ON(ACPI_CPU_HOTPLUG_ID_LIMIT > 256);
g_assert(pcms->apic_id_limit <= ACPI_CPU_HOTPLUG_ID_LIMIT);

/* create PCI0.PRES device and its _CRS to reserve CPU hotplug MMIO */
dev = aml_device("PCI0." stringify(CPU_HOTPLUG_RESOURCE_DEVICE));
aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A06")));
aml_append(dev,
aml_name_decl("_UID", aml_string("CPU Hotplug resources"))
);
/* device present, functioning, decoding, not shown in UI */
aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
crs = aml_resource_template();
aml_append(crs,
aml_io(AML_DECODE16, io_base, io_base, 1, io_len)
);
aml_append(dev, aml_name_decl("_CRS", crs));
aml_append(sb_scope, dev);
/* declare CPU hotplug MMIO region and PRS field to access it */
aml_append(sb_scope, aml_operation_region(
"PRST", AML_SYSTEM_IO, aml_int(io_base), io_len));
field = aml_field("PRST", AML_BYTE_ACC, AML_NOLOCK, AML_PRESERVE);
aml_append(field, aml_named_field("PRS", 256));
aml_append(sb_scope, field);

/* build Processor object for each processor */
for (i = 0; i < apic_ids->len; i++) {
int apic_id = apic_ids->cpus[i].arch_id;

assert(apic_id < ACPI_CPU_HOTPLUG_ID_LIMIT);

dev = aml_processor(apic_id, 0, 0, "CP%.02X", apic_id);

method = aml_method("_MAT", 0, AML_NOTSERIALIZED);
aml_append(method,
aml_return(aml_call1(CPU_MAT_METHOD, aml_int(apic_id))));
aml_append(dev, method);

method = aml_method("_STA", 0, AML_NOTSERIALIZED);
aml_append(method,
aml_return(aml_call1(CPU_STATUS_METHOD, aml_int(apic_id))));
aml_append(dev, method);

method = aml_method("_EJ0", 1, AML_NOTSERIALIZED);
aml_append(method,
aml_return(aml_call2(CPU_EJECT_METHOD, aml_int(apic_id),
aml_arg(0)))
);
aml_append(dev, method);

aml_append(sb_scope, dev);
}

/* build this code:
* Method(NTFY, 2) {If (LEqual(Arg0, 0x00)) {Notify(CP00, Arg1)} ...}
*/
/* Arg0 = Processor ID = APIC ID */
method = aml_method(AML_NOTIFY_METHOD, 2, AML_NOTSERIALIZED);
for (i = 0; i < apic_ids->len; i++) {
int apic_id = apic_ids->cpus[i].arch_id;

if_ctx = aml_if(aml_equal(aml_arg(0), aml_int(apic_id)));
aml_append(if_ctx,
aml_notify(aml_name("CP%.02X", apic_id), aml_arg(1))
);
aml_append(method, if_ctx);
}
aml_append(sb_scope, method);

/* build "Name(CPON, Package() { One, One, ..., Zero, Zero, ... })"
*
* Note: The ability to create variable-sized packages was first
* introduced in ACPI 2.0. ACPI 1.0 only allowed fixed-size packages
* ith up to 255 elements. Windows guests up to win2k8 fail when
* VarPackageOp is used.
*/
pkg = pcms->apic_id_limit <= 255 ? aml_package(pcms->apic_id_limit) :
aml_varpackage(pcms->apic_id_limit);

for (i = 0, apic_idx = 0; i < apic_ids->len; i++) {
int apic_id = apic_ids->cpus[i].arch_id;

for (; apic_idx < apic_id; apic_idx++) {
aml_append(pkg, aml_int(0));
}
aml_append(pkg, aml_int(apic_ids->cpus[i].cpu ? 1 : 0));
apic_idx = apic_id + 1;
}
aml_append(sb_scope, aml_name_decl(CPU_ON_BITMAP, pkg));
g_free(apic_ids);

aml_append(ctx, sb_scope);
}
112 changes: 1 addition & 111 deletions hw/i386/acpi-build.c
Expand Up @@ -943,114 +943,6 @@ static Aml *build_crs(PCIHostState *host,
return crs;
}

static void build_processor_devices(Aml *sb_scope, MachineState *machine,
AcpiPmInfo *pm)
{
int i, apic_idx;
Aml *dev;
Aml *crs;
Aml *pkg;
Aml *field;
Aml *ifctx;
Aml *method;
MachineClass *mc = MACHINE_GET_CLASS(machine);
CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(machine);
PCMachineState *pcms = PC_MACHINE(machine);

/* The current AML generator can cover the APIC ID range [0..255],
* inclusive, for VCPU hotplug. */
QEMU_BUILD_BUG_ON(ACPI_CPU_HOTPLUG_ID_LIMIT > 256);
g_assert(pcms->apic_id_limit <= ACPI_CPU_HOTPLUG_ID_LIMIT);

/* create PCI0.PRES device and its _CRS to reserve CPU hotplug MMIO */
dev = aml_device("PCI0." stringify(CPU_HOTPLUG_RESOURCE_DEVICE));
aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A06")));
aml_append(dev,
aml_name_decl("_UID", aml_string("CPU Hotplug resources"))
);
/* device present, functioning, decoding, not shown in UI */
aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
crs = aml_resource_template();
aml_append(crs,
aml_io(AML_DECODE16, pm->cpu_hp_io_base, pm->cpu_hp_io_base, 1,
pm->cpu_hp_io_len)
);
aml_append(dev, aml_name_decl("_CRS", crs));
aml_append(sb_scope, dev);
/* declare CPU hotplug MMIO region and PRS field to access it */
aml_append(sb_scope, aml_operation_region(
"PRST", AML_SYSTEM_IO, aml_int(pm->cpu_hp_io_base), pm->cpu_hp_io_len));
field = aml_field("PRST", AML_BYTE_ACC, AML_NOLOCK, AML_PRESERVE);
aml_append(field, aml_named_field("PRS", 256));
aml_append(sb_scope, field);

/* build Processor object for each processor */
for (i = 0; i < apic_ids->len; i++) {
int apic_id = apic_ids->cpus[i].arch_id;

assert(apic_id < ACPI_CPU_HOTPLUG_ID_LIMIT);

dev = aml_processor(apic_id, 0, 0, "CP%.02X", apic_id);

method = aml_method("_MAT", 0, AML_NOTSERIALIZED);
aml_append(method,
aml_return(aml_call1(CPU_MAT_METHOD, aml_int(apic_id))));
aml_append(dev, method);

method = aml_method("_STA", 0, AML_NOTSERIALIZED);
aml_append(method,
aml_return(aml_call1(CPU_STATUS_METHOD, aml_int(apic_id))));
aml_append(dev, method);

method = aml_method("_EJ0", 1, AML_NOTSERIALIZED);
aml_append(method,
aml_return(aml_call2(CPU_EJECT_METHOD, aml_int(apic_id),
aml_arg(0)))
);
aml_append(dev, method);

aml_append(sb_scope, dev);
}

/* build this code:
* Method(NTFY, 2) {If (LEqual(Arg0, 0x00)) {Notify(CP00, Arg1)} ...}
*/
/* Arg0 = Processor ID = APIC ID */
method = aml_method(AML_NOTIFY_METHOD, 2, AML_NOTSERIALIZED);
for (i = 0; i < apic_ids->len; i++) {
int apic_id = apic_ids->cpus[i].arch_id;

ifctx = aml_if(aml_equal(aml_arg(0), aml_int(apic_id)));
aml_append(ifctx,
aml_notify(aml_name("CP%.02X", apic_id), aml_arg(1))
);
aml_append(method, ifctx);
}
aml_append(sb_scope, method);

/* build "Name(CPON, Package() { One, One, ..., Zero, Zero, ... })"
*
* Note: The ability to create variable-sized packages was first
* introduced in ACPI 2.0. ACPI 1.0 only allowed fixed-size packages
* ith up to 255 elements. Windows guests up to win2k8 fail when
* VarPackageOp is used.
*/
pkg = pcms->apic_id_limit <= 255 ? aml_package(pcms->apic_id_limit) :
aml_varpackage(pcms->apic_id_limit);

for (i = 0, apic_idx = 0; i < apic_ids->len; i++) {
int apic_id = apic_ids->cpus[i].arch_id;

for (; apic_idx < apic_id; apic_idx++) {
aml_append(pkg, aml_int(0));
}
aml_append(pkg, aml_int(apic_ids->cpus[i].cpu ? 1 : 0));
apic_idx = apic_id + 1;
}
aml_append(sb_scope, aml_name_decl(CPU_ON_BITMAP, pkg));
g_free(apic_ids);
}

static void build_memory_devices(Aml *sb_scope, int nr_mem,
uint16_t io_base, uint16_t io_len)
{
Expand Down Expand Up @@ -2043,7 +1935,7 @@ build_dsdt(GArray *table_data, GArray *linker,
build_q35_pci0_int(dsdt);
}

build_cpu_hotplug_aml(dsdt);
build_cpu_hotplug_aml(dsdt, machine, pm->cpu_hp_io_base, pm->cpu_hp_io_len);
build_memory_hotplug_aml(dsdt, nr_mem, pm->mem_hp_io_base,
pm->mem_hp_io_len);

Expand Down Expand Up @@ -2305,8 +2197,6 @@ build_dsdt(GArray *table_data, GArray *linker,

sb_scope = aml_scope("\\_SB");
{
build_processor_devices(sb_scope, machine, pm);

build_memory_devices(sb_scope, nr_mem, pm->mem_hp_io_base,
pm->mem_hp_io_len);

Expand Down
3 changes: 2 additions & 1 deletion include/hw/acpi/cpu_hotplug.h
Expand Up @@ -34,5 +34,6 @@ void acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner,
#define CPU_STATUS_MAP "PRS"
#define CPU_SCAN_METHOD "PRSC"

void build_cpu_hotplug_aml(Aml *ctx);
void build_cpu_hotplug_aml(Aml *ctx, MachineState *machine,
uint16_t io_base, uint16_t io_len);
#endif

0 comments on commit 7c2991f

Please sign in to comment.