Move the new AMD-Vi IVHD [ACPI_IVRS_HARDWARE_NEW]definitions added in r329360 in contrib ACPI to local files till ACPI code adds new definitions reported by jkim.
Rename ACPI_IVRS_HARDWARE_NEW to ACPI_IVRS_HARDWARE_EFRSUP, since new definitions add Extended Feature Register support. Use IvrsType to distinguish three types of IVHD - 0x10(legacy), 0x11 and 0x40(with EFR). IVHD 0x40 is also called mixed type since it supports HID device entries. Fix 2 coverity bugs reported by cem. Reported by:jkim, cem Approved by:grehan Differential Revision://reviews.freebsd.org/D14501
This commit is contained in:
parent
b1dbbe4da2
commit
9363000dfe
@ -354,13 +354,44 @@ struct amdvi_domain {
|
||||
SLIST_ENTRY (amdvi_domain) next;
|
||||
};
|
||||
|
||||
/*
|
||||
* I/O Virtualization Hardware Definition Block (IVHD) type 0x10 (legacy)
|
||||
* uses ACPI_IVRS_HARDWARE define in contrib/dev/acpica/include/actbl2.h
|
||||
* New IVHD types 0x11 and 0x40 as defined in AMD IOMMU spec[48882] are missing in
|
||||
* ACPI code. These new types add extra field EFR(Extended Feature Register).
|
||||
* XXX : Use definition from ACPI when it is available.
|
||||
*/
|
||||
typedef struct acpi_ivrs_hardware_efr_sup
|
||||
{
|
||||
ACPI_IVRS_HEADER Header;
|
||||
UINT16 CapabilityOffset; /* Offset for IOMMU control fields */
|
||||
UINT64 BaseAddress; /* IOMMU control registers */
|
||||
UINT16 PciSegmentGroup;
|
||||
UINT16 Info; /* MSI number and unit ID */
|
||||
UINT32 Attr; /* IOMMU Feature */
|
||||
UINT64 ExtFR; /* IOMMU Extended Feature */
|
||||
UINT64 Reserved; /* v1 feature or v2 attribute */
|
||||
} __attribute__ ((__packed__)) ACPI_IVRS_HARDWARE_EFRSUP;
|
||||
CTASSERT(sizeof(ACPI_IVRS_HARDWARE_EFRSUP) == 40);
|
||||
|
||||
/*
|
||||
* Different type of IVHD.
|
||||
* XXX: Use AcpiIvrsType once new IVHD types are available.
|
||||
*/
|
||||
enum IvrsType
|
||||
{
|
||||
IVRS_TYPE_HARDWARE_LEGACY = 0x10, /* Legacy without EFRi support. */
|
||||
IVRS_TYPE_HARDWARE_EFR = 0x11, /* With EFR support. */
|
||||
IVRS_TYPE_HARDWARE_MIXED = 0x40, /* Mixed with EFR support. */
|
||||
};
|
||||
|
||||
/*
|
||||
* AMD IOMMU softc.
|
||||
*/
|
||||
struct amdvi_softc {
|
||||
struct amdvi_ctrl *ctrl; /* Control area. */
|
||||
device_t dev; /* IOMMU device. */
|
||||
enum AcpiIvrsType ivhd_type; /* IOMMU IVHD type 0x10/0x11 or 0x40 */
|
||||
enum IvrsType ivhd_type; /* IOMMU IVHD type. */
|
||||
bool iotlb; /* IOTLB supported by IOMMU */
|
||||
struct amdvi_cmd *cmd; /* Command descriptor area. */
|
||||
int cmd_max; /* Max number of commands. */
|
||||
|
@ -86,9 +86,9 @@ ivrs_hdr_iterate_tbl(ivhd_iter_t iter, void *arg)
|
||||
}
|
||||
|
||||
switch (ivrs_hdr->Type) {
|
||||
case ACPI_IVRS_TYPE_HARDWARE: /* Legacy */
|
||||
case 0x11:
|
||||
case 0x40: /* ACPI HID */
|
||||
case IVRS_TYPE_HARDWARE_LEGACY: /* Legacy */
|
||||
case IVRS_TYPE_HARDWARE_EFR:
|
||||
case IVRS_TYPE_HARDWARE_MIXED:
|
||||
if (!iter(ivrs_hdr, arg))
|
||||
return;
|
||||
break;
|
||||
@ -116,9 +116,9 @@ ivrs_is_ivhd(UINT8 type)
|
||||
{
|
||||
|
||||
switch(type) {
|
||||
case ACPI_IVRS_TYPE_HARDWARE:
|
||||
case ACPI_IVRS_TYPE_HARDWARE_EXT1:
|
||||
case ACPI_IVRS_TYPE_HARDWARE_EXT2:
|
||||
case IVRS_TYPE_HARDWARE_LEGACY:
|
||||
case IVRS_TYPE_HARDWARE_EFR:
|
||||
case IVRS_TYPE_HARDWARE_MIXED:
|
||||
return (true);
|
||||
|
||||
default:
|
||||
@ -206,17 +206,13 @@ ivhd_dev_parse(ACPI_IVRS_HARDWARE* ivhd, struct amdvi_softc *softc)
|
||||
softc->end_dev_rid = 0;
|
||||
|
||||
switch (ivhd->Header.Type) {
|
||||
case ACPI_IVRS_TYPE_HARDWARE_EXT1:
|
||||
case ACPI_IVRS_TYPE_HARDWARE_EXT2:
|
||||
p = (uint8_t *)ivhd + sizeof(ACPI_IVRS_HARDWARE_NEW);
|
||||
de = (ACPI_IVRS_DE_HEADER *) ((uint8_t *)ivhd +
|
||||
sizeof(ACPI_IVRS_HARDWARE_NEW));
|
||||
case IVRS_TYPE_HARDWARE_LEGACY:
|
||||
p = (uint8_t *)ivhd + sizeof(ACPI_IVRS_HARDWARE);
|
||||
break;
|
||||
|
||||
case ACPI_IVRS_TYPE_HARDWARE:
|
||||
p = (uint8_t *)ivhd + sizeof(ACPI_IVRS_HARDWARE);
|
||||
de = (ACPI_IVRS_DE_HEADER *) ((uint8_t *)ivhd +
|
||||
sizeof(ACPI_IVRS_HARDWARE));
|
||||
case IVRS_TYPE_HARDWARE_EFR:
|
||||
case IVRS_TYPE_HARDWARE_MIXED:
|
||||
p = (uint8_t *)ivhd + sizeof(ACPI_IVRS_HARDWARE_EFRSUP);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -316,9 +312,9 @@ ivhd_is_newer(ACPI_IVRS_HEADER *old, ACPI_IVRS_HEADER *new)
|
||||
* Newer IVRS header type take precedence.
|
||||
*/
|
||||
if ((old->DeviceId == new->DeviceId) &&
|
||||
(old->Type == ACPI_IVRS_TYPE_HARDWARE) &&
|
||||
((new->Type == ACPI_IVRS_TYPE_HARDWARE_EXT1) ||
|
||||
(new->Type == ACPI_IVRS_TYPE_HARDWARE_EXT1))) {
|
||||
(old->Type == IVRS_TYPE_HARDWARE_LEGACY) &&
|
||||
((new->Type == IVRS_TYPE_HARDWARE_EFR) ||
|
||||
(new->Type == IVRS_TYPE_HARDWARE_MIXED))) {
|
||||
return (true);
|
||||
}
|
||||
|
||||
@ -422,23 +418,33 @@ ivhd_probe(device_t dev)
|
||||
ivhd = ivhd_hdrs[unit];
|
||||
KASSERT(ivhd, ("ivhd is NULL"));
|
||||
|
||||
if (ivhd->Header.Type == ACPI_IVRS_TYPE_HARDWARE)
|
||||
device_set_desc(dev, "AMD-Vi/IOMMU ivhd");
|
||||
else
|
||||
switch (ivhd->Header.Type) {
|
||||
case IVRS_TYPE_HARDWARE_EFR:
|
||||
device_set_desc(dev, "AMD-Vi/IOMMU ivhd with EFR");
|
||||
break;
|
||||
|
||||
case IVRS_TYPE_HARDWARE_MIXED:
|
||||
device_set_desc(dev, "AMD-Vi/IOMMU ivhd in mixed format");
|
||||
break;
|
||||
|
||||
case IVRS_TYPE_HARDWARE_LEGACY:
|
||||
default:
|
||||
device_set_desc(dev, "AMD-Vi/IOMMU ivhd");
|
||||
break;
|
||||
}
|
||||
|
||||
return (BUS_PROBE_NOWILDCARD);
|
||||
}
|
||||
|
||||
static void
|
||||
ivhd_print_flag(device_t dev, enum AcpiIvrsType ivhd_type, uint8_t flag)
|
||||
ivhd_print_flag(device_t dev, enum IvrsType ivhd_type, uint8_t flag)
|
||||
{
|
||||
/*
|
||||
* IVHD lgeacy type has two extra high bits in flag which has
|
||||
* been moved to EFR for non-legacy device.
|
||||
*/
|
||||
switch (ivhd_type) {
|
||||
case ACPI_IVRS_TYPE_HARDWARE:
|
||||
case IVRS_TYPE_HARDWARE_LEGACY:
|
||||
device_printf(dev, "Flag:%b\n", flag,
|
||||
"\020"
|
||||
"\001HtTunEn"
|
||||
@ -451,8 +457,8 @@ ivhd_print_flag(device_t dev, enum AcpiIvrsType ivhd_type, uint8_t flag)
|
||||
"\008PPRSup");
|
||||
break;
|
||||
|
||||
case ACPI_IVRS_TYPE_HARDWARE_EXT1:
|
||||
case ACPI_IVRS_TYPE_HARDWARE_EXT2:
|
||||
case IVRS_TYPE_HARDWARE_EFR:
|
||||
case IVRS_TYPE_HARDWARE_MIXED:
|
||||
device_printf(dev, "Flag:%b\n", flag,
|
||||
"\020"
|
||||
"\001HtTunEn"
|
||||
@ -474,10 +480,10 @@ ivhd_print_flag(device_t dev, enum AcpiIvrsType ivhd_type, uint8_t flag)
|
||||
* Feature in legacy IVHD type(0x10) and attribute in newer type(0x11 and 0x40).
|
||||
*/
|
||||
static void
|
||||
ivhd_print_feature(device_t dev, enum AcpiIvrsType ivhd_type, uint32_t feature)
|
||||
ivhd_print_feature(device_t dev, enum IvrsType ivhd_type, uint32_t feature)
|
||||
{
|
||||
switch (ivhd_type) {
|
||||
case ACPI_IVRS_TYPE_HARDWARE:
|
||||
case IVRS_TYPE_HARDWARE_LEGACY:
|
||||
device_printf(dev, "Features(type:0x%x) HATS = %d GATS = %d"
|
||||
" MsiNumPPR = %d PNBanks= %d PNCounters= %d\n",
|
||||
ivhd_type,
|
||||
@ -500,8 +506,8 @@ ivhd_print_feature(device_t dev, enum AcpiIvrsType ivhd_type, uint32_t feature)
|
||||
break;
|
||||
|
||||
/* Fewer features or attributes are reported in non-legacy type. */
|
||||
case ACPI_IVRS_TYPE_HARDWARE_EXT1:
|
||||
case ACPI_IVRS_TYPE_HARDWARE_EXT2:
|
||||
case IVRS_TYPE_HARDWARE_EFR:
|
||||
case IVRS_TYPE_HARDWARE_MIXED:
|
||||
device_printf(dev, "Features(type:0x%x) MsiNumPPR = %d"
|
||||
" PNBanks= %d PNCounters= %d\n",
|
||||
ivhd_type,
|
||||
@ -605,7 +611,7 @@ static int
|
||||
ivhd_attach(device_t dev)
|
||||
{
|
||||
ACPI_IVRS_HARDWARE *ivhd;
|
||||
ACPI_IVRS_HARDWARE_NEW *ivhd1;
|
||||
ACPI_IVRS_HARDWARE_EFRSUP *ivhd_efr;
|
||||
struct amdvi_softc *softc;
|
||||
int status, unit;
|
||||
|
||||
@ -640,10 +646,10 @@ ivhd_attach(device_t dev)
|
||||
softc->event_msix = ivhd->Info & 0x1F;
|
||||
#endif
|
||||
switch (ivhd->Header.Type) {
|
||||
case ACPI_IVRS_TYPE_HARDWARE_EXT1:
|
||||
case ACPI_IVRS_TYPE_HARDWARE_EXT2:
|
||||
ivhd1 = (ACPI_IVRS_HARDWARE_NEW *)ivhd;
|
||||
softc->ext_feature = ivhd1->ExtFR;
|
||||
case IVRS_TYPE_HARDWARE_EFR:
|
||||
case IVRS_TYPE_HARDWARE_MIXED:
|
||||
ivhd_efr = (ACPI_IVRS_HARDWARE_EFRSUP *)ivhd;
|
||||
softc->ext_feature = ivhd_efr->ExtFR;
|
||||
break;
|
||||
|
||||
}
|
||||
|
@ -444,8 +444,6 @@ typedef struct acpi_ivrs_header
|
||||
enum AcpiIvrsType
|
||||
{
|
||||
ACPI_IVRS_TYPE_HARDWARE = 0x10,
|
||||
ACPI_IVRS_TYPE_HARDWARE_EXT1 = 0x11,
|
||||
ACPI_IVRS_TYPE_HARDWARE_EXT2 = 0x40,
|
||||
ACPI_IVRS_TYPE_MEMORY1 = 0x20,
|
||||
ACPI_IVRS_TYPE_MEMORY2 = 0x21,
|
||||
ACPI_IVRS_TYPE_MEMORY3 = 0x22
|
||||
@ -484,21 +482,6 @@ typedef struct acpi_ivrs_hardware
|
||||
|
||||
} ACPI_IVRS_HARDWARE;
|
||||
|
||||
/* 0x11 and 0x40: I/O Virtualization Hardware Definition Block (IVHD) */
|
||||
|
||||
typedef struct acpi_ivrs_hardware_new
|
||||
{
|
||||
ACPI_IVRS_HEADER Header;
|
||||
UINT16 CapabilityOffset; /* Offset for IOMMU control fields */
|
||||
UINT64 BaseAddress; /* IOMMU control registers */
|
||||
UINT16 PciSegmentGroup;
|
||||
UINT16 Info; /* MSI number and unit ID */
|
||||
UINT32 Attr; /* IOMMU Feature */
|
||||
UINT64 ExtFR; /* IOMMU Extended Feature */
|
||||
UINT64 Reserved; /* v1 feature or v2 attribute */
|
||||
|
||||
} ACPI_IVRS_HARDWARE_NEW;
|
||||
|
||||
/* Masks for Info field above */
|
||||
|
||||
#define ACPI_IVHD_MSI_NUMBER_MASK 0x001F /* 5 bits, MSI message number */
|
||||
|
Loading…
x
Reference in New Issue
Block a user