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 <baseboard/variants.h>
4 #include <bootstate.h>
5 #include <console/console.h>
6 #include <device/device.h>
7 #include <device/pci_def.h>
8 #include <device/pci_ops.h>
9 #include <device/pci_ids.h>
10 #include <hwilib.h>
11 #include <i210.h>
12 #include <soc/gpio.h>
13 #include <soc/ramstage.h>
14 #include <string.h>
15 #include <timer.h>
16 #include <timestamp.h>
17 
18 #define MAX_PATH_DEPTH 12
19 #define MAX_NUM_MAPPINGS 10
20 
21 /** \brief This function can decide if a given MAC address is valid or not.
22  * Currently, addresses filled with 0xff or 0x00 are not valid.
23  * @param mac Buffer to the MAC address to check
24  * @return 0 if address is not valid, otherwise 1
25  */
27 {
28  for (size_t i = 0; i < MAC_ADDR_LEN; i++) {
29  if (mac[i] != 0x00 && mac[i] != 0xff)
30  return 1;
31  if (mac[i] != mac[0])
32  return 1;
33  }
34  return 0;
35 }
36 
37 /** \brief This function will search for a MAC address which can be assigned
38  * to a MACPHY.
39  * @param dev pointer to PCI device
40  * @param mac buffer where to store the MAC address
41  * @return cb_err CB_ERR or CB_SUCCESS
42  */
44 {
45  struct bus *parent = dev->bus;
46  uint8_t buf[16], mapping[16], i = 0, chain_len = 0;
47 
48  memset(buf, 0, sizeof(buf));
49  memset(mapping, 0, sizeof(mapping));
50 
51  /* The first entry in the tree is the device itself. */
52  buf[0] = dev->path.pci.devfn;
53  chain_len = 1;
54  for (i = 1; i < MAX_PATH_DEPTH && parent->dev->bus->subordinate; i++) {
55  buf[i] = parent->dev->path.pci.devfn;
56  chain_len++;
57  parent = parent->dev->bus;
58  }
59  if (i == MAX_PATH_DEPTH) {
60  /* The path is deeper than MAX_PATH_DEPTH devices, error. */
61  printk(BIOS_ERR, "Too many bridges for %s\n", dev_path(dev));
62  return CB_ERR;
63  }
64  /*
65  * Now construct the mapping based on the device chain starting from
66  * root bridge device to the device itself.
67  */
68  mapping[0] = 1;
69  mapping[1] = chain_len;
70  for (i = 0; i < chain_len; i++)
71  mapping[i + 4] = buf[chain_len - i - 1];
72 
73  /* Open main hwinfo block */
74  if (hwilib_find_blocks("hwinfo.hex") != CB_SUCCESS)
75  return CB_ERR;
76  /* Now try to find a valid MAC address in hwinfo for this mapping. */
77  for (i = 0; i < MAX_NUM_MAPPINGS; i++) {
78  if (hwilib_get_field(XMac1Mapping + i, buf, 16) != 16)
79  continue;
80  if (memcmp(buf, mapping, chain_len + 4))
81  continue;
82  /* There is a matching mapping available, get MAC address. */
83  if (hwilib_get_field(XMac1 + i, mac, MAC_ADDR_LEN) == MAC_ADDR_LEN) {
84  if (is_mac_adr_valid(mac))
85  return CB_SUCCESS;
86  }
87  return CB_ERR;
88  }
89  /* No MAC address found for */
90  return CB_ERR;
91 }
92 
93 static void wait_for_legacy_dev(void *unused)
94 {
95  uint32_t legacy_delay, us_since_boot;
96  struct stopwatch sw;
97 
98  /* Open main hwinfo block. */
99  if (hwilib_find_blocks("hwinfo.hex") != CB_SUCCESS)
100  return;
101 
102  /* Get legacy delay parameter from hwinfo. */
103  if (hwilib_get_field(LegacyDelay, (uint8_t *) &legacy_delay,
104  sizeof(legacy_delay)) != sizeof(legacy_delay))
105  return;
106 
107  us_since_boot = get_us_since_boot();
108  /* No need to wait if the time since boot is already long enough.*/
109  if (us_since_boot > legacy_delay)
110  return;
111  stopwatch_init_msecs_expire(&sw, (legacy_delay - us_since_boot) / 1000);
112  printk(BIOS_NOTICE, "Wait remaining %d of %d us for legacy devices...",
113  legacy_delay - us_since_boot, legacy_delay);
115  printk(BIOS_NOTICE, "done!\n");
116 }
117 
119 {
120  /* Disable CPU power states (C-states) */
121  params->Cx = 0;
122 
123  /* Set maximum package C-state to PkgC0C1 */
124  params->PkgCStateLimit = 0;
125 
126  /* Disable P-States */
127  params->MaxRatio = 0;
128 
129  /* Disable PMC low power modes */
130  params->PmcLpmS0ixSubStateEnableMask = 0;
131  params->PmcV1p05PhyExtFetControlEn = 0;
132  params->PmcV1p05IsExtFetControlEn = 0;
133 }
134 
135 static void mainboard_init(void *chip_info)
136 {
137  const struct pad_config *pads;
138  size_t num;
139 
140  pads = variant_gpio_table(&num);
141  gpio_configure_pads(pads, num);
142 }
143 
144 static void mainboard_final(void *chip_info)
145 {
146  struct device *dev;
147 
148  /* Do board specific things */
150 
151  if (CONFIG(PCI_ALLOW_BUS_MASTER_ANY_DEVICE)) {
152  /* Set Master Enable for on-board PCI devices if allowed. */
153  dev = dev_find_device(PCI_VID_SIEMENS, 0x403e, 0);
154  if (dev)
156 
157  dev = dev_find_device(PCI_VID_SIEMENS, 0x403f, 0);
158  if (dev)
160  }
161 }
162 
163 /* The following function performs board specific things. */
165 {
166 }
167 
169  .init = mainboard_init,
170  .final = mainboard_final
171 };
172 
void mainboard_silicon_init_params(FSP_SIL_UPD *params)
Definition: mainboard.c:6
struct chip_operations mainboard_ops
Definition: mainboard.c:19
void * memset(void *dstpp, int c, size_t len)
Definition: memset.c:12
static struct sdram_info params
Definition: sdram_configs.c:83
@ BS_DEV_ENUMERATE
Definition: bootstate.h:80
@ BS_ON_ENTRY
Definition: bootstate.h:95
cb_err
coreboot error codes
Definition: cb_err.h:15
@ CB_ERR
Generic error code.
Definition: cb_err.h:17
@ CB_SUCCESS
Call completed successfully.
Definition: cb_err.h:16
#define printk(level,...)
Definition: stdlib.h:16
BOOT_STATE_INIT_ENTRY(BS_POST_DEVICE, BS_ON_EXIT, sch5545_ec_hwm_init, NULL)
struct device * dev_find_device(u16 vendor, u16 device, struct device *from)
Find a device of a given vendor and type.
Definition: device_util.c:42
const char * dev_path(const struct device *dev)
Definition: device_util.c:149
@ CONFIG
Definition: dsi_common.h:201
#define FSP_S_CONFIG
Definition: fsp_upd.h:9
#define MAC_ADDR_LEN
Definition: i210.h:30
static __always_inline void pci_or_config16(const struct device *dev, u16 reg, u16 ormask)
Definition: pci_ops.h:180
static void stopwatch_wait_until_expired(struct stopwatch *sw)
Definition: timer.h:161
static void stopwatch_init_msecs_expire(struct stopwatch *sw, long ms)
Definition: timer.h:133
uint32_t get_us_since_boot(void)
Definition: timestamp.c:273
#define BIOS_NOTICE
BIOS_NOTICE - Unexpected but relatively insignificant.
Definition: loglevel.h:100
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
static uint8_t * buf
Definition: uart.c:7
const struct pad_config *__weak variant_gpio_table(size_t *num)
Definition: gpio.c:406
#define PCI_COMMAND_MASTER
Definition: pci_def.h:13
#define PCI_COMMAND
Definition: pci_def.h:10
#define PCI_VID_SIEMENS
Definition: pci_ids.h:1491
const struct smm_save_state_ops *legacy_ops __weak
Definition: save_state.c:8
enum cb_err mainboard_get_mac_address(struct device *dev, uint8_t mac[MAC_ADDR_LEN])
This function will search for a MAC address which can be assigned to a MACPHY.
Definition: mainboard.c:56
void __weak variant_mainboard_final(void)
Definition: mainboard.c:245
static void wait_for_legacy_dev(void *unused)
Definition: mainboard.c:93
static void mainboard_init(void *chip_info)
Definition: mainboard.c:135
#define MAX_NUM_MAPPINGS
Definition: mainboard.c:19
#define MAX_PATH_DEPTH
Definition: mainboard.c:18
static void mainboard_final(void *chip_info)
Definition: mainboard.c:144
static uint8_t is_mac_adr_valid(uint8_t mac[MAC_ADDR_LEN])
This function can decide if a given MAC address is valid or not.
Definition: mainboard.c:26
void gpio_configure_pads(const struct soc_amd_gpio *gpio_list_ptr, size_t size)
program a particular set of GPIO
Definition: gpio.c:307
#define NULL
Definition: stddef.h:19
unsigned int uint32_t
Definition: stdint.h:14
unsigned char uint8_t
Definition: stdint.h:8
int memcmp(const void *s1, const void *s2, size_t n)
Definition: memcmp.c:3
Definition: device.h:76
uint16_t subordinate
Definition: device.h:85
DEVTREE_CONST struct device * dev
Definition: device.h:78
void(* init)(void *chip_info)
Definition: device.h:25
struct pci_path pci
Definition: path.h:116
Definition: device.h:107
struct device_path path
Definition: device.h:115
DEVTREE_CONST struct bus * bus
Definition: device.h:108
unsigned int devfn
Definition: path.h:54