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 }