[prev in list] [next in list] [prev in thread] [next in thread] 

List:       opensolaris-code
Subject:    Re: [osol-code] libpciaccess problem (sparc)
From:       jf simon <jfs () themis ! com>
Date:       2010-01-05 20:33:32
Message-ID: 4B43A21C.1080103 () themis ! com
[Download RAW message or body]

jf simon wrote:
> 
> As already reported by Martin Bochnig a while back, i too am
> having problem with libpciaccess on Sparc.
> 
> it seems that when the code in function
> src/solx_devfs.c::pci_device_solx_devfs_probe()
> 
> is doing
> 	...
>            (void) di_walk_node(rnode, DI_WALK_CLDFIRST,
>                                 (void *)&args, find_target_node);
> 	...
> 
> the callback find_target_node() is recursively called, BUT is not
> finding the right node (from device tree) it is looking for. as a
> result the MMIO base addresses from "assigned-addresses" are not
> found. so it is impossible to find the PCI MMIO base address of a
> given device.
> 
> i have printed all the nodes that are passed to
> find_target_node() and it seems that they are wrongly built. (no
> "reg" or "assigned-addresses" properties seen.
> 
> so there is a problem between libpciaccess (sparc) and the
> libdevinfo library.


i did some more searching on this problem, and after modifying
libpciaccess (plse see patch below), scanpci -v is now correctly
reporting MMIO resources. for ex:


pci bus 0x000a cardnum 0x00 function 0x00: vendor 0x1002 device
0x9491
 ATI Technologies Inc Device unknown
 CardVendor 0x1002 card 0x9491 (ATI Technologies Inc, Card unknown)
  STATUS    0x0000  COMMAND 0x0000
  CLASS     0x03 0x00 0x00  REVISION 0x00
  BIST      0x00  HEADER 0x00  LATENCY 0x00  CACHE 0x00
  BASE0     0x00000000 SIZE 268435456  MEM PREFETCHABLE
  BASE2     0x00800000 SIZE 65536  MEM
  BASE4     0x00002000 SIZE 256  I/O
  BASEROM   0x00000000  addr 0x00000000
  MAX_LAT   0x00  MIN_GNT 0x00  INT_PIN 0x00  INT_LINE 0x00

(NB:BASE0 is 0x1.0000.0000 and is uncorrectly reported by
scanpci...no biggie..).

unfortunately the last line "MAX_LAT ....MIN_GNT..." is wrong as
it reports all 0s values. this means that the function

src/solx_devfs.c::pci_device_solx_devfs_read()

is always reading back 0s values from the PCI CFG space. what
could be wrong? any ideas?  what is the deal with doing ioctl()
to the nexus?
frankly, having something like libpciaccess not readily working
is starting to kill us. plse help.


-- 

Best regards,
_______________________________________
jean-francois simon - themis computer
5, rue irene joliot curie
38320 eybens - france
+33 (0)4 76 14 77 85 - www.themis.com



jfsbox2:/FIX # diff -Naur solx_devfs.c.old solx_devfs.c.new
--- solx_devfs.c.old    2010-01-05 17:16:38.000000000 +0100
+++ solx_devfs.c.new    2010-01-05 17:16:18.000000000 +0100
@@ -70,7 +70,7 @@

 /* #define DEBUG */

-#define        MAX_DEVICES     256
+#define        MAX_DEVICES     1024
 #define        CELL_NUMS_1275  (sizeof(pci_regspec_t) /
sizeof(uint_t))

 typedef union {
@@ -96,6 +96,8 @@
 static nexus_t *nexus_list = NULL;
 static int xsvc_fd = -1;

+
+
 /*
  * Read config space in native processor endianness.  Endian-neutral
  * processing can then take place.  On big endian machines, MSB
and LSB
@@ -669,6 +671,7 @@
     int len = 0;
     uint32_t busno, funcno, devno;
     i_devnode_t *devnode = (i_devnode_t *)arg;
+    static di_prom_handle_t prom_hdl = DI_PROM_HANDLE_NIL;

     /*
      * Test the property functions, only for testing
@@ -693,6 +696,11 @@
     */

     len = di_prop_lookup_ints(DDI_DEV_T_ANY, node, "reg", &regbuf);
+    if (len <= 0){
+       prom_hdl = di_prom_init();
+        len =  di_prom_prop_lookup_ints(prom_hdl, node, "reg",
(int **) &regbuf) ;
+       di_prom_fini(prom_hdl);
+    }

     if (len <= 0) {
 #ifdef DEBUG
@@ -733,6 +741,7 @@
     pciaddr_t bytes;
     int len = 0;
     uint ent = 0;
+    static di_prom_handle_t prom_hdl = DI_PROM_HANDLE_NIL;

     err = pci_device_solx_devfs_read( dev, config, 0, 256, &
bytes );

@@ -760,6 +769,7 @@
         * starting to find if it is MEM/MEM64/IO
         * using libdevinfo
         */
+
        if ((rnode = di_init("/", DINFOCPYALL)) == DI_NODE_NIL) {
            err = errno;
            (void) fprintf(stderr, "di_init failed: %s\n",
strerror(errno));
@@ -779,6 +789,12 @@
        len = di_prop_lookup_ints(DDI_DEV_T_ANY, args.node,
                                  "assigned-addresses",
                                  &regbuf);
+        if (len <= 0){
+           prom_hdl = di_prom_init();
+            len =  di_prom_prop_lookup_ints(prom_hdl, args.node,
+                                        "assigned-addresses",
(int **) &regbuf) ;
+           di_prom_fini(prom_hdl);
+       }

     }

@@ -800,8 +816,12 @@
        /*
         * rom can only be 32 bits
         */
-       dev->rom_size = reg->pci_size_low;
+
+       dev->rom_size = (pciaddr_t)reg->pci_size_low;
        len = len - CELL_NUMS_1275;
+//jfas - debug
+//     fprintf(stderr, "Rom size = %x\n", reg->pci_size_low);
+//     fprintf(stderr, "Rom size = %x\n", (uint32_t)dev->rom_size);
     }
     else {
        /*
@@ -845,10 +865,17 @@
         * We split the shift count 32 into two 16 to
         * avoid the complaining of the compiler
         */
-       dev->regions[ent].base_addr = reg->pci_phys_low +
-           ((reg->pci_phys_mid << 16) << 16);
+
+//jfas: mind the 64bit casting. if not 64b resources are ignored
+
+//     dev->regions[ent].base_addr = reg->pci_phys_low +
+//         ((reg->pci_phys_mid << 16) << 16);
+
+       dev->regions[ent].base_addr = (uint64_t)reg->pci_phys_low +
+           (((uint64_t)reg->pci_phys_mid << 16) << 16);
+
        dev->regions[ent].size = reg->pci_size_low +
-           ((reg->pci_size_hi << 16) << 16);
+           (((uint64_t)reg->pci_size_hi << 16) << 16);

        switch (reg->pci_phys_hi & PCI_REG_ADDR_M) {
            case PCI_ADDR_IO:
@@ -869,6 +896,7 @@
     if (rnode != DI_NODE_NIL) {
        di_fini(rnode);
     }
+
     return (err);
 }





_______________________________________________
opensolaris-code mailing list
opensolaris-code@opensolaris.org
http://mail.opensolaris.org/mailman/listinfo/opensolaris-code
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic