SmbiosPlatformDxe.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962
  1. /** @file
  2. This driver installs SMBIOS information for Socionext SynQuacer platforms
  3. Copyright (c) 2015, ARM Limited. All rights reserved.
  4. Copyright (c) 2018, Linaro, Ltd. All rights reserved.
  5. SPDX-License-Identifier: BSD-2-Clause-Patent
  6. **/
  7. #include <PiDxe.h>
  8. #include <IndustryStandard/SdramSpdDdr4.h>
  9. #include <IndustryStandard/SmBios.h>
  10. #include <Library/BaseLib.h>
  11. #include <Library/BaseMemoryLib.h>
  12. #include <Library/DebugLib.h>
  13. #include <Library/HobLib.h>
  14. #include <Library/MemoryAllocationLib.h>
  15. #include <Library/PrintLib.h>
  16. #include <Library/UefiBootServicesTableLib.h>
  17. #include <Protocol/Smbios.h>
  18. STATIC EFI_SMBIOS_PROTOCOL *mSmbios;
  19. #define SPD4_MEM_BUS_WIDTH_8BIT (0x00)
  20. #define SPD4_MEM_BUS_WIDTH_16BIT (BIT0)
  21. #define SPD4_MEM_BUS_WIDTH_32BIT (BIT1)
  22. #define SPD4_MEM_BUS_WIDTH_64BIT (BIT0 | BIT1)
  23. #define SPD4_MEM_DEV_WIDTH_4BIT (0x00)
  24. #define SPD4_MEM_DEV_WIDTH_8BIT (BIT0)
  25. #define SPD4_MEM_DEV_WIDTH_16BIT (BIT1)
  26. #define SPD4_MEM_DEV_WIDTH_32BIT (BIT0 | BIT1)
  27. #define SPD4_DDR4_SDRAM_TYPE (0x0C)
  28. #define SPD4_MEM_MODULE_TYPE_RDIMM (0x01)
  29. #define SPD4_MEM_MODULE_TYPE_UDIMM (0x02)
  30. #define SPD4_MEM_MODULE_TYPE_SODIMM (0x03)
  31. #define TYPE17_DEVICE_LOCATOR_LEN (8 + 1)
  32. #define TYPE17_BANK_LOCATOR_LEN (20 + 1)
  33. #define TYPE17_MANUFACTURER_NAME_LEN (30 + 1)
  34. #define TYPE17_SERIAL_NUMBER_LEN (16 + 1)
  35. #define TYPE17_ASSETTAG_LEN (16 + 1)
  36. #define TYPE17_MODULE_PART_NUMBER_LEN (20 + 1)
  37. #define TYPE17_FIRMWARE_VERSION_LEN (8 + 1)
  38. #define TYPE17_STRINGS_MAX_LEN (TYPE17_DEVICE_LOCATOR_LEN + \
  39. TYPE17_BANK_LOCATOR_LEN + \
  40. TYPE17_MANUFACTURER_NAME_LEN + \
  41. TYPE17_SERIAL_NUMBER_LEN + \
  42. TYPE17_ASSETTAG_LEN + \
  43. TYPE17_MODULE_PART_NUMBER_LEN + \
  44. TYPE17_FIRMWARE_VERSION_LEN + \
  45. 1/* null SMBIOS_TABLE_STRING terminator */ )
  46. //
  47. // Type definition and contents of the default SMBIOS table.
  48. // This table covers only the minimum structures required by
  49. // the SMBIOS specification (section 6.2, version 3.0)
  50. //
  51. #pragma pack(1)
  52. typedef struct {
  53. SMBIOS_TABLE_TYPE0 Base;
  54. CHAR8 Strings[];
  55. } ARM_TYPE0;
  56. typedef struct {
  57. SMBIOS_TABLE_TYPE1 Base;
  58. CHAR8 Strings[];
  59. } ARM_TYPE1;
  60. typedef struct {
  61. SMBIOS_TABLE_TYPE2 Base;
  62. CHAR8 Strings[];
  63. } ARM_TYPE2;
  64. typedef struct {
  65. SMBIOS_TABLE_TYPE3 Base;
  66. CHAR8 Strings[];
  67. } ARM_TYPE3;
  68. typedef struct {
  69. SMBIOS_TABLE_TYPE4 Base;
  70. CHAR8 Strings[];
  71. } ARM_TYPE4;
  72. typedef struct {
  73. SMBIOS_TABLE_TYPE7 Base;
  74. CHAR8 Strings[];
  75. } ARM_TYPE7;
  76. typedef struct {
  77. SMBIOS_TABLE_TYPE9 Base;
  78. CHAR8 Strings[];
  79. } ARM_TYPE9;
  80. typedef struct {
  81. SMBIOS_TABLE_TYPE16 Base;
  82. CHAR8 Strings[];
  83. } ARM_TYPE16;
  84. typedef struct {
  85. SMBIOS_TABLE_TYPE17 Base;
  86. CHAR8 Strings[TYPE17_STRINGS_MAX_LEN];
  87. } ARM_TYPE17;
  88. typedef struct {
  89. SMBIOS_TABLE_TYPE19 Base;
  90. CHAR8 Strings[];
  91. } ARM_TYPE19;
  92. typedef struct {
  93. SMBIOS_TABLE_TYPE32 Base;
  94. CHAR8 Strings[];
  95. } ARM_TYPE32;
  96. #pragma pack()
  97. enum {
  98. SMBIOS_HANDLE_A53_L1I = 0x1000,
  99. SMBIOS_HANDLE_A53_L1D,
  100. SMBIOS_HANDLE_A53_L2,
  101. SMBIOS_HANDLE_A53_L3,
  102. SMBIOS_HANDLE_MOTHERBOARD,
  103. SMBIOS_HANDLE_CHASSIS,
  104. SMBIOS_HANDLE_A53_CLUSTER,
  105. SMBIOS_HANDLE_MEMORY,
  106. };
  107. struct JEP106_MANUFACTURER_TABLE {
  108. UINT16 ManufacturerId;
  109. CHAR8 ManufacturerName[TYPE17_MANUFACTURER_NAME_LEN];
  110. };
  111. STATIC CONST struct JEP106_MANUFACTURER_TABLE Manufacturer[] = {
  112. {0x0010, "NEC\0"},
  113. {0x002C, "Micron Technology\0"},
  114. {0x003D, "Tektronix\0"},
  115. {0x0097, "Texas Instruments\0"},
  116. {0x00AD, "SK Hynix\0"},
  117. {0x00B3, "IDT\0"},
  118. {0x00C1, "Infineon\0"},
  119. {0x00CE, "Samsung\0"},
  120. {0x00DA, "Winbond Electronic\0"},
  121. {0x014F, "Transcend Information\0"},
  122. {0x0194, "Smart Modular\0"},
  123. {0x0198, "Kingston\0"},
  124. {0x02C8, "Agilent Technologies\0"},
  125. {0x02FE, "Elpida\0"},
  126. {0x030B, "Nanya Technology\0"},
  127. {0x0443, "Ramaxel Technology\0"},
  128. {0x04B3, "Inphi Corporation\0"},
  129. {0x04C8, "Powerchip Semiconductor\0"},
  130. {0x0551, "Qimonda\0"},
  131. {0x0557, "AENEON\0"},
  132. {0x059B, "Crucial Technology\0"},
  133. {0xFFFF, "Unknown\0"}
  134. };
  135. enum SPD4_SDRAM_CAPACITY {
  136. SPD4_SDRAM_CAPACITY_256MBIT = 0,
  137. SPD4_SDRAM_CAPACITY_512MBIT,
  138. SPD4_SDRAM_CAPACITY_1GBIT,
  139. SPD4_SDRAM_CAPACITY_2GBIT,
  140. SPD4_SDRAM_CAPACITY_4GBIT,
  141. SPD4_SDRAM_CAPACITY_8GBIT,
  142. SPD4_SDRAM_CAPACITY_16GBIT,
  143. SPD4_SDRAM_CAPACITY_32GBIT,
  144. SPD4_SDRAM_CAPACITY_12GBIT,
  145. SPD4_SDRAM_CAPACITY_24GBIT,
  146. SPD4_SDRAM_CAPACITY_INVALID = 0xFF,
  147. };
  148. struct SPD4_SDRAM_CAPACITY_TABLE {
  149. enum SPD4_SDRAM_CAPACITY Capacity;
  150. UINT16 SizeMbit;
  151. };
  152. STATIC CONST struct SPD4_SDRAM_CAPACITY_TABLE CapacityTable[] = {
  153. {SPD4_SDRAM_CAPACITY_256MBIT, 256 },
  154. {SPD4_SDRAM_CAPACITY_512MBIT, 512 },
  155. {SPD4_SDRAM_CAPACITY_1GBIT, (1 * 1024) },
  156. {SPD4_SDRAM_CAPACITY_2GBIT, (2 * 1024) },
  157. {SPD4_SDRAM_CAPACITY_4GBIT, (4 * 1024) },
  158. {SPD4_SDRAM_CAPACITY_8GBIT, (8 * 1024) },
  159. {SPD4_SDRAM_CAPACITY_16GBIT, (16 * 1024)},
  160. {SPD4_SDRAM_CAPACITY_32GBIT, (32 * 1024)},
  161. {SPD4_SDRAM_CAPACITY_12GBIT, (12 * 1024)},
  162. {SPD4_SDRAM_CAPACITY_24GBIT, (24 * 1024)},
  163. {SPD4_SDRAM_CAPACITY_INVALID, 0 },
  164. };
  165. // BIOS information (section 7.1)
  166. STATIC CONST ARM_TYPE0 mArmDefaultType0 = {
  167. {
  168. { // SMBIOS_STRUCTURE Hdr
  169. EFI_SMBIOS_TYPE_BIOS_INFORMATION,
  170. sizeof (SMBIOS_TABLE_TYPE0),
  171. SMBIOS_HANDLE_PI_RESERVED,
  172. },
  173. 1, // Vendor
  174. 2, // BiosVersion
  175. 0xE800, // BiosSegment
  176. 3, // BiosReleaseDate
  177. (FixedPcdGet32 (PcdFdSize) - 1) / SIZE_64KB, // BiosSize
  178. {
  179. 0, 0, 0, 0, 0, 0,
  180. 1, // PCI supported
  181. 0,
  182. 1, // PNP supported
  183. 0,
  184. 1, // BIOS upgradable
  185. 0, 0, 0,
  186. 1, // Boot from CD
  187. 1, // Selectable boot
  188. },
  189. { 0x3, 0xC, }, // BIOSCharacteristicsExtensionBytes[2]
  190. FixedPcdGet32 (PcdFirmwareRevision) >> 16, // SystemBiosMajorRelease
  191. FixedPcdGet32 (PcdFirmwareRevision) & 0xff, // SystemBiosMinorRelease
  192. 0xFF, // EmbeddedControllerFirmwareMajorRelease
  193. 0xFF // EmbeddedControllerFirmwareMinorRelease
  194. }, {
  195. FIRMWARE_VENDOR " \0"
  196. "build #" BUILD_NUMBER "\0"
  197. __DATE__ "\0"
  198. }
  199. };
  200. // System information (section 7.2)
  201. STATIC CONST ARM_TYPE1 mArmDefaultType1 = {
  202. {
  203. { // SMBIOS_STRUCTURE Hdr
  204. EFI_SMBIOS_TYPE_SYSTEM_INFORMATION,
  205. sizeof(SMBIOS_TABLE_TYPE1),
  206. SMBIOS_HANDLE_PI_RESERVED,
  207. },
  208. 1, // Manufacturer
  209. 2, // Product Name
  210. 0, // Version
  211. 0, // Serial
  212. { 0xbf4ec78a, 0x431d, 0x4eb6, { 0xbb, 0xc9, 0x0c, 0x06, 0x19, 0x05, 0xca, 0x13 }},
  213. 6, // Wakeup type
  214. 0, // SKU
  215. 0, // Family
  216. }, {
  217. "Socionext\0"
  218. "SynQuacer E-series DeveloperBox\0"
  219. }
  220. };
  221. // Enclosure
  222. STATIC CONST ARM_TYPE3 mArmDefaultType3 = {
  223. {
  224. { // SMBIOS_STRUCTURE Hdr
  225. EFI_SMBIOS_TYPE_SYSTEM_ENCLOSURE,
  226. sizeof (SMBIOS_TABLE_TYPE3),
  227. SMBIOS_HANDLE_CHASSIS,
  228. },
  229. 1, // Manufacturer
  230. 4, // Enclosure type (low profile desktop)
  231. 2, // Version
  232. 0, // Serial
  233. 0, // Asset tag
  234. ChassisStateUnknown, // boot chassis state
  235. ChassisStateSafe, // power supply state
  236. ChassisStateSafe, // thermal state
  237. ChassisSecurityStatusNone, // security state
  238. { 0, 0, 0, 0 }, // OEM defined
  239. 1, // 1U height
  240. 1, // number of power cords
  241. 0, // no contained elements
  242. }, {
  243. "InWin\0"
  244. "BK623\0"
  245. }
  246. };
  247. STATIC CONST ARM_TYPE4 mArmDefaultType4 = {
  248. {
  249. { // SMBIOS_STRUCTURE Hdr
  250. EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION,
  251. sizeof (SMBIOS_TABLE_TYPE4),
  252. SMBIOS_HANDLE_A53_CLUSTER,
  253. },
  254. 0, // socket type
  255. 3, // processor type CPU
  256. ProcessorFamilyIndicatorFamily2, // processor family, acquire from field2
  257. 1, // manufacturer
  258. {}, // processor id
  259. 2, // version
  260. { 0, 0, 0, 0, 0, 1 }, // voltage
  261. 0, // external clock
  262. 1000, // max speed
  263. 1000, // current speed
  264. 0x41, // status
  265. ProcessorUpgradeNone,
  266. SMBIOS_HANDLE_A53_L1D, // l1 cache handle
  267. SMBIOS_HANDLE_A53_L2, // l2 cache handle
  268. SMBIOS_HANDLE_A53_L3, // l3 cache handle
  269. 0, // serial not set
  270. 0, // asset not set
  271. 3, // part number
  272. 24, // core count in socket
  273. 24, // enabled core count in socket
  274. 24, // threads per socket
  275. 0xEC, // processor characteristics
  276. ProcessorFamilyARM, // ARM core
  277. }, {
  278. "ARM Ltd.\0"
  279. "Cortex-A53\0"
  280. "0xd03\0"
  281. }
  282. };
  283. STATIC CONST ARM_TYPE7 mArmDefaultType7_l1i = {
  284. {
  285. { // SMBIOS_STRUCTURE Hdr
  286. EFI_SMBIOS_TYPE_CACHE_INFORMATION,
  287. sizeof (SMBIOS_TABLE_TYPE7),
  288. SMBIOS_HANDLE_A53_L1I,
  289. },
  290. 1,
  291. 0x380, // L1 enabled
  292. 32, // 32k i cache max
  293. 32, // 32k installed
  294. { 0, 1 }, // SRAM type
  295. { 0, 1 }, // SRAM type
  296. 0, // unknown speed
  297. CacheErrorParity,
  298. CacheTypeInstruction,
  299. CacheAssociativity2Way,
  300. }, {
  301. "L1 Instruction\0"
  302. }
  303. };
  304. STATIC CONST ARM_TYPE7 mArmDefaultType7_l1d = {
  305. {
  306. { // SMBIOS_STRUCTURE Hdr
  307. EFI_SMBIOS_TYPE_CACHE_INFORMATION,
  308. sizeof (SMBIOS_TABLE_TYPE7),
  309. SMBIOS_HANDLE_A53_L1D,
  310. },
  311. 1,
  312. 0x180, // L1 enabled, WB
  313. 32, // 32k d cache max
  314. 32, // 32k installed
  315. { 0, 1 }, // SRAM type
  316. { 0, 1 }, // SRAM type
  317. 0, // unknown speed
  318. CacheErrorSingleBit,
  319. CacheTypeData,
  320. CacheAssociativity4Way,
  321. }, {
  322. "L1 Data\0"
  323. }
  324. };
  325. STATIC CONST ARM_TYPE7 mArmDefaultType7_l2 = {
  326. {
  327. { // SMBIOS_STRUCTURE Hdr
  328. EFI_SMBIOS_TYPE_CACHE_INFORMATION,
  329. sizeof (SMBIOS_TABLE_TYPE7),
  330. SMBIOS_HANDLE_A53_L2,
  331. },
  332. 1,
  333. 0x181, // L2 enabled, WB
  334. 256, // 256 KB cache max
  335. 256, // 256 KB installed
  336. { 0, 1 }, // SRAM type
  337. { 0, 1 }, // SRAM type
  338. 0, // unknown speed
  339. CacheErrorSingleBit,
  340. CacheTypeUnified,
  341. CacheAssociativity16Way,
  342. }, {
  343. "L2\0"
  344. }
  345. };
  346. STATIC CONST ARM_TYPE7 mArmDefaultType7_l3 = {
  347. {
  348. { // SMBIOS_STRUCTURE Hdr
  349. EFI_SMBIOS_TYPE_CACHE_INFORMATION,
  350. sizeof (SMBIOS_TABLE_TYPE7),
  351. SMBIOS_HANDLE_A53_L3,
  352. },
  353. 1,
  354. 0x182, // L3 enabled, WB
  355. 4096, // 4M cache max
  356. 4096, // 4M installed
  357. { 0, 1 }, // SRAM type
  358. { 0, 1 }, // SRAM type
  359. 0, // unknown speed
  360. CacheErrorSingleBit,
  361. CacheTypeUnified,
  362. CacheAssociativity16Way,
  363. }, {
  364. "L3\0"
  365. }
  366. };
  367. // Slots
  368. STATIC CONST ARM_TYPE9 mArmDefaultType9_0 = {
  369. {
  370. { // SMBIOS_STRUCTURE Hdr
  371. EFI_SMBIOS_TYPE_SYSTEM_SLOTS,
  372. sizeof (SMBIOS_TABLE_TYPE9),
  373. SMBIOS_HANDLE_PI_RESERVED,
  374. },
  375. 1,
  376. SlotTypePciExpressGen2X16,
  377. SlotDataBusWidth4X,
  378. SlotUsageUnknown,
  379. SlotLengthLong,
  380. 0,
  381. { 1 },
  382. {},
  383. 1,
  384. 0,
  385. 0,
  386. }, {
  387. "J-PCIEX16\0"
  388. }
  389. };
  390. STATIC CONST ARM_TYPE9 mArmDefaultType9_1 = {
  391. {
  392. { // SMBIOS_STRUCTURE Hdr
  393. EFI_SMBIOS_TYPE_SYSTEM_SLOTS,
  394. sizeof (SMBIOS_TABLE_TYPE9),
  395. SMBIOS_HANDLE_PI_RESERVED,
  396. },
  397. 1,
  398. SlotTypePciExpressGen2X1,
  399. SlotDataBusWidth1X,
  400. SlotUsageUnknown,
  401. SlotLengthShort,
  402. 0,
  403. { 1 },
  404. {},
  405. 0x0,
  406. 0x3,
  407. 0x0,
  408. }, {
  409. "J-PCIE1\0"
  410. }
  411. };
  412. STATIC CONST ARM_TYPE9 mArmDefaultType9_2 = {
  413. {
  414. { // SMBIOS_STRUCTURE Hdr
  415. EFI_SMBIOS_TYPE_SYSTEM_SLOTS,
  416. sizeof (SMBIOS_TABLE_TYPE9),
  417. SMBIOS_HANDLE_PI_RESERVED,
  418. },
  419. 1,
  420. SlotTypePciExpressGen2X1,
  421. SlotDataBusWidth1X,
  422. SlotUsageUnknown,
  423. SlotLengthShort,
  424. 0,
  425. { 1 },
  426. {},
  427. 0x0,
  428. 0x5,
  429. 0x0,
  430. }, {
  431. "J-PCIE2\0"
  432. }
  433. };
  434. // Memory array
  435. STATIC CONST ARM_TYPE16 mArmDefaultType16 = {
  436. {
  437. { // SMBIOS_STRUCTURE Hdr
  438. EFI_SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY,
  439. sizeof (SMBIOS_TABLE_TYPE16),
  440. SMBIOS_HANDLE_MEMORY,
  441. },
  442. MemoryArrayLocationSystemBoard, // on motherboard
  443. MemoryArrayUseSystemMemory, // system RAM
  444. MemoryErrorCorrectionNone,
  445. 0x4000000, // max 64 GB
  446. 0xFFFE, // No error information structure
  447. 4, // 4 DIMMs
  448. }, {
  449. "\0"
  450. }
  451. };
  452. // Memory array mapped address, this structure
  453. // is overridden by InstallMemoryStructure
  454. STATIC CONST ARM_TYPE19 mArmDefaultType19 = {
  455. {
  456. { // SMBIOS_STRUCTURE Hdr
  457. EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS,
  458. sizeof (SMBIOS_TABLE_TYPE19),
  459. SMBIOS_HANDLE_PI_RESERVED,
  460. },
  461. 0xFFFFFFFF, // invalid, look at extended addr field
  462. 0xFFFFFFFF,
  463. SMBIOS_HANDLE_MEMORY, // handle
  464. 1,
  465. 0x0,
  466. 0x0,
  467. }, {
  468. "\0"
  469. }
  470. };
  471. // System boot info
  472. STATIC CONST ARM_TYPE32 mArmDefaultType32 = {
  473. {
  474. { // SMBIOS_STRUCTURE Hdr
  475. EFI_SMBIOS_TYPE_SYSTEM_BOOT_INFORMATION,
  476. sizeof (SMBIOS_TABLE_TYPE32),
  477. SMBIOS_HANDLE_PI_RESERVED,
  478. },
  479. {},
  480. BootInformationStatusNoError,
  481. }, {
  482. "\0"
  483. }
  484. };
  485. STATIC SMBIOS_STRUCTURE * CONST FixedTables[] = {
  486. (SMBIOS_STRUCTURE *)&mArmDefaultType0.Base.Hdr,
  487. (SMBIOS_STRUCTURE *)&mArmDefaultType1.Base.Hdr,
  488. (SMBIOS_STRUCTURE *)&mArmDefaultType3.Base.Hdr,
  489. (SMBIOS_STRUCTURE *)&mArmDefaultType7_l1i.Base.Hdr,
  490. (SMBIOS_STRUCTURE *)&mArmDefaultType7_l1d.Base.Hdr,
  491. (SMBIOS_STRUCTURE *)&mArmDefaultType7_l2.Base.Hdr,
  492. (SMBIOS_STRUCTURE *)&mArmDefaultType7_l3.Base.Hdr,
  493. (SMBIOS_STRUCTURE *)&mArmDefaultType4.Base.Hdr,
  494. (SMBIOS_STRUCTURE *)&mArmDefaultType9_0.Base.Hdr,
  495. (SMBIOS_STRUCTURE *)&mArmDefaultType9_1.Base.Hdr,
  496. (SMBIOS_STRUCTURE *)&mArmDefaultType9_2.Base.Hdr,
  497. (SMBIOS_STRUCTURE *)&mArmDefaultType16.Base.Hdr,
  498. (SMBIOS_STRUCTURE *)&mArmDefaultType32.Base.Hdr,
  499. };
  500. STATIC
  501. UINT16
  502. GetPrimaryBusWidth (
  503. IN UINT8 SpdPrimaryBusWidth
  504. )
  505. {
  506. UINT16 PrimaryBusWidth;
  507. switch (SpdPrimaryBusWidth) {
  508. case SPD4_MEM_BUS_WIDTH_8BIT:
  509. PrimaryBusWidth = 8;
  510. break;
  511. case SPD4_MEM_BUS_WIDTH_16BIT:
  512. PrimaryBusWidth = 16;
  513. break;
  514. case SPD4_MEM_BUS_WIDTH_32BIT:
  515. PrimaryBusWidth = 32;
  516. break;
  517. case SPD4_MEM_BUS_WIDTH_64BIT:
  518. PrimaryBusWidth = 64;
  519. break;
  520. default:
  521. PrimaryBusWidth = 0xFFFF;
  522. ASSERT(FALSE);
  523. break;
  524. }
  525. return PrimaryBusWidth;
  526. }
  527. STATIC
  528. UINT16
  529. GetSdramDeviceWidth (
  530. IN UINT8 SpdSdramDeviceWidth
  531. )
  532. {
  533. UINT16 SdramDeviceWidth;
  534. switch (SpdSdramDeviceWidth) {
  535. case SPD4_MEM_DEV_WIDTH_4BIT:
  536. SdramDeviceWidth = 4;
  537. break;
  538. case SPD4_MEM_DEV_WIDTH_8BIT:
  539. SdramDeviceWidth = 8;
  540. break;
  541. case SPD4_MEM_DEV_WIDTH_16BIT:
  542. SdramDeviceWidth = 16;
  543. break;
  544. case SPD4_MEM_DEV_WIDTH_32BIT:
  545. SdramDeviceWidth = 32;
  546. break;
  547. default:
  548. SdramDeviceWidth = 0;
  549. ASSERT(FALSE);
  550. break;
  551. }
  552. return SdramDeviceWidth;
  553. }
  554. STATIC
  555. UINT16
  556. CalculateModuleDramCapacityMB (
  557. IN SPD4_BASE_SECTION *Spd4Base
  558. )
  559. {
  560. UINT32 SdramCapacityMbit;
  561. UINT16 PrimaryBusWidth;
  562. UINT8 SdramDeviceWidth;
  563. UINT8 SdramDeviceWidthShiftNum;
  564. UINT8 RankCount;
  565. UINT16 DramSize;
  566. UINT32 Index;
  567. SdramCapacityMbit = 0;
  568. for (Index = 0; CapacityTable[Index].Capacity != SPD4_SDRAM_CAPACITY_INVALID; Index++) {
  569. if (Spd4Base->SdramDensityAndBanks.Bits.Density == CapacityTable[Index].Capacity) {
  570. SdramCapacityMbit = CapacityTable[Index].SizeMbit;
  571. break;
  572. }
  573. }
  574. PrimaryBusWidth = GetPrimaryBusWidth (Spd4Base->ModuleMemoryBusWidth.Bits.PrimaryBusWidth);
  575. SdramDeviceWidth = GetSdramDeviceWidth (Spd4Base->ModuleOrganization.Bits.SdramDeviceWidth);
  576. RankCount = Spd4Base->ModuleOrganization.Bits.RankCount + 1;
  577. if ((SdramCapacityMbit == 0) || (PrimaryBusWidth == 0xFFFF) ||
  578. (SdramDeviceWidth == 0) || RankCount == 0) {
  579. DEBUG ((DEBUG_ERROR, "Calculate DRAM size failed. Cap:%d, BusWidth:%d, "
  580. "DevWidth:%d, Rank:%d\n", SdramCapacityMbit,
  581. PrimaryBusWidth, SdramDeviceWidth, RankCount));
  582. return 0;
  583. }
  584. //
  585. //Total[MB] = SDRAM Capacity[Mb] / 8 * Primary Bus Width /
  586. // SDRAM Width * Logical Ranks per DIMM
  587. //
  588. switch (SdramDeviceWidth) {
  589. case 4:
  590. SdramDeviceWidthShiftNum = 2;
  591. break;
  592. case 8:
  593. SdramDeviceWidthShiftNum = 3;
  594. break;
  595. case 16:
  596. SdramDeviceWidthShiftNum = 4;
  597. break;
  598. case 32:
  599. SdramDeviceWidthShiftNum = 5;
  600. break;
  601. default:
  602. SdramDeviceWidthShiftNum = 0;
  603. ASSERT(FALSE);
  604. break;
  605. };
  606. DramSize = (((SdramCapacityMbit >> 3) * PrimaryBusWidth) >> SdramDeviceWidthShiftNum) * RankCount;
  607. return DramSize;
  608. }
  609. STATIC
  610. VOID
  611. GetManufacturerName (
  612. IN UINT16 SpdManufacturerId,
  613. OUT CHAR8 *ManufacturerStr
  614. )
  615. {
  616. UINT16 ManufacturerId;
  617. UINT32 Index;
  618. RETURN_STATUS RetStatus;
  619. ManufacturerId = SwapBytes16 (SpdManufacturerId);
  620. ManufacturerId &= 0x7FFF; // ignore odd parity bit
  621. for (Index = 0; Manufacturer[Index].ManufacturerId != 0xFFFF; Index++) {
  622. if (ManufacturerId == Manufacturer[Index].ManufacturerId) {
  623. RetStatus = AsciiStrCpyS (ManufacturerStr, TYPE17_MANUFACTURER_NAME_LEN,
  624. Manufacturer[Index].ManufacturerName);
  625. ASSERT_RETURN_ERROR (RetStatus);
  626. return;
  627. }
  628. }
  629. RetStatus = AsciiStrCpyS (ManufacturerStr, TYPE17_MANUFACTURER_NAME_LEN,
  630. Manufacturer[Index].ManufacturerName);
  631. ASSERT_RETURN_ERROR (RetStatus);
  632. }
  633. STATIC
  634. BOOLEAN
  635. IsValidSPD (
  636. IN SPD4_BASE_SECTION *Spd4Base
  637. )
  638. {
  639. //
  640. // Developerbox only supports DDR4.
  641. // If the device type is not DDR4 SDRAM, the SPD is invalid
  642. //
  643. if (Spd4Base->DramDeviceType.Bits.Type == SPD4_DDR4_SDRAM_TYPE) {
  644. return TRUE;
  645. } else {
  646. return FALSE;
  647. }
  648. }
  649. STATIC
  650. EFI_STATUS
  651. InstallMemoryDeviceStructure (
  652. VOID
  653. )
  654. {
  655. EFI_SMBIOS_HANDLE SmbiosHandle;
  656. ARM_TYPE17 *Descriptor;
  657. SPD_DDR4 *Spd;
  658. UINT8 Slot;
  659. CHAR8 *StringPtr;
  660. CHAR8 DeviceLocatorStr[TYPE17_DEVICE_LOCATOR_LEN];
  661. CHAR8 BankLocatorStr[TYPE17_BANK_LOCATOR_LEN];
  662. CHAR8 ManufacturerStr[TYPE17_MANUFACTURER_NAME_LEN];
  663. CHAR8 SerialNumberStr[TYPE17_SERIAL_NUMBER_LEN];
  664. CHAR8 PartNumberStr[TYPE17_MODULE_PART_NUMBER_LEN];
  665. CHAR8 FirmwareVersionStr[TYPE17_FIRMWARE_VERSION_LEN];
  666. Descriptor = AllocateZeroPool(sizeof (ARM_TYPE17));
  667. if (Descriptor == NULL) {
  668. return EFI_OUT_OF_RESOURCES;
  669. }
  670. Spd = (SPD_DDR4 *) FixedPcdGet32 (PcdStoredSpdDDR4Address);
  671. for (Slot = 0; Slot < 4; Slot++, Spd++) {
  672. SetMem (Descriptor, sizeof (ARM_TYPE17), 0);
  673. // fill fixed parameters
  674. Descriptor->Base.Hdr.Type = EFI_SMBIOS_TYPE_MEMORY_DEVICE;
  675. Descriptor->Base.Hdr.Length = sizeof (SMBIOS_TABLE_TYPE17);
  676. Descriptor->Base.Hdr.Handle = SMBIOS_HANDLE_PI_RESERVED;
  677. Descriptor->Base.MemoryArrayHandle = SMBIOS_HANDLE_MEMORY;
  678. Descriptor->Base.MemoryErrorInformationHandle = 0xFFFE;
  679. Descriptor->Base.ExtendedSize = 0;
  680. Descriptor->Base.ExtendedSpeed = 0;
  681. Descriptor->Base.ExtendedConfiguredMemorySpeed = 0;
  682. Descriptor->Base.MemoryOperatingModeCapability.Bits.VolatileMemory = 1;
  683. Descriptor->Base.DeviceSet = 1;
  684. Descriptor->Base.MemoryType = MemoryTypeDdr4;
  685. Descriptor->Base.DeviceLocator = 1;
  686. Descriptor->Base.BankLocator = 2;
  687. AsciiSPrint (DeviceLocatorStr, sizeof(DeviceLocatorStr), "DIMM %d\0", (Slot + 1));
  688. AsciiSPrint (BankLocatorStr, sizeof(BankLocatorStr), "CHANNEL %d SLOT %d\0", (Slot / 2), (Slot % 2));
  689. StringPtr = Descriptor->Strings;
  690. AsciiStrnCpyS (StringPtr, TYPE17_DEVICE_LOCATOR_LEN, DeviceLocatorStr,
  691. TYPE17_DEVICE_LOCATOR_LEN - 1);
  692. StringPtr += AsciiStrSize (StringPtr);
  693. AsciiStrnCpyS (StringPtr, TYPE17_BANK_LOCATOR_LEN, BankLocatorStr,
  694. TYPE17_BANK_LOCATOR_LEN - 1);
  695. StringPtr += AsciiStrSize (StringPtr);
  696. if (IsValidSPD ((SPD4_BASE_SECTION *)Spd)) {
  697. Descriptor->Base.Manufacturer = 3;
  698. Descriptor->Base.SerialNumber = 4;
  699. Descriptor->Base.AssetTag = 5;
  700. Descriptor->Base.PartNumber = 6;
  701. Descriptor->Base.FirmwareVersion = 7;
  702. Descriptor->Base.TotalWidth = Descriptor->Base.DataWidth =
  703. GetPrimaryBusWidth (Spd->Base.ModuleMemoryBusWidth.Bits.PrimaryBusWidth);
  704. if (Spd->Base.ModuleMemoryBusWidth.Bits.BusWidthExtension) {
  705. if (Descriptor->Base.TotalWidth != 0xFFFF) {
  706. Descriptor->Base.TotalWidth += 8;
  707. }
  708. }
  709. Descriptor->Base.Size = CalculateModuleDramCapacityMB ((SPD4_BASE_SECTION *)Spd);
  710. switch (Spd->Base.ModuleType.Bits.ModuleType) {
  711. case SPD4_MEM_MODULE_TYPE_RDIMM:
  712. Descriptor->Base.FormFactor = 0x09;
  713. Descriptor->Base.TypeDetail.Registered = 1;
  714. Descriptor->Base.TypeDetail.Unbuffered = 0;
  715. break;
  716. case SPD4_MEM_MODULE_TYPE_UDIMM:
  717. Descriptor->Base.FormFactor = 0x09;
  718. Descriptor->Base.TypeDetail.Registered = 0;
  719. Descriptor->Base.TypeDetail.Unbuffered = 1;
  720. break;
  721. case SPD4_MEM_MODULE_TYPE_SODIMM:
  722. Descriptor->Base.FormFactor = 0x0D;
  723. Descriptor->Base.TypeDetail.Registered = 0;
  724. Descriptor->Base.TypeDetail.Unbuffered = 1;
  725. break;
  726. default:
  727. Descriptor->Base.FormFactor = 0x01;
  728. Descriptor->Base.TypeDetail.Registered = 0;
  729. Descriptor->Base.TypeDetail.Unbuffered = 0;
  730. break;
  731. }
  732. Descriptor->Base.Attributes = Spd->Base.ModuleOrganization.Bits.RankCount + 1;
  733. Descriptor->Base.Speed = 2133;
  734. Descriptor->Base.ConfiguredMemoryClockSpeed = 2133;
  735. Descriptor->Base.MinimumVoltage = 1200;
  736. Descriptor->Base.MaximumVoltage = 1200;
  737. Descriptor->Base.ConfiguredVoltage = 1200;
  738. Descriptor->Base.MemoryTechnology = MemoryTechnologyDram;
  739. Descriptor->Base.ModuleManufacturerID = Spd->ManufactureInfo.ModuleId.IdCode.Data;
  740. GetManufacturerName (Spd->ManufactureInfo.ModuleId.IdCode.Data, ManufacturerStr);
  741. AsciiSPrint (SerialNumberStr, TYPE17_SERIAL_NUMBER_LEN, "0x%08X\0",
  742. SwapBytes32(Spd->ManufactureInfo.ModuleId.SerialNumber.Data));
  743. //
  744. // Module part number is not null terminated string in SPD DDR4,
  745. // unused digits are coded as ASCII blanks(0x20).
  746. //
  747. ZeroMem(PartNumberStr, TYPE17_MODULE_PART_NUMBER_LEN);
  748. CopyMem (PartNumberStr,
  749. (CHAR8 *)Spd->ManufactureInfo.ModulePartNumber.ModulePartNumber,
  750. TYPE17_MODULE_PART_NUMBER_LEN - 1);
  751. AsciiSPrint (FirmwareVersionStr, sizeof(FirmwareVersionStr), "%d\0", FixedPcdGet32 (PcdFirmwareRevision));
  752. AsciiStrnCpyS (StringPtr, TYPE17_MANUFACTURER_NAME_LEN, ManufacturerStr,
  753. TYPE17_MANUFACTURER_NAME_LEN - 1);
  754. StringPtr += AsciiStrSize (StringPtr);
  755. AsciiStrnCpyS (StringPtr, TYPE17_SERIAL_NUMBER_LEN, SerialNumberStr,
  756. TYPE17_SERIAL_NUMBER_LEN - 1);
  757. StringPtr += AsciiStrSize (StringPtr);
  758. AsciiStrnCpyS (StringPtr, TYPE17_ASSETTAG_LEN, "-\0",
  759. TYPE17_ASSETTAG_LEN - 1);
  760. StringPtr += AsciiStrSize (StringPtr);
  761. AsciiStrnCpyS (StringPtr, TYPE17_MODULE_PART_NUMBER_LEN, PartNumberStr,
  762. TYPE17_MODULE_PART_NUMBER_LEN - 1);
  763. StringPtr += AsciiStrSize (StringPtr);
  764. AsciiStrnCpyS (StringPtr, TYPE17_FIRMWARE_VERSION_LEN, FirmwareVersionStr,
  765. TYPE17_FIRMWARE_VERSION_LEN - 1);
  766. } else {
  767. Descriptor->Base.TotalWidth = 0xFFFF;
  768. Descriptor->Base.DataWidth = 0xFFFF;
  769. Descriptor->Base.Size = 0;
  770. Descriptor->Base.FormFactor = 0x09;
  771. Descriptor->Base.DeviceSet = 1;
  772. Descriptor->Base.Attributes = 0;
  773. Descriptor->Base.Speed = 0;
  774. Descriptor->Base.ConfiguredMemoryClockSpeed = 0;
  775. Descriptor->Base.MinimumVoltage = 0;
  776. Descriptor->Base.MaximumVoltage = 0;
  777. Descriptor->Base.ConfiguredVoltage = 0;
  778. }
  779. SmbiosHandle = Descriptor->Base.Hdr.Handle;
  780. mSmbios->Add (mSmbios, NULL, &SmbiosHandle, &Descriptor->Base.Hdr);
  781. }
  782. FreePool (Descriptor);
  783. return EFI_SUCCESS;
  784. }
  785. STATIC
  786. EFI_STATUS
  787. InstallMemoryStructure (
  788. IN UINT64 StartingAddress,
  789. IN UINT64 RegionLength
  790. )
  791. {
  792. EFI_SMBIOS_HANDLE SmbiosHandle;
  793. CHAR8 Buffer[sizeof (mArmDefaultType19)];
  794. ARM_TYPE19 *Descriptor;
  795. CopyMem (Buffer, &mArmDefaultType19, sizeof (Buffer));
  796. Descriptor = (ARM_TYPE19 *)Buffer;
  797. Descriptor->Base.ExtendedStartingAddress = StartingAddress;
  798. Descriptor->Base.ExtendedEndingAddress = StartingAddress + RegionLength;
  799. SmbiosHandle = Descriptor->Base.Hdr.Handle;
  800. return mSmbios->Add (mSmbios, NULL, &SmbiosHandle, &Descriptor->Base.Hdr);
  801. }
  802. STATIC
  803. VOID
  804. InstallAllStructures (
  805. VOID
  806. )
  807. {
  808. EFI_STATUS Status;
  809. EFI_SMBIOS_HANDLE SmbiosHandle;
  810. UINTN Idx;
  811. EFI_PEI_HOB_POINTERS Hob;
  812. for (Idx = 0; Idx < ARRAY_SIZE (FixedTables); Idx++) {
  813. SmbiosHandle = FixedTables[Idx]->Handle;
  814. Status = mSmbios->Add (mSmbios, NULL, &SmbiosHandle, FixedTables[Idx]);
  815. if (EFI_ERROR(Status)) {
  816. DEBUG ((DEBUG_WARN, "%a: failed to add SMBIOS type %u table - %r\n",
  817. __FUNCTION__, FixedTables[Idx]->Type, Status));
  818. break;
  819. }
  820. }
  821. //
  822. // SPD_DDR4 data is stored in Non Secure SRAM by SCP-firmware.
  823. // Install Type17 record by analyzing SPD_DDR4 information.
  824. //
  825. Status = InstallMemoryDeviceStructure();
  826. if (EFI_ERROR(Status)) {
  827. DEBUG ((DEBUG_WARN, "%a: failed to add SMBIOS type 17 table - %r\n",
  828. __FUNCTION__, Status));
  829. }
  830. for (Hob.Raw = GetHobList ();
  831. !END_OF_HOB_LIST (Hob);
  832. Hob.Raw = GET_NEXT_HOB (Hob)) {
  833. if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR &&
  834. Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
  835. Status = InstallMemoryStructure (Hob.ResourceDescriptor->PhysicalStart,
  836. Hob.ResourceDescriptor->ResourceLength);
  837. if (EFI_ERROR(Status)) {
  838. DEBUG ((DEBUG_WARN, "%a: failed to add SMBIOS type 19 table - %r\n",
  839. __FUNCTION__, Status));
  840. break;
  841. }
  842. }
  843. }
  844. }
  845. /**
  846. Installs SMBIOS information for SynQuacer platform
  847. @param ImageHandle Module's image handle
  848. @param SystemTable Pointer of EFI_SYSTEM_TABLE
  849. @retval EFI_SUCCESS Smbios data successfully installed
  850. @retval Other Smbios data was not installed
  851. **/
  852. EFI_STATUS
  853. EFIAPI
  854. SmbiosPlatformDxeEntryPoint (
  855. IN EFI_HANDLE ImageHandle,
  856. IN EFI_SYSTEM_TABLE *SystemTable
  857. )
  858. {
  859. EFI_STATUS Status;
  860. Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL,
  861. (VOID **)&mSmbios);
  862. ASSERT_EFI_ERROR (Status);
  863. InstallAllStructures ();
  864. return EFI_SUCCESS;
  865. }