OSDN Git Service

Add NvDimm _ADR encoder/decoder.
authorPeter Jones <pjones@redhat.com>
Thu, 20 Jul 2017 18:05:19 +0000 (14:05 -0400)
committerPeter Jones <pjones@redhat.com>
Fri, 21 Jul 2017 14:04:16 +0000 (10:04 -0400)
Signed-off-by: Peter Jones <pjones@redhat.com>
src/dp-acpi.c
src/include/efivar/efivar-dp.h

index 1359e80..844ce49 100644 (file)
@@ -115,6 +115,51 @@ _format_acpi_dn(char *buf, size_t size, const_efidp dp)
                format(buf, size, off, "Keyboard", "Serial(0x%"PRIx32")",
                       dp->acpi_hid.uid);
                break;
+       case EFIDP_ACPI_NVDIMM_HID: {
+               int rc;
+               const_efidp next = NULL;
+               efidp_acpi_adr *adrdp;
+               int end;
+
+               format(buf, size, off, "NvRoot()", "NvRoot()");
+
+               rc = efidp_next_node(dp, &next);
+               if (rc < 0 || !next) {
+                       efi_error("could not format DP");
+                       return rc;
+               }
+
+               if (efidp_type(next) != EFIDP_ACPI_TYPE ||
+                   efidp_subtype(next) != EFIDP_ACPI_ADR) {
+                       efi_error("Invalid child node type (0x%02x,0x%02x)",
+                                 efidp_type(next), efidp_subtype(next));
+                       return -EINVAL;
+               }
+               adrdp = (efidp_acpi_adr *)next;
+
+               end = efidp_size_after(adrdp, header)
+                       / sizeof(adrdp->adr[0]);
+
+               for (int i = 0; i < end; i++) {
+                       uint32_t node_controller, socket, memory_controller;
+                       uint32_t memory_channel, dimm;
+                       uint32_t adr = adrdp->adr[i];
+
+                       efidp_decode_acpi_nvdimm_adr(adr, &node_controller,
+                                                    &socket,
+                                                    &memory_controller,
+                                                    &memory_channel, &dimm);
+
+                       if (i != 0)
+                               format(buf, size, off, "NvDimm", ",");
+
+                       format(buf, size, off, "NvDimm",
+                              "NvDimm(0x%03x,0x%01x,0x%01x,0x%01x,0x%01x)",
+                              node_controller, socket, memory_controller,
+                              memory_channel, dimm);
+               }
+               break;
+                                   }
        default:
                switch (dp->subtype) {
                case EFIDP_ACPI_HID_EX:
index 162a7eb..dd556fa 100644 (file)
 #define efidp_decode_bitfield_(value, name, shift, mask)               \
        ({ (name) = ((value) & (mask)) >> (shift); })
 
+#define efidp_size_after(dp, field)                                    \
+       (efidp_size((const_efidp)dp) -                                  \
+        (offsetof(__typeof__ (*(dp)), field) + sizeof((dp)->field)))
+
 #define EFIVAR_PACKED __attribute__((__packed__))
 
 /* Generic device path header */
@@ -155,6 +159,7 @@ extern ssize_t efidp_make_acpi_hid_ex(uint8_t *buf, ssize_t size, uint32_t hid,
 #define EFIDP_ACPI_KEYBOARD_HID                EFIDP_EFI_PNP_ID(0x0301)
 #define EFIDP_ACPI_SERIAL_HID          EFIDP_EFI_PNP_ID(0x0501)
 #define EFIDP_ACPI_PARALLEL_HID                EFIDP_EFI_PNP_ID(0x0401)
+#define EFIDP_ACPI_NVDIMM_HID          EFIDP_EFI_ACPI_ID(0x0012)
 
 #define EFIDP_ACPI_ADR         0x03
 typedef struct {
@@ -257,6 +262,65 @@ typedef struct {
        (*(device_id_scheme)) == EFIDP_ACPI_ADR_DEVICE_ID_SCHEME_ACPI;  \
        })
 
+#define EFIDP_ACPI_ADR_NVDIMM_NODE_CONTROLLER_MASK     0x0fff0000
+#define EFIDP_ACPI_ADR_NVDIMM_NODE_CONTROLLER_SHIFT    16
+
+#define EFIDP_ACPI_ADR_NVDIMM_SOCKET_ID_MASK           0x0000f000
+#define EFIDP_ACPI_ADR_NVDIMM_SOCKET_ID_SHIFT          12
+
+#define EFIDP_ACPI_ADR_NVDIMM_MEMORY_CONTROLLER_MASK   0x00000f00
+#define EFIDP_ACPI_ADR_NVDIMM_MEMORY_CONTROLLER_SHIFT  8
+
+#define EFIDP_ACPI_ADR_NVDIMM_MEMORY_CHANNEL_MASK      0x000000f0
+#define EFIDP_ACPI_ADR_NVDIMM_MEMORY_CHANNEL_SHIFT     4
+
+#define EFIDP_ACPI_ADR_NVDIMM_DIMM_MASK                        0x0f00000f
+#define EFIDP_ACPI_ADR_NVDIMM_DIMM_SHIFT               0
+
+#define efidp_encode_acpi_nvdimm_adr(node_controller,                  \
+                                    socket, memory_controller,         \
+                                    memory_channel, dimm, adr)         \
+       ({                                                              \
+       ((uint32_t)(adr)) = ((uint32_t)(                                \
+        efidp_encode_bitfield_(node_controller,                        \
+                               EFIDP_ACPI_ADR_NVDIMM_NODE_CONTROLLER_SHIFT,\
+                               EFIDP_ACPI_ADR_NVDIMM_NODE_CONTROLLER_MASK) | \
+        efidp_encode_bitfield_(socket,                                 \
+                               EFIDP_ACPI_ADR_NVDIMM_SOCKET_ID_SHIFT,  \
+                               EFIDP_ACPI_ADR_NVDIMM_SOCKET_ID_MASK) | \
+        efidp_encode_bitfield_(memory_controller,                      \
+                               EFIDP_ACPI_ADR_NVDIMM_MEMORY_CONTROLLER_SHIFT,\
+                               EFIDP_ACPI_ADR_NVDIMM_MEMORY_CONTROLLER_MASK)|\
+        efidp_encode_bitfield_(memory_channel,                         \
+                               EFIDP_ACPI_ADR_NVDIMM_MEMORY_CHANNEL_SHIFT,\
+                               EFIDP_ACPI_ADR_NVDIMM_MEMORY_CHANNEL_MASK) | \
+        efidp_encode_bitfield_(dimm,                                   \
+                               EFIDP_ACPI_ADR_NVDIMM_DIMM_SHIFT,       \
+                               EFIDP_ACPI_ADR_NVDIMM_DIMM_MASK));      \
+       })
+
+#define efidp_decode_acpi_nvdimm_adr(adr, node_controller, socket,     \
+                                    memory_controller, memory_channel, \
+                                    dimm)                              \
+       ({                                                              \
+        efidp_decode_bitfield_(adr, *(node_controller),                \
+                               EFIDP_ACPI_ADR_NVDIMM_NODE_CONTROLLER_SHIFT,\
+                               EFIDP_ACPI_ADR_NVDIMM_NODE_CONTROLLER_MASK);\
+        efidp_decode_bitfield_(adr, *(socket),                         \
+                               EFIDP_ACPI_ADR_NVDIMM_SOCKET_ID_SHIFT,  \
+                               EFIDP_ACPI_ADR_NVDIMM_SOCKET_ID_MASK);  \
+        efidp_decode_bitfield_(adr, *(memory_controller),              \
+                               EFIDP_ACPI_ADR_NVDIMM_MEMORY_CONTROLLER_SHIFT,\
+                               EFIDP_ACPI_ADR_NVDIMM_MEMORY_CONTROLLER_MASK);\
+        efidp_decode_bitfield_(adr, *(memory_channel),                 \
+                               EFIDP_ACPI_ADR_NVDIMM_MEMORY_CHANNEL_SHIFT,\
+                               EFIDP_ACPI_ADR_NVDIMM_MEMORY_CHANNEL_MASK);\
+        efidp_decode_bitfield_(adr, *(dimm),                           \
+                               EFIDP_ACPI_ADR_NVDIMM_DIMM_SHIFT,       \
+                               EFIDP_ACPI_ADR_NVDIMM_DIMM_MASK);       \
+        0;                                                             \
+       })
+
 /* Each messaging subtype */
 #define EFIDP_MSG_ATAPI                0x01
 typedef struct {