From 15b82b1dc59040245f16a24c16825efe8c389050 Mon Sep 17 00:00:00 2001 From: Xiao Guangrong Date: Tue, 7 Jun 2016 20:22:09 +0800 Subject: docs: add NVDIMM ACPI documentation It describes the basic concepts of NVDIMM ACPI and the interfaces between QEMU and the ACPI BIOS Signed-off-by: Xiao Guangrong Reviewed-by: Stefan Hajnoczi Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- docs/specs/acpi_nvdimm.txt | 132 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 docs/specs/acpi_nvdimm.txt (limited to 'docs/specs') diff --git a/docs/specs/acpi_nvdimm.txt b/docs/specs/acpi_nvdimm.txt new file mode 100644 index 0000000..0fdd251 --- /dev/null +++ b/docs/specs/acpi_nvdimm.txt @@ -0,0 +1,132 @@ +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) -- cgit v1.1 From abd49bc2ed2f06bc1ea979b17e79e2fc52360de9 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Mon, 2 May 2016 11:42:59 +0200 Subject: docs: update ACPI CPU hotplug spec with new protocol Add description of new CPU hotplug interface. To switch from from legacy mode into new mode use fact that write accesses into CPU present bitmap were never used before and were ignored by QEMU. So use it to as a way to switch from legacy mode. That way pc/q35 machine starts in legacy mode and QEMU generated ACPI tables will switch to new CPU hotplug interface during runtime. In case QEMU is started with legacy BIOS (that doesn't support QEMU generated ACPI tables), legacy CPU hotplug will remain active and could be used by BIOS built in ACPI tables for CPU hotplug. Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- docs/specs/acpi_cpu_hotplug.txt | 94 +++++++++++++++++++++++++++++++++++------ 1 file changed, 82 insertions(+), 12 deletions(-) (limited to 'docs/specs') diff --git a/docs/specs/acpi_cpu_hotplug.txt b/docs/specs/acpi_cpu_hotplug.txt index 340b751..ee219c8 100644 --- a/docs/specs/acpi_cpu_hotplug.txt +++ b/docs/specs/acpi_cpu_hotplug.txt @@ -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. -- cgit v1.1