coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
mainboard.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <acpi/acpigen.h>
4 #include <arch/cpu.h>
5 #include <bootstate.h>
6 #include <cbmem.h>
7 #include <console/console.h>
8 #include <crc_byte.h>
9 #include <device/device.h>
10 #include <device/dram/spd.h>
12 #include <gpio.h>
13 #include <intelblocks/gpio.h>
14 #include <intelblocks/pmclib.h>
15 #include <smbios.h>
16 #include <soc/gpio.h>
17 #include <types.h>
18 
19 #include "eeprom.h"
20 #include "gpio.h"
21 
22 const char *mainboard_vbt_filename(void)
23 {
24  const struct eeprom_bmc_settings *bmc_cfg = get_bmc_settings();
25 
26  if (bmc_cfg && bmc_cfg->efp3_displayport)
27  return "vbt-avalanche.bin";
28  else
29  return "vbt.bin"; /* Poseidon */
30 }
31 
32 /* FIXME: Example code below */
33 
34 static void mb_configure_dp1_pwr(bool enable)
35 {
36  gpio_output(GPP_K3, enable);
37 }
38 
39 static void mb_configure_dp2_pwr(bool enable)
40 {
41  gpio_output(GPP_K4, enable);
42 }
43 
44 static void mb_configure_dp3_pwr(bool enable)
45 {
46  gpio_output(GPP_K5, enable);
47 }
48 
49 static void mb_hda_amp_enable(bool enable)
50 {
51  gpio_output(GPP_C19, enable);
52 }
53 
54 static void mb_usb31_rp1_pwr_enable(bool enable)
55 {
56  gpio_output(GPP_G0, enable);
57 }
58 
59 static void mb_usb31_rp2_pwr_enable(bool enable)
60 {
61  gpio_output(GPP_G1, enable);
62 }
63 
64 static void mb_usb31_fp_pwr_enable(bool enable)
65 {
66  gpio_output(GPP_G2, enable);
67 }
68 
69 static void mb_usb2_fp1_pwr_enable(bool enable)
70 {
71  gpio_output(GPP_G3, enable);
72 }
73 
74 static void mb_usb2_fp2_pwr_enable(bool enable)
75 {
76  gpio_output(GPP_G4, enable);
77 }
78 
79 static void copy_meminfo(const struct dimm_info *dimm, union eeprom_dimm_layout *l)
80 {
81  memset(l, 0, sizeof(*l));
82  if (dimm->dimm_size == 0)
83  return;
84 
85  strncpy(l->name, (char *)dimm->module_part_number, sizeof(l->name) - 1);
86  l->capacity_mib = dimm->dimm_size;
87  l->data_width_bits = 8 * (1 << (dimm->bus_width & 0x7));
88  l->bus_width_bits = l->data_width_bits + 8 * ((dimm->bus_width >> 3) & 0x3);
89  l->ranks = dimm->rank_per_dimm;
90  l->controller_id = 0;
91  strncpy(l->manufacturer, spd_manufacturer_name(dimm->mod_id),
92  sizeof(l->manufacturer) - 1);
93 }
94 
95 /*
96  * Collect board specific settings and update the CFG EEPROM if necessary.
97  * This allows the BMC webui to display the current hardware configuration.
98  */
99 static void update_board_layout(void)
100 {
101  struct eeprom_board_layout layout = {0};
102 
103  printk(BIOS_INFO, "MB: Collecting Board Layout information\n");
104 
105  /* Update CPU fields */
106  for (struct device *cpu = all_devices; cpu; cpu = cpu->next) {
107  if (cpu->path.type != DEVICE_PATH_APIC)
108  continue;
109  if (cpu->bus->dev->path.type != DEVICE_PATH_CPU_CLUSTER)
110  continue;
111  if (!cpu->enabled)
112  continue;
113  layout.cpu_count++;
114  if (!layout.cpu_name[0])
115  strcpy(layout.cpu_name, cpu->name);
116  }
117 
118  if (cpuid_get_max_func() >= 0x16)
119  layout.cpu_max_non_turbo_frequency = cpuid_eax(0x16);
120 
121  /* PCH */
122  strcpy(layout.pch_name, "Cannonlake-H C246");
123 
124  /* DRAM */
125  struct memory_info *meminfo = cbmem_find(CBMEM_ID_MEMINFO);
126  if (meminfo) {
127  const size_t meminfo_max = MIN(meminfo->dimm_cnt, ARRAY_SIZE(meminfo->dimm));
128  for (size_t i = 0; i < MIN(meminfo_max, ARRAY_SIZE(layout.dimm)); i++)
129  copy_meminfo(&meminfo->dimm[i], &layout.dimm[i]);
130  }
131 
132  /* Update CRC */
133  layout.signature = CRC(layout.raw_layout, sizeof(layout.raw_layout), crc32_byte);
134 
135  printk(BIOS_DEBUG, "BOARD LAYOUT:\n");
136  printk(BIOS_DEBUG, " Signature : 0x%x\n", layout.signature);
137  printk(BIOS_DEBUG, " CPU name : %s\n", layout.cpu_name);
138  printk(BIOS_DEBUG, " CPU count : %u\n", layout.cpu_count);
139  printk(BIOS_DEBUG, " CPU freq : %u\n", layout.cpu_max_non_turbo_frequency);
140  printk(BIOS_DEBUG, " PCH name : %s\n", layout.pch_name);
141  for (size_t i = 0; i < ARRAY_SIZE(layout.dimm); i++)
142  printk(BIOS_DEBUG, " DRAM SIZE : %u\n", layout.dimm[i].capacity_mib);
143 
144  if (write_board_settings(&layout))
145  printk(BIOS_ERR, "MB: Failed to update Board Layout\n");
146 }
147 
148 static void mainboard_init(void *chip_info)
149 {
150  const struct eeprom_board_settings *const board_cfg = get_board_settings();
151 
152  if (!board_cfg)
153  return;
154 
155  /* Enable internal speaker amplifier */
156  if (board_cfg->front_panel_audio == 2)
158  else
160 }
161 
162 static void mainboard_final(struct device *dev)
163 {
165 
166  const struct eeprom_board_settings *const board_cfg = get_board_settings();
167 
168  if (!board_cfg)
169  return;
170 
171  /* Encoding: 0 -> S0, 1 -> S5 */
172  const bool on = !board_cfg->power_state_after_g3;
173 
175 }
176 
177 #if CONFIG(HAVE_ACPI_TABLES)
178 static void mainboard_acpi_fill_ssdt(const struct device *dev)
179 {
180  const struct eeprom_board_settings *const board_cfg = get_board_settings();
181 
182  if (!board_cfg)
183  return;
184 
185  const unsigned int usb_power_gpios[] = { GPP_G0, GPP_G1, GPP_G2, GPP_G3, GPP_G4 };
186 
187  /* Function pointer to write STXS or CTXS according to EEPROM board setting */
188  int (*acpigen_write_soc_gpio_op)(unsigned int gpio_num);
189 
190  if (board_cfg->usb_powered_in_s5)
191  acpigen_write_soc_gpio_op = acpigen_soc_set_tx_gpio;
192  else
193  acpigen_write_soc_gpio_op = acpigen_soc_clear_tx_gpio;
194 
195  acpigen_write_method("\\_SB.MPTS", 1);
196  {
198  {
199  for (size_t i = 0; i < ARRAY_SIZE(usb_power_gpios); i++)
200  acpigen_write_soc_gpio_op(usb_power_gpios[i]);
201  }
202  acpigen_pop_len();
203  }
204  acpigen_pop_len();
205 }
206 #endif
207 
208 static void mainboard_enable(struct device *dev)
209 {
210  /* FIXME: Do runtime configuration once the board is production ready */
214 
220 
221  dev->ops->final = mainboard_final;
222 
223 #if CONFIG(HAVE_ACPI_TABLES)
224  dev->ops->acpi_fill_ssdt = mainboard_acpi_fill_ssdt;
225 #endif
226 }
227 
229  .init = mainboard_init,
230  .enable_dev = mainboard_enable,
231 };
232 
233 /* Must happen before MPinit */
234 static void mainboard_early(void *unused)
235 {
236  const struct eeprom_board_settings *const board_cfg = get_board_settings();
238 
239  if (board_cfg) {
240  /* Set Deep Sx */
241  config->deep_s5_enable_ac = board_cfg->deep_sx_enabled;
242  config->deep_s5_enable_dc = board_cfg->deep_sx_enabled;
243 
244  config->disable_vmx = board_cfg->vtx_disabled;
245  }
246 
247  if (check_signature(offsetof(struct eeprom_layout, supd), FSPS_UPD_SIGNATURE)) {
248  struct {
249  struct {
250  u8 TurboMode;
251  } FspsConfig;
252  } supd = {0};
253 
254  READ_EEPROM_FSP_S((&supd), FspsConfig.TurboMode);
255  config->cpu_turbo_disable = !supd.FspsConfig.TurboMode;
256  }
257 }
258 
struct chip_operations mainboard_ops
Definition: mainboard.c:19
void acpigen_pop_len(void)
Definition: acpigen.c:37
void acpigen_write_if_lequal_op_int(uint8_t op, uint64_t val)
Definition: acpigen.c:1472
void acpigen_write_method(const char *name, int nargs)
Definition: acpigen.c:758
#define GPP_C19
static unsigned int cpuid_get_max_func(void)
Definition: cpu.h:132
static unsigned int cpuid_eax(unsigned int op)
Definition: cpu.h:79
void * memset(void *dstpp, int c, size_t len)
Definition: memset.c:12
@ BS_PRE_DEVICE
Definition: bootstate.h:78
@ BS_ON_EXIT
Definition: bootstate.h:96
#define ARRAY_SIZE(a)
Definition: helpers.h:12
#define offsetof(TYPE, MEMBER)
Definition: helpers.h:84
#define MIN(a, b)
Definition: helpers.h:37
#define GPP_G1
Definition: gpio_soc_defs.h:89
#define GPP_G4
Definition: gpio_soc_defs.h:92
#define GPP_G2
Definition: gpio_soc_defs.h:90
#define GPP_G0
Definition: gpio_soc_defs.h:88
#define GPP_G3
Definition: gpio_soc_defs.h:91
void * cbmem_find(u32 id)
Definition: imd_cbmem.c:166
#define CBMEM_ID_MEMINFO
Definition: cbmem_id.h:33
#define printk(level,...)
Definition: stdlib.h:16
#define CRC(buf, size, crc_func)
Definition: crc_byte.h:37
uint32_t crc32_byte(uint32_t prev_crc, uint8_t data)
Definition: crc_byte.c:27
BOOT_STATE_INIT_ENTRY(BS_POST_DEVICE, BS_ON_EXIT, sch5545_ec_hwm_init, NULL)
const char * spd_manufacturer_name(const uint16_t mod_id)
Definition: spd.c:6
DEVTREE_CONST struct device *DEVTREE_CONST all_devices
Linked list of ALL devices.
Definition: device_const.c:13
bool write_board_settings(const struct eeprom_board_layout *new_layout)
Definition: eeprom.c:183
struct eeprom_bmc_settings * get_bmc_settings(void)
Definition: eeprom.c:73
struct eeprom_board_settings * get_board_settings(void)
Definition: eeprom.c:59
int check_signature(const size_t offset, const uint64_t signature)
Definition: eeprom.c:20
const char * mainboard_vbt_filename(void)
Definition: mainboard.c:177
#define GPP_K4
#define GPP_K5
#define GPP_K3
@ ARG0_OP
Definition: acpigen.h:89
int acpigen_soc_clear_tx_gpio(unsigned int gpio_num)
Definition: gpio.c:61
int acpigen_soc_set_tx_gpio(unsigned int gpio_num)
Definition: gpio.c:56
#define config_of_soc()
Definition: device.h:394
void gpio_output(gpio_t gpio, int value)
Definition: gpio.c:194
#define BIOS_INFO
BIOS_INFO - Expected events.
Definition: loglevel.h:113
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
enum board_config config
Definition: memory.c:448
#define READ_EEPROM_FSP_S(dest, opt_name)
Definition: eeprom.h:126
static const struct mb_cfg board_cfg
Definition: romstage.c:8
@ DEVICE_PATH_CPU_CLUSTER
Definition: path.h:14
@ DEVICE_PATH_APIC
Definition: path.h:12
static void mb_configure_dp1_pwr(bool enable)
Definition: mainboard.c:34
static void copy_meminfo(const struct dimm_info *dimm, union eeprom_dimm_layout *l)
Definition: mainboard.c:79
static void mb_hda_amp_enable(bool enable)
Definition: mainboard.c:49
static void mb_configure_dp3_pwr(bool enable)
Definition: mainboard.c:44
static void mb_usb2_fp1_pwr_enable(bool enable)
Definition: mainboard.c:69
static void mainboard_init(void *chip_info)
Definition: mainboard.c:148
static void mb_usb31_rp2_pwr_enable(bool enable)
Definition: mainboard.c:59
static void update_board_layout(void)
Definition: mainboard.c:99
static void mainboard_early(void *unused)
Definition: mainboard.c:234
static void mb_configure_dp2_pwr(bool enable)
Definition: mainboard.c:39
static void mb_usb2_fp2_pwr_enable(bool enable)
Definition: mainboard.c:74
static void mainboard_final(struct device *dev)
Definition: mainboard.c:162
static void mainboard_enable(struct device *dev)
Definition: mainboard.c:208
static void mb_usb31_rp1_pwr_enable(bool enable)
Definition: mainboard.c:54
static void mb_usb31_fp_pwr_enable(bool enable)
Definition: mainboard.c:64
void pmc_soc_set_afterg3_en(const bool on)
Definition: pmutil.c:263
#define NULL
Definition: stddef.h:19
uint8_t u8
Definition: stdint.h:45
char * strncpy(char *to, const char *from, int count)
Definition: string.c:72
char * strcpy(char *dst, const char *src)
Definition: string.c:92
void(* init)(void *chip_info)
Definition: device.h:25
void(* final)(struct device *dev)
Definition: device.h:43
Definition: device.h:107
struct device_operations * ops
Definition: device.h:143
DEVTREE_CONST struct device * next
Definition: device.h:113
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 rank_per_dimm
Definition: memory_info.h:35
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 mod_id
Definition: memory_info.h:52
uint32_t dimm_size
Definition: memory_info.h:23
uint8_t efp3_displayport
Definition: eeprom.h:67
uint32_t signature
Definition: eeprom.h:25
char pch_name[50]
Definition: eeprom.h:31
uint8_t cpu_count
Definition: eeprom.h:29
uint8_t raw_layout[617]
Definition: eeprom.h:34
union eeprom_dimm_layout dimm[4]
Definition: eeprom.h:32
char cpu_name[50]
Definition: eeprom.h:28
uint32_t cpu_max_non_turbo_frequency
Definition: eeprom.h:30
struct dimm_info dimm[DIMM_INFO_TOTAL]
Definition: memory_info.h:110
uint8_t dimm_cnt
Definition: memory_info.h:109