static struct pci_dev *
create_pci_dev(struct pci_access * pci, char * slot)
{
    struct pci_filter filter;
    pci_filter_init(pci, &filter);
    if (pci_filter_parse_slot(&filter, slot))
    {
        fprintf(stderr, "Failed to parse device id %s\n", slot);
        goto pci_filter_parse_failed;
    }

    pci_init(pci);

    struct pci_dev * dev = pci_get_dev(pci,
                                       filter.domain,
                                       filter.bus,
                                       filter.slot,
                                       filter.func);
    if (! dev)
    {
        fprintf(stderr, "Failed to allocate dev\n");
        goto pci_get_dev_failed;
    }

    pci_fill_info(dev, PCI_FILL_IDENT);

    return dev;

pci_get_dev_failed:
pci_filter_parse_failed:
    return NULL;
}
Exemple #2
0
int print_ambs(struct pci_dev *dev, struct pci_access *pacc)
{
	struct pci_dev *dev16;
	int branch, channel, amb;
	int max_branch, max_channel, max_amb;
	volatile void *ambconfig;
	uint64_t ambconfig_phys;

	printf("\n============= AMBs ============\n\n");

	switch (dev->device_id) {
	case PCI_DEVICE_ID_INTEL_I5000P:
	case PCI_DEVICE_ID_INTEL_I5000X:
	case PCI_DEVICE_ID_INTEL_I5000Z:

		max_branch = 2;

		if (!(dev16 = pci_get_dev(pacc, 0, 0, 0x10, 0))) {
			perror("Error: no device 0:16.0\n");
			return 1;
		}

		ambconfig_phys = ((uint64_t)pci_read_long(dev16, 0x4c) << 32) |
			pci_read_long(dev16, 0x48);

		max_channel = pci_read_byte(dev16, 0x56)/max_branch;
		max_amb = pci_read_byte(dev16, 0x57);
		pci_free_dev(dev16);
		break;

	default:
		fprintf(stderr, "Error: Dumping AMBs on this MCH is not (yet) supported.\n");
		return 1;
	}

	if (!(ambconfig = map_physical(ambconfig_phys, AMB_CONFIG_SPACE_SIZE))) {
		fprintf(stderr, "Error mapping AMB config space\n");
		return 1;
	}

	for(branch = 0; branch < max_branch; branch++) {
		for(channel = 0; channel < max_channel; channel++) {
			for(amb = 0; amb < max_amb; amb++) {
				dump_amb(ambconfig, branch, channel, amb);
			}
		}
	}
	unmap_physical((void *)ambconfig, AMB_CONFIG_SPACE_SIZE);
	return 0;
}
Exemple #3
0
int get_pch_sbreg_addr(struct pci_access *pci, pciaddr_t *sbreg_addr) {
  MSG("Checking for a Series 10 PCH system");

  struct pci_dev *d31f1 = pci_get_dev(pci, 0, 0, 31, 1);
  pci_fill_info(d31f1, PCI_FILL_IDENT);
  if(d31f1->vendor_id == 0xffff) {
    MSG("Cannot find D31:F1, assuming it is hidden by firmware");

    uint32_t p2sb_ctrl = pci_read_long(d31f1, REG_P2SB_CTRL);
    MSG("P2SB_CTRL=%02x", p2sb_ctrl);
    if(!(p2sb_ctrl & REG_P2SB_CTRL_HIDE)) {
      ERR("D31:F1 is hidden but P2SB_E1 is not 0xff, bailing out");
    }

    MSG("Unhiding P2SB");
    pci_write_long(d31f1, REG_P2SB_CTRL, p2sb_ctrl & ~REG_P2SB_CTRL_HIDE);

    p2sb_ctrl = pci_read_long(d31f1, REG_P2SB_CTRL);
    MSG("P2SB_CTRL=%02x", p2sb_ctrl);
    if(p2sb_ctrl & REG_P2SB_CTRL_HIDE) {
      ERR("Cannot unhide PS2B");
    }

    pci_fill_info(d31f1, PCI_FILL_RESCAN | PCI_FILL_IDENT);
    if(d31f1->vendor_id == 0xffff) {
      ERR("P2SB unhidden but does not enumerate, bailing out");
    }
  }

  pci_fill_info(d31f1, PCI_FILL_RESCAN | PCI_FILL_IDENT | PCI_FILL_BASES);
  if(d31f1->vendor_id != 0x8086) {
    ERR("Vendor of D31:F1 is not Intel");
  } else if((uint32_t)d31f1->base_addr[0] == 0xffffffff) {
    ERR("SBREG_BAR is not implemented in D31:F1");
  }

  *sbreg_addr = d31f1->base_addr[0] &~ 0xf;
  MSG("SBREG_ADDR=%08lx", *sbreg_addr);

  MSG("Hiding P2SB again");
  uint32_t p2sb_ctrl = pci_read_long(d31f1, REG_P2SB_CTRL);
  pci_write_long(d31f1, REG_P2SB_CTRL, p2sb_ctrl | REG_P2SB_CTRL_HIDE);

  pci_fill_info(d31f1, PCI_FILL_RESCAN | PCI_FILL_IDENT);
  if(d31f1->vendor_id != 0xffff) {
    ERR("Cannot hide P2SB");
  }

  return 0;
}
Exemple #4
0
static void
dump_init(struct pci_access *a)
{
  char *name = a->method_params[PCI_ACCESS_DUMP];
  FILE *f;
  char buf[256];
  struct pci_dev *dev = NULL;
  int len, bn, dn, fn, i, j;

  if (!a)
    a->error("dump: File name not given.");
  if (!(f = fopen(name, "r")))
    a->error("dump: Cannot open %s: %s", name, strerror(errno));
  while (fgets(buf, sizeof(buf)-1, f))
    {
      char *z = strchr(buf, '\n');
      if (!z)
	a->error("dump: line too long or unterminated");
      *z-- = 0;
      if (z >= buf && *z == '\r')
	*z-- = 0;
      len = z - buf + 1;
      if (len >= 8 && buf[2] == ':' && buf[5] == '.' && buf[7] == ' ' &&
	  sscanf(buf, "%x:%x.%d ", &bn, &dn, &fn) == 3)
	{
	  dev = pci_get_dev(a, bn, dn, fn);
	  dev->aux = pci_malloc(a, 256);
	  memset(dev->aux, 0xff, 256);
	  pci_link_dev(a, dev);
	}
      else if (!len)
	dev = NULL;
      else if (dev && len >= 51 && buf[2] == ':' && buf[3] == ' ' &&
	       sscanf(buf, "%x: ", &i) == 1)
	{
	  z = buf+3;
	  while (isspace(z[0]) && isxdigit(z[1]) && isxdigit(z[2]))
	    {
	      z++;
	      if (sscanf(z, "%x", &j) != 1 || i >= 256)
		a->error("dump: Malformed line");
	      ((byte *) dev->aux)[i++] = j;
	      z += 2;
	    }
	}
    }
}
Exemple #5
0
static int shell_pci_getdev(
	int argc,
	char *argv[],
	struct shell_pci_modifier *mod)
{
  unsigned long pciid;
  struct pci_dev *dev;

  if (argc != 3)
    return -1;

  pciid = get_pciid_from_string(argv[2]);
  if ((pciid & 0xffff0000) != 0)
    return -1;

  if (pci_get_dev(pciid, &dev)) {
    printf(" GETDEV: no device on [%lx:%lx:%lx]\n", PCI_DEV_EXPAND(pciid));
    return 0;
  }

  printf(" PCI RAM DEVICE: %p\n", dev);
  return 0;
}
Exemple #6
0
static void
dump_init(struct pci_access *a)
{
  char *name = a->method_params[PCI_ACCESS_DUMP];
  FILE *f;
  char buf[256];
  struct pci_dev *dev = NULL;
  int len, mn, bn, dn, fn, i, j;

  if (!a)
    a->error("dump: File name not given.");
  if (!(f = fopen(name, "r")))
    a->error("dump: Cannot open %s: %s", name, strerror(errno));
  while (fgets(buf, sizeof(buf)-1, f))
    {
      char *z = strchr(buf, '\n');
      if (!z)
	a->error("dump: line too long or unterminated");
      *z-- = 0;
      if (z >= buf && *z == '\r')
	*z-- = 0;
      len = z - buf + 1;
      mn = 0;
      if ((len >= 8 && buf[2] == ':' && buf[5] == '.' && buf[7] == ' ' &&
	   sscanf(buf, "%x:%x.%d ", &bn, &dn, &fn) == 3) ||
	  (len >= 13 && buf[4] == ':' && buf[7] == ':' && buf[10] == '.' && buf[12] == ' ' &&
	   sscanf(buf, "%x:%x:%x.%d", &mn, &bn, &dn, &fn) == 4))
	{
	  dev = pci_get_dev(a, mn, bn, dn, fn);
	  dump_alloc_data(dev, 256);
	  pci_link_dev(a, dev);
	}
      else if (!len)
	dev = NULL;
      else if (dev &&
	       (len >= 51 && buf[2] == ':' && buf[3] == ' ' || len >= 52 && buf[3] == ':' && buf[4] == ' ') &&
	       sscanf(buf, "%x: ", &i) == 1)
	{
	  struct dump_data *dd = dev->aux;
	  z = strchr(buf, ' ');
	  while (isspace(z[0]) && isxdigit(z[1]) && isxdigit(z[2]))
	    {
	      z++;
	      if (sscanf(z, "%x", &j) != 1 || i >= 256)
		a->error("dump: Malformed line");
	      if (i >= 4096)
		break;
	      if (i > dd->allocated)	/* Need to re-allocate the buffer */
		{
		  dump_alloc_data(dev, 4096);
		  memcpy(((struct dump_data *) dev->aux)->data, dd->data, 256);
		  pci_mfree(dd);
		  dd = dev->aux;
		}
	      dd->data[i++] = j;
	      if (i > dd->len)
		dd->len = i;
	      z += 2;
	    }
	}
    }
}
Exemple #7
0
int print_pmbase(struct pci_dev *sb, struct pci_access *pacc)
{
	int i, size;
	uint16_t pmbase;
	const io_register_t *pm_registers;
	struct pci_dev *acpi;

	printf("\n============= PMBASE ============\n\n");

	switch (sb->device_id) {
	case PCI_DEVICE_ID_INTEL_3400:
	case PCI_DEVICE_ID_INTEL_3420:
	case PCI_DEVICE_ID_INTEL_3450:
	case PCI_DEVICE_ID_INTEL_3400_DESKTOP:
	case PCI_DEVICE_ID_INTEL_3400_MOBILE:
	case PCI_DEVICE_ID_INTEL_3400_MOBILE_SFF:
	case PCI_DEVICE_ID_INTEL_B55_A:
	case PCI_DEVICE_ID_INTEL_B55_B:
	case PCI_DEVICE_ID_INTEL_H55:
	case PCI_DEVICE_ID_INTEL_H57:
	case PCI_DEVICE_ID_INTEL_HM55:
	case PCI_DEVICE_ID_INTEL_HM57:
	case PCI_DEVICE_ID_INTEL_P55:
	case PCI_DEVICE_ID_INTEL_PM55:
	case PCI_DEVICE_ID_INTEL_Q57:
	case PCI_DEVICE_ID_INTEL_QM57:
	case PCI_DEVICE_ID_INTEL_QS57:
	case PCI_DEVICE_ID_INTEL_Z68:
	case PCI_DEVICE_ID_INTEL_P67:
	case PCI_DEVICE_ID_INTEL_UM67:
	case PCI_DEVICE_ID_INTEL_HM65:
	case PCI_DEVICE_ID_INTEL_H67:
	case PCI_DEVICE_ID_INTEL_HM67:
	case PCI_DEVICE_ID_INTEL_Q65:
	case PCI_DEVICE_ID_INTEL_QS67:
	case PCI_DEVICE_ID_INTEL_Q67:
	case PCI_DEVICE_ID_INTEL_QM67:
	case PCI_DEVICE_ID_INTEL_B65:
	case PCI_DEVICE_ID_INTEL_C202:
	case PCI_DEVICE_ID_INTEL_C204:
	case PCI_DEVICE_ID_INTEL_C206:
	case PCI_DEVICE_ID_INTEL_H61:
	case PCI_DEVICE_ID_INTEL_Z77:
	case PCI_DEVICE_ID_INTEL_Z75:
	case PCI_DEVICE_ID_INTEL_Q77:
	case PCI_DEVICE_ID_INTEL_Q75:
	case PCI_DEVICE_ID_INTEL_B75:
	case PCI_DEVICE_ID_INTEL_H77:
	case PCI_DEVICE_ID_INTEL_C216:
	case PCI_DEVICE_ID_INTEL_QM77:
	case PCI_DEVICE_ID_INTEL_QS77:
	case PCI_DEVICE_ID_INTEL_HM77:
	case PCI_DEVICE_ID_INTEL_UM77:
	case PCI_DEVICE_ID_INTEL_HM76:
	case PCI_DEVICE_ID_INTEL_HM75:
	case PCI_DEVICE_ID_INTEL_HM70:
	case PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_FULL:
	case PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_PREM:
	case PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_BASE:
	case PCI_DEVICE_ID_INTEL_BAYTRAIL_LPC:
		pmbase = pci_read_word(sb, 0x40) & 0xff80;
		pm_registers = pch_pm_registers;
		size = ARRAY_SIZE(pch_pm_registers);
		break;
	case PCI_DEVICE_ID_INTEL_ICH10R:
		pmbase = pci_read_word(sb, 0x40) & 0xff80;
		pm_registers = ich10_pm_registers;
		size = ARRAY_SIZE(ich10_pm_registers);
		break;
	case PCI_DEVICE_ID_INTEL_ICH7:
	case PCI_DEVICE_ID_INTEL_ICH7M:
	case PCI_DEVICE_ID_INTEL_ICH7DH:
	case PCI_DEVICE_ID_INTEL_ICH7MDH:
	case PCI_DEVICE_ID_INTEL_NM10:
		pmbase = pci_read_word(sb, 0x40) & 0xfffc;
		pm_registers = ich7_pm_registers;
		size = ARRAY_SIZE(ich7_pm_registers);
		break;
	case PCI_DEVICE_ID_INTEL_ICH9DH:
	case PCI_DEVICE_ID_INTEL_ICH9DO:
	case PCI_DEVICE_ID_INTEL_ICH9R:
	case PCI_DEVICE_ID_INTEL_ICH9:
	case PCI_DEVICE_ID_INTEL_ICH9M:
	case PCI_DEVICE_ID_INTEL_ICH9ME:
		pmbase = pci_read_word(sb, 0x40) & 0xfffc;
		pm_registers = ich9_pm_registers;
		size = ARRAY_SIZE(ich9_pm_registers);
		break;
	case PCI_DEVICE_ID_INTEL_ICH8:
	case PCI_DEVICE_ID_INTEL_ICH8M:
	case PCI_DEVICE_ID_INTEL_ICH8ME:
		pmbase = pci_read_word(sb, 0x40) & 0xfffc;
		pm_registers = ich8_pm_registers;
		size = ARRAY_SIZE(ich8_pm_registers);
		break;
	case PCI_DEVICE_ID_INTEL_ICH6:
		pmbase = pci_read_word(sb, 0x40) & 0xfffc;
		pm_registers = ich6_pm_registers;
		size = ARRAY_SIZE(ich6_pm_registers);
		break;
	case PCI_DEVICE_ID_INTEL_ICH5:
		pmbase = pci_read_word(sb, 0x40) & 0xfffc;
		pm_registers = ich5_pm_registers;
		size = ARRAY_SIZE(ich5_pm_registers);
		break;
	case PCI_DEVICE_ID_INTEL_ICH4:
		pmbase = pci_read_word(sb, 0x40) & 0xfffc;
		pm_registers = ich4_pm_registers;
		size = ARRAY_SIZE(ich4_pm_registers);
		break;
	case PCI_DEVICE_ID_INTEL_ICH2:
		pmbase = pci_read_word(sb, 0x40) & 0xfffc;
		pm_registers = ich2_pm_registers;
		size = ARRAY_SIZE(ich2_pm_registers);
		break;
	case PCI_DEVICE_ID_INTEL_ICH0:
		pmbase = pci_read_word(sb, 0x40) & 0xfffc;
		pm_registers = ich0_pm_registers;
		size = ARRAY_SIZE(ich0_pm_registers);
		break;
	case PCI_DEVICE_ID_INTEL_82371XX:
		acpi = pci_get_dev(pacc, sb->domain, sb->bus, sb->dev, 3);
		if (!acpi) {
			printf("Southbridge function 3 not found.\n");
			return 1;
		}
		pmbase = pci_read_word(acpi, 0x40) & 0xfffc;
		pm_registers = i82371xx_pm_registers;
		size = ARRAY_SIZE(i82371xx_pm_registers);
		break;

	case PCI_DEVICE_ID_INTEL_I63XX:
		pmbase = pci_read_word(sb, 0x40) & 0xfffc;
		pm_registers = i63xx_pm_registers;
		size = ARRAY_SIZE(i63xx_pm_registers);
		break;

	case 0x1234: // Dummy for non-existent functionality
		printf("This southbridge does not have PMBASE.\n");
		return 1;
	default:
		printf("Error: Dumping PMBASE on this southbridge is not (yet) supported.\n");
		return 1;
	}

	printf("PMBASE = 0x%04x (IO)\n\n", pmbase);

	for (i = 0; i < size; i++) {
		switch (pm_registers[i].size) {
		case 8:
			printf("pmbase+0x%04x: 0x%08x (%s)\n"
			       "               0x%08x\n",
				pm_registers[i].addr,
				inl(pmbase+pm_registers[i].addr),
				pm_registers[i].name,
				inl(pmbase+pm_registers[i].addr+4));
			break;
		case 4:
			printf("pmbase+0x%04x: 0x%08x (%s)\n",
				pm_registers[i].addr,
				inl(pmbase+pm_registers[i].addr),
				pm_registers[i].name);
			break;
		case 2:
			printf("pmbase+0x%04x: 0x%04x     (%s)\n",
				pm_registers[i].addr,
				inw(pmbase+pm_registers[i].addr),
				pm_registers[i].name);
			break;
		case 1:
			printf("pmbase+0x%04x: 0x%02x       (%s)\n",
				pm_registers[i].addr,
				inb(pmbase+pm_registers[i].addr),
				pm_registers[i].name);
			break;
		}
	}

	return 0;
}
Exemple #8
0
sbone_err_t sbone_dev_open_pcie
(sbone_dev_t* dev, int dom, int bus, int _dev, int fun)
{
  static const size_t nbar = sizeof(dev->bar_addrs) / sizeof(dev->bar_addrs[0]);
  int mem_fd;
  size_t i;
  struct pci_access* pci_access;
  struct pci_dev* pci_dev;
  int err = -1;

  /* zero device */

  for (i = 0; i < nbar; ++i) dev->bar_sizes[i] = 0;

  dev->nid = -1;

  /* find the pci device */

  pci_access = pci_alloc();
  if (pci_access == NULL) { PERROR(); goto on_error_0; }
  pci_init(pci_access);
  pci_scan_bus(pci_access);

  pci_dev = pci_get_dev(pci_access, dom, bus, _dev, fun);
  if (pci_dev == NULL) { PERROR(); goto on_error_1; }
  pci_fill_info(pci_dev, PCI_FILL_IDENT | PCI_FILL_BASES);

  /* map bars */

  mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
  if (mem_fd == -1) { PERROR(); goto on_error_2; }

  for (i = 0; i < nbar; ++i)
  {
#if 1 /* FIXME: pci_dev->size[i] not detected by pci_fill_info ... */
    if (pci_dev->base_addr[i] != 0)
      pci_dev->size[i] = get_bar_size(pci_access, pci_dev, i);
#endif /* FIXME */

    dev->bar_sizes[i] = pci_dev->size[i];
    if (dev->bar_sizes[i] == 0) continue ;

    dev->bar_addrs[i] = (uintptr_t)mmap
    (
     NULL, pci_dev->size[i],
     PROT_READ | PROT_WRITE,
     MAP_SHARED | MAP_NORESERVE,
     mem_fd,
     pci_dev->base_addr[i]
    );

    if (dev->bar_addrs[i] == (uintptr_t)MAP_FAILED)
    {
      size_t j;
      for (j = 0; j < i; ++j)
	munmap((void*)dev->bar_addrs[i], dev->bar_sizes[i]);
      PERROR();
      goto on_error_3;
    }
  }

  if ((dev->fd = open("/dev/sbone", O_RDWR)) == -1)
  {
    PERROR();
    goto on_error_3;
  }

  /* success */

  err = 0;

 on_error_3:
  close(mem_fd);
 on_error_2:
  pci_free_dev(pci_dev);
 on_error_1:
  pci_cleanup(pci_access);
 on_error_0:
  return err;

}
Exemple #9
0
static void
dump_init(struct pci_access *a)
{
  char *name = pci_get_param(a, "dump.name");
  FILE *f;
  char buf[256];
  struct pci_dev *dev = NULL;
  int len, mn, bn, dn, fn, i, j;

  if (!name)
    a->error("dump: File name not given.");
  if (!(f = fopen(name, "r")))
    a->error("dump: Cannot open %s: %s", name, strerror(errno));
  while (fgets(buf, sizeof(buf)-1, f))
    {
      char *z = strchr(buf, '\n');
      if (!z)
	{
	  fclose(f);
	  a->error("dump: line too long or unterminated");
	}
      *z-- = 0;
      if (z >= buf && *z == '\r')
	*z-- = 0;
      len = z - buf + 1;
      mn = 0;
      if ((dump_validate(buf, "##:##.# ") && sscanf(buf, "%x:%x.%d", &bn, &dn, &fn) == 3) ||
	  (dump_validate(buf, "####:##:##.# ") && sscanf(buf, "%x:%x:%x.%d", &mn, &bn, &dn, &fn) == 4))
	{
	  dev = pci_get_dev(a, mn, bn, dn, fn);
	  dump_alloc_data(dev, 256);
	  pci_link_dev(a, dev);
	}
      else if (!len)
	dev = NULL;
      else if (dev &&
	       (dump_validate(buf, "##: ") || dump_validate(buf, "###: ")) &&
	       sscanf(buf, "%x: ", &i) == 1)
	{
	  struct dump_data *dd = dev->aux;
	  z = strchr(buf, ' ') + 1;
	  while (isxdigit(z[0]) && isxdigit(z[1]) && (!z[2] || z[2] == ' ') &&
		 sscanf(z, "%x", &j) == 1 && j < 256)
	    {
	      if (i >= 4096)
		{
		  fclose(f);
		  a->error("dump: At most 4096 bytes of config space are supported");
		}
	      if (i >= dd->allocated)	/* Need to re-allocate the buffer */
		{
		  dump_alloc_data(dev, 4096);
		  memcpy(((struct dump_data *) dev->aux)->data, dd->data, 256);
		  pci_mfree(dd);
		  dd = dev->aux;
		}
	      dd->data[i++] = j;
	      if (i > dd->len)
		dd->len = i;
	      z += 2;
	      if (*z)
		z++;
	    }
	  if (*z)
	    {
	      fclose(f);
	      a->error("dump: Malformed line");
	    }
	}
    }
  fclose(f);
}