1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <commonlib/helpers.h>
5 #include <console/console.h>
6 #include <device/pci_def.h>
7 #include <device/pci_ops.h>
9 #include <device/device.h>
10 #include <boot/tables.h>
11 #include <acpi/acpi.h>
12 #include <cpu/intel/smm_reloc.h>
17 /* Reserve segments A and B:
19 * 0xa0000 - 0xbffff: legacy VGA
21 static const int legacy_hole_base_k
= 0xa0000 / 1024;
22 static const int legacy_hole_size_k
= 128;
24 static int decode_pcie_bar(u32
*const base
, u32
*const len
)
29 struct device
*dev
= pcidev_on_root(0, 0);
33 const u32 pciexbar_reg
= pci_read_config32(dev
, D0F0_PCIEXBAR_LO
);
35 if (!(pciexbar_reg
& (1 << 0)))
38 switch ((pciexbar_reg
>> 1) & 3) {
40 *base
= pciexbar_reg
& (0x0f << 28);
44 *base
= pciexbar_reg
& (0x1f << 27);
48 *base
= pciexbar_reg
& (0x3f << 26);
56 static void mch_domain_read_resources(struct device
*dev
)
59 u32 tomk
, tolud
, uma_sizek
= 0, delta_cbmem
;
60 u32 pcie_config_base
, pcie_config_size
;
62 /* Total Memory 2GB example:
64 * 00000000 0000MB-2014MB 2014MB RAM (writeback)
65 * 7de00000 2014MB-2016MB 2MB GFX GTT (uncached)
66 * 7e000000 2016MB-2048MB 32MB GFX UMA (uncached)
67 * 80000000 2048MB TOLUD
70 * Total Memory 4GB example:
72 * 00000000 0000MB-3038MB 3038MB RAM (writeback)
73 * bde00000 3038MB-3040MB 2MB GFX GTT (uncached)
74 * be000000 3040MB-3072MB 32MB GFX UMA (uncached)
75 * be000000 3072MB TOLUD
76 * 100000000 4096MB TOM
77 * 100000000 4096MB-5120MB 1024MB RAM (writeback)
78 * 140000000 5120MB TOUUD
81 pci_domain_read_resources(dev
);
83 struct device
*mch
= pcidev_on_root(0, 0);
85 /* Top of Upper Usable DRAM, including remap */
86 touud
= pci_read_config16(mch
, D0F0_TOUUD
);
89 /* Top of Lower Usable DRAM */
90 tolud
= pci_read_config16(mch
, D0F0_TOLUD
) & 0xfff0;
93 /* Top of Memory - does not account for any UMA */
94 tom
= pci_read_config16(mch
, D0F0_TOM
) & 0x1ff;
97 printk(BIOS_DEBUG
, "TOUUD 0x%llx TOLUD 0x%08x TOM 0x%llx\n",
102 /* Graphics memory comes next */
103 const u16 ggc
= pci_read_config16(mch
, D0F0_GGC
);
105 printk(BIOS_DEBUG
, "IGD decoded, subtracting ");
107 /* Graphics memory */
108 const u32 gms_sizek
= decode_igd_memory_size((ggc
>> 4) & 0xf);
109 printk(BIOS_DEBUG
, "%uM UMA, ", gms_sizek
>> 10);
112 /* GTT Graphics Stolen Memory Size (GGMS) */
113 const u32 gsm_sizek
= decode_igd_gtt_size((ggc
>> 8) & 0xf);
114 printk(BIOS_DEBUG
, "%uM GTT", gsm_sizek
>> 10);
117 uma_sizek
= gms_sizek
+ gsm_sizek
;
119 const u8 esmramc
= pci_read_config8(mch
, D0F0_ESMRAMC
);
120 const u32 tseg_sizek
= decode_tseg_size(esmramc
);
121 printk(BIOS_DEBUG
, " and %uM TSEG\n", tseg_sizek
>> 10);
123 uma_sizek
+= tseg_sizek
;
125 /* cbmem_top can be shifted downwards due to alignment.
126 Mark the region between cbmem_top and tomk as unusable */
127 delta_cbmem
= tomk
- ((uint32_t)cbmem_top() >> 10);
129 uma_sizek
+= delta_cbmem
;
131 printk(BIOS_DEBUG
, "Unused RAM between cbmem_top and TOM: 0x%xK\n",
134 printk(BIOS_INFO
, "Available memory below 4GB: %uM\n", tomk
>> 10);
136 /* Report the memory regions */
137 ram_resource(dev
, 3, 0, legacy_hole_base_k
);
138 ram_resource(dev
, 4, legacy_hole_base_k
+ legacy_hole_size_k
,
139 (tomk
- (legacy_hole_base_k
+ legacy_hole_size_k
)));
142 * If >= 4GB installed then memory from TOLUD to 4GB
143 * is remapped above TOM, TOUUD will account for both
145 touud
>>= 10; /* Convert to KB */
146 if (touud
> 4096 * 1024) {
147 ram_resource(dev
, 5, 4096 * 1024, touud
- (4096 * 1024));
148 printk(BIOS_INFO
, "Available memory above 4GB: %lluM\n",
149 (touud
>> 10) - 4096);
152 printk(BIOS_DEBUG
, "Adding UMA memory area base=0x%llx "
153 "size=0x%llx\n", ((u64
)tomk
) << 10, ((u64
)uma_sizek
) << 10);
154 /* Don't use uma_resource() as our UMA touches the PCI hole. */
155 fixed_mem_resource(dev
, 6, tomk
, uma_sizek
, IORESOURCE_RESERVE
);
157 if (decode_pcie_bar(&pcie_config_base
, &pcie_config_size
)) {
158 printk(BIOS_DEBUG
, "Adding PCIe config bar base=0x%08x "
159 "size=0x%x\n", pcie_config_base
, pcie_config_size
);
160 fixed_mem_resource(dev
, 7, pcie_config_base
>> 10,
161 pcie_config_size
>> 10, IORESOURCE_RESERVE
);
165 static void mch_domain_set_resources(struct device
*dev
)
167 struct resource
*resource
;
170 for (i
= 3; i
< 8; ++i
) {
171 /* Report read resources. */
172 resource
= probe_resource(dev
, i
);
174 report_resource_stored(dev
, resource
, "");
177 assign_resources(dev
->link_list
);
180 static void mch_domain_init(struct device
*dev
)
182 struct device
*mch
= pcidev_on_root(0, 0);
185 pci_or_config16(mch
, PCI_COMMAND
, PCI_COMMAND_SERR
);
188 static const char *northbridge_acpi_name(const struct device
*dev
)
190 if (dev
->path
.type
== DEVICE_PATH_DOMAIN
)
193 if (dev
->path
.type
!= DEVICE_PATH_PCI
|| dev
->bus
->secondary
!= 0)
196 switch (dev
->path
.pci
.devfn
) {
197 case PCI_DEVFN(0, 0):
204 void northbridge_write_smram(u8 smram
)
206 struct device
*dev
= pcidev_on_root(0, 0);
209 die("could not find pci 00:00.0!\n");
211 pci_write_config8(dev
, D0F0_SMRAM
, smram
);
214 static struct device_operations pci_domain_ops
= {
215 .read_resources
= mch_domain_read_resources
,
216 .set_resources
= mch_domain_set_resources
,
217 .init
= mch_domain_init
,
218 .scan_bus
= pci_domain_scan_bus
,
219 .write_acpi_tables
= northbridge_write_acpi_tables
,
220 .acpi_fill_ssdt
= generate_cpu_entries
,
221 .acpi_name
= northbridge_acpi_name
,
224 static struct device_operations cpu_bus_ops
= {
225 .read_resources
= noop_read_resources
,
226 .set_resources
= noop_set_resources
,
227 .init
= mp_cpu_bus_init
,
230 static void enable_dev(struct device
*dev
)
232 /* Set the operations if it is a special bus type */
233 if (dev
->path
.type
== DEVICE_PATH_DOMAIN
) {
234 dev
->ops
= &pci_domain_ops
;
235 } else if (dev
->path
.type
== DEVICE_PATH_CPU_CLUSTER
) {
236 dev
->ops
= &cpu_bus_ops
;
240 static void gm45_init(void *const chip_info
)
242 int dev
, fn
, bit_base
;
244 struct device
*const d0f0
= pcidev_on_root(0x0, 0);
246 /* Hide internal functions based on devicetree info. */
247 for (dev
= 3; dev
> 0; --dev
) {
262 for (; fn
>= 0; --fn
) {
263 const struct device
*const d
= pcidev_on_root(dev
, fn
);
264 if (!d
|| d
->enabled
)
266 /* FIXME: Using bitwise ops changes the binary */
267 pci_write_config32(d0f0
, D0F0_DEVEN
,
268 pci_read_config32(d0f0
, D0F0_DEVEN
) & ~(1 << (bit_base
+ fn
)));
272 const u32 deven
= pci_read_config32(d0f0
, D0F0_DEVEN
);
273 if (!(deven
& (0xf << 6)))
274 pci_write_config32(d0f0
, D0F0_DEVEN
, deven
& ~(1 << 14));
277 struct chip_operations northbridge_intel_gm45_ops
= {
278 CHIP_NAME("Intel GM45 Northbridge")
279 .enable_dev
= enable_dev
,