blob: d0434259d4d3730eb82522e29f5bffe16f0a5449 [file] [log] [blame]
Stefan Reinauer00636b02012-04-04 00:08:51 +02001/*
2 * This file is part of the coreboot project.
3 *
Stefan Reinauer00636b02012-04-04 00:08:51 +02004 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; version 2 of
8 * the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
Stefan Reinauer00636b02012-04-04 00:08:51 +020014 */
15
16#include <types.h>
Stefan Reinauer00636b02012-04-04 00:08:51 +020017#include <console/console.h>
Nico Huberb3234742018-11-17 14:09:25 +010018#include <commonlib/helpers.h>
Stefan Reinauer00636b02012-04-04 00:08:51 +020019#include <arch/acpi.h>
Stefan Reinauer00636b02012-04-04 00:08:51 +020020#include <device/device.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +020021#include <device/pci_ops.h>
Stefan Reinauer00636b02012-04-04 00:08:51 +020022#include "sandybridge.h"
Nico Huber9d9ce0d2015-10-26 12:59:49 +010023#include <southbridge/intel/bd82x6x/pch.h>
Stefan Reinauer00636b02012-04-04 00:08:51 +020024
25unsigned long acpi_fill_mcfg(unsigned long current)
26{
Stefan Reinauer00636b02012-04-04 00:08:51 +020027 u32 pciexbar = 0;
28 u32 pciexbar_reg;
29 int max_buses;
30
Kyösti Mälkkic70eed12018-05-22 02:18:00 +030031 struct device *const dev = pcidev_on_root(0, 0);
Vagiz Trakhanove200c1c2017-09-28 15:01:06 +000032
Stefan Reinauer00636b02012-04-04 00:08:51 +020033 if (!dev)
34 return current;
35
Angel Pons7c49cb82020-03-16 23:17:32 +010036 pciexbar_reg = pci_read_config32(dev, PCIEXBAR);
Stefan Reinauer00636b02012-04-04 00:08:51 +020037
Angel Pons7c49cb82020-03-16 23:17:32 +010038 /* MMCFG not supported or not enabled */
Stefan Reinauer00636b02012-04-04 00:08:51 +020039 if (!(pciexbar_reg & (1 << 0)))
40 return current;
41
42 switch ((pciexbar_reg >> 1) & 3) {
Angel Pons7c49cb82020-03-16 23:17:32 +010043 case 0: /* 256MB */
44 pciexbar = pciexbar_reg & (0xffffffffULL << 28);
Stefan Reinauer00636b02012-04-04 00:08:51 +020045 max_buses = 256;
46 break;
Angel Pons7c49cb82020-03-16 23:17:32 +010047 case 1: /* 128M */
48 pciexbar = pciexbar_reg & (0xffffffffULL << 27);
Stefan Reinauer00636b02012-04-04 00:08:51 +020049 max_buses = 128;
50 break;
Angel Pons7c49cb82020-03-16 23:17:32 +010051 case 2: /* 64M */
52 pciexbar = pciexbar_reg & (0xffffffffULL << 26);
Stefan Reinauer00636b02012-04-04 00:08:51 +020053 max_buses = 64;
54 break;
Angel Pons7c49cb82020-03-16 23:17:32 +010055 default: /* RSVD */
Stefan Reinauer00636b02012-04-04 00:08:51 +020056 return current;
57 }
58
59 if (!pciexbar)
60 return current;
61
Angel Pons7c49cb82020-03-16 23:17:32 +010062 current += acpi_create_mcfg_mmconfig((acpi_mcfg_mmconfig_t *) current, pciexbar, 0, 0,
63 max_buses - 1);
Stefan Reinauer00636b02012-04-04 00:08:51 +020064
65 return current;
66}
67
Angel Pons7c49cb82020-03-16 23:17:32 +010068
Nico Huberb3234742018-11-17 14:09:25 +010069static unsigned long acpi_create_igfx_rmrr(const unsigned long current)
70{
71 const u32 base_mask = ~(u32)(MiB - 1);
72
Kyösti Mälkki19bad302019-02-08 18:42:19 +020073 struct device *const host = pcidev_on_root(0, 0);
Nico Huberb3234742018-11-17 14:09:25 +010074 if (!host)
75 return 0;
76
Angel Pons7c49cb82020-03-16 23:17:32 +010077 const u32 bgsm = pci_read_config32(host, BGSM) & base_mask;
Nico Huberb3234742018-11-17 14:09:25 +010078 const u32 tolud = pci_read_config32(host, TOLUD) & base_mask;
79 if (!bgsm || !tolud)
80 return 0;
81
82 return acpi_create_dmar_rmrr(current, 0, bgsm, tolud - 1);
83}
84
Nico Huber9d9ce0d2015-10-26 12:59:49 +010085static unsigned long acpi_fill_dmar(unsigned long current)
86{
Kyösti Mälkkic70eed12018-05-22 02:18:00 +030087 const struct device *const igfx = pcidev_on_root(2, 0);
Nico Huber9d9ce0d2015-10-26 12:59:49 +010088
89 if (igfx && igfx->enabled) {
Nico Huberb3234742018-11-17 14:09:25 +010090 unsigned long tmp;
91
92 tmp = current;
Angel Pons7c49cb82020-03-16 23:17:32 +010093 current += acpi_create_dmar_drhd(current, 0, 0, GFXVT_BASE);
Matt DeVillier7866d492018-03-29 14:59:57 +020094 current += acpi_create_dmar_ds_pci(current, 0, 2, 0);
95 current += acpi_create_dmar_ds_pci(current, 0, 2, 1);
Nico Huber9d9ce0d2015-10-26 12:59:49 +010096 acpi_dmar_drhd_fixup(tmp, current);
Nico Huberb3234742018-11-17 14:09:25 +010097
98 tmp = current;
99 current += acpi_create_igfx_rmrr(current);
100 if (current != tmp) {
101 current += acpi_create_dmar_ds_pci(current, 0, 2, 0);
102 current += acpi_create_dmar_ds_pci(current, 0, 2, 1);
103 acpi_dmar_rmrr_fixup(tmp, current);
104 }
Nico Huber9d9ce0d2015-10-26 12:59:49 +0100105 }
106
107 const unsigned long tmp = current;
Angel Pons7c49cb82020-03-16 23:17:32 +0100108 current += acpi_create_dmar_drhd(current, DRHD_INCLUDE_PCI_ALL, 0, VTVC0_BASE);
109
110 current += acpi_create_dmar_ds_ioapic(current, 2, PCH_IOAPIC_PCI_BUS,
111 PCH_IOAPIC_PCI_SLOT, 0);
112
Nico Huber9d9ce0d2015-10-26 12:59:49 +0100113 size_t i;
114 for (i = 0; i < 8; ++i)
Angel Pons7c49cb82020-03-16 23:17:32 +0100115 current += acpi_create_dmar_ds_msi_hpet(current, 0, PCH_HPET_PCI_BUS,
116 PCH_HPET_PCI_SLOT, i);
117
Nico Huber9d9ce0d2015-10-26 12:59:49 +0100118 acpi_dmar_drhd_fixup(tmp, current);
119
120 return current;
121}
122
Angel Pons7c49cb82020-03-16 23:17:32 +0100123unsigned long northbridge_write_acpi_tables(struct device *const dev, unsigned long current,
Nico Huber9d9ce0d2015-10-26 12:59:49 +0100124 struct acpi_rsdp *const rsdp)
125{
Angel Pons7c49cb82020-03-16 23:17:32 +0100126 const u32 capid0_a = pci_read_config32(dev, CAPID0_A);
Nico Huber9d9ce0d2015-10-26 12:59:49 +0100127 if (capid0_a & (1 << 23))
128 return current;
129
130 printk(BIOS_DEBUG, "ACPI: * DMAR\n");
Angel Pons7c49cb82020-03-16 23:17:32 +0100131
Nico Huber9d9ce0d2015-10-26 12:59:49 +0100132 acpi_dmar_t *const dmar = (acpi_dmar_t *)current;
Angel Pons7c49cb82020-03-16 23:17:32 +0100133
Nico Huber9d9ce0d2015-10-26 12:59:49 +0100134 acpi_create_dmar(dmar, DMAR_INTR_REMAP, acpi_fill_dmar);
135 current += dmar->header.length;
Aaron Durbin07a1b282015-12-10 17:07:38 -0600136 current = acpi_align_current(current);
Nico Huber9d9ce0d2015-10-26 12:59:49 +0100137
Angel Pons7c49cb82020-03-16 23:17:32 +0100138 acpi_add_table(rsdp, dmar);
Aaron Durbin07a1b282015-12-10 17:07:38 -0600139 current = acpi_align_current(current);
Nico Huber9d9ce0d2015-10-26 12:59:49 +0100140
141 printk(BIOS_DEBUG, "current = %lx\n", current);
142
143 return current;
144}