[coreboot-gerrit] Patch set updated for coreboot: device/pci_rom: Implement ACPI table VFCT
Patrick Rudolph (siro@das-labor.org)
gerrit at coreboot.org
Fri Apr 1 18:46:37 CEST 2016
Patrick Rudolph (siro at das-labor.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14224
-gerrit
commit 8ab56b16489e7dcc4e5043ead9d389de0fd24ca1
Author: Patrick Rudolph <siro at das-labor.org>
Date: Thu Mar 31 20:04:23 2016 +0200
device/pci_rom: Implement ACPI table VFCT
The ACPI table VFCT (VBIOS Fetch Table) is used by AMD to
fetch the VBIOS.
Only fill VFCT for enabled AMD VGA devices.
Test system:
* Gigabyte GA-B75M-D3H
* Intel Pentium CPU G2130
* AMD Radeon HD4870
Depends on: I3b7098f53462a3a65044e9314cf6f3cd938cc99a
Change-Id: I3b4a587c71e7165338cad3aca77ed5afa085a63c
Signed-off-by: Patrick Rudolph <siro at das-labor.org>
---
src/arch/x86/acpi.c | 25 +++++++++++++++++
src/arch/x86/include/arch/acpi.h | 29 +++++++++++++++++++
src/device/pci_device.c | 1 +
src/device/pci_rom.c | 60 ++++++++++++++++++++++++++++++++++++++++
src/include/device/pci_rom.h | 5 ++++
5 files changed, 120 insertions(+)
diff --git a/src/arch/x86/acpi.c b/src/arch/x86/acpi.c
index 5640ad0..206c4d6 100644
--- a/src/arch/x86/acpi.c
+++ b/src/arch/x86/acpi.c
@@ -536,6 +536,31 @@ void acpi_create_hpet(acpi_hpet_t *hpet)
header->checksum = acpi_checksum((void *)hpet, sizeof(acpi_hpet_t));
}
+void acpi_create_vfct(struct device *device,
+ struct acpi_vfct *vfct,
+ unsigned long (*acpi_fill_vfct)(struct device *device, struct acpi_vfct *vfct_struct, unsigned long current))
+{
+ acpi_header_t *header = &(vfct->header);
+ unsigned long current = (unsigned long)vfct + sizeof(struct acpi_vfct);
+
+ memset((void *)vfct, 0, sizeof(struct acpi_vfct));
+
+ /* Fill out header fields. */
+ memcpy(header->signature, "VFCT", 4);
+ memcpy(header->oem_id, OEM_ID, 6);
+ memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
+ memcpy(header->asl_compiler_id, ASLC, 4);
+
+ header->length = sizeof(struct acpi_vfct);
+ header->revision = 1; /* ACPI 1.0: N/A, ACPI 2.0/3.0/4.0: 1 */
+
+ current = acpi_fill_vfct(device, vfct, current);
+
+ /* (Re)calculate length and checksum. */
+ header->length = current - (unsigned long)vfct;
+ header->checksum = acpi_checksum((void *)vfct, header->length);
+}
+
void acpi_create_ivrs(acpi_ivrs_t *ivrs,
unsigned long (*acpi_fill_ivrs)(acpi_ivrs_t* ivrs_struct, unsigned long current))
{
diff --git a/src/arch/x86/include/arch/acpi.h b/src/arch/x86/include/arch/acpi.h
index 276ca52..eb2892c 100644
--- a/src/arch/x86/include/arch/acpi.h
+++ b/src/arch/x86/include/arch/acpi.h
@@ -192,6 +192,31 @@ typedef struct acpi_madt {
u32 flags; /* Multiple APIC flags */
} __attribute__ ((packed)) acpi_madt_t;
+
+/* VFCT image header */
+struct acpi_vfct_image_hdr {
+ u32 PCIBus; //0x4C
+ u32 PCIDevice; //0x50
+ u32 PCIFunction; //0x54
+ u16 VendorID; //0x58
+ u16 DeviceID; //0x5A
+ u16 SSVID; //0x5C
+ u16 SSID; //0x5E
+ u32 Revision; //0x60
+ u32 ImageLength; //0x64
+ u8 VbiosContent; // dummy - copy VBIOS here
+} __attribute__ ((packed));
+
+/* VFCT (VBIOS Fetch Table) */
+struct acpi_vfct {
+ struct acpi_table_header header;
+ u8 TableUUID[16]; //0x24
+ u32 VBIOSImageOffset; //0x34.
+ u32 Lib1ImageOffset; //0x38.
+ u32 Reserved[4]; //0x3C
+ struct acpi_vfct_image_hdr image_hdr;
+} __attribute__ ((packed));
+
typedef struct acpi_ivrs_info {
} __attribute__ ((packed)) acpi_ivrs_info_t;
@@ -565,6 +590,10 @@ void acpi_create_srat(acpi_srat_t *srat,
void acpi_create_slit(acpi_slit_t *slit,
unsigned long (*acpi_fill_slit)(unsigned long current));
+void acpi_create_vfct(struct device *device,
+ struct acpi_vfct *vfct,
+ unsigned long (*acpi_fill_vfct)(struct device *device, struct acpi_vfct *vfct_struct, unsigned long current));
+
void acpi_create_ivrs(acpi_ivrs_t *ivrs,
unsigned long (*acpi_fill_ivrs)(acpi_ivrs_t* ivrs_struct, unsigned long current));
diff --git a/src/device/pci_device.c b/src/device/pci_device.c
index 5f02955..b51e650 100644
--- a/src/device/pci_device.c
+++ b/src/device/pci_device.c
@@ -664,6 +664,7 @@ struct device_operations default_pci_ops_dev = {
.read_resources = pci_dev_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_dev_enable_resources,
+ .write_acpi_tables = pci_rom_write_acpi_tables,
.init = pci_dev_init,
.scan_bus = 0,
.enable = 0,
diff --git a/src/device/pci_rom.c b/src/device/pci_rom.c
index 288a5f0..0b3a6d8 100644
--- a/src/device/pci_rom.c
+++ b/src/device/pci_rom.c
@@ -251,3 +251,63 @@ void pci_rom_load_and_run(struct device *dev)
printk(BIOS_DEBUG, "VGA Option ROM was run\n");
#endif /* CONFIG_VGA_ROM_RUN */
}
+
+static unsigned long
+pci_rom_acpi_fill_vfct(struct device *device,
+ struct acpi_vfct *vfct_struct,
+ unsigned long current)
+{
+ struct acpi_vfct_image_hdr *header = &vfct_struct->image_hdr;
+ struct rom_header *rom, *ram;
+
+ vfct_struct->VBIOSImageOffset = (size_t)header - (size_t)vfct_struct;
+
+ rom = pci_rom_probe(device);
+ if (!rom) {
+ printk(BIOS_DEBUG, "pci_rom_probe: %p\n", rom);
+ return current;
+ }
+
+ ram = pci_rom_load(device, rom, (void *)&header->VbiosContent);
+ if (!ram) {
+ printk(BIOS_DEBUG, "pci_rom_load: %p\n", rom);
+ return current;
+ }
+ header->DeviceID = device->device;
+ header->VendorID = device->vendor;
+ header->PCIBus = device->bus->secondary;
+ header->PCIFunction = PCI_FUNC(device->path.pci.devfn);
+ header->PCIDevice = PCI_SLOT(device->path.pci.devfn);
+ header->ImageLength = ram->size * 512;
+
+ current += header->ImageLength;
+ return current;
+}
+
+unsigned long
+pci_rom_write_acpi_tables(struct device *device,
+ unsigned long current,
+ struct acpi_rsdp *rsdp)
+{
+ struct acpi_vfct *vfct;
+
+ /* only handle VGA devices */
+ if ((device->class >> 8) != PCI_CLASS_DISPLAY_VGA)
+ return current;
+
+ /* only handle enabled devices */
+ if (!device->enabled)
+ return current;
+
+ /* AMD/ATI uses VFCT */
+ if (device->vendor == PCI_VENDOR_ID_ATI) {
+ current = ALIGN(current, 8);
+ printk(BIOS_DEBUG, "ACPI: * VFCT at %lx\n", current);
+ vfct = (struct acpi_vfct *)current;
+ acpi_create_vfct(device, vfct, pci_rom_acpi_fill_vfct);
+ current += vfct->header.length;
+ acpi_add_table(rsdp, vfct);
+ }
+
+ return current;
+}
diff --git a/src/include/device/pci_rom.h b/src/include/device/pci_rom.h
index 1dff9a7..ebda54c 100644
--- a/src/include/device/pci_rom.h
+++ b/src/include/device/pci_rom.h
@@ -2,6 +2,7 @@
#define PCI_ROM_H
#include <endian.h>
#include <stddef.h>
+#include <arch/acpi.h>
#define PCI_ROM_HDR 0xAA55
#define PCI_DATA_HDR (uint32_t) ( ('R' << 24) | ('I' << 16) | ('C' << 8) | 'P' )
@@ -37,6 +38,10 @@ struct rom_header *pci_rom_probe(struct device *dev);
struct rom_header *pci_rom_load(struct device *dev,
struct rom_header *rom_header,
void *load_addr);
+unsigned long
+pci_rom_write_acpi_tables(struct device *device,
+ unsigned long current,
+ struct acpi_rsdp *rsdp);
void pci_rom_load_and_run(struct device *dev);
u32 map_oprom_vendev(u32 vendev);
More information about the coreboot-gerrit
mailing list