coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
root_complex.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 /* TODO: Check if this is still correct */
4 
5 #include <acpi/acpigen.h>
6 #include <amdblocks/acpi.h>
7 #include <amdblocks/alib.h>
8 #include <amdblocks/ioapic.h>
9 #include <amdblocks/memmap.h>
10 #include <arch/ioapic.h>
11 #include <cbmem.h>
12 #include <console/console.h>
13 #include <cpu/amd/msr.h>
14 #include <device/device.h>
15 #include <device/pci.h>
16 #include <device/pci_ids.h>
17 #include <fsp/util.h>
18 #include <soc/iomap.h>
19 #include <stdint.h>
20 #include "chip.h"
21 
22 #define DPTC_TOTAL_UPDATE_PARAMS 4
23 
24 struct dptc_input {
25  uint16_t size;
28 
29 #define DPTC_INPUTS(_thermctllmit, _sustained, _fast, _slow) \
30  { \
31  .size = sizeof(struct dptc_input), \
32  .params = { \
33  { \
34  .id = ALIB_DPTC_THERMAL_CONTROL_LIMIT_ID, \
35  .value = _thermctllmit, \
36  }, \
37  { \
38  .id = ALIB_DPTC_SUSTAINED_POWER_LIMIT_ID, \
39  .value = _sustained, \
40  }, \
41  { \
42  .id = ALIB_DPTC_FAST_PPT_LIMIT_ID, \
43  .value = _fast, \
44  }, \
45  { \
46  .id = ALIB_DPTC_SLOW_PPT_LIMIT_ID, \
47  .value = _slow, \
48  }, \
49  }, \
50  }
51 
52 /*
53  *
54  * +--------------------------------+
55  * | |
56  * | |
57  * | |
58  * | |
59  * | |
60  * | |
61  * | |
62  * reserved_dram_end +--------------------------------+
63  * | |
64  * | verstage (if reqd) |
65  * | (VERSTAGE_SIZE) |
66  * +--------------------------------+ VERSTAGE_ADDR
67  * | |
68  * | FSP-M |
69  * | (FSP_M_SIZE) |
70  * +--------------------------------+ FSP_M_ADDR
71  * | romstage |
72  * | (ROMSTAGE_SIZE) |
73  * +--------------------------------+ ROMSTAGE_ADDR = BOOTBLOCK_END
74  * | | X86_RESET_VECTOR = BOOTBLOCK_END - 0x10
75  * | bootblock |
76  * | (C_ENV_BOOTBLOCK_SIZE) |
77  * +--------------------------------+ BOOTBLOCK_ADDR = BOOTBLOCK_END - C_ENV_BOOTBLOCK_SIZE
78  * | Unused hole |
79  * | (86KiB) |
80  * +--------------------------------+
81  * | FMAP cache (FMAP_SIZE) |
82  * +--------------------------------+ PSP_SHAREDMEM_BASE + PSP_SHAREDMEM_SIZE + PRERAM_CBMEM_CONSOLE_SIZE + 0x200
83  * | Early Timestamp region (512B) |
84  * +--------------------------------+ PSP_SHAREDMEM_BASE + PSP_SHAREDMEM_SIZE + PRERAM_CBMEM_CONSOLE_SIZE
85  * | Preram CBMEM console |
86  * | (PRERAM_CBMEM_CONSOLE_SIZE) |
87  * +--------------------------------+ PSP_SHAREDMEM_BASE + PSP_SHAREDMEM_SIZE
88  * | PSP shared (vboot workbuf) |
89  * | (PSP_SHAREDMEM_SIZE) |
90  * +--------------------------------+ PSP_SHAREDMEM_BASE
91  * | APOB (64KiB) |
92  * +--------------------------------+ PSP_APOB_DRAM_ADDRESS
93  * | Early BSP stack |
94  * | (EARLYRAM_BSP_STACK_SIZE) |
95  * reserved_dram_start +--------------------------------+ EARLY_RESERVED_DRAM_BASE
96  * | DRAM |
97  * +--------------------------------+ 0x100000
98  * | Option ROM |
99  * +--------------------------------+ 0xc0000
100  * | Legacy VGA |
101  * +--------------------------------+ 0xa0000
102  * | DRAM |
103  * +--------------------------------+ 0x0
104  */
105 static void read_resources(struct device *dev)
106 {
107  uint32_t mem_usable = (uintptr_t)cbmem_top();
108  unsigned int idx = 0;
109  const struct hob_header *hob = fsp_get_hob_list();
110  const struct hob_resource *res;
111  struct resource *gnb_apic;
112 
113  uintptr_t early_reserved_dram_start, early_reserved_dram_end;
115 
116  early_reserved_dram_start = e->base;
117  early_reserved_dram_end = e->base + e->size;
118 
119  /* The root complex has no PCI BARs implemented, so there's no need to call
120  pci_dev_read_resources for it */
121 
122  /* 0x0 - 0x9ffff */
123  ram_resource(dev, idx++, 0, 0xa0000 / KiB);
124 
125  /* 0xa0000 - 0xbffff: legacy VGA */
126  mmio_resource(dev, idx++, 0xa0000 / KiB, 0x20000 / KiB);
127 
128  /* 0xc0000 - 0xfffff: Option ROM */
129  reserved_ram_resource(dev, idx++, 0xc0000 / KiB, 0x40000 / KiB);
130 
131  /* 1MiB - bottom of DRAM reserved for early coreboot usage */
132  ram_resource(dev, idx++, (1 * MiB) / KiB,
133  (early_reserved_dram_start - (1 * MiB)) / KiB);
134 
135  /* DRAM reserved for early coreboot usage */
136  reserved_ram_resource(dev, idx++, early_reserved_dram_start / KiB,
137  (early_reserved_dram_end - early_reserved_dram_start) / KiB);
138 
139  /*
140  * top of DRAM consumed early - low top usable RAM
141  * cbmem_top() accounts for low UMA and TSEG if they are used.
142  */
143  ram_resource(dev, idx++, early_reserved_dram_end / KiB,
144  (mem_usable - early_reserved_dram_end) / KiB);
145 
146  mmconf_resource(dev, idx++);
147 
148  if (!hob) {
149  printk(BIOS_ERR, "Error: %s incomplete because no HOB list was found\n",
150  __func__);
151  return;
152  }
153 
154  for (; hob->type != HOB_TYPE_END_OF_HOB_LIST; hob = fsp_next_hob(hob)) {
155 
157  continue;
158 
159  res = fsp_hob_header_to_resource(hob);
160 
161  if (res->type == EFI_RESOURCE_SYSTEM_MEMORY && res->addr < mem_usable)
162  continue; /* 0 through low usable was set above */
163  if (res->type == EFI_RESOURCE_MEMORY_MAPPED_IO)
164  continue; /* Done separately */
165 
166  if (res->type == EFI_RESOURCE_SYSTEM_MEMORY)
167  ram_resource(dev, idx++, res->addr / KiB, res->length / KiB);
168  else if (res->type == EFI_RESOURCE_MEMORY_RESERVED)
169  reserved_ram_resource(dev, idx++, res->addr / KiB, res->length / KiB);
170  else
171  printk(BIOS_ERR, "Error: failed to set resources for type %d\n",
172  res->type);
173  }
174 
175  /* GNB IOAPIC resource */
176  gnb_apic = new_resource(dev, idx++);
177  gnb_apic->base = GNB_IO_APIC_ADDR;
178  gnb_apic->size = 0x00001000;
180 }
181 
182 static void root_complex_init(struct device *dev)
183 {
184  setup_ioapic((u8 *)GNB_IO_APIC_ADDR, GNB_IOAPIC_ID);
185 }
186 
187 static void acipgen_dptci(void)
188 {
189  const struct soc_amd_sabrina_config *config = config_of_soc();
190 
191  if (!config->dptc_enable)
192  return;
193 
194  struct dptc_input default_input = DPTC_INPUTS(config->thermctl_limit_degreeC,
195  config->sustained_power_limit_mW,
196  config->fast_ppt_limit_mW,
197  config->slow_ppt_limit_mW);
198  struct dptc_input tablet_mode_input = DPTC_INPUTS(
199  config->thermctl_limit_tablet_mode_degreeC,
200  config->sustained_power_limit_tablet_mode_mW,
201  config->fast_ppt_limit_tablet_mode_mW,
202  config->slow_ppt_limit_tablet_mode_mW);
203 
204  acpigen_write_alib_dptc((uint8_t *)&default_input, sizeof(default_input),
205  (uint8_t *)&tablet_mode_input, sizeof(tablet_mode_input));
206 }
207 
208 static void root_complex_fill_ssdt(const struct device *device)
209 {
211  acipgen_dptci();
212 }
213 
214 static const char *gnb_acpi_name(const struct device *dev)
215 {
216  return "GNB";
217 }
218 
221  .set_resources = noop_set_resources,
222  .enable_resources = pci_dev_enable_resources,
223  .init = root_complex_init,
224  .acpi_name = gnb_acpi_name,
225  .acpi_fill_ssdt = root_complex_fill_ssdt,
226 };
227 
228 static const struct pci_driver family17_root_complex __pci_driver = {
229  .ops = &root_complex_operations,
230  .vendor = PCI_VID_AMD,
232 };
void acpigen_write_alib_dptc(uint8_t *default_param, size_t default_param_len, uint8_t *tablet_param, size_t tablet_param_len)
Definition: alib.c:19
void setup_ioapic(void *ioapic_base, u8 ioapic_id)
Definition: ioapic.c:160
#define MiB
Definition: helpers.h:76
#define KiB
Definition: helpers.h:75
void * cbmem_top(void)
Definition: imd_cbmem.c:18
struct dptc_input __packed
#define printk(level,...)
Definition: stdlib.h:16
struct resource * new_resource(struct device *dev, unsigned int index)
See if a resource structure already exists for a given index and if not allocate one.
Definition: device_util.c:346
void mmconf_resource(struct device *dev, unsigned long index)
Definition: device_util.c:857
@ HOB_TYPE_RESOURCE_DESCRIPTOR
Definition: util.h:93
@ HOB_TYPE_END_OF_HOB_LIST
Definition: util.h:102
void * fsp_get_hob_list(void)
Definition: fsp_util.c:202
const struct hob_resource * fsp_hob_header_to_resource(const struct hob_header *hob)
const struct hob_header * fsp_next_hob(const struct hob_header *parent)
static void noop_set_resources(struct device *dev)
Definition: device.h:74
#define ram_resource(dev, idx, basek, sizek)
Definition: device.h:321
#define config_of_soc()
Definition: device.h:394
#define mmio_resource(dev, idx, basek, sizek)
Definition: device.h:334
#define reserved_ram_resource(dev, idx, basek, sizek)
Definition: device.h:324
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
enum board_config config
Definition: memory.c:448
void pci_dev_enable_resources(struct device *dev)
Definition: pci_device.c:721
#define PCI_VID_AMD
Definition: pci_ids.h:496
#define PCI_DID_AMD_17H_MODEL_A0AF_NB
Definition: pci_ids.h:508
#define IORESOURCE_MEM
Definition: resource.h:10
#define IORESOURCE_ASSIGNED
Definition: resource.h:34
#define IORESOURCE_FIXED
Definition: resource.h:36
static void root_complex_init(struct device *dev)
Definition: root_complex.c:182
static const char * gnb_acpi_name(const struct device *dev)
Definition: root_complex.c:214
static void acipgen_dptci(void)
Definition: root_complex.c:187
static struct device_operations root_complex_operations
Definition: root_complex.c:219
static void root_complex_fill_ssdt(const struct device *device)
Definition: root_complex.c:208
#define DPTC_TOTAL_UPDATE_PARAMS
Definition: root_complex.c:22
static const struct pci_driver family17_root_complex __pci_driver
Definition: root_complex.c:228
static void read_resources(struct device *dev)
Definition: root_complex.c:105
#define DPTC_INPUTS(_thermctllmit, _sustained, _fast, _slow)
Definition: root_complex.c:29
void acpi_fill_root_complex_tom(const struct device *device)
Definition: tables.c:42
const struct memmap_early_dram * memmap_get_early_dram_usage(void)
Definition: memmap.c:28
#define GNB_IOAPIC_ID
Definition: ioapic.h:8
unsigned short uint16_t
Definition: stdint.h:11
unsigned int uint32_t
Definition: stdint.h:14
unsigned long uintptr_t
Definition: stdint.h:21
uint8_t u8
Definition: stdint.h:45
unsigned char uint8_t
Definition: stdint.h:8
void(* read_resources)(struct device *dev)
Definition: device.h:39
Definition: device.h:107
uint16_t size
Definition: root_complex.c:23
struct alib_dptc_param params[DPTC_TOTAL_UPDATE_PARAMS]
Definition: root_complex.c:24
uint16_t type
Definition: util.h:27
uint32_t type
Definition: util.h:53
uint64_t length
Definition: util.h:56
uint64_t addr
Definition: util.h:55
uint32_t size
Definition: memmap.h:14
uint32_t base
Definition: memmap.h:13
unsigned long flags
Definition: resource.h:49
resource_t base
Definition: resource.h:45
resource_t size
Definition: resource.h:46