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