From: Wei Wang <wei.wang2@amd.com>
To: JBeulich@suse.com, keir@xen.org
Cc: xen-devel@lists.xensource.com
Subject: [PATCH 12 of 16] hvmloader: Build IVRS table
Date: Wed, 14 Dec 2011 16:29:33 +0100 [thread overview]
Message-ID: <42ecb2ba593c2827b2dc.1323876573@gran.amd.com> (raw)
In-Reply-To: <patchbomb.1323876561@gran.amd.com>
# HG changeset patch
# User Wei Wang <wei.wang2@amd.com>
# Date 1323876140 -3600
# Node ID 42ecb2ba593c2827b2dc4e54360f8c6a42a4dbfc
# Parent 9a93e064dd3c467ce4b87ddef8739a3573ef547c
hvmloader: Build IVRS table.
Signed-off-by: Wei Wang <wei.wang2@amd.com>
diff -r 9a93e064dd3c -r 42ecb2ba593c tools/firmware/hvmloader/acpi/acpi2_0.h
--- a/tools/firmware/hvmloader/acpi/acpi2_0.h Wed Dec 14 16:16:16 2011 +0100
+++ b/tools/firmware/hvmloader/acpi/acpi2_0.h Wed Dec 14 16:22:20 2011 +0100
@@ -389,6 +389,60 @@ struct acpi_20_madt_intsrcovr {
#define ACPI_2_0_WAET_REVISION 0x01
#define ACPI_1_0_FADT_REVISION 0x01
+#define IVRS_SIGNATURE ASCII32('I','V','R','S')
+#define IVRS_REVISION 1
+#define IVRS_VASIZE 64
+#define IVRS_PASIZE 52
+#define IVRS_GVASIZE 64
+
+#define IVHD_BLOCK_TYPE 0x10
+#define IVHD_FLAG_HTTUNEN (1 << 0)
+#define IVHD_FLAG_PASSPW (1 << 1)
+#define IVHD_FLAG_RESPASSPW (1 << 2)
+#define IVHD_FLAG_ISOC (1 << 3)
+#define IVHD_FLAG_IOTLBSUP (1 << 4)
+#define IVHD_FLAG_COHERENT (1 << 5)
+#define IVHD_FLAG_PREFSUP (1 << 6)
+#define IVHD_FLAG_PPRSUP (1 << 7)
+
+#define IVHD_EFR_GTSUP (1 << 2)
+#define IVHD_EFR_IASUP (1 << 5)
+
+#define IVHD_SELECT_4_BYTE 0x2
+
+struct ivrs_ivhd_block
+{
+ uint8_t type;
+ uint8_t flags;
+ uint16_t length;
+ uint16_t devid;
+ uint16_t cap_offset;
+ uint64_t iommu_base_addr;
+ uint16_t pci_segment;
+ uint16_t iommu_info;
+ uint32_t reserved;
+};
+
+/* IVHD 4-byte device entries */
+struct ivrs_ivhd_device
+{
+ uint8_t type;
+ uint16_t dev_id;
+ uint8_t flags;
+};
+
+#define PT_DEV_MAX_NR 32
+#define IOMMU_CAP_OFFSET 0x40
+struct acpi_40_ivrs
+{
+ struct acpi_header header;
+ uint32_t iv_info;
+ uint32_t reserved[2];
+ struct ivrs_ivhd_block ivhd_block;
+ struct ivrs_ivhd_device ivhd_device[PT_DEV_MAX_NR];
+};
+
+
#pragma pack ()
struct acpi_config {
diff -r 9a93e064dd3c -r 42ecb2ba593c tools/firmware/hvmloader/acpi/build.c
--- a/tools/firmware/hvmloader/acpi/build.c Wed Dec 14 16:16:16 2011 +0100
+++ b/tools/firmware/hvmloader/acpi/build.c Wed Dec 14 16:22:20 2011 +0100
@@ -23,6 +23,8 @@
#include "ssdt_pm.h"
#include "../config.h"
#include "../util.h"
+#include "../hypercall.h"
+#include <xen/hvm/params.h>
#define align16(sz) (((sz) + 15) & ~15)
#define fixed_strcpy(d, s) strncpy((d), (s), sizeof(d))
@@ -198,6 +200,77 @@ static struct acpi_20_waet *construct_wa
return waet;
}
+extern uint32_t ptdev_bdf[PT_DEV_MAX_NR];
+extern uint32_t ptdev_nr;
+extern uint32_t iommu_bdf;
+static struct acpi_40_ivrs* construct_ivrs(void)
+{
+ struct acpi_40_ivrs *ivrs;
+ uint64_t mmio;
+ struct ivrs_ivhd_block *ivhd;
+ struct ivrs_ivhd_device *dev_entry;
+ struct xen_hvm_param p;
+
+ if (ptdev_nr == 0) return NULL;
+
+ ivrs = mem_alloc(sizeof(*ivrs), 16);
+ if (!ivrs) return NULL;
+
+ memset(ivrs, 0, sizeof(*ivrs));
+
+ /* initialize acpi header */
+ ivrs->header.signature = IVRS_SIGNATURE;
+ ivrs->header.revision = IVRS_REVISION;
+ fixed_strcpy(ivrs->header.oem_id, ACPI_OEM_ID);
+ fixed_strcpy(ivrs->header.oem_table_id, ACPI_OEM_TABLE_ID);
+
+ ivrs->header.oem_revision = ACPI_OEM_REVISION;
+ ivrs->header.creator_id = ACPI_CREATOR_ID;
+ ivrs->header.creator_revision = ACPI_CREATOR_REVISION;
+
+ ivrs->header.length = sizeof(*ivrs);
+
+ /* initialize IVHD Block */
+ ivhd = &ivrs->ivhd_block;
+ ivrs->iv_info = (IVRS_VASIZE << 15) | (IVRS_PASIZE << 8) |
+ (IVRS_GVASIZE << 5);
+
+ ivhd->type = IVHD_BLOCK_TYPE;
+ ivhd->flags = IVHD_FLAG_PPRSUP | IVHD_FLAG_IOTLBSUP;
+ ivhd->devid = iommu_bdf;
+ ivhd->cap_offset = IOMMU_CAP_OFFSET;
+
+ /*reserve 32K IOMMU MMIO space */
+ mmio = virt_to_phys(mem_alloc(0x8000, 0x1000));
+ if (!mmio) return NULL;
+
+ p.domid = DOMID_SELF;
+ p.index = HVM_PARAM_IOMMU_BASE;
+ p.value = mmio;
+
+ /* Return non-zero if IOMMUv2 hardware is not avaliable */
+ if ( hypercall_hvm_op(HVMOP_set_param, &p) )
+ return NULL;
+
+ ivhd->iommu_base_addr = mmio;
+ ivhd->reserved = IVHD_EFR_IASUP | IVHD_EFR_GTSUP;
+
+ /* Build IVHD device entries */
+ dev_entry = ivrs->ivhd_device;
+ for ( int i = 0; i < ptdev_nr; i++ )
+ {
+ dev_entry[i].type = IVHD_SELECT_4_BYTE;
+ dev_entry[i].dev_id = ptdev_bdf[i];
+ dev_entry[i].flags = 0;
+ }
+
+ ivhd->length = sizeof(*ivhd) + sizeof(*dev_entry) * PT_DEV_MAX_NR;
+ set_checksum(ivrs, offsetof(struct acpi_header, checksum),
+ ivrs->header.length);
+
+ return ivrs;
+}
+
static int construct_secondary_tables(unsigned long *table_ptrs,
struct acpi_info *info)
{
@@ -206,6 +279,7 @@ static int construct_secondary_tables(un
struct acpi_20_hpet *hpet;
struct acpi_20_waet *waet;
struct acpi_20_tcpa *tcpa;
+ struct acpi_40_ivrs *ivrs;
unsigned char *ssdt;
static const uint16_t tis_signature[] = {0x0001, 0x0001, 0x0001};
uint16_t *tis_hdr;
@@ -293,6 +367,13 @@ static int construct_secondary_tables(un
}
}
+ if ( hvm_info->iommu_enabled )
+ {
+ ivrs = construct_ivrs();
+ if ( ivrs != NULL )
+ table_ptrs[nr_tables++] = (unsigned long)ivrs;
+ }
+
table_ptrs[nr_tables] = 0;
return nr_tables;
}
diff -r 9a93e064dd3c -r 42ecb2ba593c tools/firmware/hvmloader/pci.c
--- a/tools/firmware/hvmloader/pci.c Wed Dec 14 16:16:16 2011 +0100
+++ b/tools/firmware/hvmloader/pci.c Wed Dec 14 16:22:20 2011 +0100
@@ -34,11 +34,17 @@ unsigned long pci_mem_end = PCI_MEM_END;
enum virtual_vga virtual_vga = VGA_none;
unsigned long igd_opregion_pgbase = 0;
+/* support up to 32 passthrough devices */
+#define PT_DEV_MAX_NR 32
+uint32_t ptdev_bdf[PT_DEV_MAX_NR];
+uint32_t ptdev_nr;
+uint32_t iommu_bdf;
+
void pci_setup(void)
{
uint32_t base, devfn, bar_reg, bar_data, bar_sz, cmd, mmio_total = 0;
uint32_t vga_devfn = 256;
- uint16_t class, vendor_id, device_id;
+ uint16_t class, vendor_id, device_id, sub_vendor_id;
unsigned int bar, pin, link, isa_irq;
/* Resources assignable to PCI devices via BARs. */
@@ -72,11 +78,34 @@ void pci_setup(void)
class = pci_readw(devfn, PCI_CLASS_DEVICE);
vendor_id = pci_readw(devfn, PCI_VENDOR_ID);
device_id = pci_readw(devfn, PCI_DEVICE_ID);
+ sub_vendor_id = pci_readw(devfn, PCI_SUBSYSTEM_VENDOR_ID);
+
if ( (vendor_id == 0xffff) && (device_id == 0xffff) )
continue;
ASSERT((devfn != PCI_ISA_DEVFN) ||
((vendor_id == 0x8086) && (device_id == 0x7000)));
+ /* Found amd iommu device. */
+ if ( class == 0x0806 && vendor_id == 0x1022 )
+ {
+ iommu_bdf = devfn;
+ printf("Found iommu devfn %x class %x\n", iommu_bdf, class);
+ continue;
+ }
+
+ /* IVRS: Detecting passthrough devices.
+ * sub_vendor_id != citrix && sub_vendor_id != qemu */
+ if ( sub_vendor_id != 0x5853 && sub_vendor_id != 0x1af4 )
+ {
+ /* found amd iommu device */
+ if ( ptdev_nr < PT_DEV_MAX_NR )
+ {
+ ptdev_bdf[ptdev_nr] = devfn;
+ ptdev_nr ++;
+ }
+ else
+ printf("Number of passthru devices > PT_DEV_MAX_NR \n");
+ }
switch ( class )
{
diff -r 9a93e064dd3c -r 42ecb2ba593c xen/include/public/hvm/hvm_info_table.h
--- a/xen/include/public/hvm/hvm_info_table.h Wed Dec 14 16:16:16 2011 +0100
+++ b/xen/include/public/hvm/hvm_info_table.h Wed Dec 14 16:22:20 2011 +0100
@@ -67,6 +67,9 @@ struct hvm_info_table {
/* Bitmap of which CPUs are online at boot time. */
uint8_t vcpu_online[(HVM_MAX_VCPUS + 7)/8];
+
+ /* guest iommu enabled */
+ uint8_t iommu_enabled;
};
#endif /* __XEN_PUBLIC_HVM_HVM_INFO_TABLE_H__ */
next prev parent reply other threads:[~2011-12-14 15:29 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-12-14 15:29 [PATCH 00 of 16] [RFC] amd iommu: support ATS device passthru on IOMMUv2 systems Wei Wang
2011-12-14 15:29 ` [PATCH 01 of 16] amd iommu: Refactoring iommu ring buffer definition Wei Wang
2011-12-14 15:29 ` [PATCH 02 of 16] amd iommu: Introduces new helper functions to simplify iommu bitwise operations Wei Wang
2011-12-14 15:29 ` [PATCH 03 of 16] amd iommu: Add iommu emulation for hvm guest Wei Wang
2011-12-15 13:35 ` Tim Deegan
2011-12-15 14:09 ` Wei Wang2
2011-12-15 14:13 ` Jan Beulich
2011-12-15 14:30 ` Wei Wang2
2011-12-14 15:29 ` [PATCH 04 of 16] amd iommu: Enable ppr log Wei Wang
2011-12-14 15:29 ` [PATCH 05 of 16] amd iommu: Enable guest level translation Wei Wang
2011-12-14 15:29 ` [PATCH 06 of 16] amd iommu: add ppr log processing into iommu interrupt handling Wei Wang
2011-12-14 15:29 ` [PATCH 07 of 16] amd iommu: Add 2 hypercalls for libxc Wei Wang
2011-12-14 16:44 ` Jan Beulich
2011-12-14 16:57 ` Wei Wang2
2011-12-14 17:03 ` Jan Beulich
2011-12-15 10:02 ` Wei Wang2
2011-12-14 15:29 ` [PATCH 08 of 16] amd iommu: Add a hypercall for hvmloader Wei Wang
2011-12-14 15:29 ` [PATCH 09 of 16] amd iommu: add iommu mmio handler Wei Wang
2011-12-14 15:29 ` [PATCH 10 of 16] amd iommu: Enable FC bit in iommu host level PTE Wei Wang
2011-12-14 15:29 ` [PATCH 11 of 16] amd iommu: Add a new flag to indication iommuv2 feature enabled or not Wei Wang
2011-12-15 13:39 ` Tim Deegan
2011-12-15 14:05 ` Wei Wang2
2011-12-14 15:29 ` Wei Wang [this message]
2011-12-15 12:29 ` [PATCH 12 of 16] hvmloader: Build IVRS table Ian Campbell
2011-12-14 15:29 ` [PATCH 13 of 16] libxc: add wrappers for new hypercalls Wei Wang
2011-12-14 15:29 ` [PATCH 14 of 16] libxl: bind virtual bdf to physical bdf after device assignment Wei Wang
2011-12-15 14:26 ` Ian Campbell
2011-12-14 15:29 ` [PATCH 15 of 16] libxl: Introduce a new guest config file parameter Wei Wang
2011-12-15 16:27 ` Ian Jackson
2011-12-14 15:29 ` [PATCH 16 of 16] libxl: add iommu parameter to qemu-dm Wei Wang
2011-12-15 14:30 ` Ian Campbell
2011-12-15 14:52 ` Wei Wang2
2011-12-15 16:59 ` Ian Campbell
2011-12-15 17:10 ` Wei Wang2
2011-12-16 11:44 ` Ian Campbell
2011-12-15 10:23 ` [PATCH 00 of 16] [RFC] amd iommu: support ATS device passthru on IOMMUv2 systems Jan Beulich
2011-12-15 11:18 ` Wei Wang2
-- strict thread matches above, loose matches on Subject: below --
2011-12-23 11:29 [PATCH 00 of 16] [V2] " Wei Wang
2011-12-23 11:29 ` [PATCH 12 of 16] hvmloader: Build IVRS table Wei Wang
2011-12-23 11:36 ` Ian Campbell
2011-12-23 11:52 ` Wei Wang2
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=42ecb2ba593c2827b2dc.1323876573@gran.amd.com \
--to=wei.wang2@amd.com \
--cc=JBeulich@suse.com \
--cc=keir@xen.org \
--cc=xen-devel@lists.xensource.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.