1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <console/console.h>
5 #include <commonlib/helpers.h>
7 #include <arch/ioapic.h>
8 #include <device/device.h>
9 #include <device/pci_ops.h>
11 #include <southbridge/intel/lynxpoint/pch.h>
13 static unsigned long acpi_fill_dmar(unsigned long current
)
15 struct device
*const igfx_dev
= pcidev_on_root(2, 0);
16 const u32 gfxvtbar
= mchbar_read32(GFXVTBAR
) & ~0xfff;
17 const u32 vtvc0bar
= mchbar_read32(VTVC0BAR
) & ~0xfff;
18 const bool gfxvten
= mchbar_read32(GFXVTBAR
) & 0x1;
19 const bool vtvc0en
= mchbar_read32(VTVC0BAR
) & 0x1;
21 /* iGFX has to be enabled; GFXVTBAR set, enabled, in 32-bit space */
23 igfx_dev
&& igfx_dev
->enabled
&&
24 gfxvtbar
&& gfxvten
&&
25 !mchbar_read32(GFXVTBAR
+ 4);
27 /* First, add DRHD entries */
29 const unsigned long tmp
= current
;
31 current
+= acpi_create_dmar_drhd_4k(current
, 0, 0, gfxvtbar
);
32 current
+= acpi_create_dmar_ds_pci(current
, 0, 2, 0);
34 acpi_dmar_drhd_fixup(tmp
, current
);
37 /* VTVC0BAR has to be set, enabled, and in 32-bit space */
38 if (vtvc0bar
&& vtvc0en
&& !mchbar_read32(VTVC0BAR
+ 4)) {
39 const unsigned long tmp
= current
;
40 current
+= acpi_create_dmar_drhd_4k(current
, DRHD_INCLUDE_PCI_ALL
, 0, vtvc0bar
);
41 current
+= acpi_create_dmar_ds_ioapic_from_hw(current
, IO_APIC_ADDR
,
43 PCH_IOAPIC_PCI_SLOT
, 0);
46 for (i
= 0; i
< 8; ++i
)
47 current
+= acpi_create_dmar_ds_msi_hpet(current
, 0, PCH_HPET_PCI_BUS
,
48 PCH_HPET_PCI_SLOT
, i
);
49 acpi_dmar_drhd_fixup(tmp
, current
);
52 /* Then, add RMRR entries after all DRHD entries */
54 const unsigned long tmp
= current
;
56 const struct device
*sa_dev
= pcidev_on_root(0, 0);
58 /* Bit 0 is lock bit, not part of address */
59 const u32 tolud
= pci_read_config32(sa_dev
, TOLUD
) & ~1;
60 const u32 bgsm
= pci_read_config32(sa_dev
, BGSM
) & ~1;
62 current
+= acpi_create_dmar_rmrr(current
, 0, bgsm
, tolud
- 1);
63 current
+= acpi_create_dmar_ds_pci(current
, 0, 2, 0);
64 acpi_dmar_rmrr_fixup(tmp
, current
);
70 unsigned long northbridge_write_acpi_tables(const struct device
*const dev
,
71 unsigned long current
,
72 struct acpi_rsdp
*const rsdp
)
74 /* Create DMAR table only if we have VT-d capability. */
75 const u32 capid0_a
= pci_read_config32(dev
, CAPID0_A
);
76 if (capid0_a
& VTD_DISABLE
)
79 acpi_dmar_t
*const dmar
= (acpi_dmar_t
*)current
;
80 printk(BIOS_DEBUG
, "ACPI: * DMAR\n");
81 acpi_create_dmar(dmar
, DMAR_INTR_REMAP
, acpi_fill_dmar
);
82 current
+= dmar
->header
.length
;
83 current
= acpi_align_current(current
);
84 acpi_add_table(rsdp
, dmar
);