1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <console/console.h>
6 #include <memory_info.h>
7 #include <soc/intel/common/smbios.h>
8 #include <soc/meminit.h>
11 #define FSP_SMBIOS_MEMORY_INFO_GUID \
13 0x8c, 0x10, 0xa1, 0x01, 0xee, 0x9d, 0x84, 0x49, \
14 0x88, 0xc3, 0xee, 0xe8, 0xc4, 0x9e, 0xfb, 0x89 \
17 void save_lpddr4_dimm_info_part_num(const char *dram_part_num
)
19 int channel
, dimm
, dimm_max
, index
;
21 const DIMM_INFO
*src_dimm
;
22 struct dimm_info
*dest_dimm
;
23 struct memory_info
*mem_info
;
24 const CHANNEL_INFO
*channel_info
;
25 const FSP_SMBIOS_MEMORY_INFO
*memory_info_hob
;
26 const uint8_t smbios_memory_info_guid
[16] =
27 FSP_SMBIOS_MEMORY_INFO_GUID
;
30 dram_part_num
= "Unknown";
32 /* Locate the memory info HOB */
33 memory_info_hob
= fsp_find_extension_hob_by_guid(
34 smbios_memory_info_guid
,
37 if (memory_info_hob
== NULL
|| hob_size
== 0) {
38 printk(BIOS_ERR
, "SMBIOS memory info HOB is missing\n");
43 * Allocate CBMEM area for DIMM information used to populate SMBIOS
46 mem_info
= cbmem_add(CBMEM_ID_MEMINFO
, sizeof(*mem_info
));
47 if (mem_info
== NULL
) {
48 printk(BIOS_ERR
, "CBMEM entry for DIMM info missing\n");
51 memset(mem_info
, 0, sizeof(*mem_info
));
53 /* Describe the first N DIMMs in the system */
55 dimm_max
= ARRAY_SIZE(mem_info
->dimm
);
57 for (channel
= 0; channel
< memory_info_hob
->ChannelCount
; channel
++) {
58 if (index
>= dimm_max
)
60 channel_info
= &memory_info_hob
->ChannelInfo
[channel
];
61 for (dimm
= 0; dimm
< channel_info
->DimmCount
; dimm
++) {
62 if (index
>= dimm_max
)
64 src_dimm
= &channel_info
->DimmInfo
[dimm
];
65 dest_dimm
= &mem_info
->dimm
[index
];
67 if (!src_dimm
->SizeInMb
)
70 /* Populate the DIMM information */
71 dimm_info_fill(dest_dimm
,
73 memory_info_hob
->MemoryType
,
74 memory_info_hob
->MemoryFrequencyInMHz
,
76 channel_info
->ChannelId
,
79 strlen(dram_part_num
),
80 NULL
, /* SPD not available */
81 memory_info_hob
->DataWidth
,
91 mem_info
->dimm_cnt
= index
;
92 printk(BIOS_DEBUG
, "%d DIMMs found\n", mem_info
->dimm_cnt
);
95 void save_lpddr4_dimm_info(const struct lpddr4_cfg
*lp4cfg
, size_t mem_sku
)
97 const char *part_num
= NULL
;
99 if (mem_sku
>= lp4cfg
->num_skus
) {
100 printk(BIOS_ERR
, "Too few LPDDR4 SKUs: 0x%zx/0x%zx\n",
101 mem_sku
, lp4cfg
->num_skus
);
103 part_num
= lp4cfg
->skus
[mem_sku
].part_num
;
106 save_lpddr4_dimm_info_part_num(part_num
);