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

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



pc, pci, virtio: new features, cleanups, fixes

nvdimm label support
cpu acpi hotplug rework
virtio rework
misc cleanups and fixes

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

# gpg: Signature made Fri 24 Jun 2016 06:50:32 BST
# gpg:                using RSA key 0x281F0DB8D28D5469
# gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>"
# gpg:                 aka "Michael S. Tsirkin <mst@redhat.com>"
# Primary key fingerprint: 0270 606B 6F3C DF3D 0B17  0970 C350 3912 AFBE 8E67
#      Subkey fingerprint: 5D09 FD08 71C8 F85B 94CA  8A0D 281F 0DB8 D28D 5469

* remotes/mst/tags/for_upstream: (34 commits)
  virtio-bus: remove old set_host_notifier callback
  virtio-mmio: convert to ioeventfd callbacks
  virtio-pci: convert to ioeventfd callbacks
  virtio-ccw: convert to ioeventfd callbacks
  virtio-bus: have callers tolerate new host notifier api
  virtio-bus: common ioeventfd infrastructure
  pc: acpi: drop intermediate PCMachineState.node_cpu
  acpi-test-data: update expected
  pc: use new CPU hotplug interface since 2.7 machine type
  acpi: cpuhp: add cpu._OST handling
  acpi: cpuhp: implement hot-remove parts of CPU hotplug interface
  acpi: cpuhp: implement hot-add parts of CPU hotplug interface
  pc: acpi: introduce AcpiDeviceIfClass.madt_cpu hook
  acpi: cpuhp: add CPU devices AML with _STA method
  pc: piix4/ich9: add 'cpu-hotplug-legacy' property
  docs: update ACPI CPU hotplug spec with new protocol
  i386: pci-assign: Fix MSI-X table size
  docs: add NVDIMM ACPI documentation
  nvdimm acpi: support Set Namespace Label Data function
  nvdimm acpi: support Get Namespace Label Data function
  ...

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents c7288767 21a4d962
Loading
Loading
Loading
Loading
+82 −12
Original line number Diff line number Diff line
@@ -4,21 +4,91 @@ QEMU<->ACPI BIOS CPU hotplug interface
QEMU supports CPU hotplug via ACPI. This document
describes the interface between QEMU and the ACPI BIOS.

ACPI GPE block (IO ports 0xafe0-0xafe3, byte access):
-----------------------------------------

Generic ACPI GPE block. Bit 2 (GPE.2) used to notify CPU
hot-add/remove event to ACPI BIOS, via SCI interrupt.
ACPI BIOS GPE.2 handler is dedicated for notifying OS about CPU hot-add
and hot-remove events.

============================================
Legacy ACPI CPU hotplug interface registers:
--------------------------------------------
CPU present bitmap for:
  ICH9-LPC (IO port 0x0cd8-0xcf7, 1-byte access)
  PIIX-PM  (IO port 0xaf00-0xaf1f, 1-byte access)
  One bit per CPU. Bit position reflects corresponding CPU APIC ID. Read-only.
  The first DWORD in bitmap is used in write mode to switch from legacy
  to new CPU hotplug interface, write 0 into it to do switch.
---------------------------------------------------------------
One bit per CPU. Bit position reflects corresponding CPU APIC ID.
Read-only.
QEMU sets corresponding CPU bit on hot-add event and issues SCI
with GPE.2 event set. CPU present map is read by ACPI BIOS GPE.2 handler
to notify OS about CPU hot-add events. CPU hot-remove isn't supported.

=====================================
ACPI CPU hotplug interface registers:
-------------------------------------
Register block base address:
    ICH9-LPC IO port 0x0cd8
    PIIX-PM  IO port 0xaf00
Register block size:
    ACPI_CPU_HOTPLUG_REG_LEN = 12

read access:
    offset:
    [0x0-0x3] reserved
    [0x4] CPU device status fields: (1 byte access)
        bits:
           0: Device is enabled and may be used by guest
           1: Device insert event, used to distinguish device for which
              no device check event to OSPM was issued.
              It's valid only when bit 0 is set.
           2: Device remove event, used to distinguish device for which
              no device eject request to OSPM was issued.
           3-7: reserved and should be ignored by OSPM
    [0x5-0x7] reserved
    [0x8] Command data: (DWORD access)
          in case of error or unsupported command reads is 0xFFFFFFFF
          current 'Command field' value:
              0: returns PXM value corresponding to device

write access:
    offset:
    [0x0-0x3] CPU selector: (DWORD access)
              selects active CPU device. All following accesses to other
              registers will read/store data from/to selected CPU.
    [0x4] CPU device control fields: (1 byte access)
        bits:
            0: reserved, OSPM must clear it before writing to register.
            1: if set to 1 clears device insert event, set by OSPM
               after it has emitted device check event for the
               selected CPU device
            2: if set to 1 clears device remove event, set by OSPM
               after it has emitted device eject request for the
               selected CPU device
            3: if set to 1 initiates device eject, set by OSPM when it
               triggers CPU device removal and calls _EJ0 method
            4-7: reserved, OSPM must clear them before writing to register
    [0x5] Command field: (1 byte access)
          value:
            0: selects a CPU device with inserting/removing events and
               following reads from 'Command data' register return
               selected CPU (CPU selector value). If no CPU with events
               found, the current CPU selector doesn't change and
               corresponding insert/remove event flags are not set.
            1: following writes to 'Command data' register set OST event
               register in QEMU
            2: following writes to 'Command data' register set OST status
               register in QEMU
            other values: reserved
    [0x6-0x7] reserved
    [0x8] Command data: (DWORD access)
          current 'Command field' value:
              0: OSPM reads value of CPU selector
              1: stores value into OST event register
              2: stores value into OST status register, triggers
                 ACPI_DEVICE_OST QMP event from QEMU to external applications
                 with current values of OST event and status registers.
            other values: reserved

CPU hot-add/remove notification:
-----------------------------------------------------
QEMU sets/clears corresponding CPU bit on hot-add/remove event.
CPU present map read by ACPI BIOS GPE.2 handler to notify OS of CPU
hot-(un)plug events.
Selecting CPU device beyond possible range has no effect on platform:
   - write accesses to CPU hot-plug registers not documented above are
     ignored
   - read accesses to CPU hot-plug registers not documented above return
     all bits set to 0.
+132 −0
Original line number Diff line number Diff line
QEMU<->ACPI BIOS NVDIMM interface
---------------------------------

QEMU supports NVDIMM via ACPI. This document describes the basic concepts of
NVDIMM ACPI and the interface between QEMU and the ACPI BIOS.

NVDIMM ACPI Background
----------------------
NVDIMM is introduced in ACPI 6.0 which defines an NVDIMM root device under
_SB scope with a _HID of “ACPI0012”. For each NVDIMM present or intended
to be supported by platform, platform firmware also exposes an ACPI
Namespace Device under the root device.

The NVDIMM child devices under the NVDIMM root device are defined with _ADR
corresponding to the NFIT device handle. The NVDIMM root device and the
NVDIMM devices can have device specific methods (_DSM) to provide additional
functions specific to a particular NVDIMM implementation.

This is an example from ACPI 6.0, a platform contains one NVDIMM:

Scope (\_SB){
   Device (NVDR) // Root device
   {
      Name (_HID, “ACPI0012”)
      Method (_STA) {...}
      Method (_FIT) {...}
      Method (_DSM, ...) {...}
      Device (NVD)
      {
         Name(_ADR, h) //where h is NFIT Device Handle for this NVDIMM
         Method (_DSM, ...) {...}
      }
   }
}

Method supported on both NVDIMM root device and NVDIMM device
_DSM (Device Specific Method)
   It is a control method that enables devices to provide device specific
   control functions that are consumed by the device driver.
   The NVDIMM DSM specification can be found at:
        http://pmem.io/documents/NVDIMM_DSM_Interface_Example.pdf

   Arguments:
   Arg0 – A Buffer containing a UUID (16 Bytes)
   Arg1 – An Integer containing the Revision ID (4 Bytes)
   Arg2 – An Integer containing the Function Index (4 Bytes)
   Arg3 – A package containing parameters for the function specified by the
          UUID, Revision ID, and Function Index

   Return Value:
   If Function Index = 0, a Buffer containing a function index bitfield.
   Otherwise, the return value and type depends on the UUID, revision ID
   and function index which are described in the DSM specification.

Methods on NVDIMM ROOT Device
_FIT(Firmware Interface Table)
   It evaluates to a buffer returning data in the format of a series of NFIT
   Type Structure.

   Arguments: None

   Return Value:
   A Buffer containing a list of NFIT Type structure entries.

   The detailed definition of the structure can be found at ACPI 6.0: 5.2.25
   NVDIMM Firmware Interface Table (NFIT).

QEMU NVDIMM Implemention
========================
QEMU uses 4 bytes IO Port starting from 0x0a18 and a RAM-based memory page
for NVDIMM ACPI.

Memory:
   QEMU uses BIOS Linker/loader feature to ask BIOS to allocate a memory
   page and dynamically patch its into a int32 object named "MEMA" in ACPI.

   This page is RAM-based and it is used to transfer data between _DSM
   method and QEMU. If ACPI has control, this pages is owned by ACPI which
   writes _DSM input data to it, otherwise, it is owned by QEMU which
   emulates _DSM access and writes the output data to it.

   ACPI writes _DSM Input Data (based on the offset in the page):
   [0x0 - 0x3]: 4 bytes, NVDIMM Device Handle, 0 is reserved for NVDIMM
                Root device.
   [0x4 - 0x7]: 4 bytes, Revision ID, that is the Arg1 of _DSM method.
   [0x8 - 0xB]: 4 bytes. Function Index, that is the Arg2 of _DSM method.
   [0xC - 0xFFF]: 4084 bytes, the Arg3 of _DSM method.

   QEMU Writes Output Data (based on the offset in the page):
   [0x0 - 0x3]: 4 bytes, the length of result
   [0x4 - 0xFFF]: 4092 bytes, the DSM result filled by QEMU

IO Port 0x0a18 - 0xa1b:
   ACPI writes the address of the memory page allocated by BIOS to this
   port then QEMU gets the control and fills the result in the memory page.

   write Access:
   [0x0a18 - 0xa1b]: 4 bytes, the address of the memory page allocated
                     by BIOS.

_DSM process diagram:
---------------------
"MEMA" indicates the address of memory page allocated by BIOS.

 +----------------------+      +-----------------------+
 |    1. OSPM           |      |    2. OSPM            |
 | save _DSM input data |      |  write "MEMA" to      | Exit to QEMU
 | to the page          +----->|  IO port 0x0a18       +------------+
 | indicated by "MEMA"  |      |                       |            |
 +----------------------+      +-----------------------+            |
                                                                    |
                                                                    v
 +-------------   ----+       +-----------+      +------------------+--------+
 |      5 QEMU        |       | 4 QEMU    |      |        3. QEMU            |
 | write _DSM result  |       |  emulate  |      | get _DSM input data from  |
 | to the page        +<------+ _DSM      +<-----+ the page indicated by the |
 |                    |       |           |      | value from the IO port    |
 +--------+-----------+       +-----------+      +---------------------------+
          |
          | Enter Guest
          |
          v
 +--------------------------+      +--------------+
 |     6 OSPM               |      |   7 OSPM     |
 | result size is returned  |      |  _DSM return |
 | by reading  DSM          +----->+              |
 | result from the page     |      |              |
 +--------------------------+      +--------------+

 _FIT implementation
 -------------------
 TODO (will fill it when nvdimm hotplug is introduced)
+2 −0
Original line number Diff line number Diff line
@@ -2,7 +2,9 @@ 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 memory_hotplug_acpi_table.o
common-obj-$(CONFIG_ACPI_CPU_HOTPLUG) += cpu.o
obj-$(CONFIG_ACPI_NVDIMM) += nvdimm.o
common-obj-$(CONFIG_ACPI) += acpi_interface.o
common-obj-$(CONFIG_ACPI) += bios-linker-loader.o
common-obj-$(CONFIG_ACPI) += aml-build.o
common-obj-$(call land,$(CONFIG_ACPI),$(CONFIG_IPMI)) += ipmi.o
+22 −0
Original line number Diff line number Diff line
@@ -660,6 +660,20 @@ Aml *aml_call4(const char *method, Aml *arg1, Aml *arg2, Aml *arg3, Aml *arg4)
    return var;
}

/* helper to call method with 5 arguments */
Aml *aml_call5(const char *method, Aml *arg1, Aml *arg2, Aml *arg3, Aml *arg4,
               Aml *arg5)
{
    Aml *var = aml_alloc();
    build_append_namestring(var->buf, "%s", method);
    aml_append(var, arg1);
    aml_append(var, arg2);
    aml_append(var, arg3);
    aml_append(var, arg4);
    aml_append(var, arg5);
    return var;
}

/*
 * ACPI 5.0: 6.4.3.8.1 GPIO Connection Descriptor
 * Type 1, Large Item Name 0xC
@@ -1481,6 +1495,14 @@ Aml *aml_concatenate(Aml *source1, Aml *source2, Aml *target)
                                 target);
}

/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefObjectType */
Aml *aml_object_type(Aml *object)
{
    Aml *var = aml_opcode(0x8E /* ObjectTypeOp */);
    aml_append(var, object);
    return var;
}

void
build_header(BIOSLinker *linker, GArray *table_data,
             AcpiTableHeader *h, const char *sig, int len, uint8_t rev,

hw/acpi/cpu.c

0 → 100644
+561 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading