From 13b4913199b513b9cdce1ac05c7237e9cb31b8e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Tue, 14 Jun 2022 14:09:02 +0200 Subject: setpci: Define CAPABILITIES register --- setpci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/setpci.c b/setpci.c index 2cb70fa..1a0a736 100644 --- a/setpci.c +++ b/setpci.c @@ -281,6 +281,7 @@ static const struct reg_name pci_reg_names[] = { { 0, 0x2c, 2, "SUBSYSTEM_VENDOR_ID" }, { 0, 0x2e, 2, "SUBSYSTEM_ID" }, { 0, 0x30, 4, "ROM_ADDRESS" }, + { 0, 0x34, 1, "CAPABILITIES" }, { 0, 0x3c, 1, "INTERRUPT_LINE" }, { 0, 0x3d, 1, "INTERRUPT_PIN" }, { 0, 0x3e, 1, "MIN_GNT" }, -- cgit v1.2.1 From 94a53fc6ec2ee74ff36e4a13ec8081d6697f630f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Thu, 16 Jun 2022 16:14:56 +0200 Subject: setpci: Check if standard register on device exist Some standard registers are available only on device with header type 0, some only on header type 1, some other only on header type 2 and some on header type 0 and 1. Add definitions which registers are available on which header type and add check to access only available registers. --- setpci.c | 262 +++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 137 insertions(+), 125 deletions(-) diff --git a/setpci.c b/setpci.c index 1a0a736..ca1f31d 100644 --- a/setpci.c +++ b/setpci.c @@ -33,6 +33,8 @@ struct op { struct op *next; u16 cap_type; /* PCI_CAP_xxx or 0 */ u16 cap_id; + const char *name; + unsigned int hdr_type_mask; unsigned int addr; unsigned int width; /* Byte width of the access */ unsigned int num_values; /* Number of values to write; 0=read */ @@ -144,6 +146,13 @@ exec_op(struct op *op, struct pci_dev *dev) if (addr + width > 0x1000) die("%s: Access of width %d to register %04x out of range", slot, width, addr); + if (op->hdr_type_mask) + { + unsigned int hdr_type = pci_read_byte(dev, PCI_HEADER_TYPE) & 0x7f; + if (hdr_type > 2 || !((1 << hdr_type) & op->hdr_type_mask)) + die("%s: Does not have register %s.", slot, op->name); + } + if (op->num_values) { for (i=0; inum_values; i++) @@ -256,135 +265,136 @@ struct reg_name { unsigned int cap; unsigned int offset; unsigned int width; + unsigned int hdr_type_mask; const char *name; }; static const struct reg_name pci_reg_names[] = { - { 0, 0x00, 2, "VENDOR_ID" }, - { 0, 0x02, 2, "DEVICE_ID" }, - { 0, 0x04, 2, "COMMAND" }, - { 0, 0x06, 2, "STATUS" }, - { 0, 0x08, 1, "REVISION" }, - { 0, 0x09, 1, "CLASS_PROG" }, - { 0, 0x0a, 2, "CLASS_DEVICE" }, - { 0, 0x0c, 1, "CACHE_LINE_SIZE" }, - { 0, 0x0d, 1, "LATENCY_TIMER" }, - { 0, 0x0e, 1, "HEADER_TYPE" }, - { 0, 0x0f, 1, "BIST" }, - { 0, 0x10, 4, "BASE_ADDRESS_0" }, - { 0, 0x14, 4, "BASE_ADDRESS_1" }, - { 0, 0x18, 4, "BASE_ADDRESS_2" }, - { 0, 0x1c, 4, "BASE_ADDRESS_3" }, - { 0, 0x20, 4, "BASE_ADDRESS_4" }, - { 0, 0x24, 4, "BASE_ADDRESS_5" }, - { 0, 0x28, 4, "CARDBUS_CIS" }, - { 0, 0x2c, 2, "SUBSYSTEM_VENDOR_ID" }, - { 0, 0x2e, 2, "SUBSYSTEM_ID" }, - { 0, 0x30, 4, "ROM_ADDRESS" }, - { 0, 0x34, 1, "CAPABILITIES" }, - { 0, 0x3c, 1, "INTERRUPT_LINE" }, - { 0, 0x3d, 1, "INTERRUPT_PIN" }, - { 0, 0x3e, 1, "MIN_GNT" }, - { 0, 0x3f, 1, "MAX_LAT" }, - { 0, 0x18, 1, "PRIMARY_BUS" }, - { 0, 0x19, 1, "SECONDARY_BUS" }, - { 0, 0x1a, 1, "SUBORDINATE_BUS" }, - { 0, 0x1b, 1, "SEC_LATENCY_TIMER" }, - { 0, 0x1c, 1, "IO_BASE" }, - { 0, 0x1d, 1, "IO_LIMIT" }, - { 0, 0x1e, 2, "SEC_STATUS" }, - { 0, 0x20, 2, "MEMORY_BASE" }, - { 0, 0x22, 2, "MEMORY_LIMIT" }, - { 0, 0x24, 2, "PREF_MEMORY_BASE" }, - { 0, 0x26, 2, "PREF_MEMORY_LIMIT" }, - { 0, 0x28, 4, "PREF_BASE_UPPER32" }, - { 0, 0x2c, 4, "PREF_LIMIT_UPPER32" }, - { 0, 0x30, 2, "IO_BASE_UPPER16" }, - { 0, 0x32, 2, "IO_LIMIT_UPPER16" }, - { 0, 0x38, 4, "BRIDGE_ROM_ADDRESS" }, - { 0, 0x3e, 2, "BRIDGE_CONTROL" }, - { 0, 0x10, 4, "CB_CARDBUS_BASE" }, - { 0, 0x14, 2, "CB_CAPABILITIES" }, - { 0, 0x16, 2, "CB_SEC_STATUS" }, - { 0, 0x18, 1, "CB_BUS_NUMBER" }, - { 0, 0x19, 1, "CB_CARDBUS_NUMBER" }, - { 0, 0x1a, 1, "CB_SUBORDINATE_BUS" }, - { 0, 0x1b, 1, "CB_CARDBUS_LATENCY" }, - { 0, 0x1c, 4, "CB_MEMORY_BASE_0" }, - { 0, 0x20, 4, "CB_MEMORY_LIMIT_0" }, - { 0, 0x24, 4, "CB_MEMORY_BASE_1" }, - { 0, 0x28, 4, "CB_MEMORY_LIMIT_1" }, - { 0, 0x2c, 2, "CB_IO_BASE_0" }, - { 0, 0x2e, 2, "CB_IO_BASE_0_HI" }, - { 0, 0x30, 2, "CB_IO_LIMIT_0" }, - { 0, 0x32, 2, "CB_IO_LIMIT_0_HI" }, - { 0, 0x34, 2, "CB_IO_BASE_1" }, - { 0, 0x36, 2, "CB_IO_BASE_1_HI" }, - { 0, 0x38, 2, "CB_IO_LIMIT_1" }, - { 0, 0x3a, 2, "CB_IO_LIMIT_1_HI" }, - { 0, 0x40, 2, "CB_SUBSYSTEM_VENDOR_ID" }, - { 0, 0x42, 2, "CB_SUBSYSTEM_ID" }, - { 0, 0x44, 4, "CB_LEGACY_MODE_BASE" }, - { 0x10001, 0, 0, "CAP_PM" }, - { 0x10002, 0, 0, "CAP_AGP" }, - { 0x10003, 0, 0, "CAP_VPD" }, - { 0x10004, 0, 0, "CAP_SLOTID" }, - { 0x10005, 0, 0, "CAP_MSI" }, - { 0x10006, 0, 0, "CAP_CHSWP" }, - { 0x10007, 0, 0, "CAP_PCIX" }, - { 0x10008, 0, 0, "CAP_HT" }, - { 0x10009, 0, 0, "CAP_VNDR" }, - { 0x1000a, 0, 0, "CAP_DBG" }, - { 0x1000b, 0, 0, "CAP_CCRC" }, - { 0x1000c, 0, 0, "CAP_HOTPLUG" }, - { 0x1000d, 0, 0, "CAP_SSVID" }, - { 0x1000e, 0, 0, "CAP_AGP3" }, - { 0x1000f, 0, 0, "CAP_SECURE" }, - { 0x10010, 0, 0, "CAP_EXP" }, - { 0x10011, 0, 0, "CAP_MSIX" }, - { 0x10012, 0, 0, "CAP_SATA" }, - { 0x10013, 0, 0, "CAP_AF" }, - { 0x10014, 0, 0, "CAP_EA" }, - { 0x20001, 0, 0, "ECAP_AER" }, - { 0x20002, 0, 0, "ECAP_VC" }, - { 0x20003, 0, 0, "ECAP_DSN" }, - { 0x20004, 0, 0, "ECAP_PB" }, - { 0x20005, 0, 0, "ECAP_RCLINK" }, - { 0x20006, 0, 0, "ECAP_RCILINK" }, - { 0x20007, 0, 0, "ECAP_RCEC" }, - { 0x20008, 0, 0, "ECAP_MFVC" }, - { 0x20009, 0, 0, "ECAP_VC2" }, - { 0x2000a, 0, 0, "ECAP_RBCB" }, - { 0x2000b, 0, 0, "ECAP_VNDR" }, - { 0x2000d, 0, 0, "ECAP_ACS" }, - { 0x2000e, 0, 0, "ECAP_ARI" }, - { 0x2000f, 0, 0, "ECAP_ATS" }, - { 0x20010, 0, 0, "ECAP_SRIOV" }, - { 0x20011, 0, 0, "ECAP_MRIOV" }, - { 0x20012, 0, 0, "ECAP_MCAST" }, - { 0x20013, 0, 0, "ECAP_PRI" }, - { 0x20015, 0, 0, "ECAP_REBAR" }, - { 0x20016, 0, 0, "ECAP_DPA" }, - { 0x20017, 0, 0, "ECAP_TPH" }, - { 0x20018, 0, 0, "ECAP_LTR" }, - { 0x20019, 0, 0, "ECAP_SECPCI" }, - { 0x2001a, 0, 0, "ECAP_PMUX" }, - { 0x2001b, 0, 0, "ECAP_PASID" }, - { 0x2001c, 0, 0, "ECAP_LNR" }, - { 0x2001d, 0, 0, "ECAP_DPC" }, - { 0x2001e, 0, 0, "ECAP_L1PM" }, - { 0x2001f, 0, 0, "ECAP_PTM" }, - { 0x20020, 0, 0, "ECAP_M_PCIE" }, - { 0x20021, 0, 0, "ECAP_FRS" }, - { 0x20022, 0, 0, "ECAP_RTR" }, - { 0x20023, 0, 0, "ECAP_DVSEC" }, - { 0x20024, 0, 0, "ECAP_VF_REBAR" }, - { 0x20025, 0, 0, "ECAP_DLNK" }, - { 0x20026, 0, 0, "ECAP_16GT" }, - { 0x20027, 0, 0, "ECAP_LMR" }, - { 0x20028, 0, 0, "ECAP_HIER_ID" }, - { 0x20029, 0, 0, "ECAP_NPEM" }, - { 0, 0, 0, NULL } + { 0, 0x00, 2, 0x0, "VENDOR_ID" }, + { 0, 0x02, 2, 0x0, "DEVICE_ID" }, + { 0, 0x04, 2, 0x0, "COMMAND" }, + { 0, 0x06, 2, 0x0, "STATUS" }, + { 0, 0x08, 1, 0x0, "REVISION" }, + { 0, 0x09, 1, 0x0, "CLASS_PROG" }, + { 0, 0x0a, 2, 0x0, "CLASS_DEVICE" }, + { 0, 0x0c, 1, 0x0, "CACHE_LINE_SIZE" }, + { 0, 0x0d, 1, 0x0, "LATENCY_TIMER" }, + { 0, 0x0e, 1, 0x0, "HEADER_TYPE" }, + { 0, 0x0f, 1, 0x0, "BIST" }, + { 0, 0x10, 4, 0x3, "BASE_ADDRESS_0" }, + { 0, 0x14, 4, 0x3, "BASE_ADDRESS_1" }, + { 0, 0x18, 4, 0x1, "BASE_ADDRESS_2" }, + { 0, 0x1c, 4, 0x1, "BASE_ADDRESS_3" }, + { 0, 0x20, 4, 0x1, "BASE_ADDRESS_4" }, + { 0, 0x24, 4, 0x1, "BASE_ADDRESS_5" }, + { 0, 0x28, 4, 0x1, "CARDBUS_CIS" }, + { 0, 0x2c, 2, 0x1, "SUBSYSTEM_VENDOR_ID" }, + { 0, 0x2e, 2, 0x1, "SUBSYSTEM_ID" }, + { 0, 0x30, 4, 0x1, "ROM_ADDRESS" }, + { 0, 0x34, 1, 0x3, "CAPABILITIES" }, + { 0, 0x3c, 1, 0x3, "INTERRUPT_LINE" }, + { 0, 0x3d, 1, 0x3, "INTERRUPT_PIN" }, + { 0, 0x3e, 1, 0x1, "MIN_GNT" }, + { 0, 0x3f, 1, 0x1, "MAX_LAT" }, + { 0, 0x18, 1, 0x2, "PRIMARY_BUS" }, + { 0, 0x19, 1, 0x2, "SECONDARY_BUS" }, + { 0, 0x1a, 1, 0x2, "SUBORDINATE_BUS" }, + { 0, 0x1b, 1, 0x2, "SEC_LATENCY_TIMER" }, + { 0, 0x1c, 1, 0x2, "IO_BASE" }, + { 0, 0x1d, 1, 0x2, "IO_LIMIT" }, + { 0, 0x1e, 2, 0x2, "SEC_STATUS" }, + { 0, 0x20, 2, 0x2, "MEMORY_BASE" }, + { 0, 0x22, 2, 0x2, "MEMORY_LIMIT" }, + { 0, 0x24, 2, 0x2, "PREF_MEMORY_BASE" }, + { 0, 0x26, 2, 0x2, "PREF_MEMORY_LIMIT" }, + { 0, 0x28, 4, 0x2, "PREF_BASE_UPPER32" }, + { 0, 0x2c, 4, 0x2, "PREF_LIMIT_UPPER32" }, + { 0, 0x30, 2, 0x2, "IO_BASE_UPPER16" }, + { 0, 0x32, 2, 0x2, "IO_LIMIT_UPPER16" }, + { 0, 0x38, 4, 0x2, "BRIDGE_ROM_ADDRESS" }, + { 0, 0x3e, 2, 0x2, "BRIDGE_CONTROL" }, + { 0, 0x10, 4, 0x4, "CB_CARDBUS_BASE" }, + { 0, 0x14, 2, 0x4, "CB_CAPABILITIES" }, + { 0, 0x16, 2, 0x4, "CB_SEC_STATUS" }, + { 0, 0x18, 1, 0x4, "CB_BUS_NUMBER" }, + { 0, 0x19, 1, 0x4, "CB_CARDBUS_NUMBER" }, + { 0, 0x1a, 1, 0x4, "CB_SUBORDINATE_BUS" }, + { 0, 0x1b, 1, 0x4, "CB_CARDBUS_LATENCY" }, + { 0, 0x1c, 4, 0x4, "CB_MEMORY_BASE_0" }, + { 0, 0x20, 4, 0x4, "CB_MEMORY_LIMIT_0" }, + { 0, 0x24, 4, 0x4, "CB_MEMORY_BASE_1" }, + { 0, 0x28, 4, 0x4, "CB_MEMORY_LIMIT_1" }, + { 0, 0x2c, 2, 0x4, "CB_IO_BASE_0" }, + { 0, 0x2e, 2, 0x4, "CB_IO_BASE_0_HI" }, + { 0, 0x30, 2, 0x4, "CB_IO_LIMIT_0" }, + { 0, 0x32, 2, 0x4, "CB_IO_LIMIT_0_HI" }, + { 0, 0x34, 2, 0x4, "CB_IO_BASE_1" }, + { 0, 0x36, 2, 0x4, "CB_IO_BASE_1_HI" }, + { 0, 0x38, 2, 0x4, "CB_IO_LIMIT_1" }, + { 0, 0x3a, 2, 0x4, "CB_IO_LIMIT_1_HI" }, + { 0, 0x40, 2, 0x4, "CB_SUBSYSTEM_VENDOR_ID" }, + { 0, 0x42, 2, 0x4, "CB_SUBSYSTEM_ID" }, + { 0, 0x44, 4, 0x4, "CB_LEGACY_MODE_BASE" }, + { 0x10001, 0, 0, 0x0, "CAP_PM" }, + { 0x10002, 0, 0, 0x0, "CAP_AGP" }, + { 0x10003, 0, 0, 0x0, "CAP_VPD" }, + { 0x10004, 0, 0, 0x0, "CAP_SLOTID" }, + { 0x10005, 0, 0, 0x0, "CAP_MSI" }, + { 0x10006, 0, 0, 0x0, "CAP_CHSWP" }, + { 0x10007, 0, 0, 0x0, "CAP_PCIX" }, + { 0x10008, 0, 0, 0x0, "CAP_HT" }, + { 0x10009, 0, 0, 0x0, "CAP_VNDR" }, + { 0x1000a, 0, 0, 0x0, "CAP_DBG" }, + { 0x1000b, 0, 0, 0x0, "CAP_CCRC" }, + { 0x1000c, 0, 0, 0x0, "CAP_HOTPLUG" }, + { 0x1000d, 0, 0, 0x0, "CAP_SSVID" }, + { 0x1000e, 0, 0, 0x0, "CAP_AGP3" }, + { 0x1000f, 0, 0, 0x0, "CAP_SECURE" }, + { 0x10010, 0, 0, 0x0, "CAP_EXP" }, + { 0x10011, 0, 0, 0x0, "CAP_MSIX" }, + { 0x10012, 0, 0, 0x0, "CAP_SATA" }, + { 0x10013, 0, 0, 0x0, "CAP_AF" }, + { 0x10014, 0, 0, 0x0, "CAP_EA" }, + { 0x20001, 0, 0, 0x0, "ECAP_AER" }, + { 0x20002, 0, 0, 0x0, "ECAP_VC" }, + { 0x20003, 0, 0, 0x0, "ECAP_DSN" }, + { 0x20004, 0, 0, 0x0, "ECAP_PB" }, + { 0x20005, 0, 0, 0x0, "ECAP_RCLINK" }, + { 0x20006, 0, 0, 0x0, "ECAP_RCILINK" }, + { 0x20007, 0, 0, 0x0, "ECAP_RCEC" }, + { 0x20008, 0, 0, 0x0, "ECAP_MFVC" }, + { 0x20009, 0, 0, 0x0, "ECAP_VC2" }, + { 0x2000a, 0, 0, 0x0, "ECAP_RBCB" }, + { 0x2000b, 0, 0, 0x0, "ECAP_VNDR" }, + { 0x2000d, 0, 0, 0x0, "ECAP_ACS" }, + { 0x2000e, 0, 0, 0x0, "ECAP_ARI" }, + { 0x2000f, 0, 0, 0x0, "ECAP_ATS" }, + { 0x20010, 0, 0, 0x0, "ECAP_SRIOV" }, + { 0x20011, 0, 0, 0x0, "ECAP_MRIOV" }, + { 0x20012, 0, 0, 0x0, "ECAP_MCAST" }, + { 0x20013, 0, 0, 0x0, "ECAP_PRI" }, + { 0x20015, 0, 0, 0x0, "ECAP_REBAR" }, + { 0x20016, 0, 0, 0x0, "ECAP_DPA" }, + { 0x20017, 0, 0, 0x0, "ECAP_TPH" }, + { 0x20018, 0, 0, 0x0, "ECAP_LTR" }, + { 0x20019, 0, 0, 0x0, "ECAP_SECPCI" }, + { 0x2001a, 0, 0, 0x0, "ECAP_PMUX" }, + { 0x2001b, 0, 0, 0x0, "ECAP_PASID" }, + { 0x2001c, 0, 0, 0x0, "ECAP_LNR" }, + { 0x2001d, 0, 0, 0x0, "ECAP_DPC" }, + { 0x2001e, 0, 0, 0x0, "ECAP_L1PM" }, + { 0x2001f, 0, 0, 0x0, "ECAP_PTM" }, + { 0x20020, 0, 0, 0x0, "ECAP_M_PCIE" }, + { 0x20021, 0, 0, 0x0, "ECAP_FRS" }, + { 0x20022, 0, 0, 0x0, "ECAP_RTR" }, + { 0x20023, 0, 0, 0x0, "ECAP_DVSEC" }, + { 0x20024, 0, 0, 0x0, "ECAP_VF_REBAR" }, + { 0x20025, 0, 0, 0x0, "ECAP_DLNK" }, + { 0x20026, 0, 0, 0x0, "ECAP_16GT" }, + { 0x20027, 0, 0, 0x0, "ECAP_LMR" }, + { 0x20028, 0, 0, 0x0, "ECAP_HIER_ID" }, + { 0x20029, 0, 0, 0x0, "ECAP_NPEM" }, + { 0, 0, 0, 0x0, NULL } }; static void @@ -615,6 +625,8 @@ static void parse_register(struct op *op, char *base) } op->cap_id = r->cap & 0xffff; op->addr = r->offset; + op->hdr_type_mask = r->hdr_type_mask; + op->name = r->name; if (r->width && !op->width) op->width = r->width; return; -- cgit v1.2.1