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>
10 #include "sandybridge.h"
11 #include <southbridge/intel/bd82x6x/pch.h>
13 static unsigned long acpi_create_igfx_rmrr(const unsigned long current
)
15 const u32 base_mask
= ~(u32
)(MiB
- 1);
17 struct device
*const host
= pcidev_on_root(0, 0);
21 const u32 bgsm
= pci_read_config32(host
, BGSM
) & base_mask
;
22 const u32 tolud
= pci_read_config32(host
, TOLUD
) & base_mask
;
26 return acpi_create_dmar_rmrr(current
, 0, bgsm
, tolud
- 1);
29 static unsigned long acpi_fill_dmar(unsigned long current
)
31 const struct device
*const igfx
= pcidev_on_root(2, 0);
33 /* First, add DRHD entries */
34 if (igfx
&& igfx
->enabled
) {
35 const unsigned long tmp
= current
;
37 current
+= acpi_create_dmar_drhd_4k(current
, 0, 0, GFXVT_BASE
);
38 current
+= acpi_create_dmar_ds_pci(current
, 0, 2, 0);
39 acpi_dmar_drhd_fixup(tmp
, current
);
43 const unsigned long tmp
= current
;
44 current
+= acpi_create_dmar_drhd_4k(current
, DRHD_INCLUDE_PCI_ALL
, 0, VTVC0_BASE
);
46 current
+= acpi_create_dmar_ds_ioapic_from_hw(current
, IO_APIC_ADDR
,
48 PCH_IOAPIC_PCI_SLOT
, 0);
51 for (i
= 0; i
< 8; ++i
)
52 current
+= acpi_create_dmar_ds_msi_hpet(current
, 0, PCH_HPET_PCI_BUS
,
53 PCH_HPET_PCI_SLOT
, i
);
55 acpi_dmar_drhd_fixup(tmp
, current
);
58 /* Then, add RMRR entries after all DRHD entries */
59 if (igfx
&& igfx
->enabled
) {
60 const unsigned long tmp
= current
;
62 current
+= acpi_create_igfx_rmrr(current
);
64 current
+= acpi_create_dmar_ds_pci(current
, 0, 2, 0);
65 acpi_dmar_rmrr_fixup(tmp
, current
);
72 unsigned long northbridge_write_acpi_tables(const struct device
*const dev
,
73 unsigned long current
,
74 struct acpi_rsdp
*const rsdp
)
76 const u32 capid0_a
= pci_read_config32(dev
, CAPID0_A
);
77 if (capid0_a
& (1 << 23))
80 printk(BIOS_DEBUG
, "ACPI: * DMAR\n");
82 acpi_dmar_t
*const dmar
= (acpi_dmar_t
*)current
;
84 acpi_create_dmar(dmar
, DMAR_INTR_REMAP
, acpi_fill_dmar
);
85 current
+= dmar
->header
.length
;
86 current
= acpi_align_current(current
);
88 acpi_add_table(rsdp
, dmar
);
89 current
= acpi_align_current(current
);
91 printk(BIOS_DEBUG
, "current = %lx\n", current
);