+2004-08-13 Martin Mares <mj@ucw.cz>
+
+ * lspci.c (show_rom): Use the same logic for printing disabled
+ or unassigned ROM's as we do in show_bases() for the other BAR's.
+
+ * lib/generic.c (pci_generic_fill_info): Better reaction to
+ invalid 64-bit addresses. Also d->hdrtype should not include
+ bit 7, which caused mysterious errors on multi-function devices.
+
+ * lib/generic.c (pci_generic_fill_info): Fill in base addresses
+ even if the regions are known to be disabled. It is the client's
+ job to interpret them. (And it is not a trivial job if you want
+ to do it correctly, since you need to check I/O and memory enables
+ on all upstream bridges, too.) However, it could be interesting to
+ introduce functions for interpreting the addresses and even for
+ mapping the regions and doing I/O on them.
+
2004-07-30 Martin Mares <mj@ucw.cz>
* lspci.c: HyperTransport improvements from Maciej.
struct pci_access *a = d->access;
if ((flags & (PCI_FILL_BASES | PCI_FILL_ROM_BASE)) && d->hdrtype < 0)
- d->hdrtype = pci_read_byte(d, PCI_HEADER_TYPE);
+ d->hdrtype = pci_read_byte(d, PCI_HEADER_TYPE) & 0x7f;
if (flags & PCI_FILL_IDENT)
{
d->vendor_id = pci_read_word(d, PCI_VENDOR_ID);
}
if (cnt)
{
- u16 cmd = pci_read_word(d, PCI_COMMAND);
for(i=0; i<cnt; i++)
{
u32 x = pci_read_long(d, PCI_BASE_ADDRESS_0 + i*4);
if (!x || x == (u32) ~0)
continue;
- d->base_addr[i] = x;
- if (x & PCI_BASE_ADDRESS_SPACE_IO)
- {
- if (!a->buscentric && !(cmd & PCI_COMMAND_IO))
- d->base_addr[i] = 0;
- }
- else if (a->buscentric || (cmd & PCI_COMMAND_MEMORY))
+ if ((x & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO)
+ d->base_addr[i] = x;
+ else
{
- if ((x & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64)
+ if ((x & PCI_BASE_ADDRESS_MEM_TYPE_MASK) != PCI_BASE_ADDRESS_MEM_TYPE_64)
+ d->base_addr[i] = x;
+ else if (i >= cnt-1)
+ a->warning("%04x:%02x:%02x.%d: Invalid 64-bit address seen for BAR %d.", d->domain, d->bus, d->dev, d->func, i);
+ else
{
- if (i >= cnt-1)
- a->warning("%04x:%02x:%02x.%d: Invalid 64-bit address seen.", d->domain, d->bus, d->dev, d->func);
- else
- {
- u32 y = pci_read_long(d, PCI_BASE_ADDRESS_0 + (++i)*4);
+ u32 y = pci_read_long(d, PCI_BASE_ADDRESS_0 + (++i)*4);
#ifdef HAVE_64BIT_ADDRESS
- d->base_addr[i-1] |= ((pciaddr_t) y) << 32;
+ d->base_addr[i-1] = x | (((pciaddr_t) y) << 32);
#else
- if (y)
- {
- a->warning("%04x:%02x:%02x.%d 64-bit device address ignored.", d->domain, d->bus, d->dev, d->func);
- d->base_addr[i-1] = 0;
- }
+ if (y)
+ a->warning("%04x:%02x:%02x.%d 64-bit device address ignored.", d->domain, d->bus, d->dev, d->func);
+ else
+ d->base_addr[i-1] = x;
#endif
- }
}
}
- else
- d->base_addr[i] = 0;
}
}
}
}
if (reg)
{
- u32 a = pci_read_long(d, reg);
- if (a & PCI_ROM_ADDRESS_ENABLE)
- d->rom_base_addr = a;
+ u32 u = pci_read_long(d, reg);
+ if (u != 0xffffffff)
+ d->rom_base_addr = u;
}
}
return flags & ~PCI_FILL_SIZES;
struct pci_methods *methods;
byte *cache; /* Cached config registers */
int cache_len;
- int hdrtype; /* Cached header type, -1 if unknown */
+ int hdrtype; /* Cached low 7 bits of header type, -1 if unknown */
void *aux; /* Auxillary data */
};
}
static void
-show_rom(struct device *d)
+show_rom(struct device *d, int reg)
{
struct pci_dev *p = d->dev;
pciaddr_t rom = p->rom_base_addr;
pciaddr_t len = (p->known_fields & PCI_FILL_SIZES) ? p->rom_size : 0;
+ u32 flg = get_conf_long(d, reg);
+ word cmd = get_conf_word(d, PCI_COMMAND);
- if (!rom && !len)
+ if (!rom && !flg && !len)
return;
- printf("\tExpansion ROM at ");
+ putchar('\t');
+ if ((rom & PCI_ROM_ADDRESS_MASK) && !(flg & PCI_ROM_ADDRESS_MASK))
+ {
+ printf("[virtual] ");
+ flg = rom;
+ }
+ printf("Expansion ROM at ");
if (rom & PCI_ROM_ADDRESS_MASK)
printf(PCIADDR_T_FMT, rom & PCI_ROM_ADDRESS_MASK);
+ else if (flg & PCI_ROM_ADDRESS_MASK)
+ printf("<ignored>");
else
printf("<unassigned>");
- if (!(rom & PCI_ROM_ADDRESS_ENABLE))
+ if (!(flg & PCI_ROM_ADDRESS_ENABLE))
printf(" [disabled]");
+ else if (!(cmd & PCI_COMMAND_MEMORY))
+ printf(" [disabled by cmd]");
show_size(len);
putchar('\n');
}
show_htype0(struct device *d)
{
show_bases(d, 6);
- show_rom(d);
+ show_rom(d, PCI_ROM_ADDRESS);
show_caps(d);
}
FLAG(sec_stat, PCI_STATUS_SIG_SYSTEM_ERROR),
FLAG(sec_stat, PCI_STATUS_DETECTED_PARITY));
- show_rom(d);
+ show_rom(d, PCI_ROM_ADDRESS1);
if (verbose > 1)
printf("\tBridgeCtl: Parity%c SERR%c NoISA%c VGA%c MAbort%c >Reset%c FastB2B%c\n",