Werner Zeh (werner.zeh(a)siemens.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/15913
-gerrit
commit 0209930b98b24aa8434a3ff4a9def239c2021d6a
Author: Werner Zeh <werner.zeh(a)siemens.com>
Date: Wed Jul 27 08:22:50 2016 +0200
fsp_broadwell_de: Add DMAR table to ACPI
Create DMAR table for Broadwell-DE SoC.
TEST=Booted MC BDX1 into lubuntu15, dumped ACPI tables with acpidump and
disassembled DMAR table using iasl. The table contents are as
expected and the kernel loads DMAR table without errors.
Change-Id: I7933ba4f5f0539a50f2ab9a5571e502c84873ec6
Signed-off-by: Werner Zeh <werner.zeh(a)siemens.com>
---
src/soc/intel/fsp_broadwell_de/acpi.c | 98 +++++++++++++++++++++++
src/soc/intel/fsp_broadwell_de/include/soc/acpi.h | 4 +
src/soc/intel/fsp_broadwell_de/northcluster.c | 19 +++--
3 files changed, 113 insertions(+), 8 deletions(-)
diff --git a/src/soc/intel/fsp_broadwell_de/acpi.c b/src/soc/intel/fsp_broadwell_de/acpi.c
index 1e08868..12aa08a 100644
--- a/src/soc/intel/fsp_broadwell_de/acpi.c
+++ b/src/soc/intel/fsp_broadwell_de/acpi.c
@@ -4,6 +4,7 @@
* Copyright (C) 2007-2009 coresystems GmbH
* Copyright (C) 2013 Google Inc.
* Copyright (C) 2015-2016 Intel Corp.
+ * Copyright (C) 2016 Siemens AG
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -312,6 +313,103 @@ void acpi_fill_in_fadt(acpi_fadt_t *fadt, acpi_facs_t *facs, void *dsdt)
header->checksum = acpi_checksum((void *) fadt, sizeof(acpi_fadt_t));
}
+static unsigned long acpi_fill_dmar(unsigned long current)
+{
+ uint32_t vtbar = 0, tmp = current;
+ device_t dev = dev_find_slot(0, PCI_DEVFN(5, 0));
+ uint16_t bdf = 0, hpet_bdf[8];
+ uint8_t i = 0, j = 0;
+
+ if (!dev)
+ return current;
+
+ vtbar = pci_read_config32(dev, 0x180) & 0xffffe000;
+ if (!vtbar)
+ return current;
+
+ current += acpi_create_dmar_drhd(current,
+ DRHD_INCLUDE_PCI_ALL, 0, vtbar);
+ /* The IIO I/O APIC is fixed on PCI 00:05.4 on Broadwell-DE */
+ current += acpi_create_dmar_drhd_ds_ioapic(current,
+ 9, 0, 5, 4);
+ /* Get the PCI BDF for the PCH I/O APIC */
+ dev = dev_find_slot(0, LPC_DEV_FUNC);
+ bdf = pci_read_config16(dev, 0x6c);
+ current += acpi_create_dmar_drhd_ds_ioapic(current,
+ 8, (bdf >> 8), PCI_SLOT(bdf), PCI_FUNC(bdf));
+
+ /*
+ * Check if there are different PCI paths for the 8 HPET timers
+ * and add every different PCI path as a separate HPET entry.
+ * Although the DMAR specification talks about HPET block for this
+ * entry, it is possible to assign a unique PCI BDF to every single
+ * timer within a HPET block which will result in different source
+ * IDs reported by a generated MSI.
+ * In default configuration every single timer will have the same
+ * PCI BDF which will result in a single HPET entry in DMAR table.
+ * I have checked several different systems and all of them had one
+ * single entry for HPET in DMAR.
+ */
+ memset(hpet_bdf, 0, sizeof(hpet_bdf));
+ /* Get all unique HPET paths. */
+ for (i = 0; i < 8; i++) {
+ bdf = pci_read_config16(dev, 0x70 + (i * 2));
+ for (j = 0; j < ARRAY_SIZE(hpet_bdf); j++) {
+ if (hpet_bdf[j] == bdf)
+ break;
+ }
+ if (j == ARRAY_SIZE(hpet_bdf))
+ hpet_bdf[i] = bdf;
+ }
+ /* Create one HPET entry in DMAR for every unique HPET PCI path. */
+ for (i = 0; i < 8; i++) {
+ if (hpet_bdf[i])
+ current += acpi_create_dmar_drhd_ds_msi_hpet(current,
+ 0, (hpet_bdf[i] >> 8), PCI_SLOT(hpet_bdf[i]),
+ PCI_FUNC(hpet_bdf[i]));
+ }
+ acpi_dmar_drhd_fixup(tmp, current);
+
+ /* Create root port ATSR capability */
+ tmp = current;
+ current += acpi_create_dmar_atsr(current, 0, 0);
+ /* Add one entry to ATSR for each PCI root port */
+ dev = all_devices;
+ do {
+ dev = dev_find_class(PCI_CLASS_BRIDGE_PCI << 8, dev);
+ if (dev && dev->bus->secondary == 0 &&
+ PCI_SLOT(dev->path.pci.devfn) <= 3)
+ current += acpi_create_dmar_drhd_ds_pci_br(current,
+ dev->bus->secondary,
+ PCI_SLOT(dev->path.pci.devfn),
+ PCI_FUNC(dev->path.pci.devfn));
+ } while (dev);
+ acpi_dmar_atsr_fixup(tmp, current);
+
+ return current;
+}
+
+unsigned long northcluster_write_acpi_tables(struct device *const dev,
+ unsigned long current,
+ struct acpi_rsdp *const rsdp)
+{
+ acpi_dmar_t *const dmar = (acpi_dmar_t *)current;
+ device_t vtdev = dev_find_slot(0, PCI_DEVFN(5, 0));
+
+ /* Create DMAR table only if virtualization is enabled */
+ if (!(pci_read_config32(vtdev, 0x180) & 0x01))
+ return current;
+
+ printk(BIOS_DEBUG, "ACPI: * DMAR\n");
+ acpi_create_dmar(dmar, DMAR_INTR_REMAP, acpi_fill_dmar);
+ current += dmar->header.length;
+ current = acpi_align_current(current);
+ acpi_add_table(rsdp, dmar);
+ current = acpi_align_current(current);
+
+ return current;
+}
+
static int calculate_power(int tdp, int p1_ratio, int ratio)
{
u32 m;
diff --git a/src/soc/intel/fsp_broadwell_de/include/soc/acpi.h b/src/soc/intel/fsp_broadwell_de/include/soc/acpi.h
index f717d15..da552cc 100644
--- a/src/soc/intel/fsp_broadwell_de/include/soc/acpi.h
+++ b/src/soc/intel/fsp_broadwell_de/include/soc/acpi.h
@@ -3,6 +3,7 @@
*
* Copyright (C) 2013 Google, Inc.
* Copyright (C) 2015-2016 Intel Corp.
+ * Copyright (C) 2016 Siemens AG
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,5 +24,8 @@ void acpi_create_intel_hpet(acpi_hpet_t *hpet);
void acpi_fill_in_fadt(acpi_fadt_t *fadt, acpi_facs_t *facs, void *dsdt);
unsigned long acpi_madt_irq_overrides(unsigned long current);
uint16_t get_pmbase(void);
+unsigned long northcluster_write_acpi_tables(struct device *const dev,
+ unsigned long current,
+ struct acpi_rsdp *const rsdp);
#endif /* _SOC_ACPI_H_ */
diff --git a/src/soc/intel/fsp_broadwell_de/northcluster.c b/src/soc/intel/fsp_broadwell_de/northcluster.c
index 307137b..c15ff5f 100644
--- a/src/soc/intel/fsp_broadwell_de/northcluster.c
+++ b/src/soc/intel/fsp_broadwell_de/northcluster.c
@@ -3,6 +3,7 @@
*
* Copyright (C) 2013 Google Inc.
* Copyright (C) 2015-2016 Intel Corp.
+ * Copyright (C) 2016 Siemens AG
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,6 +25,7 @@
#include <soc/iomap.h>
#include <soc/pci_devs.h>
#include <soc/ramstage.h>
+#include <soc/acpi.h>
static const int legacy_hole_base_k = 0xa0000 / 1024;
static const int legacy_hole_size_k = 384;
@@ -133,14 +135,15 @@ static void nc_enable(device_t dev)
}
static struct device_operations nc_ops = {
- .read_resources = nc_read_resources,
+ .read_resources = nc_read_resources,
.acpi_fill_ssdt_generator = generate_cpu_entries,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = NULL,
- .enable = &nc_enable,
- .scan_bus = 0,
- .ops_pci = &soc_pci_ops,
+ .write_acpi_tables = northcluster_write_acpi_tables,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = NULL,
+ .enable = &nc_enable,
+ .scan_bus = 0,
+ .ops_pci = &soc_pci_ops,
};
static const struct pci_driver nc_driver __pci_driver = {
@@ -153,4 +156,4 @@ static const struct pci_driver nc_driver_es2 __pci_driver = {
.ops = &nc_ops,
.vendor = PCI_VENDOR_ID_INTEL,
.device = SOC_DEVID_ES2,
-};
\ No newline at end of file
+};
Werner Zeh (werner.zeh(a)siemens.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/15911
-gerrit
commit b5016cce3aad176be012a773c51f8742cfec1d36
Author: Werner Zeh <werner.zeh(a)siemens.com>
Date: Wed Jul 27 06:56:36 2016 +0200
ACPI: Add code to include ATSR structure in DMAR table
When creating DMAR table one needs to report all PCI root ports in the
scope of a ATSR structure. Add code to create this ATS reporting
structure. In addition, a function to fix up the size of the ATSR
structure is added as this is a new type and using the function
acpi_dmar_drhd_fixup() can lead to confusion.
Change-Id: Idc3f6025f597048151f0fd5ea6be04843041e1ab
Signed-off-by: Werner Zeh <werner.zeh(a)siemens.com>
---
src/arch/x86/acpi.c | 19 +++++++++++++++++++
src/arch/x86/include/arch/acpi.h | 11 +++++++++++
2 files changed, 30 insertions(+)
diff --git a/src/arch/x86/acpi.c b/src/arch/x86/acpi.c
index 3661297..3aee2a1 100644
--- a/src/arch/x86/acpi.c
+++ b/src/arch/x86/acpi.c
@@ -433,12 +433,31 @@ unsigned long acpi_create_dmar_drhd(unsigned long current, u8 flags,
return drhd->length;
}
+unsigned long acpi_create_dmar_atsr(unsigned long current, u8 flags,
+ u16 segment)
+{
+ dmar_atsr_entry_t *atsr = (dmar_atsr_entry_t *)current;
+ memset(atsr, 0, sizeof(*atsr));
+ atsr->type = DMAR_ATSR;
+ atsr->length = sizeof(*atsr); /* will be fixed up later */
+ atsr->flags = flags;
+ atsr->segment = segment;
+
+ return atsr->length;
+}
+
void acpi_dmar_drhd_fixup(unsigned long base, unsigned long current)
{
dmar_entry_t *drhd = (dmar_entry_t *)base;
drhd->length = current - base;
}
+void acpi_dmar_atsr_fixup(unsigned long base, unsigned long current)
+{
+ dmar_atsr_entry_t *atsr = (dmar_atsr_entry_t *)base;
+ atsr->length = current - base;
+}
+
static unsigned long acpi_create_dmar_drhd_ds(unsigned long current,
enum dev_scope_type type, u8 enumeration_id, u8 bus, u8 dev, u8 fn)
{
diff --git a/src/arch/x86/include/arch/acpi.h b/src/arch/x86/include/arch/acpi.h
index dfbffb3..b67213d 100644
--- a/src/arch/x86/include/arch/acpi.h
+++ b/src/arch/x86/include/arch/acpi.h
@@ -285,6 +285,14 @@ typedef struct dmar_entry {
u64 bar;
} __attribute__ ((packed)) dmar_entry_t;
+typedef struct dmar_atsr_entry {
+ u16 type;
+ u16 length;
+ u8 flags;
+ u8 reserved;
+ u16 segment;
+} __attribute__ ((packed)) dmar_atsr_entry_t;
+
/* DMAR (DMA Remapping Reporting Structure) */
typedef struct acpi_dmar {
struct acpi_table_header header;
@@ -607,7 +615,10 @@ void acpi_create_dmar(acpi_dmar_t *dmar, enum dmar_flags flags,
unsigned long (*acpi_fill_dmar) (unsigned long));
unsigned long acpi_create_dmar_drhd(unsigned long current, u8 flags,
u16 segment, u32 bar);
+unsigned long acpi_create_dmar_atsr(unsigned long current, u8 flags,
+ u16 segment);
void acpi_dmar_drhd_fixup(unsigned long base, unsigned long current);
+void acpi_dmar_atsr_fixup(unsigned long base, unsigned long current);
unsigned long acpi_create_dmar_drhd_ds_pci(unsigned long current,
u8 bus, u8 dev, u8 fn);
unsigned long acpi_create_dmar_drhd_ds_ioapic(unsigned long current,
Werner Zeh (werner.zeh(a)siemens.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/15912
-gerrit
commit 541c7af206c0a5bcfa62c8ee7b72131cf9d83d3f
Author: Werner Zeh <werner.zeh(a)siemens.com>
Date: Wed Jul 27 07:07:20 2016 +0200
ACPI: Add code to create root port entry in DMAR table
PCI root ports need to be reported in DMAR table in the ATSR scope.
Add code to create an entry for a PCI root port using the type
"SCOPE_PCI_SUB".
Change-Id: Ie2c46db7292d9f1637ffe2e9cfaf6619372ddf13
Signed-off-by: Werner Zeh <werner.zeh(a)siemens.com>
---
src/arch/x86/acpi.c | 7 +++++++
src/arch/x86/include/arch/acpi.h | 2 ++
2 files changed, 9 insertions(+)
diff --git a/src/arch/x86/acpi.c b/src/arch/x86/acpi.c
index 3aee2a1..667340e 100644
--- a/src/arch/x86/acpi.c
+++ b/src/arch/x86/acpi.c
@@ -476,6 +476,13 @@ static unsigned long acpi_create_dmar_drhd_ds(unsigned long current,
return ds->length;
}
+unsigned long acpi_create_dmar_drhd_ds_pci_br(unsigned long current, u8 bus,
+ u8 dev, u8 fn)
+{
+ return acpi_create_dmar_drhd_ds(current,
+ SCOPE_PCI_SUB, 0, bus, dev, fn);
+}
+
unsigned long acpi_create_dmar_drhd_ds_pci(unsigned long current, u8 bus,
u8 dev, u8 fn)
{
diff --git a/src/arch/x86/include/arch/acpi.h b/src/arch/x86/include/arch/acpi.h
index b67213d..2b320a2 100644
--- a/src/arch/x86/include/arch/acpi.h
+++ b/src/arch/x86/include/arch/acpi.h
@@ -619,6 +619,8 @@ unsigned long acpi_create_dmar_atsr(unsigned long current, u8 flags,
u16 segment);
void acpi_dmar_drhd_fixup(unsigned long base, unsigned long current);
void acpi_dmar_atsr_fixup(unsigned long base, unsigned long current);
+unsigned long acpi_create_dmar_drhd_ds_pci_br(unsigned long current,
+ u8 bus, u8 dev, u8 fn);
unsigned long acpi_create_dmar_drhd_ds_pci(unsigned long current,
u8 bus, u8 dev, u8 fn);
unsigned long acpi_create_dmar_drhd_ds_ioapic(unsigned long current,
the following patch was just integrated into master:
commit a90f41bdd71bd3f98c683702f90247e674a50896
Author: Subrata Banik <subrata.banik(a)intel.com>
Date: Wed Jul 27 05:30:50 2016 +0530
intel/fsp1_1: Add C entry support to locate FSP Temp RAM Init
FSP temp ram init was getting called earlier from ROMCC bootblock.
Now with C entry boot block, it is needed to locate FSP header and
call FspTempRamInit.
Hence add fsp 1_1 driver code to locate FSP Temp ram and execute.
BUG=chrome-os-partner:55357
BRANCH=none
TEST=Built kunimitsu and ensure FSP Temp Ram Init return success
Change-Id: If40b267777a8dc5c473d1115b19b98609ff3fd74
Signed-off-by: Subrata Banik <subrata.banik(a)intel.com>
Reviewed-on: https://review.coreboot.org/15787
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin(a)chromium.org>
See https://review.coreboot.org/15787 for details.
-gerrit
Subrata Banik (subrata.banik(a)intel.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/15787
-gerrit
commit e05d9a97ca0936025e281c81af3657ed8decace2
Author: Subrata Banik <subrata.banik(a)intel.com>
Date: Wed Jul 27 05:30:50 2016 +0530
intel/fsp1_1: Add C entry support to locate FSP Temp RAM Init
FSP temp ram init was getting called earlier from ROMCC bootblock.
Now with C entry boot block, it is needed to locate FSP header and
call FspTempRamInit.
Hence add fsp 1_1 driver code to locate FSP Temp ram and execute.
BUG=chrome-os-partner:55357
BRANCH=none
TEST=Built kunimitsu and ensure FSP Temp Ram Init return success
Change-Id: If40b267777a8dc5c473d1115b19b98609ff3fd74
Signed-off-by: Subrata Banik <subrata.banik(a)intel.com>
---
src/drivers/intel/fsp1_1/Makefile.inc | 3 ++
src/drivers/intel/fsp1_1/bootblock.c | 53 ++++++++++++++++++++++++
src/drivers/intel/fsp1_1/include/fsp/bootblock.h | 21 ++++++++++
src/soc/intel/skylake/bootblock/bootblock.c | 13 +++---
4 files changed, 85 insertions(+), 5 deletions(-)
diff --git a/src/drivers/intel/fsp1_1/Makefile.inc b/src/drivers/intel/fsp1_1/Makefile.inc
index 011df67..397bad8 100644
--- a/src/drivers/intel/fsp1_1/Makefile.inc
+++ b/src/drivers/intel/fsp1_1/Makefile.inc
@@ -20,6 +20,9 @@ verstage-y += car.c
verstage-y += fsp_util.c
verstage-y += verstage.c
+bootblock-y += bootblock.c
+bootblock-y += fsp_util.c
+
romstage-y += car.c
romstage-y += fsp_util.c
romstage-y += hob.c
diff --git a/src/drivers/intel/fsp1_1/bootblock.c b/src/drivers/intel/fsp1_1/bootblock.c
new file mode 100644
index 0000000..c0f26d9
--- /dev/null
+++ b/src/drivers/intel/fsp1_1/bootblock.c
@@ -0,0 +1,53 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <console/console.h>
+#include <fsp/bootblock.h>
+#include <fsp/util.h>
+
+static void fill_temp_ram_init_params(FSP_TEMP_RAM_INIT_PARAMS *params)
+{
+ params->MicrocodeRegionBase = CONFIG_CPU_MICROCODE_CBFS_LOC;
+ params->MicrocodeRegionLength = CONFIG_CPU_MICROCODE_CBFS_LEN;
+ params->CodeRegionBase = 0xFFFFFFFF - CONFIG_ROM_SIZE + 1;
+ params->CodeRegionLength = CONFIG_ROM_SIZE;
+}
+
+void bootblock_fsp_temp_ram_init(void)
+{
+ FSP_TEMP_RAM_INIT fsp_temp_ram_init;
+ FSP_TEMP_RAM_INIT_PARAMS temp_ram_init_params;
+ FSP_INFO_HEADER *fih;
+ EFI_STATUS status;
+
+ /* Locate the FSP header */
+ fih = find_fsp(CONFIG_FSP_LOC);
+ /* Check the FSP header */
+ if (fih == NULL)
+ die("FSP_INFO_HEADER not set!\n");
+
+ fill_temp_ram_init_params(&temp_ram_init_params);
+
+ /* Perform Temp RAM Init */
+ printk(BIOS_DEBUG, "Calling FspTempRamInit\n");
+ post_code(POST_FSP_TEMP_RAM_INIT);
+ fsp_temp_ram_init = (FSP_TEMP_RAM_INIT)(fih->ImageBase
+ + fih->TempRamInitEntryOffset);
+ status = fsp_temp_ram_init(&temp_ram_init_params);
+ if (status != FSP_SUCCESS)
+ die("FspTempRamInit failed. Giving up.");
+
+ printk(BIOS_DEBUG, "FspTempRamInit returned 0x%08x\n", status);
+}
diff --git a/src/drivers/intel/fsp1_1/include/fsp/bootblock.h b/src/drivers/intel/fsp1_1/include/fsp/bootblock.h
new file mode 100644
index 0000000..a962bdf
--- /dev/null
+++ b/src/drivers/intel/fsp1_1/include/fsp/bootblock.h
@@ -0,0 +1,21 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef FSP1_1_BOOTBLOCK_H
+#define FSP1_1_BOOTBLOCK_H
+
+void bootblock_fsp_temp_ram_init(void);
+
+#endif
diff --git a/src/soc/intel/skylake/bootblock/bootblock.c b/src/soc/intel/skylake/bootblock/bootblock.c
index 028bb7b..ab1720c 100644
--- a/src/soc/intel/skylake/bootblock/bootblock.c
+++ b/src/soc/intel/skylake/bootblock/bootblock.c
@@ -14,6 +14,7 @@
*/
#include <bootblock_common.h>
+#include <fsp/bootblock.h>
#include <soc/bootblock.h>
#include <soc/romstage.h>
@@ -33,13 +34,15 @@ void bootblock_soc_early_init(void)
pch_uart_init();
}
-/*
- * Perform early chipset initialization before fsp memory init
- * example: pirq->irq programming, enabling smbus, pmcbase, abase,
- * get platform info, i2c programming
- */
void bootblock_soc_init(void)
{
+ /* locate and call FspTempRamInit */
+ bootblock_fsp_temp_ram_init();
+ /*
+ * Perform early chipset initialization before fsp memory init
+ * example: pirq->irq programming, enabling smbus, pmcbase, abase,
+ * get platform info, i2c programming
+ */
report_platform_info();
set_max_freq();
pch_early_init();