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