Commit d21ccd7b authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging



acpi dsdt rework, misc fixes

This completes the dsdt rewrite, and includes misc fixes all over the place.

Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>

# gpg: Signature made Sat 09 Jan 2016 21:20:34 GMT using RSA key ID D28D5469
# gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>"
# gpg:                 aka "Michael S. Tsirkin <mst@redhat.com>"

* remotes/mst/tags/for_upstream: (59 commits)
  virtio: fix error message for number of queues
  ivshmem: Store file descriptor for vhost-user negotiation
  migration/virtio: Remove simple .get/.put use
  Add VMSTATE_STRUCT_VARRAY_KNOWN
  i386/pc: expose identifying the floppy controller
  pc: acpi: remove unused ASL templates and related blobs/utils
  pc: acpi: switch to AML API composed DSDT
  pc: acpi: q35: PCST, PCSB opregions and PCIB field into SSDT
  pc: acpi: q35: move PCI0 device definition into SSDT
  pc: acpi: q35: move PCI0._OSC() method into SSDT
  pc: acpi: q35: move _PIC() method into SSDT
  pc: acpi: q35: move PRTP routing table into SSDT
  pc: acpi: q35: move PRTA routing table into SSDT
  pc: acpi: q35: move _PRT() into SSDT
  pc: acpi: q35: move ISA bridge into SSDT
  pc: acpi: q35: move IQST() into SSDT
  pc: acpi: q35: move IQCR() into SSDT
  pc: acpi: q35: move link devices to SSDT
  pc: acpi: q35: move GSI links to SSDT
  pc: acpi: piix4: acpi move PCI0 device to SSDT
  ...

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 6bb9ead7 8a1be662
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -1757,6 +1757,16 @@ int qemu_get_ram_fd(ram_addr_t addr)
    return fd;
}

void qemu_set_ram_fd(ram_addr_t addr, int fd)
{
    RAMBlock *block;

    rcu_read_lock();
    block = qemu_get_ram_block(addr);
    block->fd = fd;
    rcu_read_unlock();
}

void *qemu_get_ram_block_host_ptr(ram_addr_t addr)
{
    RAMBlock *block;
+2 −2
Original line number Diff line number Diff line
common-obj-$(CONFIG_ACPI_X86) += core.o piix4.o pcihp.o
common-obj-$(CONFIG_ACPI_X86_ICH) += ich9.o tco.o
common-obj-$(CONFIG_ACPI_CPU_HOTPLUG) += cpu_hotplug.o
common-obj-$(CONFIG_ACPI_MEMORY_HOTPLUG) += memory_hotplug.o
common-obj-$(CONFIG_ACPI_CPU_HOTPLUG) += cpu_hotplug.o cpu_hotplug_acpi_table.o
common-obj-$(CONFIG_ACPI_MEMORY_HOTPLUG) += memory_hotplug.o memory_hotplug_acpi_table.o
common-obj-$(CONFIG_ACPI_NVDIMM) += nvdimm.o
common-obj-$(CONFIG_ACPI) += acpi_interface.o
common-obj-$(CONFIG_ACPI) += bios-linker-loader.o
+135 −0
Original line number Diff line number Diff line
/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License along
 * with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include "hw/acpi/cpu_hotplug.h"

void build_cpu_hotplug_aml(Aml *ctx)
{
    Aml *method;
    Aml *if_ctx;
    Aml *else_ctx;
    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);
    Aml *cpu_on = aml_local(0);
    Aml *madt = aml_local(1);
    Aml *cpus_map = aml_name(CPU_ON_BITMAP);
    Aml *zero = aml_int(0);
    Aml *one = aml_int(1);

    /*
     * _MAT method - creates an madt apic buffer
     * cpu_id = Arg0 = Processor ID = Local APIC ID
     * cpu_on = Local0 = CPON flag for this cpu
     * madt = Local1 = Buffer (in madt apic form) to return
     */
    method = aml_method(CPU_MAT_METHOD, 1, AML_NOTSERIALIZED);
    aml_append(method,
        aml_store(aml_derefof(aml_index(cpus_map, cpu_id)), cpu_on));
    aml_append(method,
        aml_store(aml_buffer(sizeof(madt_tmpl), madt_tmpl), madt));
    /* Update the processor id, lapic id, and enable/disable status */
    aml_append(method, aml_store(cpu_id, aml_index(madt, aml_int(2))));
    aml_append(method, aml_store(cpu_id, aml_index(madt, aml_int(3))));
    aml_append(method, aml_store(cpu_on, aml_index(madt, aml_int(4))));
    aml_append(method, aml_return(madt));
    aml_append(sb_scope, method);

    /*
     * _STA method - return ON status of cpu
     * cpu_id = Arg0 = Processor ID = Local APIC ID
     * cpu_on = Local0 = CPON flag for this cpu
     */
    method = aml_method(CPU_STATUS_METHOD, 1, AML_NOTSERIALIZED);
    aml_append(method,
        aml_store(aml_derefof(aml_index(cpus_map, cpu_id)), cpu_on));
    if_ctx = aml_if(cpu_on);
    {
        aml_append(if_ctx, aml_return(aml_int(0xF)));
    }
    aml_append(method, if_ctx);
    else_ctx = aml_else();
    {
        aml_append(else_ctx, aml_return(zero));
    }
    aml_append(method, else_ctx);
    aml_append(sb_scope, method);

    method = aml_method(CPU_EJECT_METHOD, 2, AML_NOTSERIALIZED);
    aml_append(method, aml_sleep(200));
    aml_append(sb_scope, method);

    method = aml_method(CPU_SCAN_METHOD, 0, AML_NOTSERIALIZED);
    {
        Aml *while_ctx, *if_ctx2, *else_ctx2;
        Aml *bus_check_evt = aml_int(1);
        Aml *remove_evt = aml_int(3);
        Aml *status_map = aml_local(5); /* Local5 = active cpu bitmap */
        Aml *byte = aml_local(2); /* Local2 = last read byte from bitmap */
        Aml *idx = aml_local(0); /* Processor ID / APIC ID iterator */
        Aml *is_cpu_on = aml_local(1); /* Local1 = CPON flag for cpu */
        Aml *status = aml_local(3); /* Local3 = active state for cpu */

        aml_append(method, aml_store(aml_name(CPU_STATUS_MAP), status_map));
        aml_append(method, aml_store(zero, byte));
        aml_append(method, aml_store(zero, idx));

        /* While (idx < SizeOf(CPON)) */
        while_ctx = aml_while(aml_lless(idx, aml_sizeof(cpus_map)));
        aml_append(while_ctx,
            aml_store(aml_derefof(aml_index(cpus_map, idx)), is_cpu_on));

        if_ctx = aml_if(aml_and(idx, aml_int(0x07), NULL));
        {
            /* Shift down previously read bitmap byte */
            aml_append(if_ctx, aml_shiftright(byte, one, byte));
        }
        aml_append(while_ctx, if_ctx);

        else_ctx = aml_else();
        {
            /* Read next byte from cpu bitmap */
            aml_append(else_ctx, aml_store(aml_derefof(aml_index(status_map,
                       aml_shiftright(idx, aml_int(3), NULL))), byte));
        }
        aml_append(while_ctx, else_ctx);

        aml_append(while_ctx, aml_store(aml_and(byte, one, NULL), status));
        if_ctx = aml_if(aml_lnot(aml_equal(is_cpu_on, status)));
        {
            /* State change - update CPON with new state */
            aml_append(if_ctx, aml_store(status, aml_index(cpus_map, idx)));
            if_ctx2 = aml_if(aml_equal(status, one));
            {
                aml_append(if_ctx2,
                    aml_call2(AML_NOTIFY_METHOD, idx, bus_check_evt));
            }
            aml_append(if_ctx, if_ctx2);
            else_ctx2 = aml_else();
            {
                aml_append(else_ctx2,
                    aml_call2(AML_NOTIFY_METHOD, idx, remove_evt));
            }
        }
        aml_append(if_ctx, else_ctx2);
        aml_append(while_ctx, if_ctx);

        aml_append(while_ctx, aml_increment(idx)); /* go to next cpu */
        aml_append(method, while_ctx);
    }
    aml_append(sb_scope, method);

    aml_append(ctx, sb_scope);
}
+262 −0
Original line number Diff line number Diff line
/*
 * Memory hotplug AML code of DSDT ACPI table
 *
 * Copyright (C) 2015 Red Hat Inc
 *
 * Author: Igor Mammedov <imammedo@redhat.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 */

#include <stdbool.h>
#include "hw/acpi/memory_hotplug.h"
#include "include/hw/acpi/pc-hotplug.h"
#include "hw/boards.h"

void build_memory_hotplug_aml(Aml *ctx, uint32_t nr_mem,
                              uint16_t io_base, uint16_t io_len)
{
    Aml *ifctx;
    Aml *method;
    Aml *pci_scope;
    Aml *mem_ctrl_dev;

    /* scope for memory hotplug controller device node */
    pci_scope = aml_scope("_SB.PCI0");
    mem_ctrl_dev = aml_device(MEMORY_HOTPLUG_DEVICE);
    {
        Aml *one = aml_int(1);
        Aml *zero = aml_int(0);
        Aml *ret_val = aml_local(0);
        Aml *slot_arg0 = aml_arg(0);
        Aml *slots_nr = aml_name(MEMORY_SLOTS_NUMBER);
        Aml *ctrl_lock = aml_name(MEMORY_SLOT_LOCK);
        Aml *slot_selector = aml_name(MEMORY_SLOT_SLECTOR);

        aml_append(mem_ctrl_dev, aml_name_decl("_HID", aml_string("PNP0A06")));
        aml_append(mem_ctrl_dev,
            aml_name_decl("_UID", aml_string("Memory hotplug resources")));

        method = aml_method("_STA", 0, AML_NOTSERIALIZED);
        ifctx = aml_if(aml_equal(slots_nr, zero));
        {
            aml_append(ifctx, aml_return(zero));
        }
        aml_append(method, ifctx);
        /* present, functioning, decoding, not shown in UI */
        aml_append(method, aml_return(aml_int(0xB)));
        aml_append(mem_ctrl_dev, method);

        aml_append(mem_ctrl_dev, aml_mutex(MEMORY_SLOT_LOCK, 0));

        method = aml_method(MEMORY_SLOT_SCAN_METHOD, 0, AML_NOTSERIALIZED);
        {
            Aml *else_ctx;
            Aml *while_ctx;
            Aml *idx = aml_local(0);
            Aml *eject_req = aml_int(3);
            Aml *dev_chk = aml_int(1);

            ifctx = aml_if(aml_equal(slots_nr, zero));
            {
                aml_append(ifctx, aml_return(zero));
            }
            aml_append(method, ifctx);

            aml_append(method, aml_store(zero, idx));
            aml_append(method, aml_acquire(ctrl_lock, 0xFFFF));
            /* build AML that:
             * loops over all slots and Notifies DIMMs with
             * Device Check or Eject Request notifications if
             * slot has corresponding status bit set and clears
             * slot status.
             */
            while_ctx = aml_while(aml_lless(idx, slots_nr));
            {
                Aml *ins_evt = aml_name(MEMORY_SLOT_INSERT_EVENT);
                Aml *rm_evt = aml_name(MEMORY_SLOT_REMOVE_EVENT);

                aml_append(while_ctx, aml_store(idx, slot_selector));
                ifctx = aml_if(aml_equal(ins_evt, one));
                {
                    aml_append(ifctx,
                               aml_call2(MEMORY_SLOT_NOTIFY_METHOD,
                                         idx, dev_chk));
                    aml_append(ifctx, aml_store(one, ins_evt));
                }
                aml_append(while_ctx, ifctx);

                else_ctx = aml_else();
                ifctx = aml_if(aml_equal(rm_evt, one));
                {
                    aml_append(ifctx,
                        aml_call2(MEMORY_SLOT_NOTIFY_METHOD,
                                  idx, eject_req));
                    aml_append(ifctx, aml_store(one, rm_evt));
                }
                aml_append(else_ctx, ifctx);
                aml_append(while_ctx, else_ctx);

                aml_append(while_ctx, aml_add(idx, one, idx));
            }
            aml_append(method, while_ctx);
            aml_append(method, aml_release(ctrl_lock));
            aml_append(method, aml_return(one));
        }
        aml_append(mem_ctrl_dev, method);

        method = aml_method(MEMORY_SLOT_STATUS_METHOD, 1, AML_NOTSERIALIZED);
        {
            Aml *slot_enabled = aml_name(MEMORY_SLOT_ENABLED);

            aml_append(method, aml_store(zero, ret_val));
            aml_append(method, aml_acquire(ctrl_lock, 0xFFFF));
            aml_append(method,
                aml_store(aml_to_integer(slot_arg0), slot_selector));

            ifctx = aml_if(aml_equal(slot_enabled, one));
            {
                aml_append(ifctx, aml_store(aml_int(0xF), ret_val));
            }
            aml_append(method, ifctx);

            aml_append(method, aml_release(ctrl_lock));
            aml_append(method, aml_return(ret_val));
        }
        aml_append(mem_ctrl_dev, method);

        method = aml_method(MEMORY_SLOT_CRS_METHOD, 1, AML_SERIALIZED);
        {
            Aml *mr64 = aml_name("MR64");
            Aml *mr32 = aml_name("MR32");
            Aml *crs_tmpl = aml_resource_template();
            Aml *minl = aml_name("MINL");
            Aml *minh = aml_name("MINH");
            Aml *maxl =  aml_name("MAXL");
            Aml *maxh =  aml_name("MAXH");
            Aml *lenl = aml_name("LENL");
            Aml *lenh = aml_name("LENH");

            aml_append(method, aml_acquire(ctrl_lock, 0xFFFF));
            aml_append(method, aml_store(aml_to_integer(slot_arg0),
                                         slot_selector));

            aml_append(crs_tmpl,
                aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,
                                 AML_CACHEABLE, AML_READ_WRITE,
                                 0, 0x0, 0xFFFFFFFFFFFFFFFEULL, 0,
                                 0xFFFFFFFFFFFFFFFFULL));
            aml_append(method, aml_name_decl("MR64", crs_tmpl));
            aml_append(method,
                aml_create_dword_field(mr64, aml_int(14), "MINL"));
            aml_append(method,
                aml_create_dword_field(mr64, aml_int(18), "MINH"));
            aml_append(method,
                aml_create_dword_field(mr64, aml_int(38), "LENL"));
            aml_append(method,
                aml_create_dword_field(mr64, aml_int(42), "LENH"));
            aml_append(method,
                aml_create_dword_field(mr64, aml_int(22), "MAXL"));
            aml_append(method,
                aml_create_dword_field(mr64, aml_int(26), "MAXH"));

            aml_append(method,
                aml_store(aml_name(MEMORY_SLOT_ADDR_HIGH), minh));
            aml_append(method,
                aml_store(aml_name(MEMORY_SLOT_ADDR_LOW), minl));
            aml_append(method,
                aml_store(aml_name(MEMORY_SLOT_SIZE_HIGH), lenh));
            aml_append(method,
                aml_store(aml_name(MEMORY_SLOT_SIZE_LOW), lenl));

            /* 64-bit math: MAX = MIN + LEN - 1 */
            aml_append(method, aml_add(minl, lenl, maxl));
            aml_append(method, aml_add(minh, lenh, maxh));
            ifctx = aml_if(aml_lless(maxl, minl));
            {
                aml_append(ifctx, aml_add(maxh, one, maxh));
            }
            aml_append(method, ifctx);
            ifctx = aml_if(aml_lless(maxl, one));
            {
                aml_append(ifctx, aml_subtract(maxh, one, maxh));
            }
            aml_append(method, ifctx);
            aml_append(method, aml_subtract(maxl, one, maxl));

            /* return 32-bit _CRS if addr/size is in low mem */
            /* TODO: remove it since all hotplugged DIMMs are in high mem */
            ifctx = aml_if(aml_equal(maxh, zero));
            {
                crs_tmpl = aml_resource_template();
                aml_append(crs_tmpl,
                    aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED,
                                     AML_MAX_FIXED, AML_CACHEABLE,
                                     AML_READ_WRITE,
                                     0, 0x0, 0xFFFFFFFE, 0,
                                     0xFFFFFFFF));
                aml_append(ifctx, aml_name_decl("MR32", crs_tmpl));
                aml_append(ifctx,
                    aml_create_dword_field(mr32, aml_int(10), "MIN"));
                aml_append(ifctx,
                    aml_create_dword_field(mr32, aml_int(14), "MAX"));
                aml_append(ifctx,
                    aml_create_dword_field(mr32, aml_int(22), "LEN"));
                aml_append(ifctx, aml_store(minl, aml_name("MIN")));
                aml_append(ifctx, aml_store(maxl, aml_name("MAX")));
                aml_append(ifctx, aml_store(lenl, aml_name("LEN")));

                aml_append(ifctx, aml_release(ctrl_lock));
                aml_append(ifctx, aml_return(mr32));
            }
            aml_append(method, ifctx);

            aml_append(method, aml_release(ctrl_lock));
            aml_append(method, aml_return(mr64));
        }
        aml_append(mem_ctrl_dev, method);

        method = aml_method(MEMORY_SLOT_PROXIMITY_METHOD, 1,
                            AML_NOTSERIALIZED);
        {
            Aml *proximity = aml_name(MEMORY_SLOT_PROXIMITY);

            aml_append(method, aml_acquire(ctrl_lock, 0xFFFF));
            aml_append(method, aml_store(aml_to_integer(slot_arg0),
                                         slot_selector));
            aml_append(method, aml_store(proximity, ret_val));
            aml_append(method, aml_release(ctrl_lock));
            aml_append(method, aml_return(ret_val));
        }
        aml_append(mem_ctrl_dev, method);

        method = aml_method(MEMORY_SLOT_OST_METHOD, 4, AML_NOTSERIALIZED);
        {
            Aml *ost_evt = aml_name(MEMORY_SLOT_OST_EVENT);
            Aml *ost_status = aml_name(MEMORY_SLOT_OST_STATUS);

            aml_append(method, aml_acquire(ctrl_lock, 0xFFFF));
            aml_append(method, aml_store(aml_to_integer(slot_arg0),
                                         slot_selector));
            aml_append(method, aml_store(aml_arg(1), ost_evt));
            aml_append(method, aml_store(aml_arg(2), ost_status));
            aml_append(method, aml_release(ctrl_lock));
        }
        aml_append(mem_ctrl_dev, method);

        method = aml_method(MEMORY_SLOT_EJECT_METHOD, 2, AML_NOTSERIALIZED);
        {
            Aml *eject = aml_name(MEMORY_SLOT_EJECT);

            aml_append(method, aml_acquire(ctrl_lock, 0xFFFF));
            aml_append(method, aml_store(aml_to_integer(slot_arg0),
                                         slot_selector));
            aml_append(method, aml_store(one, eject));
            aml_append(method, aml_release(ctrl_lock));
        }
        aml_append(mem_ctrl_dev, method);
    }
    aml_append(pci_scope, mem_ctrl_dev);
    aml_append(ctx, pci_scope);
}
+5 −3
Original line number Diff line number Diff line
@@ -353,16 +353,18 @@ static void nvdimm_build_nfit(GSList *device_list, GArray *table_offsets,
                              GArray *table_data, GArray *linker)
{
    GArray *structures = nvdimm_build_device_structure(device_list);
    void *header;
    unsigned int header;

    acpi_add_table(table_offsets, table_data);

    /* NFIT header. */
    header = acpi_data_push(table_data, sizeof(NvdimmNfitHeader));
    header = table_data->len;
    acpi_data_push(table_data, sizeof(NvdimmNfitHeader));
    /* NVDIMM device structures. */
    g_array_append_vals(table_data, structures->data, structures->len);

    build_header(linker, table_data, header, "NFIT",
    build_header(linker, table_data,
                 (void *)(table_data->data + header), "NFIT",
                 sizeof(NvdimmNfitHeader) + structures->len, 1, NULL);
    g_array_free(structures, true);
}
Loading