1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <commonlib/helpers.h>
5 #include <console/console.h>
6 #include <device/pci_ops.h>
8 #include <device/device.h>
9 #include <device/pci.h>
10 #include <device/pci_ids.h>
11 #include <acpi/acpi.h>
12 #include <cpu/intel/smm_reloc.h>
13 #include <cpu/intel/speedstep.h>
14 #include <cpu/x86/smm.h>
17 static void mch_domain_read_resources(struct device
*dev
)
21 struct device
*const d0f0
= pcidev_on_root(0, 0);
24 pci_domain_read_resources(dev
);
26 /* Can we find out how much memory we can use at most
29 pci_tolm
= find_pci_tolm(dev
->downstream
);
30 printk(BIOS_DEBUG
, "pci_tolm: 0x%x\n", pci_tolm
);
32 tolud
= pci_read_config8(d0f0
, TOLUD
) << 24;
33 printk(BIOS_SPEW
, "Top of Low Used DRAM: 0x%08lx\n", tolud
);
35 /* Report the memory regions */
36 ram_range(dev
, idx
++, 0, 0xa0000);
37 ram_from_to(dev
, idx
++, 1 * MiB
, cbmem_top());
42 smm_region(&tseg_base
, &tseg_size
);
43 mmio_range(dev
, idx
++, tseg_base
, tseg_size
);
45 /* cbmem_top can be shifted downwards due to alignment.
46 Mark the region between cbmem_top and tseg_base as unusable */
47 if (cbmem_top() < tseg_base
) {
48 printk(BIOS_DEBUG
, "Unused RAM between cbmem_top and TOM: 0x%lx\n",
49 tseg_base
- cbmem_top());
50 mmio_from_to(dev
, idx
++, cbmem_top(), tseg_base
);
52 if (tseg_base
+ tseg_size
< tolud
)
53 mmio_from_to(dev
, idx
++, tseg_base
+ tseg_size
, tolud
);
55 /* legacy VGA memory */
56 mmio_from_to(dev
, idx
++, 0xa0000, 0xc0000);
57 /* RAM to be used for option roms and BIOS */
58 reserved_ram_from_to(dev
, idx
++, 0xc0000, 1 * MiB
);
61 static void mch_domain_set_resources(struct device
*dev
)
65 for (res
= dev
->resource_list
; res
; res
= res
->next
)
66 report_resource_stored(dev
, res
, "");
68 assign_resources(dev
->downstream
);
71 static const char *northbridge_acpi_name(const struct device
*dev
)
73 if (dev
->path
.type
== DEVICE_PATH_DOMAIN
)
76 if (!is_pci_dev_on_bus(dev
, 0))
79 switch (dev
->path
.pci
.devfn
) {
87 void northbridge_write_smram(u8 smram
)
89 struct device
*dev
= pcidev_on_root(0, 0);
92 die("could not find pci 00:00.0!\n");
94 pci_write_config8(dev
, SMRAM
, smram
);
97 struct device_operations i945_pci_domain_ops
= {
98 .read_resources
= mch_domain_read_resources
,
99 .set_resources
= mch_domain_set_resources
,
100 .scan_bus
= pci_host_bridge_scan_bus
,
101 .acpi_name
= northbridge_acpi_name
,
104 static void mc_read_resources(struct device
*dev
)
106 pci_dev_read_resources(dev
);
108 mmconf_resource(dev
, PCIEXBAR
);
111 static struct device_operations mc_ops
= {
112 .read_resources
= mc_read_resources
,
113 .set_resources
= pci_dev_set_resources
,
114 .enable_resources
= pci_dev_enable_resources
,
115 .acpi_fill_ssdt
= generate_cpu_entries
,
116 .ops_pci
= &pci_dev_ops_pci
,
119 static const unsigned short pci_device_ids
[] = {
120 0x2770, /* desktop */
121 0x27a0, 0x27ac, /* mobile */
124 static const struct pci_driver mc_driver __pci_driver
= {
126 .vendor
= PCI_VID_INTEL
,
127 .devices
= pci_device_ids
,
130 struct device_operations i945_cpu_bus_ops
= {
131 .read_resources
= noop_read_resources
,
132 .set_resources
= noop_set_resources
,
133 .init
= mp_cpu_bus_init
,
136 struct chip_operations northbridge_intel_i945_ops
= {
137 .name
= "Intel i945 Northbridge",
140 bool northbridge_support_slfm(void)