coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
hob_mem.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <cbmem.h>
4 #include <console/console.h>
5 #include <string.h>
6 
7 #include <soc/hob_mem.h>
8 
9 #include <smbios.h>
10 #include <memory_info.h>
11 #include <soc/ramstage.h>
12 
13 /* Save the DIMM information for SMBIOS table 17 */
15 {
16  int channel;
17  const CHANNEL_INFO *channel_info;
18  int dimm;
19  const DIMM_INFO *dimm_info;
20  int dimm_max;
21  int index;
22  struct memory_info *mem_info;
23  const FSP_SMBIOS_MEMORY_INFO *memory_info_hob;
24 
25  /* Get the memory info HOB */
26  memory_info_hob = soc_get_fsp_smbios_memory_info_hob();
27 
28  if (memory_info_hob == NULL)
29  return;
30 
31  /* Display the data in the FSP_SMBIOS_MEMORY_INFO HOB */
32  if (CONFIG(DISPLAY_HOBS))
34 
35  /*
36  * Allocate CBMEM area for DIMM information used to populate SMBIOS
37  * table 17
38  */
39  mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(*mem_info));
40  printk(BIOS_DEBUG, "CBMEM entry for DIMM info: %p\n", mem_info);
41  if (mem_info == NULL)
42  return;
43  memset(mem_info, 0, sizeof(*mem_info));
44 
45  /* Describe the first N DIMMs in the system */
46  index = 0;
47  dimm_max = ARRAY_SIZE(mem_info->dimm);
48  for (channel = 0; channel < memory_info_hob->ChannelCount; channel++) {
49  if (index >= dimm_max)
50  break;
51  channel_info = &memory_info_hob->ChannelInfo[channel];
52  for (dimm = 0; dimm < channel_info->DimmCount; dimm++) {
53  if (index >= dimm_max)
54  break;
55  dimm_info = &channel_info->DimmInfo[dimm];
56 
57  /* Populate the DIMM information */
58  if (!dimm_info->SizeInMb)
59  continue;
60 
61  mem_info->dimm[index].dimm_size =
62  dimm_info->SizeInMb;
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 =
70  dimm_info->DimmId;
71 
72  strncpy((char *)
73  mem_info->dimm[index].module_part_number,
74  (char *)dimm_info->ModulePartNum, 18);
75  mem_info->dimm[index].mod_id =
76  dimm_info->MfgId;
77  switch (memory_info_hob->DataWidth) {
78  default:
79  case 8:
80  mem_info->dimm[index].bus_width =
82  break;
83 
84  case 16:
85  mem_info->dimm[index].bus_width =
87  break;
88 
89  case 32:
90  mem_info->dimm[index].bus_width =
92  break;
93 
94  case 64:
95  mem_info->dimm[index].bus_width =
97  break;
98 
99  case 128:
100  mem_info->dimm[index].bus_width =
102  break;
103  }
104 
105  /* Add any mainboard specific information */
106  mainboard_add_dimm_info(mem_info, channel, dimm, index);
107  index++;
108  }
109  }
110  mem_info->dimm_cnt = index;
111  printk(BIOS_DEBUG, "%d DIMMs found\n", mem_info->dimm_cnt);
112 }
113 
114 /* Add any mainboard specific information */
115 __attribute__((weak)) void mainboard_add_dimm_info(struct memory_info *mem_info,
116  int channel, int dimm,
117  int index)
118 {
119  printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
120 }
void * memset(void *dstpp, int c, size_t len)
Definition: memset.c:12
#define ARRAY_SIZE(a)
Definition: helpers.h:12
void * cbmem_add(u32 id, u64 size)
Definition: imd_cbmem.c:144
#define CBMEM_ID_MEMINFO
Definition: cbmem_id.h:33
#define printk(level,...)
Definition: stdlib.h:16
@ CONFIG
Definition: dsi_common.h:201
void soc_save_dimm_info(void)
Definition: hob_mem.c:14
void mainboard_add_dimm_info(struct memory_info *mem_info, int channel, int dimm, int index)
Definition: hob_mem.c:115
static const FSP_SMBIOS_MEMORY_INFO * soc_get_fsp_smbios_memory_info_hob(void)
Definition: hob_mem.h:21
@ MEMORY_BUS_WIDTH_32
Definition: smbios.h:136
@ MEMORY_BUS_WIDTH_128
Definition: smbios.h:138
@ MEMORY_BUS_WIDTH_64
Definition: smbios.h:137
@ MEMORY_BUS_WIDTH_16
Definition: smbios.h:135
@ MEMORY_BUS_WIDTH_8
Definition: smbios.h:134
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
struct dimm_info_st dimm_info
void soc_display_fsp_smbios_memory_info_hob(const FSP_SMBIOS_MEMORY_INFO *memory_info_hob)
Definition: hob_display.c:60
#define NULL
Definition: stddef.h:19
char * strncpy(char *to, const char *from, int count)
Definition: string.c:72
If this table is filled and put in CBMEM, then these info in CBMEM will be used to generate smbios ty...
Definition: memory_info.h:19
uint8_t channel_num
Definition: memory_info.h:36
uint8_t dimm_num
Definition: memory_info.h:37
uint8_t bus_width
Definition: memory_info.h:80
uint8_t module_part_number[DIMM_INFO_PART_NUMBER_SIZE]
Definition: memory_info.h:48
uint16_t ddr_type
Definition: memory_info.h:29
uint16_t ddr_frequency
Definition: memory_info.h:34
uint16_t mod_id
Definition: memory_info.h:52
uint32_t dimm_size
Definition: memory_info.h:23
struct dimm_info dimm[DIMM_INFO_TOTAL]
Definition: memory_info.h:110
uint8_t dimm_cnt
Definition: memory_info.h:109