1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <console/console.h>
7 #include <soc/hob_mem.h>
10 #include <memory_info.h>
11 #include <soc/ramstage.h>
13 /* Save the DIMM information for SMBIOS table 17 */
14 void soc_save_dimm_info(void)
17 const CHANNEL_INFO
*channel_info
;
19 const DIMM_INFO
*dimm_info
;
22 struct memory_info
*mem_info
;
23 const FSP_SMBIOS_MEMORY_INFO
*memory_info_hob
;
25 /* Get the memory info HOB */
26 memory_info_hob
= soc_get_fsp_smbios_memory_info_hob();
28 if (memory_info_hob
== NULL
)
31 /* Display the data in the FSP_SMBIOS_MEMORY_INFO HOB */
32 if (CONFIG(DISPLAY_HOBS
))
33 soc_display_fsp_smbios_memory_info_hob(memory_info_hob
);
36 * Allocate CBMEM area for DIMM information used to populate SMBIOS
39 mem_info
= cbmem_add(CBMEM_ID_MEMINFO
, sizeof(*mem_info
));
40 printk(BIOS_DEBUG
, "CBMEM entry for DIMM info: %p\n", mem_info
);
43 memset(mem_info
, 0, sizeof(*mem_info
));
45 /* Describe the first N DIMMs in the system */
47 dimm_max
= ARRAY_SIZE(mem_info
->dimm
);
48 for (channel
= 0; channel
< memory_info_hob
->ChannelCount
; channel
++) {
49 if (index
>= dimm_max
)
51 channel_info
= &memory_info_hob
->ChannelInfo
[channel
];
52 for (dimm
= 0; dimm
< channel_info
->DimmCount
; dimm
++) {
53 if (index
>= dimm_max
)
55 dimm_info
= &channel_info
->DimmInfo
[dimm
];
57 /* Populate the DIMM information */
58 if (!dimm_info
->SizeInMb
)
61 mem_info
->dimm
[index
].dimm_size
=
63 mem_info
->dimm
[index
].ddr_type
=
64 memory_info_hob
->MemoryType
;
65 mem_info
->dimm
[index
].ddr_frequency
=
66 memory_info_hob
->MemoryFrequencyInMHz
;
67 mem_info
->dimm
[index
].channel_num
=
68 channel_info
->ChannelId
;
69 mem_info
->dimm
[index
].dimm_num
=
73 mem_info
->dimm
[index
].module_part_number
,
74 (char *)dimm_info
->ModulePartNum
, 18);
75 mem_info
->dimm
[index
].mod_id
=
77 switch (memory_info_hob
->DataWidth
) {
80 mem_info
->dimm
[index
].bus_width
=
85 mem_info
->dimm
[index
].bus_width
=
90 mem_info
->dimm
[index
].bus_width
=
95 mem_info
->dimm
[index
].bus_width
=
100 mem_info
->dimm
[index
].bus_width
=
101 MEMORY_BUS_WIDTH_128
;
105 /* Add any mainboard specific information */
106 mainboard_add_dimm_info(mem_info
, channel
, dimm
, index
);
110 mem_info
->dimm_cnt
= index
;
111 printk(BIOS_DEBUG
, "%d DIMMs found\n", mem_info
->dimm_cnt
);
114 /* Add any mainboard specific information */
115 __weak
void mainboard_add_dimm_info(struct memory_info
*mem_info
,
116 int channel
, int dimm
,
119 printk(BIOS_DEBUG
, "WEAK: %s/%s called\n", __FILE__
, __func__
);