示例#1
0
static int
pci_cfg_modify (pci_dev_t bdf, ulong addr, ulong size, ulong value, int incrflag)
{
	ulong	i;
	int	nbytes;
	uint	val4;
	ushort  val2;
	u_char	val1;

	/* Print the address, followed by value.  Then accept input for
	 * the next value.  A non-converted value exits.
	 */
	do {
		printf("%08lx:", addr);
		if (size == 4) {
			pci_read_config_dword(bdf, addr, &val4);
			printf(" %08x", val4);
		}
		else if (size == 2) {
			pci_read_config_word(bdf, addr, &val2);
			printf(" %04x", val2);
		}
		else {
			pci_read_config_byte(bdf, addr, &val1);
			printf(" %02x", val1);
		}

		nbytes = cli_readline(" ? ");
		if (nbytes == 0 || (nbytes == 1 && console_buffer[0] == '-')) {
			/* <CR> pressed as only input, don't modify current
			 * location and move to next. "-" pressed will go back.
			 */
			if (incrflag)
				addr += nbytes ? -size : size;
			nbytes = 1;
			/* good enough to not time out */
			bootretry_reset_cmd_timeout();
		}
#ifdef CONFIG_BOOT_RETRY_TIME
		else if (nbytes == -2) {
			break;	/* timed out, exit the command	*/
		}
#endif
		else {
			char *endp;
			i = simple_strtoul(console_buffer, &endp, 16);
			nbytes = endp - console_buffer;
			if (nbytes) {
				/* good enough to not time out
				 */
				bootretry_reset_cmd_timeout();
				pci_cfg_write (bdf, addr, size, i);
				if (incrflag)
					addr += size;
			}
		}
	} while (nbytes);

	return 0;
}
示例#2
0
文件: pci.c 项目: OpenNoah/u-boot
static int pci_cfg_modify(pci_dev_t bdf, ulong addr, ulong size, ulong value,
			  int incrflag)
#endif
{
	ulong	i;
	int	nbytes;
	ulong val;

	/* Print the address, followed by value.  Then accept input for
	 * the next value.  A non-converted value exits.
	 */
	do {
		printf("%08lx:", addr);
#ifdef CONFIG_DM_PCI
		dm_pci_read_config(dev, addr, &val, size);
#else
		val = pci_read_config(bdf, addr, size);
#endif
		printf(" %0*lx", pci_field_width(size), val);

		nbytes = cli_readline(" ? ");
		if (nbytes == 0 || (nbytes == 1 && console_buffer[0] == '-')) {
			/* <CR> pressed as only input, don't modify current
			 * location and move to next. "-" pressed will go back.
			 */
			if (incrflag)
				addr += nbytes ? -size : size;
			nbytes = 1;
			/* good enough to not time out */
			bootretry_reset_cmd_timeout();
		}
#ifdef CONFIG_BOOT_RETRY_TIME
		else if (nbytes == -2) {
			break;	/* timed out, exit the command	*/
		}
#endif
		else {
			char *endp;
			i = simple_strtoul(console_buffer, &endp, 16);
			nbytes = endp - console_buffer;
			if (nbytes) {
				/* good enough to not time out
				 */
				bootretry_reset_cmd_timeout();
#ifdef CONFIG_DM_PCI
				dm_pci_write_config(dev, addr, i, size);
#else
				pci_cfg_write(bdf, addr, size, i);
#endif
				if (incrflag)
					addr += size;
			}
		}
	} while (nbytes);

	return 0;
}
示例#3
0
/* PCI Configuration Space access commands
 *
 * Syntax:
 *	pci display[.b, .w, .l] bus.device.function} [addr] [len]
 *	pci next[.b, .w, .l] bus.device.function [addr]
 *      pci modify[.b, .w, .l] bus.device.function [addr]
 *      pci write[.b, .w, .l] bus.device.function addr value
 */
static int do_pci(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	ulong addr = 0, value = 0, size = 0;
	pci_dev_t bdf = 0;
	char cmd = 's';

	if (argc > 1)
		cmd = argv[1][0];

	switch (cmd) {
	case 'd':		/* display */
	case 'n':		/* next */
	case 'm':		/* modify */
	case 'w':		/* write */
		/* Check for a size specification. */
		size = cmd_get_data_size(argv[1], 4);
		if (argc > 3)
			addr = simple_strtoul(argv[3], NULL, 16);
		if (argc > 4)
			value = simple_strtoul(argv[4], NULL, 16);
	case 'h':		/* header */
		if (argc < 3)
			goto usage;
		if ((bdf = get_pci_dev(argv[2])) == -1)
			return 1;
		break;
#ifdef CONFIG_CMD_PCI_ENUM
	case 'e':
		break;
#endif
	default:		/* scan bus */
		value = 1; /* short listing */
		bdf = 0;   /* bus number  */
		if (argc > 1) {
			if (argv[argc-1][0] == 'l') {
				value = 0;
				argc--;
			}
			if (argc > 1)
				bdf = simple_strtoul(argv[1], NULL, 16);
		}
		pciinfo(bdf, value);
		return 0;
	}

	switch (argv[1][0]) {
	case 'h':		/* header */
		pci_header_show(bdf);
		return 0;
	case 'd':		/* display */
		return pci_cfg_display(bdf, addr, size, value);
#ifdef CONFIG_CMD_PCI_ENUM
	case 'e':
		pci_init();
		return 0;
#endif
	case 'n':		/* next */
		if (argc < 4)
			goto usage;
		return pci_cfg_modify(bdf, addr, size, value, 0);
	case 'm':		/* modify */
		if (argc < 4)
			goto usage;
		return pci_cfg_modify(bdf, addr, size, value, 1);
	case 'w':		/* write */
		if (argc < 5)
			goto usage;
		return pci_cfg_write(bdf, addr, size, value);
	}

	return 1;
 usage:
	return CMD_RET_USAGE;
}
示例#4
0
void pci_cfg_e1k(net_info_t *net)
{
   pci_cfg_dev_vdr_t dvd;
   e1k_info_t        *e1k = &net->arch;
   pci_cfg_val_t     *pci = &net->pci;

   /* search dev */
   dvd.vendor = PCI_CFG_VENDOR_INTEL;
   dvd.device = PCI_CFG_DEVICE_i82545EM_C;
   if(!pci_search(pci_check_dvd, dvd.raw, 1, pci))
   {
      dvd.device = PCI_CFG_DEVICE_i82540EM;
      if(!pci_search(pci_check_dvd, dvd.raw, 1, pci))
	 goto __not_found;
   }

   pci->addr.reg = PCI_CFG_CLASS_REV_OFFSET;
   pci_cfg_read(pci);
   if(pci->cr.class != PCI_CFG_CLASS_i8254x)
      goto __not_found;

   pci->addr.reg = PCI_CFG_CMD_STS_OFFSET;
   pci_cfg_read(pci);

   /* dma enable */
   if(!pci->cs.cmd.mm || !pci->cs.cmd.bus_master)
   {
      pci->cs.cmd.mm = 1;
      pci->cs.cmd.bus_master = 1;
      pci_cfg_write(pci);
   }

   pci_cfg_read(pci);
   debug(PCI_E1000, "e1k CMD/STS 0x%x 0x%x | CMD io %d mm %d dma %d\n"
	 ,pci->cs.cmd.raw, pci->cs.sts.raw
	 ,pci->cs.cmd.io, pci->cs.cmd.mm, pci->cs.cmd.bus_master);

   /* BAR regs */
   if(!pci_read_bar(pci, 0) && pci->br.io)
      panic("could not read i8254x registers (bar0 0x%x)", pci->br.raw);

   e1k->base.linear = pci->br.raw & 0xfffffff0;

   if(pci->br.type == PCI_CFG_MEM_BAR_64)
   {
      raw64_t addr = { .low = 0 };

      pci_read_bar(pci, 1);
      addr.high = pci->data.raw;
      e1k->base.linear += addr.raw;
   }

   debug(PCI_E1000, "e1k BAR 0x%X\n", e1k->base.linear);

   setptr(e1k->ctl,    e1k->base.linear + 0);
   setptr(e1k->sts,    e1k->base.linear + 8);
   setptr(e1k->eerd,   e1k->base.linear + 0x14);
   setptr(e1k->fcal,   e1k->base.linear + 0x28);
   setptr(e1k->fcah,   e1k->base.linear + 0x2c);
   setptr(e1k->fct,    e1k->base.linear + 0x30);
   setptr(e1k->fcttv,  e1k->base.linear + 0x170);

   setptr(e1k->icr,    e1k->base.linear + 0xc0);
   setptr(e1k->ics,    e1k->base.linear + 0xc8);
   setptr(e1k->ims,    e1k->base.linear + 0xd0);
   setptr(e1k->imc,    e1k->base.linear + 0xd8);

   setptr(e1k->rx.ctl, e1k->base.linear + 0x100);
   setptr(e1k->rx.bal, e1k->base.linear + 0x2800);
   setptr(e1k->rx.bah, e1k->base.linear + 0x2804);
   setptr(e1k->rx.dl,  e1k->base.linear + 0x2808);
   setptr(e1k->rx.dh,  e1k->base.linear + 0x2810);
   setptr(e1k->rx.dt,  e1k->base.linear + 0x2818);

   setptr(e1k->tx.ctl, e1k->base.linear + 0x400);
   setptr(e1k->tx.ipg, e1k->base.linear + 0x410);
   setptr(e1k->tx.bal, e1k->base.linear + 0x3800);
   setptr(e1k->tx.bah, e1k->base.linear + 0x3804);
   setptr(e1k->tx.dl,  e1k->base.linear + 0x3808);
   setptr(e1k->tx.dh,  e1k->base.linear + 0x3810);
   setptr(e1k->tx.dt,  e1k->base.linear + 0x3818);

   setptr(e1k->mta,    e1k->base.linear + 0x5200);
   setptr(e1k->ra,     e1k->base.linear + 0x5400);

   /* Interrupt line */
   pci->addr.reg = PCI_CFG_INT_OFFSET;
   pci_cfg_read(pci);

   net->irq = pci->data.blow;

   debug(PCI_E1000, "e1k irq line %d\n", net->irq);

   return;

__not_found:
   panic("no i8254x ethernet controller found");
}
示例#5
0
文件: pci.c 项目: OpenNoah/u-boot
/* PCI Configuration Space access commands
 *
 * Syntax:
 *	pci display[.b, .w, .l] bus.device.function} [addr] [len]
 *	pci next[.b, .w, .l] bus.device.function [addr]
 *      pci modify[.b, .w, .l] bus.device.function [addr]
 *      pci write[.b, .w, .l] bus.device.function addr value
 */
static int do_pci(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	ulong addr = 0, value = 0, cmd_size = 0;
	enum pci_size_t size = PCI_SIZE_32;
#ifdef CONFIG_DM_PCI
	struct udevice *dev, *bus;
#else
	pci_dev_t dev;
#endif
	int busnum = 0;
	pci_dev_t bdf = 0;
	char cmd = 's';
	int ret = 0;

	if (argc > 1)
		cmd = argv[1][0];

	switch (cmd) {
	case 'd':		/* display */
	case 'n':		/* next */
	case 'm':		/* modify */
	case 'w':		/* write */
		/* Check for a size specification. */
		cmd_size = cmd_get_data_size(argv[1], 4);
		size = (cmd_size == 4) ? PCI_SIZE_32 : cmd_size - 1;
		if (argc > 3)
			addr = simple_strtoul(argv[3], NULL, 16);
		if (argc > 4)
			value = simple_strtoul(argv[4], NULL, 16);
	case 'h':		/* header */
#ifdef CONFIG_DM_PCI
	case 'b':		/* bars */
#endif
		if (argc < 3)
			goto usage;
		if ((bdf = get_pci_dev(argv[2])) == -1)
			return 1;
		break;
#if defined(CONFIG_DM_PCI)
	case 'e':
		pci_init();
		return 0;
#endif
	case 'r': /* no break */
	default:		/* scan bus */
		value = 1; /* short listing */
		if (argc > 1) {
			if (cmd != 'r' && argv[argc-1][0] == 'l') {
				value = 0;
				argc--;
			}
			if (argc > 1)
				busnum = simple_strtoul(argv[1], NULL, 16);
		}
#ifdef CONFIG_DM_PCI
		ret = uclass_get_device_by_seq(UCLASS_PCI, busnum, &bus);
		if (ret) {
			printf("No such bus\n");
			return CMD_RET_FAILURE;
		}
		if (cmd == 'r')
			pci_show_regions(bus);
		else
			pciinfo(bus, value);
#else
		pciinfo(busnum, value);
#endif
		return 0;
	}

#ifdef CONFIG_DM_PCI
	ret = dm_pci_bus_find_bdf(bdf, &dev);
	if (ret) {
		printf("No such device\n");
		return CMD_RET_FAILURE;
	}
#else
	dev = bdf;
#endif

	switch (argv[1][0]) {
	case 'h':		/* header */
		pci_header_show(dev);
		break;
	case 'd':		/* display */
		return pci_cfg_display(dev, addr, size, value);
	case 'n':		/* next */
		if (argc < 4)
			goto usage;
		ret = pci_cfg_modify(dev, addr, size, value, 0);
		break;
	case 'm':		/* modify */
		if (argc < 4)
			goto usage;
		ret = pci_cfg_modify(dev, addr, size, value, 1);
		break;
	case 'w':		/* write */
		if (argc < 5)
			goto usage;
#ifdef CONFIG_DM_PCI
		ret = dm_pci_write_config(dev, addr, value, size);
#else
		ret = pci_cfg_write(dev, addr, size, value);
#endif
		break;
#ifdef CONFIG_DM_PCI

	case 'b':		/* bars */
		return pci_bar_show(dev);
#endif
	default:
		ret = CMD_RET_USAGE;
		break;
	}

	return ret;
 usage:
	return CMD_RET_USAGE;
}