1QEMU<->ACPI BIOS NVDIMM interface 2--------------------------------- 3 4QEMU supports NVDIMM via ACPI. This document describes the basic concepts of 5NVDIMM ACPI and the interface between QEMU and the ACPI BIOS. 6 7NVDIMM ACPI Background 8---------------------- 9NVDIMM is introduced in ACPI 6.0 which defines an NVDIMM root device under 10_SB scope with a _HID of “ACPI0012”. For each NVDIMM present or intended 11to be supported by platform, platform firmware also exposes an ACPI 12Namespace Device under the root device. 13 14The NVDIMM child devices under the NVDIMM root device are defined with _ADR 15corresponding to the NFIT device handle. The NVDIMM root device and the 16NVDIMM devices can have device specific methods (_DSM) to provide additional 17functions specific to a particular NVDIMM implementation. 18 19This is an example from ACPI 6.0, a platform contains one NVDIMM: 20 21Scope (\_SB){ 22 Device (NVDR) // Root device 23 { 24 Name (_HID, “ACPI0012”) 25 Method (_STA) {...} 26 Method (_FIT) {...} 27 Method (_DSM, ...) {...} 28 Device (NVD) 29 { 30 Name(_ADR, h) //where h is NFIT Device Handle for this NVDIMM 31 Method (_DSM, ...) {...} 32 } 33 } 34} 35 36Method supported on both NVDIMM root device and NVDIMM device 37_DSM (Device Specific Method) 38 It is a control method that enables devices to provide device specific 39 control functions that are consumed by the device driver. 40 The NVDIMM DSM specification can be found at: 41 http://pmem.io/documents/NVDIMM_DSM_Interface_Example.pdf 42 43 Arguments: 44 Arg0 – A Buffer containing a UUID (16 Bytes) 45 Arg1 – An Integer containing the Revision ID (4 Bytes) 46 Arg2 – An Integer containing the Function Index (4 Bytes) 47 Arg3 – A package containing parameters for the function specified by the 48 UUID, Revision ID, and Function Index 49 50 Return Value: 51 If Function Index = 0, a Buffer containing a function index bitfield. 52 Otherwise, the return value and type depends on the UUID, revision ID 53 and function index which are described in the DSM specification. 54 55Methods on NVDIMM ROOT Device 56_FIT(Firmware Interface Table) 57 It evaluates to a buffer returning data in the format of a series of NFIT 58 Type Structure. 59 60 Arguments: None 61 62 Return Value: 63 A Buffer containing a list of NFIT Type structure entries. 64 65 The detailed definition of the structure can be found at ACPI 6.0: 5.2.25 66 NVDIMM Firmware Interface Table (NFIT). 67 68QEMU NVDIMM Implementation 69========================== 70QEMU uses 4 bytes IO Port starting from 0x0a18 and a RAM-based memory page 71for NVDIMM ACPI. 72 73Memory: 74 QEMU uses BIOS Linker/loader feature to ask BIOS to allocate a memory 75 page and dynamically patch its address into an int32 object named "MEMA" 76 in ACPI. 77 78 This page is RAM-based and it is used to transfer data between _DSM 79 method and QEMU. If ACPI has control, this pages is owned by ACPI which 80 writes _DSM input data to it, otherwise, it is owned by QEMU which 81 emulates _DSM access and writes the output data to it. 82 83 ACPI writes _DSM Input Data (based on the offset in the page): 84 [0x0 - 0x3]: 4 bytes, NVDIMM Device Handle. 85 86 The handle is completely QEMU internal thing, the values in 87 range [1, 0xFFFF] indicate nvdimm device. Other values are 88 reserved for other purposes. 89 90 Reserved handles: 91 0 is reserved for nvdimm root device named NVDR. 92 0x10000 is reserved for QEMU internal DSM function called on 93 the root device. 94 95 [0x4 - 0x7]: 4 bytes, Revision ID, that is the Arg1 of _DSM method. 96 [0x8 - 0xB]: 4 bytes. Function Index, that is the Arg2 of _DSM method. 97 [0xC - 0xFFF]: 4084 bytes, the Arg3 of _DSM method. 98 99 QEMU Writes Output Data (based on the offset in the page): 100 [0x0 - 0x3]: 4 bytes, the length of result 101 [0x4 - 0xFFF]: 4092 bytes, the DSM result filled by QEMU 102 103IO Port 0x0a18 - 0xa1b: 104 ACPI writes the address of the memory page allocated by BIOS to this 105 port then QEMU gets the control and fills the result in the memory page. 106 107 write Access: 108 [0x0a18 - 0xa1b]: 4 bytes, the address of the memory page allocated 109 by BIOS. 110 111_DSM process diagram: 112--------------------- 113"MEMA" indicates the address of memory page allocated by BIOS. 114 115 +----------------------+ +-----------------------+ 116 | 1. OSPM | | 2. OSPM | 117 | save _DSM input data | | write "MEMA" to | Exit to QEMU 118 | to the page +----->| IO port 0x0a18 +------------+ 119 | indicated by "MEMA" | | | | 120 +----------------------+ +-----------------------+ | 121 | 122 v 123 +------------- ----+ +-----------+ +------------------+--------+ 124 | 5 QEMU | | 4 QEMU | | 3. QEMU | 125 | write _DSM result | | emulate | | get _DSM input data from | 126 | to the page +<------+ _DSM +<-----+ the page indicated by the | 127 | | | | | value from the IO port | 128 +--------+-----------+ +-----------+ +---------------------------+ 129 | 130 | Enter Guest 131 | 132 v 133 +--------------------------+ +--------------+ 134 | 6 OSPM | | 7 OSPM | 135 | result size is returned | | _DSM return | 136 | by reading DSM +----->+ | 137 | result from the page | | | 138 +--------------------------+ +--------------+ 139 140NVDIMM hotplug 141-------------- 142ACPI BIOS GPE.4 handler is dedicated for notifying OS about nvdimm device 143hot-add event. 144 145QEMU internal use only _DSM function 146------------------------------------ 1471) Read FIT 148 _FIT method uses _DSM method to fetch NFIT structures blob from QEMU 149 in 1 page sized increments which are then concatenated and returned 150 as _FIT method result. 151 152 Input parameters: 153 Arg0 – UUID {set to 648B9CF2-CDA1-4312-8AD9-49C4AF32BD62} 154 Arg1 – Revision ID (set to 1) 155 Arg2 - Function Index, 0x1 156 Arg3 - A package containing a buffer whose layout is as follows: 157 158 +----------+--------+--------+-------------------------------------------+ 159 | Field | Length | Offset | Description | 160 +----------+--------+--------+-------------------------------------------+ 161 | offset | 4 | 0 | offset in QEMU's NFIT structures blob to | 162 | | | | read from | 163 +----------+--------+--------+-------------------------------------------+ 164 165 Output layout in the dsm memory page: 166 +----------+--------+--------+-------------------------------------------+ 167 | Field | Length | Offset | Description | 168 +----------+--------+--------+-------------------------------------------+ 169 | length | 4 | 0 | length of entire returned data | 170 | | | | (including this header) | 171 +----------+-----------------+-------------------------------------------+ 172 | | | | return status codes | 173 | | | | 0x0 - success | 174 | | | | 0x100 - error caused by NFIT update while | 175 | status | 4 | 4 | read by _FIT wasn't completed, other | 176 | | | | codes follow Chapter 3 in DSM Spec Rev1 | 177 +----------+-----------------+-------------------------------------------+ 178 | fit data | Varies | 8 | contains FIT data, this field is present | 179 | | | | if status field is 0; | 180 +----------+--------+--------+-------------------------------------------+ 181 182 The FIT offset is maintained by the OSPM itself, current offset plus 183 the size of the fit data returned by the function is the next offset 184 OSPM should read. When all FIT data has been read out, zero fit data 185 size is returned. 186 187 If it returns status code 0x100, OSPM should restart to read FIT (read 188 from offset 0 again). 189