[PATCH 0/3] Added code to use libpciaccess to utils/conntest utilities
In reply to this message I submit three patches to the radeonhd project to update the rhd_dump and rhd_conntest utilities to optionally compile with libpciaccess. The reasons why I undertook this update are: 1) The existing rhd_dump and rhd_conntest do not work on the Alpha architecture (which is what I have). In addition the legacy VBIOS is only available on the ia64 and x86 architectures, thus rendering rhd_conntest unuseable to others. Making these utilities available to those using other architectures seems desireable. 2) There have been reports of needing to enable PCI cards and/or the PCI ROM access to run radeonhd. Others have initialisation problems that may or may not be related. Indeed I have such problems. I wanted to better understand what is really going on during the initialisation of the PCI card and how the PCI memory is accessed. By updating the utilities I have gained a much deeper understanding of what's going on. I now know, for example, that the problems I see with radeonhd, and many that others have reported, are not related to the enabling of the PCI card and ROM. The udpated code has the following features: The use of libpciaccess is activated if the XSERVER_LIBPCIACCESS macro is defined. This is the same mechanism that triggers use of libpciaccess in the radeonhd driver itself. The command line argument -e has been added to both utilities. It causes the PCI card to be first enabled. It's only needed for the rare situation where someone has a PCI card that hasn't been enabled otherwise. By default rhd_conntest first tries to read the legacy VBIOS (as it always did) but now if the VBIOS read fails and the PCI tag is given it will attempt to read the BIOS from the PCI ROM. This enables those who using architectures which do not support the legacy VBIOS to run rhd_conntest. The command line argument -r has been added to rhd_conntest. It causes rhd_conntest to skip the attempt to read the legacy VBIOS and only read the BIOS from the PCI ROM. The rationale to add that was that I thought it might be useful for those who are trying to test a second card - it makes sure the BIOS read is the BIOS for the card being tested and not for the primary card. Anyway the offerings follow. Michael Cree (3): [rhd_dump] Added code to use libpciaccess [rhd_conntest] Added code to use libpciaccess and access PCI ROM Updated Makefile in utils/conntest to enable link with libpciaccess. utils/conntest/Makefile.am | 15 ++- utils/conntest/rhd_conntest.c | 368 +++++++++++++++++++++++++++++++++++++--- utils/conntest/rhd_dump.c | 89 +++++++++- 3 files changed, 437 insertions(+), 35 deletions(-) -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
On 18/03/2009, at 11:17 PM, Michael Cree wrote:
In reply to this message I submit three patches to the radeonhd project to update the rhd_dump and rhd_conntest utilities to optionally compile with libpciaccess.
I thought this was a developers' email list! It's just bounced my patches. IMHO, It's pretty ridiculous when a developers' email list rejects emails formatted and sent by git-send-email!!! Such a list policy beggars belief. I'm going to have to email the patches by hand (fume, fume, fume). Michael. -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
Michael Cree
I thought this was a developers' email list! It's just bounced my patches. IMHO, It's pretty ridiculous when a developers' email list rejects emails formatted and sent by git-send-email!!! Such a list policy beggars belief.
I seem to see all your patch emails... are you sure it wasn't just a particular _recipient_ that bounced them (i.e., everybody else got them)...? -Miles -- Would you like fries with that? -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
On 19/03/2009, at 1:18 PM, Miles Bader wrote:
I thought this was a developers' email list! It's just bounced my patches. I seem to see all your patch emails... are you sure it wasn't just a
Michael Cree
writes: particular _recipient_ that bounced them (i.e., everybody else got them)...?
No, I posted them to the list again by hand. That's what has come through. Cheerz Michael. -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
Michael Cree
I seem to see all your patch emails... are you sure it wasn't just a particular _recipient_ that bounced them (i.e., everybody else got them)...?
No, I posted them to the list again by hand. That's what has come through.
What's the difference between the auto-emails and the send-by-hand mails? Obviously they contain patches, so it's not rejecting stuff containing patches... some funny header? Seems worth investigating... [I've had a fair number of problems before with automatic mail-sending tools (not git-send-email in particular, but similar things) getting the headers wrong by default, so I'm always slightly reluctant to use them.] -Miles -- Guilt, n. The condition of one who is known to have committed an indiscretion, as distinguished from the state of him who has covered his tracks. -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
On 19/03/2009, at 1:49 PM, Miles Bader wrote:
Michael Cree
writes: I seem to see all your patch emails... are you sure it wasn't just a particular _recipient_ that bounced them (i.e., everybody else got them)...?
No, I posted them to the list again by hand. That's what has come through.
What's the difference between the auto-emails and the send-by-hand mails? Obviously they contain patches, so it's not rejecting stuff containing patches... some funny header? Seems worth investigating...
Probably that git formats the followup patch emails as if they are replies to the first cover email for the benefit of those using threaded mail user agents. The list server may detect that the followup emails, which have In-Reply-To and References header lines, references an email that hasn't yet been through the list. The ones I did by hand I inserted the mail body into a reply to the cover email using my mail user agent. That will have References, etc., headers that use the actual references generated by the list server. Anyway, that's my guess as to why they were rejected. Cheers Michael. -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
Michael Cree
Probably that git formats the followup patch emails as if they are replies to the first cover email for the benefit of those using threaded mail user agents. The list server may detect that the followup emails, which have In-Reply-To and References header lines, references an email that hasn't yet been through the list.
Note that such a circumstance can easily happen in real conversations too (for instance, if people are sending to each other and CCing the list), so such filtering would obviously be wrong... -Miles -- `Cars give people wonderful freedom and increase their opportunities. But they also destroy the environment, to an extent so drastic that they kill all social life' (from _A Pattern Language_) -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
On Mar 19, 09 08:44:43 +1300, Michael Cree wrote:
On 18/03/2009, at 11:17 PM, Michael Cree wrote:
In reply to this message I submit three patches to the radeonhd project to update the rhd_dump and rhd_conntest utilities to optionally compile with libpciaccess.
I thought this was a developers' email list! It's just bounced my patches. IMHO, It's pretty ridiculous when a developers' email list rejects emails formatted and sent by git-send-email!!! Such a list policy beggars belief.
I'm going to have to email the patches by hand (fume, fume, fume).
I have no freaking idea what's going on here. We had patches on this
list already...
Sorry for the additional work
Matthias
--
Matthias Hopf
Added support for using libpciaccess to access PCI resources. Uses libpciaccess if XSERVER_LIBPCIACCESS defined. Added -e option to enable pci card. --- utils/conntest/rhd_dump.c | 89 ++++++++++++++++++++++++++++++++++++++ ++++--- 1 files changed, 83 insertions(+), 6 deletions(-) diff --git a/utils/conntest/rhd_dump.c b/utils/conntest/rhd_dump.c index 4f17212..ec74ecc 100644 --- a/utils/conntest/rhd_dump.c +++ b/utils/conntest/rhd_dump.c @@ -30,16 +30,23 @@ #include#include #include + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifdef XSERVER_LIBPCIACCESS +#include +#else #include +#endif + #include #include #define DEFAULT_START 0x7200 #define DEFAULT_END 0x7300 -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif #include "git_version.h" #ifndef ULONG @@ -272,6 +279,8 @@ struct RHDDevice { /* * */ +#ifndef XSERVER_LIBPCIACCESS +/* Only for libpci use */ static struct pci_dev * DeviceLocate(struct pci_dev *devices, int bus, int dev, int func) { @@ -283,12 +292,17 @@ DeviceLocate(struct pci_dev *devices, int bus, int dev, int func) return device; return NULL; } +#endif /* * */ static struct RHDDevice * +#ifdef XSERVER_LIBPCIACCESS +DeviceMatch(struct pci_device *device) +#else DeviceMatch(struct pci_dev *device) +#endif { int i; @@ -303,6 +317,8 @@ DeviceMatch(struct pci_dev *device) /* * */ +#ifndef XSERVER_LIBPCIACCESS +/* Only used by pci */ static void * MapBar(struct pci_dev *device, int ioBar, int devMem) { @@ -318,6 +334,7 @@ MapBar(struct pci_dev *device, int ioBar, int devMem) return map; } +#endif /* * @@ -363,7 +380,12 @@ print_help(const char* progname, const char* message, const char* msgarg) { if (message != NULL) fprintf(stderr, "%s %s\n", message, msgarg); +#ifdef XSERVER_LIBPCIACCESS + fprintf(stderr, "Usage: %s [-e] [-r start,end | -w addr val | -l {0| 1}] PCI-tag\n" + " -e: enable PCI card (not normally needed)\n" +#else fprintf(stderr, "Usage: %s [-r start,end | -w addr val | -l {0|1}] PCI-tag\n" +#endif " PCI-tag: bus:dev.func\n\n", progname); } @@ -375,14 +397,19 @@ print_help(const char* progname, const char* message, const char* msgarg) int main(int argc, char *argv[]) { +#ifdef XSERVER_LIBPCIACCESS + struct pci_device *device = NULL; + int enable_device = FALSE; +#else struct pci_dev *device = NULL; struct pci_access *pciAccess; - struct RHDDevice *rhdDevice = NULL; int devMem; + int saved_errno; +#endif + struct RHDDevice *rhdDevice = NULL; void *io; int bus, dev, func; int ret; - int saved_errno; Bool deviceSet = FALSE; CARD32 start = DEFAULT_START, end = DEFAULT_END; CARD32 addr, val; @@ -400,10 +427,20 @@ main(int argc, char *argv[]) printf("%s: v%s, %s\n", "rhd_dump", PACKAGE_VERSION, GIT_MESSAGE); + +#ifdef XSERVER_LIBPCIACCESS + /* Initialise pciaccess */ + if ((i = pci_system_init())) { + fprintf(stderr, "ERROR: pciaccess failed to initialise PCI bus" + " (error %d)\n", i); + return 1; + } +#else /* init libpci */ pciAccess = pci_alloc(); pci_init(pciAccess); pci_scan_bus(pciAccess); +#endif if (argc < 2) { print_help(argv[0], "Missing argument: please provide a PCI tag\n", @@ -412,6 +449,11 @@ main(int argc, char *argv[]) } for (i = 1; i < argc; i++) { +#ifdef XSERVER_LIBPCIACCESS + if (!strncmp("-e", argv[i], 3)) { + enable_device = TRUE; + }else +#endif if (!strncmp("-r",argv[i],3)) { action = READ; @@ -490,13 +532,24 @@ main(int argc, char *argv[]) } if (deviceSet) { - /* find our toy */ +#ifdef XSERVER_LIBPCIACCESS + /* Find the toy using pciaccess */ + if ((device = pci_device_find_by_slot(0, bus, dev, func)) == NULL) { + fprintf(stderr, "ERROR: Unable to find PCI device at %02X:%02X. %02X.\n", + bus, dev, func); + return 1; + } +#else + /* find our toy using pci */ device = DeviceLocate(pciAccess->devices, bus, dev, func); if (!device) { fprintf(stderr, "Unable to find PCI device at %02X:%02X.%02X.\n", bus, dev, func); return 1; } + if (enable_device) + pci_device_enable(device); +#endif rhdDevice = DeviceMatch(device); if (!rhdDevice) { @@ -511,6 +564,24 @@ main(int argc, char *argv[]) return 1; } + /* Map into CPU memory space the required PCI memory */ + +#ifdef XSERVER_LIBPCIACCESS + pci_device_probe(device); + + if (device->regions[rhdDevice->bar].base_addr == 0) { + fprintf(stderr, "ERROR: Failed to find required resource on PCI card. \n"); + return 1; + } + + if ((i = pci_device_map_range(device,device->regions[rhdDevice- >bar].base_addr, + device->regions[rhdDevice->bar].size, + PCI_DEV_MAP_FLAG_WRITABLE, &io))) { + fprintf(stderr, "ERROR: Couldn't map IO memory: %s.\n", strerror(i)); + return i; + } + +#else /* make sure we can actually read DEV_MEM before we do anything else */ devMem = open(DEV_MEM, O_RDWR); @@ -527,6 +598,7 @@ main(int argc, char *argv[]) strerror(saved_errno)); return 1; } +#endif ChipType = rhdDevice->type; if (action == READ) { @@ -557,5 +629,10 @@ main(int argc, char *argv[]) } } +#ifdef XSERVER_LIBPCIACCESS + pci_device_unmap_range(device, io, device->regions[rhdDevice- >bar].size); + pci_system_cleanup(); +#endif + return 0; } -- 1.5.6.5 -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
Uses libpciaccess if XSERVER_LIBPCIACCESS defined. New features: Can read BIOS from PCI ROM if unposted when using libpciaccess. New options -e (enable PCI card) and -r (use PCI ROM not VBIOS) --- utils/conntest/rhd_conntest.c | 368 ++++++++++++++++++++++++++++++++++ +++--- 1 files changed, 340 insertions(+), 28 deletions(-) diff --git a/utils/conntest/rhd_conntest.c b/utils/conntest/ rhd_conntest.c index 9e9a595..52f8d2b 100644 --- a/utils/conntest/rhd_conntest.c +++ b/utils/conntest/rhd_conntest.c @@ -35,7 +35,6 @@ #include#include #include -#include #include #include @@ -44,6 +43,12 @@ #endif #include "git_version.h" +#ifdef XSERVER_LIBPCIACCESS +#include +#else +#include +#endif + #ifndef ULONG typedef unsigned int ULONG; # define ULONG ULONG @@ -79,6 +84,26 @@ typedef unsigned int CARD32; /* Some register names */ enum { + /* Needed for enable PCI ROM read */ + BUS_CNTL = 0x4C, /* (RW) */ + GPIOPAD_MASK = 0x198, /* (RW) */ + GPIOPAD_A = 0x19C, /* (RW) */ + GPIOPAD_EN = 0x1A0, /* (RW) */ + VIPH_CONTROL = 0xC40, /* (RW) */ + SEPROM_CNTL1 = 0x1C0, /* (RW) */ + + ROM_CNTL = 0x1600, + GENERAL_PWRMGT = 0x0618, + LOW_VID_LOWER_GPIO_CNTL = 0x0724, + MEDIUM_VID_LOWER_GPIO_CNTL = 0x0720, + HIGH_VID_LOWER_GPIO_CNTL = 0x071C, + CTXSW_VID_LOWER_GPIO_CNTL = 0x0718, + LOWER_GPIO_ENABLE = 0x0710, + + VGA_RENDER_CONTROL = 0x0300, + D1VGA_CONTROL = 0x0330, + D2VGA_CONTROL = 0x0338, + /* DAC A */ DACA_ENABLE = 0x7800, DACA_SOURCE_SELECT = 0x7804, @@ -256,6 +281,21 @@ typedef enum dacOutput { DAC_COMPONENT } dacOutput; +/* Some defines needed for getting access to unposted BIOS */ + +#define SCK_PRESCALE (0xff << 24) +#define VIPH_EN (1 << 21) +#define BIOS_ROM_DIS (1 << 2) +#define D1VGA_MODE_ENABLE (1 << 0) +#define D1VGA_TIMING_SELECT (1 << 8) +#define D2VGA_MODE_ENABLE (1 << 0) +#define D2VGA_TIMING_SELECT (1 << 8) +#define VGA_VSTATUS_CNTL (0x3 << 16) +#define SCK_OVERWRITE (1 << 1) +#define SCK_PRESCALE_CRYSTAL_CLK_SHIFT 28 +#define OPEN_DRAIN_PADS (1 << 11) + + /* for RHD_R500/R600/RS690/RV620 */ chipType ChipType; @@ -509,6 +549,8 @@ dprint(unsigned char *start, unsigned long size) /* * */ +#ifndef XSERVER_LIBPCIACCESS +/* Only for libpci use */ static struct pci_dev * DeviceLocate(struct pci_dev *devices, int bus, int dev, int func) { @@ -520,12 +562,17 @@ DeviceLocate(struct pci_dev *devices, int bus, int dev, int func) return device; return NULL; } +#endif /* * */ static struct RHDDevice * +#ifdef XSERVER_LIBPCIACCESS +DeviceMatch(struct pci_device *device) +#else DeviceMatch(struct pci_dev *device) +#endif { int i; @@ -540,6 +587,8 @@ DeviceMatch(struct pci_dev *device) /* * */ +#ifndef XSERVER_LIBPCIACCESS +/* Only for libpci use */ static void * MapBar(struct pci_dev *device, int ioBar, int devMem) { @@ -561,6 +610,7 @@ MapBar(struct pci_dev *device, int ioBar, int devMem) return map; } +#endif /* * @@ -2375,6 +2425,129 @@ FreeVBIOS(unsigned char *rombase, int size) munmap(rombase,size); } + +#ifdef XSERVER_LIBPCIACCESS + +/* Copy BIOS from PCI ROM into memory buffer */ +unsigned char * +GetBIOS_from_PCI(struct RHDDevice *rhdDevice, struct pci_device *dev, void *io, int *size) +{ + unsigned char *rombase = NULL; + int errnum; + + CARD32 save_seprom_cntl1 = 0, + save_gpiopad_a, save_gpiopad_en, save_gpiopad_mask, + save_viph_cntl, + save_bus_cntl, + save_d1vga_control, save_d2vga_control, save_vga_render_control, + save_rom_cntl = 0, + save_gen_pwrmgt = 0, + save_low_vid_lower_gpio_cntl = 0, save_med_vid_lower_gpio_cntl = 0, + save_high_vid_lower_gpio_cntl = 0, save_ctxsw_vid_lower_gpio_cntl = 0, + save_lower_gpio_en = 0; + + /* We have to enable BIOS on an unposted card. But first we save the + state. Much of this code pinched from RHDReadPCIBios() in + rhd_driver.c */ + + if (rhdDevice->type < RHD_R600) + save_seprom_cntl1 = RegRead(io, SEPROM_CNTL1); + save_gpiopad_en = RegRead(io, GPIOPAD_EN); + save_gpiopad_a = RegRead(io, GPIOPAD_A); + save_gpiopad_mask = RegRead(io, GPIOPAD_MASK); + save_viph_cntl = RegRead(io, VIPH_CONTROL); + save_bus_cntl = RegRead(io, BUS_CNTL); + save_d1vga_control = RegRead(io, D1VGA_CONTROL); + save_d2vga_control = RegRead(io, D2VGA_CONTROL); + save_vga_render_control = RegRead(io, VGA_RENDER_CONTROL); + if (rhdDevice->type >= RHD_R600) { + save_rom_cntl = RegRead(io, ROM_CNTL); + save_gen_pwrmgt = RegRead(io, GENERAL_PWRMGT); + save_low_vid_lower_gpio_cntl = RegRead(io, LOW_VID_LOWER_GPIO_CNTL); + save_med_vid_lower_gpio_cntl = RegRead(io, MEDIUM_VID_LOWER_GPIO_CNTL); + save_high_vid_lower_gpio_cntl = RegRead(io, HIGH_VID_LOWER_GPIO_CNTL); + save_ctxsw_vid_lower_gpio_cntl = RegRead(io, CTXSW_VID_LOWER_GPIO_CNTL); + save_lower_gpio_en = RegRead(io, LOWER_GPIO_ENABLE); + } + + /* Set SPI ROM prescale value to change the SCK period */ + if (rhdDevice->type < RHD_R600) + RegMask(io, SEPROM_CNTL1, 0x0C << 24, SCK_PRESCALE); + /* Let chip control GPIO pads - this is the default state after power up */ + RegWrite(io, GPIOPAD_EN, 0); + RegWrite(io, GPIOPAD_A, 0); + /* Put GPIO pads in read mode */ + RegWrite(io, GPIOPAD_MASK, 0); + /* Disable VIP Host port */ + RegMask(io, VIPH_CONTROL, 0, VIPH_EN); + /* Enable BIOS ROM */ + RegMask(io, BUS_CNTL, 0, BIOS_ROM_DIS); + /* Disable VGA and select extended timings */ + RegMask(io, D1VGA_CONTROL, 0, + D1VGA_MODE_ENABLE | D1VGA_TIMING_SELECT); + RegMask(io, D2VGA_CONTROL, 0, + D2VGA_MODE_ENABLE | D2VGA_TIMING_SELECT); + RegMask(io, VGA_RENDER_CONTROL, 0, VGA_VSTATUS_CNTL); + if (rhdDevice->type >= RHD_R600) { + RegMask(io, ROM_CNTL, SCK_OVERWRITE + | 1 << SCK_PRESCALE_CRYSTAL_CLK_SHIFT, + SCK_OVERWRITE + | 1 << SCK_PRESCALE_CRYSTAL_CLK_SHIFT); + RegMask(io, GENERAL_PWRMGT, 0, OPEN_DRAIN_PADS); + RegMask(io, LOW_VID_LOWER_GPIO_CNTL, 0, 0x400); + RegMask(io, MEDIUM_VID_LOWER_GPIO_CNTL, 0, 0x400); + RegMask(io, HIGH_VID_LOWER_GPIO_CNTL, 0, 0x400); + RegMask(io, CTXSW_VID_LOWER_GPIO_CNTL, 0, 0x400); + RegMask(io, LOWER_GPIO_ENABLE, 0x400, 0x400); + } + + /* Read the ROM */ + + *size = (dev->rom_size > 0) ? dev->rom_size : 0x20000; + + rombase = malloc((size_t)*size); + + if ((errnum = pci_device_read_rom(dev, rombase))) { + fprintf(stderr,"Attempt to read ROM from PCI failed: %s.\n", + strerror(errnum)); + free(rombase); + rombase = NULL; + } + + /* Restore the state prior to being called */ + + if (rhdDevice->type < RHD_R600) + RegWrite(io, SEPROM_CNTL1, save_seprom_cntl1); + RegWrite(io, GPIOPAD_EN, save_gpiopad_en); + RegWrite(io, GPIOPAD_A, save_gpiopad_a); + RegWrite(io, GPIOPAD_MASK, save_gpiopad_mask); + RegWrite(io, VIPH_CONTROL, save_viph_cntl); + RegWrite(io, BUS_CNTL, save_bus_cntl); + RegWrite(io, D1VGA_CONTROL, save_d1vga_control); + RegWrite(io, D2VGA_CONTROL, save_d2vga_control); + RegWrite(io, VGA_RENDER_CONTROL, save_vga_render_control); + if (rhdDevice->type >= RHD_R600) { + RegWrite(io, ROM_CNTL, save_rom_cntl); + RegWrite(io, GENERAL_PWRMGT, save_gen_pwrmgt); + RegWrite(io, LOW_VID_LOWER_GPIO_CNTL, save_low_vid_lower_gpio_cntl); + RegWrite(io, MEDIUM_VID_LOWER_GPIO_CNTL, save_med_vid_lower_gpio_cntl); + RegWrite(io, HIGH_VID_LOWER_GPIO_CNTL, save_high_vid_lower_gpio_cntl); + RegWrite(io, CTXSW_VID_LOWER_GPIO_CNTL, save_ctxsw_vid_lower_gpio_cntl); + RegWrite(io, LOWER_GPIO_ENABLE, save_lower_gpio_en); + } + + return rombase; +} + + + +void FreeBIOS_from_PCI(unsigned char *rombase) +{ + if (rombase) free(rombase); +} +#endif + + /* * */ @@ -2478,8 +2651,12 @@ print_help(const char* progname, const char* message, const char* msgarg) fprintf(stderr, "%s %s\n", message, msgarg); fprintf(stderr, "Usage: %s [options] PCI-tag\n" " Options: -d: dumpBios\n" +#ifdef XSERVER_LIBPCIACCESS + " -e: enable pci card (not normally needed)\n" + " -r: only attempt BIOS read via PCI ROM\n" +#endif " -s: scanDDCBus\n" - " -x num: dump num bytes from available i2c channels\n" + " -x num: dump num bytes from available i2c channels \n" " PCI-tag: bus:dev.func\n\n", progname); } @@ -2615,28 +2792,48 @@ InterpretATOMBIOS(unsigned char *base) int main(int argc, char *argv[]) { +#ifdef XSERVER_LIBPCIACCESS + struct pci_device *device = NULL; + int enable_device; +#else struct pci_dev *device = NULL; struct pci_access *pciAccess; - struct RHDDevice *rhdDevice = NULL; int devMem; + int saved_errno; +#endif + struct RHDDevice *rhdDevice = NULL; void *io; int bus, dev, func; int ret; - int saved_errno; Bool deviceSet = FALSE; Bool dumpBios = FALSE, scanDDCBus = FALSE; unsigned long DumpI2CData = 0; int i; unsigned char *rombase; int size; + int using_vbios; printf("%s: v%s, %s\n", "rhd_conntest", PACKAGE_VERSION, GIT_MESSAGE); +#ifdef XSERVER_LIBPCIACCESS + /* Initialise pciaccess */ + if ((i = pci_system_init())) { + fprintf(stderr, "ERROR: pciaccess failed to initialise PCI bus" + " (error %d)\n", i); + return 1; + } + /* Default actions */ + enable_device = FALSE; + using_vbios = TRUE; +#else /* init libpci */ pciAccess = pci_alloc(); pci_init(pciAccess); pci_scan_bus(pciAccess); + /* Default action */ + using_vbios = TRUE; +#endif if (argc < 2) { print_help(argv[0], "Missing argument: please provide a PCI tag\n", @@ -2645,6 +2842,13 @@ main(int argc, char *argv[]) } for (i = 1; i < argc; i++) { +#ifdef XSERVER_LIBPCIACCESS + if (!strncmp("-e", argv[i], 3)) { + enable_device = TRUE; + }else if (!strncmp("-r", argv[i], 3)) { + using_vbios = FALSE; + }else +#endif if (!strncmp("-d",argv[i],3)) { dumpBios = TRUE; } else if (!strncmp("-s",argv[i],3)) { @@ -2681,14 +2885,33 @@ main(int argc, char *argv[]) } } + if (!using_vbios & !deviceSet) { + /* Not technically an error, but only a right plonker would specify + this combination of command line options. */ + printf("What?!! You want me to do nothing!\n" + "Specify a PCI tag and/or don't specify '-r' for some action. \n"); + return 0; + } + if (deviceSet) { - /* find our toy */ +#ifdef XSERVER_LIBPCIACCESS + /* Find the toy using pciaccess */ + if ((device = pci_device_find_by_slot(0, bus, dev, func)) == NULL) { + fprintf(stderr, "ERROR: Unable to find PCI device at %02X:%02X. %02X.\n", + bus, dev, func); + return 1; + } + if (enable_device) + pci_device_enable(device); +#else + /* find our toy using pci */ device = DeviceLocate(pciAccess->devices, bus, dev, func); if (!device) { fprintf(stderr, "Unable to find PCI device at %02X:%02X.%02X.\n", bus, dev, func); return 1; } +#endif rhdDevice = DeviceMatch(device); if (!rhdDevice) { @@ -2697,43 +2920,82 @@ main(int argc, char *argv[]) device->vendor_id, device->device_id, bus, dev, func); return 1; } - } - rombase = GetVBIOS(&size); - if (!rombase) { - fprintf(stderr, "Cannot get VBIOS. Are we root?\n"); - } else - if (!InterpretATOMBIOS(rombase)) { - fprintf(stderr, "Cannot analyze AtomBIOS\n"); - return 1; +#ifdef XSERVER_LIBPCIACCESS + printf("Found card: %s - %s\n", + pci_device_get_vendor_name(device), + pci_device_get_device_name(device)); +#endif } - if (dumpBios && rombase) { - char name[1024] = "posted.vga.rom"; - - if (deviceSet) { - snprintf(name, 1023, "%04X.%04X.%04X.vga.rom", - device->device_id, - pci_read_word(device, PCI_SUBSYSTEM_VENDOR_ID), - pci_read_word(device, PCI_SUBSYSTEM_ID)); + if (using_vbios) { + /* Attempt to read BIOS from legacy VBIOS. */ + rombase = GetVBIOS(&size); + if (!rombase) { + printf("Cannot get VBIOS. Are we root?\n"); + }else{ + if (!InterpretATOMBIOS(rombase)) { + printf("Cannot analyze AtomBIOS from VBIOS\n"); + rombase = NULL; + } } - WriteToFile(name, rombase, size); + if (dumpBios && rombase) { + char name[1024] = "posted.vga.rom"; + + if (deviceSet) { +#ifdef XSERVER_LIBPCIACCESS + snprintf(name, 1023, "%04X.%04X.%04X.vga.rom", + device->device_id, device->subvendor_id, device->subdevice_id); +#else + snprintf(name, 1023, "%04X.%04X.%04X.vga.rom", + device->device_id, + pci_read_word(device, PCI_SUBSYSTEM_VENDOR_ID), + pci_read_word(device, PCI_SUBSYSTEM_ID)); +#endif + } + WriteToFile(name, rombase, size); + } + }else{ + /* We ain't goin' to read VBIOS - flag that */ + rombase = NULL; } - if (!deviceSet) + /* We reuse the flag using_vbios now to indicate whether we successfully + read the VBIOS (rombase is not suitable for the purpose) */ + using_vbios = rombase ? 1 : 0; + + if (!deviceSet) { + if (! using_vbios) { + fprintf(stderr, "ERROR: Failed to read VBIOS.\n"); + return 1; + } return 0; + } if (rhdDevice->bar > 5) { - fprintf(stderr, "Program error: No acceptable BAR defined for this device.\n"); + fprintf(stderr, "ERROR: No acceptable PCI BAR defined for this device.\n"); return 1; } - printf("Checking connectors on 0x%04X, 0x%04X, 0x%04X (@%02X: %02X:%02X):\n", - device->device_id, pci_read_word(device, PCI_SUBSYSTEM_VENDOR_ID), - pci_read_word(device, PCI_SUBSYSTEM_ID), - device->bus, device->dev, device->func); + /* Map into CPU memory space the required PCI memory */ + +#ifdef XSERVER_LIBPCIACCESS + pci_device_probe(device); + if (device->regions[rhdDevice->bar].base_addr == 0) { + fprintf(stderr, "ERROR: Failed to find required resource on PCI card. \n"); + return 1; + } + + if ((i = pci_device_map_range(device,device->regions[rhdDevice- >bar].base_addr, + device->regions[rhdDevice->bar].size, + PCI_DEV_MAP_FLAG_WRITABLE, &io))) { + fprintf(stderr, "ERROR: Couldn't map IO memory: %s.\n", strerror(i)); + return i; + } + +#else /* make sure we can actually read DEV_MEM before we do anything else */ devMem = open(DEV_MEM, O_RDWR); if (devMem < 0) { @@ -2749,6 +3011,45 @@ main(int argc, char *argv[]) strerror(saved_errno)); return 1; } +#endif + +#ifdef XSERVER_LIBPCIACCESS + /* Attempt to get unposted BIOS if failed before */ + + if (! using_vbios) { + printf("Trying to get BIOS from PCI ROM...\n"); + + if ((rombase = GetBIOS_from_PCI(rhdDevice, device, io, &size)) == NULL) { + fprintf(stderr,"ERROR: Fat lot of use that was -- can't read BIOS image\n"); + return 1; + } + + if (!InterpretATOMBIOS(rombase)) { + fprintf(stderr, "ERROR: Cannot analyze AtomBIOS from PCI ROM\n"); + return 1; + } + + if (dumpBios && rombase) { + char name[1024]; + + snprintf(name, 1023, "%04X.%04X.%04X.vga.rom", + device->device_id, device->subvendor_id, device->subdevice_id); + WriteToFile(name, rombase, size); + } + } +#endif + + +#ifdef XSERVER_LIBPCIACCESS + printf("Checking connectors on 0x%04X, 0x%04X, 0x%04X (@%02X: %02X:%02X):\n", + device->device_id, device->subvendor_id, device->subdevice_id, + device->bus, device->dev, device->func); +#else + printf("Checking connectors on 0x%04X, 0x%04X, 0x%04X (@%02X: %02X:%02X):\n", + device->device_id, pci_read_word(device, PCI_SUBSYSTEM_VENDOR_ID), + pci_read_word(device, PCI_SUBSYSTEM_ID), + device->bus, device->dev, device->func); +#endif ChipType = rhdDevice->type; @@ -2760,7 +3061,18 @@ main(int argc, char *argv[]) if (scanDDCBus || DumpI2CData) DDCScanBus(io, DumpI2CData); +#ifdef XSERVER_LIBPCIACCESS + if (using_vbios) { + FreeVBIOS(rombase, size); + }else{ + FreeBIOS_from_PCI(rombase); + } + + pci_device_unmap_range(device, io, device->regions[rhdDevice- >bar].size); + pci_system_cleanup(); +#else FreeVBIOS(rombase, size); +#endif return 0; } -- 1.5.6.5 -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
This is needed to compile rhd_dump and rhd_conntest with libpciaccess. --- utils/conntest/Makefile.am | 15 ++++++++++++++- 1 files changed, 14 insertions(+), 1 deletions(-) diff --git a/utils/conntest/Makefile.am b/utils/conntest/Makefile.am index b7cc322..48fafbe 100644 --- a/utils/conntest/Makefile.am +++ b/utils/conntest/Makefile.am @@ -5,6 +5,11 @@ include $(top_srcdir)/RadeonHD.am EXTRA_DIST = README Imakefile EXTRA_PROGRAMS = rhd_conntest rhd_dump + +if XSERVER_LIBPCIACCESS +noinst_PROGRAMS = rhd_conntest rhd_dump +endif + if HAVE_PCI_PCI_H if HAVE_ZLIB noinst_PROGRAMS = rhd_conntest rhd_dump @@ -24,8 +29,16 @@ AM_CPPFLAGS = -I$(top_srcdir)/src/AtomBios/includes rhd_conntest_SOURCES = rhd_conntest.c nodist_rhd_conntest_SOURCES = git_version.h +if XSERVER_LIBPCIACCESS +rhd_conntest_LDADD = @PCIACCESS_LIBS@ +else rhd_conntest_LDADD = @PCIUTILS_LIBS@ +endif rhd_dump_SOURCES = rhd_dump.c nodist_rhd_dump_SOURCES = git_version.h -rhd_dump_LDADD = @PCIUTILS_LIBS@ \ No newline at end of file +if XSERVER_LIBPCIACCESS +rhd_dump_LDADD = @PCIACCESS_LIBS@ +else +rhd_dump_LDADD = @PCIUTILS_LIBS@ +endif -- 1.5.6.5 -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
On Mar 18, 09 23:17:55 +1300, Michael Cree wrote:
In reply to this message I submit three patches to the radeonhd project to update the rhd_dump and rhd_conntest utilities to optionally compile with libpciaccess.
Machael, I just wanted to apply your patches, but in the second (manual)
run the patches came through mangled, almost beyond repair.
Can you resend the patches to me privately?
They seem reasonable to me.
CU
Matthias
--
Matthias Hopf
On Apr 03, 09 14:18:08 +0200, Matthias Hopf wrote:
On Mar 18, 09 23:17:55 +1300, Michael Cree wrote: Machael, I just wanted to apply your patches, but in the second (manual) ^^^^^^^ blush...
Sorry, Michael :]
Matthias
--
Matthias Hopf
On Mar 18, 09 23:17:55 +1300, Michael Cree wrote: Machael, I just wanted to apply your patches, but in the second (manual) run the patches came through mangled, almost beyond repair. Can you resend the patches to me privately?
Yes, can do, but I am now travelling and won't be back to my computer for 10 days or so, so it will have to wait. Michael -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
participants (3)
-
Matthias Hopf
-
Michael Cree
-
Miles Bader