I'm trying to access the devices located behind the P2SB on an Intel Series 400 (comet lake) hub, via the SBREG_BAR from PCI device 31 function 1. All the registers come back as 1, however bit 8 (HIDE) from the P2SB Control Register indicates the device should have this exact behavior when set but that writes are not affected. This is documented in datasheets 620854 and 620855 (specifically page 131)
I figured (blindly) writing 0's to this register should re-enable reads from this device, but it seems to have no effect (all the bytes, including vendor and device id) still come back as all 1's. Are there any other bits or configuration or setup that has to happen, or is my method otherwise deficient?
My attempt using libpci as follows.
#include <stdio.h>
#include <pci/pci.h>
int main (int argc, char *argv[])
{
struct pci_access *pci;
struct pci_dev *d31f1;
uint32_t p2sb_P2SBC;
uint32_t p2sb_PCIID;
uint32_t p2sb_SBREG_BAR;
int res;
pci = pci_alloc();
pci->debugging = 1;
pci->method = PCI_ACCESS_I386_TYPE1;
pci->writeable = 1;
pci_init(pci);
d31f1 = pci_get_dev(pci, 0, 0, 31, 1);
if (d31f1 != NULL)
{
p2sb_PCIID = pci_read_long(d31f1, 0x00);
printf("p2sb_PCIID : %x\n", p2sb_PCIID);
if (p2sb_PCIID == 0xffffffff)
{
res = pci_write_long(d31f1, 0xe0, 0);
printf("write result: %d\n", res);
p2sb_P2SBC = pci_read_long(d31f1, 0xe0); // all are still 1
printf("p2sb_P2SBC: %x\n", p2sb_P2SBC);
p2sb_SBREG_BAR = pci_read_long(d31f1, 0x10);
printf("p2sb_SBREG_BAR: %x\n", p2sb_SBREG_BAR);
p2sb_PCIID = pci_read_long(d31f1, 0x00);
printf("p2sb_PCIID : %x\n", p2sb_PCIID);
}
}
else
{
fprintf(stderr, "pci_get_dev\n");
}
pci_cleanup(pci);
}