1/* 2 * Dump PCI device headers 3 */ 4 5#include <stdio.h> 6#include <string.h> 7#include <stdlib.h> 8#include <sys/pci.h> 9#include "sysdump.h" 10 11static void dump_pci_device(struct upload_backend *be, pciaddr_t a, uint8_t hdrtype) 12{ 13 unsigned int bus = pci_bus(a); 14 unsigned int dev = pci_dev(a); 15 unsigned int func = pci_func(a); 16 uint8_t data[256]; 17 unsigned int i; 18 char filename[32]; 19 20 hdrtype &= 0x7f; 21 22 printf("Scanning PCI bus... %02x:%02x.%x\r", bus, dev, func); 23 24 /* Assume doing a full device dump is actually safe... */ 25 for (i = 0; i < sizeof data; i += 4) 26 *(uint32_t *)(data+i) = pci_readl(a + i); 27 28 snprintf(filename, sizeof filename, "pci/%02x:%02x.%x", 29 bus, dev, func); 30 cpio_writefile(be, filename, data, sizeof data); 31} 32 33void dump_pci(struct upload_backend *be) 34{ 35 int cfgtype; 36 unsigned int nbus, ndev, nfunc, maxfunc; 37 pciaddr_t a; 38 uint32_t did; 39 uint8_t hdrtype; 40 41 cfgtype = pci_set_config_type(PCI_CFG_AUTO); 42 if (cfgtype == PCI_CFG_NONE) 43 return; 44 45 cpio_mkdir(be, "pci"); 46 47 for (nbus = 0; nbus < MAX_PCI_BUSES; nbus++) { 48 for (ndev = 0; ndev < MAX_PCI_DEVICES; ndev++) { 49 maxfunc = 1; /* Assume a single-function device */ 50 51 for (nfunc = 0; nfunc < maxfunc; nfunc++) { 52 a = pci_mkaddr(nbus, ndev, nfunc, 0); 53 did = pci_readl(a); 54 55 if (did == 0xffffffff || did == 0xffff0000 || 56 did == 0x0000ffff || did == 0x00000000) 57 continue; 58 59 hdrtype = pci_readb(a + 0x0e); 60 if (hdrtype & 0x80) 61 maxfunc = MAX_PCI_FUNC; /* Multifunction device */ 62 63 dump_pci_device(be, a, hdrtype); 64 } 65 } 66 } 67 68 printf("Scanning PCI bus... done. \n"); 69} 70