On Mon, 04 May 2015 19:11:39 +0800 Shannon Zhao <shannon.z...@linaro.org> wrote:
> > > On 2015/5/4 17:58, Igor Mammedov wrote: > > On Wed, 15 Apr 2015 21:24:55 +0800 > > Shannon Zhao <zhaoshengl...@huawei.com> wrote: > > > >> From: Shannon Zhao <shannon.z...@linaro.org> > >> > >> DSDT consists of the usual common table header plus a definition > >> block in AML encoding which describes all devices in the platform. > >> > >> After initializing DSDT with header information the namespace is > >> created which is followed by the device encodings. The devices are > >> described using the Resource Template for the 32-Bit Fixed Memory > >> Range and the Extended Interrupt Descriptors. > >> > >> Signed-off-by: Shannon Zhao <zhaoshengl...@huawei.com> > >> Signed-off-by: Shannon Zhao <shannon.z...@linaro.org> > >> --- > >> hw/arm/virt-acpi-build.c | 128 > >> +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, > >> 128 insertions(+) > >> > >> diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c > >> index c5a3cf9..d044880 100644 > >> --- a/hw/arm/virt-acpi-build.c > >> +++ b/hw/arm/virt-acpi-build.c > >> @@ -50,6 +50,130 @@ > >> #include "qom/qom-qobject.h" > >> #include "exec/ram_addr.h" > >> > >> +static void acpi_dsdt_add_cpus(Aml *scope, int max_cpus) > >> +{ > >> + uint16_t i; > >> + > >> + for (i = 0; i < max_cpus; i++) { > >> + Aml *dev = aml_device("C%03x", i); > >> + aml_append(dev, aml_name_decl("_HID", > >> aml_string("ACPI0007"))); > >> + aml_append(dev, aml_name_decl("_UID", aml_int(i))); > >> + Aml *crs = aml_resource_template(); > >> + aml_append(dev, aml_name_decl("_CRS", crs)); > >> + aml_append(scope, dev); > >> + } > >> +} > > Is maxcpus a correct here? Usually maxcpus includes non present CPUs > > as well but there is no STA method that tells whether it's present > > or not. > > > 5.2.12.14 GICC Structure > "In the GICC interrupt model, logical processors are required to have > a Processor Device object in the DSDT" > > Here we create Processor Device object for all possible CPUs and in > MADT the gicc->flags tells whether it's present or not. And this > flags is for kernel booting initialization, not for dynamic > configuration. > > BTW, ARM doesn't support vCPU hotplug now. If we want to support > hotplug later, we should add _STA method for each Processor. lack of _STA in current code implicitly means present, while flag in MADT could say not present. Since currently cpu hotplug is not supported for ARM, pls use smp_cpus instead of max_cpus and create only device objects and MADT entries only for present CPUs. > > >> + > >> +static void acpi_dsdt_add_uart(Aml *scope, const MemMap > >> *uart_memmap, > >> + const int *uart_irq) > >> +{ > >> + Aml *dev = aml_device("COM0"); > >> + aml_append(dev, aml_name_decl("_HID", > >> aml_string("ARMH0011"))); > >> + aml_append(dev, aml_name_decl("_UID", aml_int(0))); > >> + > >> + Aml *crs = aml_resource_template(); > >> + aml_append(crs, aml_memory32_fixed(uart_memmap->addr, > >> + uart_memmap->size, > >> aml_ReadWrite)); > >> + aml_append(crs, > >> + aml_interrupt(aml_consumer, aml_level, > >> aml_active_high, > >> + aml_exclusive, aml_not_wake_capable, *uart_irq + > >> 32)); > >> + aml_append(dev, aml_name_decl("_CRS", crs)); > >> + aml_append(scope, dev); > >> +} > >> + > >> +static void acpi_dsdt_add_rtc(Aml *scope, const MemMap > >> *rtc_memmap, > >> + const int *rtc_irq) > >> +{ > >> + Aml *dev = aml_device("RTC0"); > >> + aml_append(dev, aml_name_decl("_HID", > >> aml_string("LNRO0013"))); > >> + aml_append(dev, aml_name_decl("_UID", aml_int(0))); > >> + > >> + Aml *crs = aml_resource_template(); > >> + aml_append(crs, aml_memory32_fixed(rtc_memmap->addr, > >> + rtc_memmap->size, > >> aml_ReadWrite)); > >> + aml_append(crs, > >> + aml_interrupt(aml_consumer, aml_level, > >> aml_active_high, > >> + aml_exclusive, aml_not_wake_capable, *rtc_irq + > >> 32)); > >> + aml_append(dev, aml_name_decl("_CRS", crs)); > >> + aml_append(scope, dev); > >> +} > >> + > >> +static void acpi_dsdt_add_flash(Aml *scope, const MemMap > >> *flash_memmap) +{ > >> + Aml *dev, *crs; > >> + hwaddr base = flash_memmap->addr; > >> + hwaddr size = flash_memmap->size; > >> + > >> + dev = aml_device("FLS0"); > >> + aml_append(dev, aml_name_decl("_HID", > >> aml_string("LNRO0015"))); > >> + aml_append(dev, aml_name_decl("_UID", aml_int(0))); > >> + > >> + crs = aml_resource_template(); > >> + aml_append(crs, aml_memory32_fixed(base, size, > >> aml_ReadWrite)); > >> + aml_append(dev, aml_name_decl("_CRS", crs)); > >> + aml_append(scope, dev); > >> + > >> + dev = aml_device("FLS1"); > >> + aml_append(dev, aml_name_decl("_HID", > >> aml_string("LNRO0015"))); > >> + aml_append(dev, aml_name_decl("_UID", aml_int(1))); > >> + crs = aml_resource_template(); > >> + aml_append(crs, aml_memory32_fixed(base + size, size, > >> aml_ReadWrite)); > >> + aml_append(dev, aml_name_decl("_CRS", crs)); > >> + aml_append(scope, dev); > >> +} > >> + > >> +static void acpi_dsdt_add_virtio(Aml *scope, const MemMap > >> *virtio_mmio_memmap, > >> + const int *mmio_irq, > >> int num) +{ > >> + hwaddr base = virtio_mmio_memmap->addr; > >> + hwaddr size = virtio_mmio_memmap->size; > >> + int irq = *mmio_irq + 32; > >> + int i; > >> + > >> + for (i = 0; i < num; i++) { > >> + Aml *dev = aml_device("VR%02u", i); > >> + aml_append(dev, aml_name_decl("_HID", > >> aml_string("LNRO0005"))); > >> + aml_append(dev, aml_name_decl("_UID", aml_int(i))); > >> + > >> + Aml *crs = aml_resource_template(); > >> + aml_append(crs, aml_memory32_fixed(base, size, > >> aml_ReadWrite)); > >> + aml_append(crs, > >> + aml_interrupt(aml_consumer, aml_level, > >> aml_active_high, > >> + aml_exclusive, aml_not_wake_capable, irq + i)); > >> + aml_append(dev, aml_name_decl("_CRS", crs)); > >> + aml_append(scope, dev); > >> + base += size; > >> + } > >> +} > >> + > >> +/* DSDT */ > >> +static void > >> +build_dsdt(GArray *table_data, GArray *linker, VirtGuestInfo > >> *guest_info) +{ > >> + Aml *scope, *dsdt; > >> + AcpiDsdtInfo *info = guest_info->dsdt_info; > >> + > >> + dsdt = init_aml_allocator(); > >> + /* Reserve space for header */ > >> + acpi_data_push(dsdt->buf, sizeof(AcpiTableHeader)); > >> + > >> + scope = aml_scope("\\_SB"); > >> + acpi_dsdt_add_cpus(scope, guest_info->max_cpus); > >> + acpi_dsdt_add_uart(scope, info->uart_memmap, info->uart_irq); > >> + acpi_dsdt_add_rtc(scope, info->rtc_memmap, info->rtc_irq); > >> + acpi_dsdt_add_flash(scope, info->flash_memmap); > >> + acpi_dsdt_add_virtio(scope, info->virtio_mmio_memmap, > >> + info->virtio_mmio_irq, info->virtio_mmio_num); > >> + aml_append(dsdt, scope); > >> + > >> + /* copy AML table into ACPI tables blob and patch header > >> there */ > >> + g_array_append_vals(table_data, dsdt->buf->data, > >> dsdt->buf->len); > >> + build_header(linker, table_data, > >> + (void *)(table_data->data + table_data->len - > >> dsdt->buf->len), > >> + "DSDT", dsdt->buf->len, 1); > > shouldn't revision be 5? > > > > Thanks, will fix. > > >> + free_aml_allocator(); > >> +} > >> + > >> typedef > >> struct AcpiBuildState { > >> /* Copy of table in RAM (for patching). */ > >> @@ -65,6 +189,7 @@ static > >> void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables > >> *tables) { > >> GArray *table_offsets; > >> + GArray *tables_blob = tables->table_data; > >> > >> table_offsets = g_array_new(false, true /* clear */, > >> sizeof(uint32_t)); > >> @@ -82,6 +207,9 @@ void virt_acpi_build(VirtGuestInfo *guest_info, > >> AcpiBuildTables *tables) > >> * DSDT > >> */ > >> > >> + /* DSDT is pointed to by FADT */ > >> + build_dsdt(tables_blob, tables->linker, guest_info); > >> + > >> /* Cleanup memory that's no longer used. */ > >> g_array_free(table_offsets, true); > >> } > > >