blob: d83be9f8266da8d5c32cb146a5af857ca83be1ab [file] [log] [blame]
Angel Ponsc3f58f62020-04-05 15:46:41 +02001/* SPDX-License-Identifier: GPL-2.0-only */
2/* This file is part of the coreboot project. */
Aaron Durbin191570d2013-09-24 12:41:08 -05003
Aaron Durbin191570d2013-09-24 12:41:08 -05004#include <cpu/x86/smm.h>
5#include <device/device.h>
6#include <device/pci.h>
7#include <device/pci_ids.h>
Kein Yuan35110232014-02-22 12:26:55 -08008#include <vendorcode/google/chromeos/chromeos.h>
Vladimir Serbinenko7fb149d2014-10-08 22:56:27 +02009#include <arch/acpi.h>
Matt DeVillierf05d2e12017-06-06 23:56:18 -050010#include <stddef.h>
Julius Werner18ea2d32014-10-07 16:42:17 -070011#include <soc/iomap.h>
12#include <soc/iosf.h>
13#include <soc/pci_devs.h>
14#include <soc/ramstage.h>
Aaron Durbin191570d2013-09-24 12:41:08 -050015
16/* Host Memory Map:
17 *
18 * +--------------------------+ BMBOUND_HI
19 * | Usable DRAM |
20 * +--------------------------+ 4GiB
21 * | PCI Address Space |
22 * +--------------------------+ BMBOUND
23 * | TPM |
24 * +--------------------------+ IMR2
25 * | TXE |
26 * +--------------------------+ IMR1
27 * | iGD |
28 * +--------------------------+
29 * | GTT |
30 * +--------------------------+ SMMRRH, IRM0
31 * | TSEG |
32 * +--------------------------+ SMMRRL
33 * | Usable DRAM |
34 * +--------------------------+ 0
35 *
36 * Note that there are really only a few regions that need to enumerated w.r.t.
Martin Roth99a3bba2014-12-07 14:57:26 -070037 * coreboot's resource model:
Aaron Durbin191570d2013-09-24 12:41:08 -050038 *
39 * +--------------------------+ BMBOUND_HI
40 * | Cacheable/Usable |
41 * +--------------------------+ 4GiB
42 *
43 * +--------------------------+ BMBOUND
44 * | Uncacheable/Reserved |
45 * +--------------------------+ SMMRRH
46 * | Cacheable/Reserved |
47 * +--------------------------+ SMMRRL
48 * | Cacheable/Usable |
49 * +--------------------------+ 0
50 */
51#define RES_IN_KiB(r) ((r) >> 10)
52
Duncan Laurie1f52f512013-11-04 17:02:45 -080053uint32_t nc_read_top_of_low_memory(void)
54{
Kyösti Mälkki117cf2b2019-08-20 06:01:57 +030055 MAYBE_STATIC_BSS uint32_t tolm = 0;
Matt DeVillierf05d2e12017-06-06 23:56:18 -050056
57 if (tolm)
58 return tolm;
59
60 tolm = iosf_bunit_read(BUNIT_BMBOUND) & ~((1 << 27) - 1);
61
62 return tolm;
Duncan Laurie1f52f512013-11-04 17:02:45 -080063}
64
Elyes HAOUAS17a3ceb2018-05-22 10:42:28 +020065static void nc_read_resources(struct device *dev)
Aaron Durbin191570d2013-09-24 12:41:08 -050066{
67 unsigned long mmconf;
68 unsigned long bmbound;
69 unsigned long bmbound_hi;
70 unsigned long smmrrh;
71 unsigned long smmrrl;
72 unsigned long base_k, size_k;
73 const unsigned long four_gig_kib = (4 << (30 - 10));
74 int index = 0;
75
76 /* Read standard PCI resources. */
77 pci_dev_read_resources(dev);
78
79 /* PCIe memory-mapped config space access - 256 MiB. */
80 mmconf = iosf_bunit_read(BUNIT_MMCONF_REG) & ~((1 << 28) - 1);
81 mmio_resource(dev, BUNIT_MMCONF_REG, RES_IN_KiB(mmconf), 256 * 1024);
82
Kein Yuan35110232014-02-22 12:26:55 -080083 /* 0 -> 0xa0000 */
84 base_k = RES_IN_KiB(0);
Aaron Durbin191570d2013-09-24 12:41:08 -050085 size_k = RES_IN_KiB(0xa0000) - base_k;
86 ram_resource(dev, index++, base_k, size_k);
87
88 /* The SMMRR registers are 1MiB granularity with smmrrh being
89 * inclusive of the SMM region. */
90 smmrrl = (iosf_bunit_read(BUNIT_SMRRL) & 0xffff) << 10;
91 smmrrh = ((iosf_bunit_read(BUNIT_SMRRH) & 0xffff) + 1) << 10;
92
93 /* 0xc0000 -> smrrl - cacheable and usable */
94 base_k = RES_IN_KiB(0xc0000);
95 size_k = smmrrl - base_k;
96 ram_resource(dev, index++, base_k, size_k);
97
98 if (smmrrh > smmrrl)
99 reserved_ram_resource(dev, index++, smmrrl, smmrrh - smmrrl);
100
101 /* All address space between bmbound and smmrrh is unusable. */
Duncan Laurie1f52f512013-11-04 17:02:45 -0800102 bmbound = RES_IN_KiB(nc_read_top_of_low_memory());
Aaron Durbin191570d2013-09-24 12:41:08 -0500103 mmio_resource(dev, index++, smmrrh, bmbound - smmrrh);
104
105 /* The BMBOUND_HI register matches register bits of 31:24 with address
106 * bits of 35:28. Therefore, shift register to align properly. */
107 bmbound_hi = iosf_bunit_read(BUNIT_BMBOUND_HI) & ~((1 << 24) - 1);
108 bmbound_hi = RES_IN_KiB(bmbound_hi) << 4;
109 if (bmbound_hi > four_gig_kib)
110 ram_resource(dev, index++, four_gig_kib,
111 bmbound_hi - four_gig_kib);
Duncan Lauriee7e78d62013-11-03 19:38:12 -0800112
113 /* Reserve everything between A segment and 1MB:
114 *
115 * 0xa0000 - 0xbffff: legacy VGA
116 * 0xc0000 - 0xfffff: RAM
117 */
118 mmio_resource(dev, index++, (0xa0000 >> 10), (0xc0000 - 0xa0000) >> 10);
119 reserved_ram_resource(dev, index++, (0xc0000 >> 10),
120 (0x100000 - 0xc0000) >> 10);
Kein Yuan35110232014-02-22 12:26:55 -0800121
Julius Wernercd49cce2019-03-05 16:53:33 -0800122 if (CONFIG(CHROMEOS))
Frans Hendriksef05dc82018-11-27 10:35:16 +0100123 chromeos_reserve_ram_oops(dev, index++);
Aaron Durbin191570d2013-09-24 12:41:08 -0500124}
125
Aaron Durbin191570d2013-09-24 12:41:08 -0500126static struct device_operations nc_ops = {
127 .read_resources = nc_read_resources,
Nico Huber68680dd2020-03-31 17:34:52 +0200128 .acpi_fill_ssdt = generate_cpu_entries,
Aaron Durbin191570d2013-09-24 12:41:08 -0500129 .ops_pci = &soc_pci_ops,
130};
131
132static const struct pci_driver nc_driver __pci_driver = {
133 .ops = &nc_ops,
134 .vendor = PCI_VENDOR_ID_INTEL,
135 .device = SOC_DEVID,
136};