]> mj.ucw.cz Git - pciutils.git/commitdiff
Fixed bugs in reading and interpreting of base addresses.
authorMartin Mares <mj@ucw.cz>
Fri, 13 Aug 2004 19:51:05 +0000 (19:51 +0000)
committerMartin Mares <mj@ucw.cz>
Fri, 5 May 2006 12:18:23 +0000 (14:18 +0200)
git-archimport-id: mj@ucw.cz--public/pciutils--main--2.2--patch-58

ChangeLog
lib/generic.c
lib/pci.h
lspci.c

index 86f8d9195896f9dbae3dccabf7c2f0d48960f562..1fc2e74b9bca722675585ff7baaf4ae15f1c2569 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+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.
index 25d3faab2d65923b484d86cf1b9e4f6e799e7e22..0402ad1efadb778390ad1fda98fa5b3359e05cb8 100644 (file)
@@ -80,7 +80,7 @@ pci_generic_fill_info(struct pci_dev *d, int flags)
   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);
@@ -106,41 +106,32 @@ pci_generic_fill_info(struct pci_dev *d, int flags)
        }
       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;
            }
        }
     }
@@ -159,9 +150,9 @@ pci_generic_fill_info(struct pci_dev *d, int flags)
        }
       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;
index 188f2e545c16c899c0913e565c2c6f5da8b7cce9..1083cb79ea36f506d1df8be1d318a545f3854bfb 100644 (file)
--- a/lib/pci.h
+++ b/lib/pci.h
@@ -140,7 +140,7 @@ struct pci_dev {
   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 */
 };
 
diff --git a/lspci.c b/lspci.c
index aa6b37a8c1c42ceb47c14fcb72f536f090b94fec..943c1cdc71066fb12bff247fd87db29b9b6560c0 100644 (file)
--- a/lspci.c
+++ b/lspci.c
@@ -916,21 +916,33 @@ show_ht(struct device *d, int where, int cmd)
 }
 
 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');
 }
@@ -1363,7 +1375,7 @@ static void
 show_htype0(struct device *d)
 {
   show_bases(d, 6);
-  show_rom(d);
+  show_rom(d, PCI_ROM_ADDRESS);
   show_caps(d);
 }
 
@@ -1451,7 +1463,7 @@ show_htype1(struct device *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",