coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
romstage.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <arch/romstage.h>
4 #include <cbmem.h>
5 #include <console/console.h>
6 #include <fsp/util.h>
7 #include <intelblocks/cfg.h>
8 #include <intelblocks/cse.h>
9 #include <intelblocks/pmclib.h>
10 #include <intelblocks/smbus.h>
11 #include <memory_info.h>
13 #include <soc/iomap.h>
14 #include <soc/pci_devs.h>
15 #include <soc/pm.h>
16 #include <soc/romstage.h>
17 #include <string.h>
18 
19 #include "../chip.h"
20 
21 #define FSP_SMBIOS_MEMORY_INFO_GUID \
22 { \
23  0xd4, 0x71, 0x20, 0x9b, 0x54, 0xb0, 0x0c, 0x4e, \
24  0x8d, 0x09, 0x11, 0xcf, 0x8b, 0x9f, 0x03, 0x23 \
25 }
26 
27 /* Save the DIMM information for SMBIOS table 17 */
28 static void save_dimm_info(void)
29 {
30  int channel, dimm, dimm_max, index;
31  size_t hob_size;
32  const CONTROLLER_INFO *ctrlr_info;
33  const CHANNEL_INFO *channel_info;
34  const DIMM_INFO *src_dimm;
35  struct dimm_info *dest_dimm;
36  struct memory_info *mem_info;
37  const MEMORY_INFO_DATA_HOB *memory_info_hob;
40  const char *dram_part_num;
41  size_t dram_part_num_len = 0;
42  bool part_num_overridden = false;
43 
44  /* Locate the memory info HOB, presence validated by raminit */
45  memory_info_hob = fsp_find_extension_hob_by_guid(
47  &hob_size);
48  if (memory_info_hob == NULL || hob_size == 0) {
49  printk(BIOS_ERR, "SMBIOS MEMORY_INFO_DATA_HOB not found\n");
50  return;
51  }
52 
53  /*
54  * Allocate CBMEM area for DIMM information used to populate SMBIOS
55  * table 17
56  */
57  mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(*mem_info));
58  if (mem_info == NULL) {
59  printk(BIOS_ERR, "CBMEM entry for DIMM info missing\n");
60  return;
61  }
62  memset(mem_info, 0, sizeof(*mem_info));
63 
64  /* Allow mainboard to override DRAM part number. */
65  dram_part_num = mainboard_get_dram_part_num();
66  if (dram_part_num) {
67  dram_part_num_len = strlen(dram_part_num);
68  part_num_overridden = true;
69  }
70 
71  /* Describe the first N DIMMs in the system */
72  index = 0;
73  dimm_max = ARRAY_SIZE(mem_info->dimm);
74  ctrlr_info = &memory_info_hob->Controller[0];
75  for (channel = 0; channel < MAX_CH && index < dimm_max; channel++) {
76  channel_info = &ctrlr_info->ChannelInfo[channel];
77  if (channel_info->Status != CHANNEL_PRESENT)
78  continue;
79  for (dimm = 0; dimm < MAX_DIMM && index < dimm_max; dimm++) {
80  src_dimm = &channel_info->DimmInfo[dimm];
81  dest_dimm = &mem_info->dimm[index];
82 
83  if (src_dimm->Status != DIMM_PRESENT)
84  continue;
85 
86  if (!part_num_overridden) {
87  dram_part_num_len =
88  sizeof(src_dimm->ModulePartNum);
89  dram_part_num = (const char *)
90  &src_dimm->ModulePartNum[0];
91  }
92 
93  u8 memProfNum = memory_info_hob->MemoryProfile;
94 
95  /* Populate the DIMM information */
96  dimm_info_fill(dest_dimm,
97  src_dimm->DimmCapacity,
98  memory_info_hob->MemoryType,
99  memory_info_hob->ConfiguredMemoryClockSpeed,
100  src_dimm->RankInDimm,
101  channel_info->ChannelId,
102  src_dimm->DimmId,
103  dram_part_num,
104  dram_part_num_len,
105  src_dimm->SpdSave + SPD_SAVE_OFFSET_SERIAL,
106  memory_info_hob->DataWidth,
107  memory_info_hob->VddVoltage[memProfNum],
108  memory_info_hob->EccSupport,
109  src_dimm->MfgId,
110  src_dimm->SpdModuleType);
111  index++;
112  }
113  }
114  mem_info->dimm_cnt = index;
115  printk(BIOS_DEBUG, "%d DIMMs found\n", mem_info->dimm_cnt);
116 }
117 
119 {
120  bool s3wake;
122 
123  /* Program MCHBAR, DMIBAR, GDXBAR and EDRAMBAR */
125  /* Program SMBus base address and enable it */
127  /* initialize Heci interface */
129 
130  s3wake = pmc_fill_power_state(ps) == ACPI_S3;
131  fsp_memory_init(s3wake);
132  pmc_set_disb();
133  if (!s3wake) {
134  /*
135  * cse_fw_sync() must be called after DRAM initialization as
136  * HMRFPO_ENABLE HECI command (which is used by cse_fw_sync())
137  * is expected to be executed after DRAM initialization.
138  */
139 
140  if (CONFIG(SOC_INTEL_CSE_LITE_SKU))
141  cse_fw_sync();
142 
143  save_dimm_info();
144  }
145 }
void pmc_set_disb(void)
Definition: pmutil.c:121
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
void heci_init(uintptr_t tempbar)
Definition: cse.c:92
#define printk(level,...)
Definition: stdlib.h:16
void cse_fw_sync(void)
Definition: cse_lite.c:1042
static const uint8_t smbios_memory_info_guid[16]
Definition: hob_display.c:55
@ CONFIG
Definition: dsi_common.h:201
void fsp_memory_init(bool s3wake)
Definition: memory_init.c:350
const void * fsp_find_extension_hob_by_guid(const uint8_t *guid, size_t *size)
@ ACPI_S3
Definition: acpi.h:1383
#define HECI1_BASE_ADDRESS
Definition: iomap.h:77
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
void mainboard_romstage_entry(void)
Definition: romstage.c:6
const char * mainboard_get_dram_part_num(void)
Definition: spd_bin.c:21
void systemagent_early_init(void)
Definition: early_init.c:151
static void save_dimm_info(void)
Definition: romstage.c:28
#define FSP_SMBIOS_MEMORY_INFO_GUID
Definition: romstage.c:21
int pmc_fill_power_state(struct chipset_power_state *ps)
Definition: pmclib.c:437
struct chipset_power_state * pmc_get_power_state(void)
Definition: pmclib.c:58
void smbus_common_init(void)
Definition: smbus_early.c:11
void dimm_info_fill(struct dimm_info *dimm, u32 dimm_capacity, u8 ddr_type, u32 frequency, u8 rank_per_dimm, u8 channel_id, u8 dimm_id, const char *module_part_num, size_t module_part_number_size, const u8 *module_serial_num, u16 data_width, u32 vdd_voltage, bool ecc_support, u16 mod_id, u8 mod_type)
Definition: smbios.c:13
#define SPD_SAVE_OFFSET_SERIAL
Definition: smbios.h:10
@ CHANNEL_PRESENT
Definition: romstage.c:30
#define NULL
Definition: stddef.h:19
uint8_t u8
Definition: stdint.h:45
unsigned char uint8_t
Definition: stdint.h:8
size_t strlen(const char *src)
Definition: string.c:42
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
struct dimm_info dimm[DIMM_INFO_TOTAL]
Definition: memory_info.h:110
uint8_t dimm_cnt
Definition: memory_info.h:109