gitlab.com/apertussolutions/u-root@v7.0.0+incompatible/pkg/smbios/type17_memory_device.go (about)

     1  // Copyright 2016-2019 the u-root Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package smbios
     6  
     7  import (
     8  	"errors"
     9  	"fmt"
    10  	"strings"
    11  )
    12  
    13  // Much of this is auto-generated. If adding a new type, see README for instructions.
    14  
    15  // MemoryDevice is defined in DSP0134 7.18.
    16  type MemoryDevice struct {
    17  	Table
    18  	PhysicalMemoryArrayHandle         uint16                              // 04h
    19  	MemoryErrorInfoHandle             uint16                              // 06h
    20  	TotalWidth                        uint16                              // 08h
    21  	DataWidth                         uint16                              // 0Ah
    22  	Size                              uint16                              // 0Ch
    23  	FormFactor                        MemoryDeviceFormFactor              // 0Eh
    24  	DeviceSet                         uint8                               // 0Fh
    25  	DeviceLocator                     string                              // 10h
    26  	BankLocator                       string                              // 11h
    27  	Type                              MemoryDeviceType                    // 12h
    28  	TypeDetail                        MemoryDeviceTypeDetail              // 13h
    29  	Speed                             uint16                              // 15h
    30  	Manufacturer                      string                              // 17h
    31  	SerialNumber                      string                              // 18h
    32  	AssetTag                          string                              // 19h
    33  	PartNumber                        string                              // 1Ah
    34  	Attributes                        uint8                               // 1Bh
    35  	ExtendedSize                      uint32                              // 1Ch
    36  	ConfiguredSpeed                   uint16                              // 20h
    37  	MinimumVoltage                    uint16                              // 22h
    38  	MaximumVoltage                    uint16                              // 24h
    39  	ConfiguredVoltage                 uint16                              // 26h
    40  	Technology                        MemoryDeviceTechnology              // 28h
    41  	OperatingModeCapability           MemoryDeviceOperatingModeCapability // 29h
    42  	FirmwareVersion                   string                              // 2Bh
    43  	ModuleManufacturerID              uint16                              // 2Ch
    44  	ModuleProductID                   uint16                              // 2Eh
    45  	SubsystemControllerManufacturerID uint16                              // 30h
    46  	SubsystemControllerProductID      uint16                              // 32h
    47  	NonvolatileSize                   uint64                              // 34h
    48  	VolatileSize                      uint64                              // 3Ch
    49  	CacheSize                         uint64                              // 44h
    50  	LogicalSize                       uint64                              // 4Ch
    51  }
    52  
    53  var MemoryDeviceManufacturer = map[string]uint16{
    54  	"Micron":   0x2C00,
    55  	"Samsung":  0xCE00,
    56  	"Montage":  0x3206,
    57  	"Kinston":  0x9801,
    58  	"Elpida":   0xFE02,
    59  	"Hynix":    0xAD00,
    60  	"Infineon": 0xC100,
    61  	"Smart":    0x9401,
    62  	"Aeneon":   0x5705,
    63  	"Qimonda":  0x5105,
    64  	"NEC":      0x1000,
    65  	"Nanya":    0x0B03,
    66  	"TI":       0x9700,
    67  	"IDT":      0xB300,
    68  	"TEK":      0x3D00,
    69  	"Agilent":  0xC802,
    70  	"Inphi":    0xB304,
    71  	"Intel":    0x8900,
    72  	"Viking":   0x4001,
    73  }
    74  
    75  // NewMemoryDevice parses a generic Table into MemoryDevice.
    76  func NewMemoryDevice(t *Table) (*MemoryDevice, error) {
    77  	if t.Type != TableTypeMemoryDevice {
    78  		return nil, fmt.Errorf("invalid table type %d", t.Type)
    79  	}
    80  	if t.Len() < 0x15 {
    81  		return nil, errors.New("required fields missing")
    82  	}
    83  	md := &MemoryDevice{Table: *t}
    84  	_, err := parseStruct(t, 0 /* off */, false /* complete */, md)
    85  	if err != nil {
    86  		return nil, err
    87  	}
    88  	return md, nil
    89  }
    90  
    91  // GetSizeBytes returns size of the memory device, in bytes.
    92  func (md *MemoryDevice) GetSizeBytes() uint64 {
    93  	switch md.Size {
    94  	case 0:
    95  		return 0
    96  	case 0x7fff:
    97  		return uint64(md.ExtendedSize&0x7fffffff) * 1024 * 1024
    98  	default:
    99  		mul := uint64(1024 * 1024)
   100  		if md.Size&0x8000 != 0 {
   101  			mul = 1024
   102  		}
   103  		return uint64(md.Size&0x7fff) * mul
   104  	}
   105  }
   106  
   107  func (md *MemoryDevice) String() string {
   108  	ehStr := ""
   109  	switch md.MemoryErrorInfoHandle {
   110  	case 0xffff:
   111  		ehStr = "No Error"
   112  	case 0xfffe:
   113  		ehStr = "Not Provided"
   114  	default:
   115  		ehStr = fmt.Sprintf("0x%04X", md.MemoryErrorInfoHandle)
   116  	}
   117  
   118  	bitWidthStr := func(v uint16) string {
   119  		if v == 0 || v == 0xffff {
   120  			return "Unknown"
   121  		}
   122  		return fmt.Sprintf("%d bits", v)
   123  	}
   124  
   125  	setStr := ""
   126  	switch md.DeviceSet {
   127  	case 0:
   128  		setStr = "None"
   129  	case 0xff:
   130  		setStr = "Unknown"
   131  	default:
   132  		setStr = fmt.Sprintf("%d", md.DeviceSet)
   133  	}
   134  
   135  	speedStr := func(v uint16) string {
   136  		if v == 0 || v == 0xffff {
   137  			return "Unknown"
   138  		}
   139  		return fmt.Sprintf("%d MT/s", v)
   140  	}
   141  
   142  	moduleSizeStr := "No Module Installed"
   143  	if md.GetSizeBytes() > 0 {
   144  		moduleSizeStr = kmgt(md.GetSizeBytes())
   145  	}
   146  
   147  	lines := []string{
   148  		md.Header.String(),
   149  		fmt.Sprintf("Array Handle: 0x%04X", md.PhysicalMemoryArrayHandle),
   150  		fmt.Sprintf("Error Information Handle: %s", ehStr),
   151  		fmt.Sprintf("Total Width: %s", bitWidthStr(md.TotalWidth)),
   152  		fmt.Sprintf("Data Width: %s", bitWidthStr(md.DataWidth)),
   153  		fmt.Sprintf("Size: %s", moduleSizeStr),
   154  		fmt.Sprintf("Form Factor: %s", md.FormFactor),
   155  		fmt.Sprintf("Set: %s", setStr),
   156  		fmt.Sprintf("Locator: %s", md.DeviceLocator),
   157  		fmt.Sprintf("Bank Locator: %s", md.BankLocator),
   158  		fmt.Sprintf("Type: %s", md.Type),
   159  		fmt.Sprintf("Type Detail: %s", md.TypeDetail),
   160  	}
   161  	if md.Len() > 0x15 {
   162  		lines = append(lines,
   163  			fmt.Sprintf("Speed: %s", speedStr(md.Speed)),
   164  			fmt.Sprintf("Manufacturer: %s", md.Manufacturer),
   165  			fmt.Sprintf("Serial Number: %s", md.SerialNumber),
   166  			fmt.Sprintf("Asset Tag: %s", md.AssetTag),
   167  			fmt.Sprintf("Part Number: %s", md.PartNumber),
   168  		)
   169  	}
   170  	if md.Len() > 0x1b {
   171  		rankStr := "Unknown"
   172  		if md.Attributes&0xf != 0 {
   173  			rankStr = fmt.Sprintf("%d", md.Attributes&0xf)
   174  		}
   175  		lines = append(lines, fmt.Sprintf("Rank: %s", rankStr))
   176  	}
   177  	if md.Len() > 0x1c {
   178  		lines = append(lines, fmt.Sprintf("Configured Memory Speed: %s", speedStr(md.ConfiguredSpeed)))
   179  	}
   180  	if md.Len() > 0x22 {
   181  		voltageStr := func(v uint16) string {
   182  			switch {
   183  			case v == 0:
   184  				return "Unknown"
   185  			case v%100 == 0:
   186  				return fmt.Sprintf("%.1f V", float32(v)/1000.0)
   187  			default:
   188  				return fmt.Sprintf("%g V", float32(v)/1000.0)
   189  			}
   190  		}
   191  		lines = append(lines,
   192  			fmt.Sprintf("Minimum Voltage: %s", voltageStr(md.MinimumVoltage)),
   193  			fmt.Sprintf("Maximum Voltage: %s", voltageStr(md.MaximumVoltage)),
   194  			fmt.Sprintf("Configured Voltage: %s", voltageStr(md.ConfiguredVoltage)),
   195  		)
   196  	}
   197  	if md.Len() > 0x28 {
   198  		manufacturerIDStr := func(id uint16) string {
   199  			if id == 0 {
   200  				return "Unknown"
   201  			}
   202  			return fmt.Sprintf("Bank %d, Hex 0x%02X", (id&0x7F)+1, id>>8)
   203  		}
   204  		productIDStr := func(v uint16) string {
   205  			if v == 0 {
   206  				return "Unknown"
   207  			}
   208  			return fmt.Sprintf("0x%04X", v)
   209  		}
   210  		sizeStr := func(v uint64) string {
   211  			switch v {
   212  			case 0:
   213  				return "None"
   214  			case 0xffffffffffffffff:
   215  				return "Unknown"
   216  			default:
   217  				return kmgt(v)
   218  			}
   219  		}
   220  		lines = append(lines,
   221  			fmt.Sprintf("Memory Technology: %s", md.Technology),
   222  			fmt.Sprintf("Memory Operating Mode Capability: %s", md.OperatingModeCapability),
   223  			fmt.Sprintf("Firmware Version: %s", md.FirmwareVersion),
   224  			fmt.Sprintf("Module Manufacturer ID: %s", manufacturerIDStr(md.ModuleManufacturerID)),
   225  			fmt.Sprintf("Module Product ID: %s", productIDStr(md.ModuleProductID)),
   226  			fmt.Sprintf("Memory Subsystem Controller Manufacturer ID: %s", manufacturerIDStr(md.SubsystemControllerManufacturerID)),
   227  			fmt.Sprintf("Memory Subsystem Controller Product ID: %s", productIDStr(md.SubsystemControllerProductID)),
   228  			fmt.Sprintf("Non-Volatile Size: %s", sizeStr(md.NonvolatileSize)),
   229  			fmt.Sprintf("Volatile Size: %s", sizeStr(md.VolatileSize)),
   230  			fmt.Sprintf("Cache Size: %s", sizeStr(md.CacheSize)),
   231  			fmt.Sprintf("Logical Size: %s", sizeStr(md.LogicalSize)),
   232  		)
   233  	}
   234  	return strings.Join(lines, "\n\t")
   235  }
   236  
   237  // MemoryDeviceFormFactor is defined in DSP0134 7.18.1.
   238  type MemoryDeviceFormFactor uint8
   239  
   240  // MemoryDeviceFormFactor values are defined in DSP0134 7.18.1.
   241  const (
   242  	MemoryDeviceFormFactorOther           MemoryDeviceFormFactor = 0x01 // Other
   243  	MemoryDeviceFormFactorUnknown         MemoryDeviceFormFactor = 0x02 // Unknown
   244  	MemoryDeviceFormFactorSIMM            MemoryDeviceFormFactor = 0x03 // SIMM
   245  	MemoryDeviceFormFactorSIP             MemoryDeviceFormFactor = 0x04 // SIP
   246  	MemoryDeviceFormFactorChip            MemoryDeviceFormFactor = 0x05 // Chip
   247  	MemoryDeviceFormFactorDIP             MemoryDeviceFormFactor = 0x06 // DIP
   248  	MemoryDeviceFormFactorZIP             MemoryDeviceFormFactor = 0x07 // ZIP
   249  	MemoryDeviceFormFactorProprietaryCard MemoryDeviceFormFactor = 0x08 // Proprietary Card
   250  	MemoryDeviceFormFactorDIMM            MemoryDeviceFormFactor = 0x09 // DIMM
   251  	MemoryDeviceFormFactorTSOP            MemoryDeviceFormFactor = 0x0a // TSOP
   252  	MemoryDeviceFormFactorRowOfChips      MemoryDeviceFormFactor = 0x0b // Row of chips
   253  	MemoryDeviceFormFactorRIMM            MemoryDeviceFormFactor = 0x0c // RIMM
   254  	MemoryDeviceFormFactorSODIMM          MemoryDeviceFormFactor = 0x0d // SODIMM
   255  	MemoryDeviceFormFactorSRIMM           MemoryDeviceFormFactor = 0x0e // SRIMM
   256  	MemoryDeviceFormFactorFBDIMM          MemoryDeviceFormFactor = 0x0f // FB-DIMM
   257  )
   258  
   259  func (v MemoryDeviceFormFactor) String() string {
   260  	names := map[MemoryDeviceFormFactor]string{
   261  		MemoryDeviceFormFactorOther:           "Other",
   262  		MemoryDeviceFormFactorUnknown:         "Unknown",
   263  		MemoryDeviceFormFactorSIMM:            "SIMM",
   264  		MemoryDeviceFormFactorSIP:             "SIP",
   265  		MemoryDeviceFormFactorChip:            "Chip",
   266  		MemoryDeviceFormFactorDIP:             "DIP",
   267  		MemoryDeviceFormFactorZIP:             "ZIP",
   268  		MemoryDeviceFormFactorProprietaryCard: "Proprietary Card",
   269  		MemoryDeviceFormFactorDIMM:            "DIMM",
   270  		MemoryDeviceFormFactorTSOP:            "TSOP",
   271  		MemoryDeviceFormFactorRowOfChips:      "Row of chips",
   272  		MemoryDeviceFormFactorRIMM:            "RIMM",
   273  		MemoryDeviceFormFactorSODIMM:          "SODIMM",
   274  		MemoryDeviceFormFactorSRIMM:           "SRIMM",
   275  		MemoryDeviceFormFactorFBDIMM:          "FB-DIMM",
   276  	}
   277  	if name, ok := names[v]; ok {
   278  		return name
   279  	}
   280  	return fmt.Sprintf("%#x", uint8(v))
   281  }
   282  
   283  // MemoryDeviceType is defined in DSP0134 7.18.2.
   284  type MemoryDeviceType uint8
   285  
   286  // MemoryDeviceType values are defined in DSP0134 7.18.2.
   287  const (
   288  	MemoryDeviceTypeOther                    MemoryDeviceType = 0x01 // Other
   289  	MemoryDeviceTypeUnknown                  MemoryDeviceType = 0x02 // Unknown
   290  	MemoryDeviceTypeDRAM                     MemoryDeviceType = 0x03 // DRAM
   291  	MemoryDeviceTypeEDRAM                    MemoryDeviceType = 0x04 // EDRAM
   292  	MemoryDeviceTypeVRAM                     MemoryDeviceType = 0x05 // VRAM
   293  	MemoryDeviceTypeSRAM                     MemoryDeviceType = 0x06 // SRAM
   294  	MemoryDeviceTypeRAM                      MemoryDeviceType = 0x07 // RAM
   295  	MemoryDeviceTypeROM                      MemoryDeviceType = 0x08 // ROM
   296  	MemoryDeviceTypeFlash                    MemoryDeviceType = 0x09 // Flash
   297  	MemoryDeviceTypeEEPROM                   MemoryDeviceType = 0x0a // EEPROM
   298  	MemoryDeviceTypeFEPROM                   MemoryDeviceType = 0x0b // FEPROM
   299  	MemoryDeviceTypeEPROM                    MemoryDeviceType = 0x0c // EPROM
   300  	MemoryDeviceTypeCDRAM                    MemoryDeviceType = 0x0d // CDRAM
   301  	MemoryDeviceType3DRAM                    MemoryDeviceType = 0x0e // 3DRAM
   302  	MemoryDeviceTypeSDRAM                    MemoryDeviceType = 0x0f // SDRAM
   303  	MemoryDeviceTypeSGRAM                    MemoryDeviceType = 0x10 // SGRAM
   304  	MemoryDeviceTypeRDRAM                    MemoryDeviceType = 0x11 // RDRAM
   305  	MemoryDeviceTypeDDR                      MemoryDeviceType = 0x12 // DDR
   306  	MemoryDeviceTypeDDR2                     MemoryDeviceType = 0x13 // DDR2
   307  	MemoryDeviceTypeDDR2FBDIMM               MemoryDeviceType = 0x14 // DDR2 FB-DIMM
   308  	MemoryDeviceTypeDDR3                     MemoryDeviceType = 0x18 // DDR3
   309  	MemoryDeviceTypeFBD2                     MemoryDeviceType = 0x19 // FBD2
   310  	MemoryDeviceTypeDDR4                     MemoryDeviceType = 0x1a // DDR4
   311  	MemoryDeviceTypeLPDDR                    MemoryDeviceType = 0x1b // LPDDR
   312  	MemoryDeviceTypeLPDDR2                   MemoryDeviceType = 0x1c // LPDDR2
   313  	MemoryDeviceTypeLPDDR3                   MemoryDeviceType = 0x1d // LPDDR3
   314  	MemoryDeviceTypeLPDDR4                   MemoryDeviceType = 0x1e // LPDDR4
   315  	MemoryDeviceTypeLogicalNonvolatileDevice MemoryDeviceType = 0x1f // Logical non-volatile device
   316  )
   317  
   318  func (v MemoryDeviceType) String() string {
   319  	names := map[MemoryDeviceType]string{
   320  		MemoryDeviceTypeOther:                    "Other",
   321  		MemoryDeviceTypeUnknown:                  "Unknown",
   322  		MemoryDeviceTypeDRAM:                     "DRAM",
   323  		MemoryDeviceTypeEDRAM:                    "EDRAM",
   324  		MemoryDeviceTypeVRAM:                     "VRAM",
   325  		MemoryDeviceTypeSRAM:                     "SRAM",
   326  		MemoryDeviceTypeRAM:                      "RAM",
   327  		MemoryDeviceTypeROM:                      "ROM",
   328  		MemoryDeviceTypeFlash:                    "Flash",
   329  		MemoryDeviceTypeEEPROM:                   "EEPROM",
   330  		MemoryDeviceTypeFEPROM:                   "FEPROM",
   331  		MemoryDeviceTypeEPROM:                    "EPROM",
   332  		MemoryDeviceTypeCDRAM:                    "CDRAM",
   333  		MemoryDeviceType3DRAM:                    "3DRAM",
   334  		MemoryDeviceTypeSDRAM:                    "SDRAM",
   335  		MemoryDeviceTypeSGRAM:                    "SGRAM",
   336  		MemoryDeviceTypeRDRAM:                    "RDRAM",
   337  		MemoryDeviceTypeDDR:                      "DDR",
   338  		MemoryDeviceTypeDDR2:                     "DDR2",
   339  		MemoryDeviceTypeDDR2FBDIMM:               "DDR2 FB-DIMM",
   340  		MemoryDeviceTypeDDR3:                     "DDR3",
   341  		MemoryDeviceTypeFBD2:                     "FBD2",
   342  		MemoryDeviceTypeDDR4:                     "DDR4",
   343  		MemoryDeviceTypeLPDDR:                    "LPDDR",
   344  		MemoryDeviceTypeLPDDR2:                   "LPDDR2",
   345  		MemoryDeviceTypeLPDDR3:                   "LPDDR3",
   346  		MemoryDeviceTypeLPDDR4:                   "LPDDR4",
   347  		MemoryDeviceTypeLogicalNonvolatileDevice: "Logical non-volatile device",
   348  	}
   349  	if name, ok := names[v]; ok {
   350  		return name
   351  	}
   352  	return fmt.Sprintf("%#x", uint8(v))
   353  }
   354  
   355  // MemoryDeviceTypeDetail is defined in DSP0134 7.18.3.
   356  type MemoryDeviceTypeDetail uint16
   357  
   358  // MemoryDeviceTypeDetail fields are defined in DSP0134 7.18.3
   359  const (
   360  	MemoryDeviceTypeDetailOther                  MemoryDeviceTypeDetail = 1 << 1  // Other
   361  	MemoryDeviceTypeDetailUnknown                MemoryDeviceTypeDetail = 1 << 2  // Unknown
   362  	MemoryDeviceTypeDetailFastpaged              MemoryDeviceTypeDetail = 1 << 3  // Fast-paged
   363  	MemoryDeviceTypeDetailStaticColumn           MemoryDeviceTypeDetail = 1 << 4  // Static column
   364  	MemoryDeviceTypeDetailPseudostatic           MemoryDeviceTypeDetail = 1 << 5  // Pseudo-static
   365  	MemoryDeviceTypeDetailRAMBUS                 MemoryDeviceTypeDetail = 1 << 6  // RAMBUS
   366  	MemoryDeviceTypeDetailSynchronous            MemoryDeviceTypeDetail = 1 << 7  // Synchronous
   367  	MemoryDeviceTypeDetailCMOS                   MemoryDeviceTypeDetail = 1 << 8  // CMOS
   368  	MemoryDeviceTypeDetailEDO                    MemoryDeviceTypeDetail = 1 << 9  // EDO
   369  	MemoryDeviceTypeDetailWindowDRAM             MemoryDeviceTypeDetail = 1 << 10 // Window DRAM
   370  	MemoryDeviceTypeDetailCacheDRAM              MemoryDeviceTypeDetail = 1 << 11 // Cache DRAM
   371  	MemoryDeviceTypeDetailNonvolatile            MemoryDeviceTypeDetail = 1 << 12 // Non-volatile
   372  	MemoryDeviceTypeDetailRegisteredBuffered     MemoryDeviceTypeDetail = 1 << 13 // Registered (Buffered)
   373  	MemoryDeviceTypeDetailUnbufferedUnregistered MemoryDeviceTypeDetail = 1 << 14 // Unbuffered (Unregistered)
   374  	MemoryDeviceTypeDetailLRDIMM                 MemoryDeviceTypeDetail = 1 << 15 // LRDIMM
   375  )
   376  
   377  func (v MemoryDeviceTypeDetail) String() string {
   378  	if v&0xfffe == 0 {
   379  		return "None"
   380  	}
   381  	var lines []string
   382  	if v&MemoryDeviceTypeDetailOther != 0 {
   383  		lines = append(lines, "Other")
   384  	}
   385  	if v&MemoryDeviceTypeDetailUnknown != 0 {
   386  		lines = append(lines, "Unknown")
   387  	}
   388  	if v&MemoryDeviceTypeDetailFastpaged != 0 {
   389  		lines = append(lines, "Fast-paged")
   390  	}
   391  	if v&MemoryDeviceTypeDetailStaticColumn != 0 {
   392  		lines = append(lines, "Static column")
   393  	}
   394  	if v&MemoryDeviceTypeDetailPseudostatic != 0 {
   395  		lines = append(lines, "Pseudo-static")
   396  	}
   397  	if v&MemoryDeviceTypeDetailRAMBUS != 0 {
   398  		lines = append(lines, "RAMBUS")
   399  	}
   400  	if v&MemoryDeviceTypeDetailSynchronous != 0 {
   401  		lines = append(lines, "Synchronous")
   402  	}
   403  	if v&MemoryDeviceTypeDetailCMOS != 0 {
   404  		lines = append(lines, "CMOS")
   405  	}
   406  	if v&MemoryDeviceTypeDetailEDO != 0 {
   407  		lines = append(lines, "EDO")
   408  	}
   409  	if v&MemoryDeviceTypeDetailWindowDRAM != 0 {
   410  		lines = append(lines, "Window DRAM")
   411  	}
   412  	if v&MemoryDeviceTypeDetailCacheDRAM != 0 {
   413  		lines = append(lines, "Cache DRAM")
   414  	}
   415  	if v&MemoryDeviceTypeDetailNonvolatile != 0 {
   416  		lines = append(lines, "Non-volatile")
   417  	}
   418  	if v&MemoryDeviceTypeDetailRegisteredBuffered != 0 {
   419  		lines = append(lines, "Registered (Buffered)")
   420  	}
   421  	if v&MemoryDeviceTypeDetailUnbufferedUnregistered != 0 {
   422  		lines = append(lines, "Unbuffered (Unregistered)")
   423  	}
   424  	if v&MemoryDeviceTypeDetailLRDIMM != 0 {
   425  		lines = append(lines, "LRDIMM")
   426  	}
   427  	return strings.Join(lines, " ")
   428  }
   429  
   430  // MemoryDeviceTechnology is defined in DSP0134 7.18.6.
   431  type MemoryDeviceTechnology uint8
   432  
   433  // MemoryDeviceTechnology values are defined in DSP0134 7.18.6.
   434  const (
   435  	MemoryDeviceTechnologyOther                 MemoryDeviceTechnology = 0x01 // Other
   436  	MemoryDeviceTechnologyUnknown               MemoryDeviceTechnology = 0x02 // Unknown
   437  	MemoryDeviceTechnologyDRAM                  MemoryDeviceTechnology = 0x03 // DRAM
   438  	MemoryDeviceTechnologyNVDIMMN               MemoryDeviceTechnology = 0x04 // NVDIMM-N
   439  	MemoryDeviceTechnologyNVDIMMF               MemoryDeviceTechnology = 0x05 // NVDIMM-F
   440  	MemoryDeviceTechnologyNVDIMMP               MemoryDeviceTechnology = 0x06 // NVDIMM-P
   441  	MemoryDeviceTechnologyIntelPersistentMemory MemoryDeviceTechnology = 0x07 // Intel persistent memory
   442  )
   443  
   444  func (v MemoryDeviceTechnology) String() string {
   445  	names := map[MemoryDeviceTechnology]string{
   446  		MemoryDeviceTechnologyOther:                 "Other",
   447  		MemoryDeviceTechnologyUnknown:               "Unknown",
   448  		MemoryDeviceTechnologyDRAM:                  "DRAM",
   449  		MemoryDeviceTechnologyNVDIMMN:               "NVDIMM-N",
   450  		MemoryDeviceTechnologyNVDIMMF:               "NVDIMM-F",
   451  		MemoryDeviceTechnologyNVDIMMP:               "NVDIMM-P",
   452  		MemoryDeviceTechnologyIntelPersistentMemory: "Intel persistent memory",
   453  	}
   454  	if name, ok := names[v]; ok {
   455  		return name
   456  	}
   457  	return fmt.Sprintf("%#x", uint8(v))
   458  }
   459  
   460  // MemoryDeviceOperatingModeCapability is defined in DSP0134 7.18.7.
   461  type MemoryDeviceOperatingModeCapability uint16
   462  
   463  // MemoryDeviceOperatingModeCapability fields are defined in DSP0134 x.x.x
   464  const (
   465  	MemoryDeviceOperatingModeCapabilityOther                           MemoryDeviceOperatingModeCapability = 1 << 1 // Other
   466  	MemoryDeviceOperatingModeCapabilityUnknown                         MemoryDeviceOperatingModeCapability = 1 << 2 // Unknown
   467  	MemoryDeviceOperatingModeCapabilityVolatileMemory                  MemoryDeviceOperatingModeCapability = 1 << 3 // Volatile memory
   468  	MemoryDeviceOperatingModeCapabilityByteaccessiblePersistentMemory  MemoryDeviceOperatingModeCapability = 1 << 4 // Byte-accessible persistent memory
   469  	MemoryDeviceOperatingModeCapabilityBlockaccessiblePersistentMemory MemoryDeviceOperatingModeCapability = 1 << 5 // Block-accessible persistent memory
   470  )
   471  
   472  func (v MemoryDeviceOperatingModeCapability) String() string {
   473  	if v&0xfffe == 0 {
   474  		return "None"
   475  	}
   476  	var lines []string
   477  	if v&MemoryDeviceOperatingModeCapabilityOther != 0 {
   478  		lines = append(lines, "Other")
   479  	}
   480  	if v&MemoryDeviceOperatingModeCapabilityUnknown != 0 {
   481  		lines = append(lines, "Unknown")
   482  	}
   483  	if v&MemoryDeviceOperatingModeCapabilityVolatileMemory != 0 {
   484  		lines = append(lines, "Volatile memory")
   485  	}
   486  	if v&MemoryDeviceOperatingModeCapabilityByteaccessiblePersistentMemory != 0 {
   487  		lines = append(lines, "Byte-accessible persistent memory")
   488  	}
   489  	if v&MemoryDeviceOperatingModeCapabilityBlockaccessiblePersistentMemory != 0 {
   490  		lines = append(lines, "Block-accessible persistent memory")
   491  	}
   492  	return strings.Join(lines, " ")
   493  }