[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", ®buf);
+ if (len <= 0){
+ prom_hdl = di_prom_init();
+ len = di_prom_prop_lookup_ints(prom_hdl, node, "reg",
(int **) ®buf) ;
+ 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",
®buf);
+ if (len <= 0){
+ prom_hdl = di_prom_init();
+ len = di_prom_prop_lookup_ints(prom_hdl, args.node,
+ "assigned-addresses",
(int **) ®buf) ;
+ 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