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 <amdblocks/acpimmio.h>
4 #include <device/mmio.h>
5 #include <device/pci_ops.h>
6 #include <console/console.h>
7 #include <device/device.h>
8 #include <device/pci_def.h>
9 #include <gpio.h>
17 #include <smbios.h>
18 #include <string.h>
19 #include <AGESA.h>
20 #include "gpio_ftns.h"
21 
22 #define SPD_SIZE 128
23 #define PM_RTC_CONTROL 0x56
24 #define PM_S_STATE_CONTROL 0xBA
25 
26 /***********************************************************
27  * These arrays set up the FCH PCI_INTR registers 0xC00/0xC01.
28  * This table is responsible for physically routing the PIC and
29  * IOAPIC IRQs to the different PCI devices on the system. It
30  * is read and written via registers 0xC00/0xC01 as an
31  * Index/Data pair. These values are chipset and mainboard
32  * dependent and should be updated accordingly.
33  *
34  * These values are used by the PCI configuration space,
35  * MP Tables. TODO: Make ACPI use these values too.
36  */
38  [0 ... FCH_INT_TABLE_SIZE-1] = 0x1F,
39  /* INTA# - INTH# */
40  [0x00] = 0x03,0x03,0x05,0x07,0x0B,0x0A,0x1F,0x1F,
41  /* Misc-nil,0,1,2, INT from Serial irq */
42  [0x08] = 0xFA,0xF1,0x00,0x00,0x1F,0x1F,0x1F,0x1F,
43  /* SCI, SMBUS0, ASF, HDA, FC, RSVD, PerMon, SD */
44  [0x10] = 0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
45  [0x18] = 0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
46  /* IMC INT0 - 5 */
47  [0x20] = 0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x00,0x00,
48  [0x28] = 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
49  /* USB Devs 18/19/22 INTA-C */
50  [0x30] = 0x05,0x1F,0x05,0x1F,0x04,0x1F,0x1F,0x1F,
51  [0x38] = 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
52  /* SATA */
53  [0x40] = 0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,
54  [0x48] = 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
55  [0x50] = 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
56  [0x58] = 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
57  [0x60] = 0x00,0x00,0x1F
58 };
59 
61  [0 ... FCH_INT_TABLE_SIZE-1] = 0x1F,
62  /* INTA# - INTH# */
63  [0x00] = 0x10,0x10,0x12,0x13,0x14,0x15,0x1F,0x1F,
64  /* Misc-nil,0,1,2, INT from Serial irq */
65  [0x08] = 0x00,0x00,0x00,0x00,0x1F,0x1F,0x1F,0x1F,
66  /* SCI, SMBUS0, ASF, HDA, FC, RSVD, PerMon, SD */
67  [0x10] = 0x09,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x10,
68  [0x18] = 0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
69  /* IMC INT0 - 5 */
70  [0x20] = 0x05,0x1F,0x1F,0x1F,0x1F,0x1F,0x00,0x00,
71  [0x28] = 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
72  /* USB Devs 18/19/20/22 INTA-C */
73  [0x30] = 0x12,0x1F,0x12,0x1F,0x12,0x1F,0x1F,0x00,
74  [0x38] = 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
75  /* SATA */
76  [0x40] = 0x1F,0x13,0x00,0x00,0x00,0x00,0x00,0x00,
77  [0x48] = 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
78  [0x50] = 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
79  [0x58] = 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
80  [0x60] = 0x00,0x00,0x1F
81 };
82 
83 /*
84  * This table defines the index into the picr/intr_data
85  * tables for each device. Any enabled device and slot
86  * that uses hardware interrupts should have an entry
87  * in this table to define its index into the FCH
88  * PCI_INTR register 0xC00/0xC01. This index will define
89  * the interrupt that it should use. Putting PIRQ_A into
90  * the PIN A index for a device will tell that device to
91  * use PIC IRQ 10 if it uses PIN A for its hardware INT.
92  */
93 static const struct pirq_struct mainboard_pirq_data[] = {
94  /* {PCI_devfn, {PIN A, PIN B, PIN C, PIN D}}, */
95  {GFX_DEVFN, {PIRQ_A, PIRQ_NC, PIRQ_NC, PIRQ_NC}}, /* VGA: 01.0 */
96  {ACTL_DEVFN,{PIRQ_NC, PIRQ_B, PIRQ_NC, PIRQ_NC}}, /* Audio: 01.1 */
97  {NB_PCIE_PORT1_DEVFN, {PIRQ_A, PIRQ_B, PIRQ_C, PIRQ_D}}, /* x4 PCIe: 02.1 */
98  {NB_PCIE_PORT2_DEVFN, {PIRQ_B, PIRQ_C, PIRQ_D, PIRQ_A}}, /* mPCIe: 02.2 */
99  {NB_PCIE_PORT3_DEVFN, {PIRQ_C, PIRQ_D, PIRQ_A, PIRQ_B}}, /* NIC: 02.3 */
100  {XHCI_DEVFN, {PIRQ_C, PIRQ_NC, PIRQ_NC, PIRQ_NC}}, /* XHCI: 10.0 */
101  {SATA_DEVFN, {PIRQ_SATA, PIRQ_NC, PIRQ_NC, PIRQ_NC}}, /* SATA: 11.0 */
102  {OHCI1_DEVFN, {PIRQ_OHCI1, PIRQ_NC, PIRQ_NC, PIRQ_NC}}, /* OHCI1: 12.0 */
103  {EHCI1_DEVFN, {PIRQ_NC, PIRQ_EHCI1, PIRQ_NC, PIRQ_NC}}, /* EHCI1: 12.2 */
104  {OHCI2_DEVFN, {PIRQ_OHCI2, PIRQ_NC, PIRQ_NC, PIRQ_NC}}, /* OHCI2: 13.0 */
105  {EHCI2_DEVFN, {PIRQ_NC, PIRQ_EHCI2, PIRQ_NC, PIRQ_NC}}, /* EHCI2: 13.2 */
106  {SMBUS_DEVFN, {PIRQ_SMBUS, PIRQ_NC, PIRQ_NC, PIRQ_NC}}, /* SMBUS: 14.0 */
107  {HDA_DEVFN, {PIRQ_HDA, PIRQ_NC, PIRQ_NC, PIRQ_NC}}, /* HDA: 14.2 */
108  {SD_DEVFN, {PIRQ_SD, PIRQ_NC, PIRQ_NC, PIRQ_NC}}, /* SD: 14.7 */
109  {OHCI3_DEVFN, {PIRQ_OHCI3, PIRQ_NC, PIRQ_NC, PIRQ_NC}}, /* OHCI3: 16.0 (same device as xHCI 10.0) */
110  {EHCI3_DEVFN, {PIRQ_NC, PIRQ_EHCI3, PIRQ_NC, PIRQ_NC}}, /* EHCI3: 16.2 (same device as xHCI 10.1) */
111 };
112 
113 /* PIRQ Setup */
114 static void pirq_setup(void)
115 {
120 }
121 
122 /* Wrapper to enable GPIO/UART devices under menuconfig. Revisit
123  * once configuration file format for SPI flash storage is complete.
124  */
125 #define SIO_PORT 0x2e
126 
127 static void config_gpio_mux(void)
128 {
129  struct device *uart, *gpio;
130 
133  if (uart)
134  uart->enabled = CONFIG(APU2_PINMUX_UART_C);
135  if (gpio)
136  gpio->enabled = CONFIG(APU2_PINMUX_GPIO0);
137 
140  if (uart)
141  uart->enabled = CONFIG(APU2_PINMUX_UART_D);
142  if (gpio)
143  gpio->enabled = CONFIG(APU2_PINMUX_GPIO1);
144 }
145 
146 /**********************************************
147  * enable the dedicated function in mainboard.
148  **********************************************/
149 #if CONFIG(GENERATE_SMBIOS_TABLES)
150 static int mainboard_smbios_type16(DMI_INFO *agesa_dmi, int *handle,
151  unsigned long *current)
152 {
153  const u32 max_capacity = get_spd_offset() ? 4 : 2; /* 4GB or 2GB variant */
154 
156  sizeof(*t), *handle);
157 
160  t->memory_error_correction = agesa_dmi->T16.MemoryErrorCorrection;
161  t->maximum_capacity = max_capacity * 1024 * 1024;
164 
165  const int len = smbios_full_table_len(&t->header, t->eos);
166  *current += len;
167  return len;
168 }
169 
170 static int mainboard_smbios_type17(DMI_INFO *agesa_dmi, int *handle,
171  unsigned long *current)
172 {
174  sizeof(*t), *handle + 1);
175 
176  t->phys_memory_array_handle = *handle;
178  t->total_width = agesa_dmi->T17[0][0][0].TotalWidth;
179  t->data_width = agesa_dmi->T17[0][0][0].DataWidth;
180  t->size = agesa_dmi->T17[0][0][0].MemorySize;
181  t->form_factor = agesa_dmi->T17[0][0][0].FormFactor;
182  t->device_set = agesa_dmi->T17[0][0][0].DeviceSet;
184  agesa_dmi->T17[0][0][0].DeviceLocator);
186  agesa_dmi->T17[0][0][0].BankLocator);
187  t->memory_type = agesa_dmi->T17[0][0][0].MemoryType;
188  t->type_detail = *(u16 *)&agesa_dmi->T17[0][0][0].TypeDetail;
189  t->speed = agesa_dmi->T17[0][0][0].Speed;
190  t->manufacturer = agesa_dmi->T17[0][0][0].ManufacturerIdCode;
192  agesa_dmi->T17[0][0][0].SerialNumber);
194  agesa_dmi->T17[0][0][0].PartNumber);
195  t->attributes = agesa_dmi->T17[0][0][0].Attributes;
196  t->extended_size = agesa_dmi->T17[0][0][0].ExtSize;
197  t->clock_speed = agesa_dmi->T17[0][0][0].ConfigSpeed;
198  t->minimum_voltage = 1500; /* From SPD: 1.5V */
199  t->maximum_voltage = 1500;
200 
201  const int len = smbios_full_table_len(&t->header, t->eos);
202  *current += len;
203  return len;
204 }
205 
206 static int mainboard_smbios_data(struct device *dev, int *handle,
207  unsigned long *current)
208 {
209  DMI_INFO *agesa_dmi;
210  int len = 0;
211 
213 
214  if (!agesa_dmi)
215  return len;
216 
217  len += mainboard_smbios_type16(agesa_dmi, handle, current);
218  len += mainboard_smbios_type17(agesa_dmi, handle, current);
219 
220  *handle += 2;
221 
222  return len;
223 }
224 #endif
225 
226 static void mainboard_enable(struct device *dev)
227 {
228  /* Maintain this text unchanged for manufacture process. */
229  printk(BIOS_INFO, "Mainboard " CONFIG_MAINBOARD_PART_NUMBER " Enable.\n");
230 
231  config_gpio_mux();
232 
233  //
234  // Enable the RTC output
235  //
237 
238  //
239  // Enable power on from WAKE#
240  //
242 
243  /* Initialize the PIRQ data structures for consumption */
244  pirq_setup();
245 #if CONFIG(GENERATE_SMBIOS_TABLES)
246  dev->ops->get_smbios_data = mainboard_smbios_data;
247 #endif
248 }
249 
250 static void mainboard_final(void *chip_info)
251 {
252  //
253  // Turn off LED 2 and LED 3
254  //
255  gpio_set(GPIO_58, 1);
256  gpio_set(GPIO_59, 1);
257 }
258 
259 /*
260  * We will stuff a modified version of the first NICs (BDF 1:0.0) MAC address
261  * into the smbios serial number location.
262  */
264 {
265  static char serial[10];
266  struct device *dev;
267  uintptr_t bar10;
268  u32 mac_addr = 0;
269  int i;
270 
271  /* Already initialized. */
272  if (serial[0] != 0)
273  return serial;
274 
275  dev = pcidev_on_root(2, 2);
276  if (dev)
277  dev = pcidev_path_behind(dev->link_list, PCI_DEVFN(0, 0));
278  if (!dev)
279  return serial;
280 
281  /* Read in the last 3 bytes of NIC's MAC address. */
283  bar10 &= 0xFFFE0000;
284  bar10 += 0x5400;
285  for (i = 3; i < 6; i++) {
286  mac_addr <<= 8;
287  mac_addr |= read8((u8 *)bar10 + i);
288  }
289  mac_addr &= 0x00FFFFFF;
290  mac_addr /= 4;
291  mac_addr -= 64;
292 
293  snprintf(serial, sizeof(serial), "%d", mac_addr);
294  return serial;
295 }
296 
297 /*
298  * We will stuff the memory size into the smbios sku location.
299  */
300 const char *smbios_system_sku(void)
301 {
302  static char sku[5];
303  if (sku[0] != 0)
304  return sku;
305 
306  if (!get_spd_offset())
307  snprintf(sku, sizeof(sku), "2 GB");
308  else
309  snprintf(sku, sizeof(sku), "4 GB");
310  return sku;
311 }
312 
315  .final = mainboard_final,
316 };
struct chip_operations mainboard_ops
Definition: mainboard.c:19
@ PIRQ_A
Definition: acpi_pirq_gen.h:22
@ PIRQ_C
Definition: acpi_pirq_gen.h:24
@ PIRQ_D
Definition: acpi_pirq_gen.h:25
@ PIRQ_B
Definition: acpi_pirq_gen.h:23
static void pm_write16(uint8_t reg, uint16_t value)
Definition: acpimmio.h:186
static uint16_t pm_read16(uint8_t reg)
Definition: acpimmio.h:171
@ PICK_DMI
Definition: agesa_helper.h:10
int get_spd_offset(void)
Definition: gpio_ftns.c:25
#define GPIO_58
Definition: gpio_ftns.h:22
#define GPIO_59
Definition: gpio_ftns.h:23
static uint8_t read8(const void *addr)
Definition: mmio.h:12
int smbios_add_string(u8 *start, const char *str)
Definition: smbios.c:40
void * smbios_carve_table(unsigned long start, u8 type, u8 length, u16 handle)
Definition: smbios.c:91
int smbios_full_table_len(struct smbios_header *header, u8 *str_table_start)
Definition: smbios.c:86
#define ARRAY_SIZE(a)
Definition: helpers.h:12
#define printk(level,...)
Definition: stdlib.h:16
DEVTREE_CONST struct device * pcidev_path_behind(const struct bus *parent, pci_devfn_t devfn)
Definition: device_const.c:211
DEVTREE_CONST struct device * dev_find_slot_pnp(u16 port, u16 device)
Given a PnP port and a device number, find the device structure.
Definition: device_const.c:331
DEVTREE_CONST struct device * pcidev_on_root(uint8_t dev, uint8_t fn)
Definition: device_const.c:260
void * agesawrapper_getlateinitptr(int pick)
Definition: acpi_tables.c:34
@ CONFIG
Definition: dsi_common.h:201
static int mainboard_smbios_data(struct device *dev, int *handle, unsigned long *current)
Definition: mainboard.c:18
const char * smbios_system_sku(void)
Definition: mainboard.c:174
#define SD_DEVFN
Definition: variants.h:11
enum project_sku sku
Definition: mainboard.c:51
static __always_inline u32 pci_read_config32(const struct device *dev, u16 reg)
Definition: pci_ops.h:58
void gpio_set(gpio_t gpio, int value)
Definition: gpio.c:174
@ MEMORY_ARRAY_USE_SYSTEM
Definition: smbios.h:220
@ SMBIOS_MEMORY_DEVICE
Definition: smbios.h:250
@ SMBIOS_PHYS_MEMORY_ARRAY
Definition: smbios.h:249
@ MEMORY_ARRAY_LOCATION_SYSTEM_BOARD
Definition: smbios.h:202
unsigned int serial
Definition: edid.c:52
#define BIOS_INFO
BIOS_INFO - Expected events.
Definition: loglevel.h:113
#define NCT5104D_SP3
Definition: nct5104d.h:29
#define NCT5104D_GPIO0
Definition: nct5104d.h:40
#define NCT5104D_SP4
Definition: nct5104d.h:30
#define NCT5104D_GPIO1
Definition: nct5104d.h:41
#define NB_PCIE_PORT2_DEVFN
Definition: pci_devs.h:34
#define NB_PCIE_PORT3_DEVFN
Definition: pci_devs.h:35
#define NB_PCIE_PORT1_DEVFN
Definition: pci_devs.h:33
#define GFX_DEVFN
Definition: pci_devs.h:13
#define ACTL_DEVFN
Definition: pci_devs.h:27
const char * smbios_mainboard_serial_number(void)
Definition: mainboard.c:271
static void config_gpio_mux(void)
Definition: mainboard.c:127
#define SIO_PORT
Definition: mainboard.c:125
static const u8 mainboard_picr_data[FCH_INT_TABLE_SIZE]
Definition: mainboard.c:37
static const struct pirq_struct mainboard_pirq_data[]
Definition: mainboard.c:93
static void mainboard_final(void *chip_info)
Definition: mainboard.c:250
#define PM_S_STATE_CONTROL
Definition: mainboard.c:24
static void mainboard_enable(struct device *dev)
Definition: mainboard.c:226
static void pirq_setup(void)
Definition: mainboard.c:114
#define PM_RTC_CONTROL
Definition: mainboard.c:23
static const u8 mainboard_intr_data[FCH_INT_TABLE_SIZE]
Definition: mainboard.c:60
#define PCI_DEVFN(slot, func)
Definition: pci_def.h:548
#define PCI_BASE_ADDRESS_0
Definition: pci_def.h:63
#define PIRQ_SATA
#define PIRQ_SMBUS
#define PIRQ_SD
#define PIRQ_NC
#define SMBUS_DEVFN
Definition: pci_devs.h:117
u32 pirq_data_size
Definition: amd_pci_util.c:12
const u8 * intr_data_ptr
Definition: amd_pci_util.c:13
const u8 * picr_data_ptr
Definition: amd_pci_util.c:14
const struct pirq_struct * pirq_data_ptr
Definition: amd_pci_util.c:11
#define SATA_DEVFN
Definition: pci_devs.h:83
#define PIRQ_HDA
#define EHCI1_DEVFN
Definition: pci_devs.h:170
#define XHCI_DEVFN
Definition: pci_devs.h:153
#define PIRQ_OHCI2
#define PIRQ_OHCI1
#define PIRQ_EHCI3
#define PIRQ_OHCI3
#define PIRQ_EHCI2
#define PIRQ_EHCI1
#define HDA_DEVFN
Definition: pci_devs.h:69
#define OHCI1_DEVFN
Definition: pci_devs.h:34
#define EHCI3_DEVFN
Definition: pci_devs.h:49
#define OHCI3_DEVFN
Definition: pci_devs.h:36
#define EHCI2_DEVFN
Definition: pci_devs.h:48
#define OHCI2_DEVFN
Definition: pci_devs.h:35
#define FCH_INT_TABLE_SIZE
uint32_t u32
Definition: stdint.h:51
unsigned long uintptr_t
Definition: stdint.h:21
uint16_t u16
Definition: stdint.h:48
uint8_t u8
Definition: stdint.h:45
void(* enable_dev)(struct device *dev)
Definition: device.h:24
Definition: device.h:107
struct device_operations * ops
Definition: device.h:143
DEVTREE_CONST struct bus * link_list
Definition: device.h:139
unsigned int enabled
Definition: device.h:122
Definition: pinmux.c:36
struct smbios_header header
Definition: smbios.h:849
u16 number_of_memory_devices
Definition: smbios.h:855
u8 memory_error_correction
Definition: smbios.h:852
u16 memory_error_information_handle
Definition: smbios.h:854
u32 maximum_capacity
Definition: smbios.h:853
u8 eos[2]
Definition: smbios.h:857
u16 memory_error_information_handle
Definition: smbios.h:863
u8 manufacturer
Definition: smbios.h:874
u16 data_width
Definition: smbios.h:865
u8 device_locator
Definition: smbios.h:869
u16 type_detail
Definition: smbios.h:872
u32 extended_size
Definition: smbios.h:879
u16 minimum_voltage
Definition: smbios.h:881
u16 clock_speed
Definition: smbios.h:880
u8 bank_locator
Definition: smbios.h:870
u8 serial_number
Definition: smbios.h:875
u8 form_factor
Definition: smbios.h:867
u8 memory_type
Definition: smbios.h:871
u8 device_set
Definition: smbios.h:868
u8 eos[2]
Definition: smbios.h:884
u16 phys_memory_array_handle
Definition: smbios.h:862
u16 total_width
Definition: smbios.h:864
u8 attributes
Definition: smbios.h:878
struct smbios_header header
Definition: smbios.h:861
u16 maximum_voltage
Definition: smbios.h:882
u8 part_number
Definition: smbios.h:877
int snprintf(char *buf, size_t size, const char *fmt,...)
Note: This file is only for POSIX compatibility, and is meant to be chain-included via string....
Definition: vsprintf.c:35