acpi_nvdimm.rst 8.3 KB

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