⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pci.c

📁 umon bootloader source code, support mips cpu.
💻 C
📖 第 1 页 / 共 2 页
字号:
		printf("BAR%d  : 0x%08lx", barnum,bar);
	}

	printf(" Size: 0x");
	if (!(implemented & BASEADDRESS_IO) && (implemented & TYPE_64)) { 
		printf("%08lx%08lx ",sizehi,sizelo);
		rtot = 2;
	}
	else {
		printf("%08lx ",sizelo);
		rtot = 1;
	}

	if (bar & BASEADDRESS_IO)  {
		printf("IO");
	}
	else {
		printf("MEM %sbit",bar & TYPE_64 ? "64" : "32");
	}

	if (bar & PREFETCHABLE)
		printf(" prefetchable");

	putchar('\n');
	return(rtot);
}

void
dumpRawCfg(long interface,long bus,long device,long func,char *range,
	char* varname)
{
	int gotone;
	long regno;
	ulong value;

	value = 0;
	gotone = 0;
	for(regno=0;regno<64;regno++) {
		if (inRange(range,regno)) {
			value = pciCfgRead(interface,bus,device,func,regno);
			printf("Cfg reg #%02ld: 0x%08lx\n",regno,value);
			gotone = 1;
		}
	}
	if ((varname) && (gotone))
		shell_sprintf(varname,"0x%08lx",value);
}

void
dumpConfig(long interface,long bus,long device,long func)
{
	int	i;
	char *multifunc, *type;
	ulong hdrtype, values[16];

	for(i=0;i<16;i++)
		values[i] = pciCfgRead(interface,bus,device,func,i);

	hdrtype = values[3] & HDR_MASK;

	if (hdrtype & HDR_MULTIFUNC) {
		multifunc = "multi-function ";
		hdrtype &= ~HDR_MULTIFUNC;
	}
	else {
		multifunc = "";
	}

	switch(hdrtype) {
		case HDR_PCI2PCI:
			type = "PCI-to-PCI";
			break;
		case HDR_CARDBUS:
			type = "CardBus";
			break;
		case HDR_STANDARD:
			type = "Standard";
			break;
		default:
			printf("dumpConfig(): hdrtype 0x%08lx not supported\n",hdrtype);
			return;
	}
	printf("%s %sconfig...\n",type,multifunc);

	printf("DevId/VendorId:   0x%04lx/%04lx\n",
		(values[0] & 0xffff0000) >> 16,values[0] & 0xffff);

	printf("Status/Command:   0x%04lx/%04lx\n",
		(values[1] & 0xffff0000) >> 16,values[1] & 0xffff);

	printf("ClassCode/RevId:  0x%06lx/%02lx\n",
		(values[2] & 0xffffff00) >> 8,values[2] & 0xff);


	printf("BIST/HdrType/LatencyTmr/CacheLnSz: 0x%02lx/%02lx/%02lx/%02lx\n",
		(values[3] & 0xff000000) >> 24, (values[3] & 0xff0000) >> 16,
		(values[3] & 0xff00) >> 8,values[3] & 0xff);

	if (showBar(0,interface,bus,device,func) == 1)
		showBar(1,interface,bus,device,func);

	if (hdrtype == HDR_STANDARD) {
		if (showBar(2,interface,bus,device,func) == 1)
			showBar(3,interface,bus,device,func);
		if (showBar(4,interface,bus,device,func) == 1)
			showBar(5,interface,bus,device,func);

		printf("Cardbus CIS Ptr:        0x%08lx\n",values[10]);
		printf("SubSysId/SubVendorId:   0x%04lx/%04lx\n",
			(values[11] & 0xffff0000) >> 16,values[11] & 0xffff);
		printf("Expansion ROM BaseAddr: 0x%08lx\n",values[12]);
	}
	else if (hdrtype == HDR_PCI2PCI) {
		printf("Secondary Latency Tmr:  0x%02lx\n",
			(values[6] & 0xff000000) >> 24);
		printf("BusNum Subordinate/Secondary/Primary: 0x%02lx/%02lx/%02lx\n",
			(values[6] & 0xff0000) >> 16,
			(values[6] & 0xff00) >> 8,values[6] & 0xff);

		printf("Secondary Status: 0x%04lx\n",
			(values[7] & 0xffff0000) >> 16);
		printf("IO Limit/Base:    0x%02lx/%02lx\n",
			(values[7] & 0xff00) >> 8,(values[7] & 0xff));

		printf("Memory Limit/Base:                0x%04lx/%04lx\n",
			(values[8] & 0xffff0000) >> 16,values[8] & 0xffff);

		printf("Prefetchable Memory Limit/Base:   0x%04lx/%04lx\n",
			(values[9] & 0xffff0000) >> 16,values[9] & 0xffff);

		printf("Prefetchable Base Upper 32 bits:  0x%08lx\n",values[10]);
		printf("Prefetchable Limit Upper 32 bits: 0x%08lx\n",values[11]);
		
		printf("IO Upper 16 Bits Limit/Base:      0x%04lx/%04lx\n",
			(values[12] & 0xffff0000) >> 16,values[12] & 0xffff);
	}

	printf("Capabilities Ptr:       0x%02lx\n",values[13] & 0xff);

	if (hdrtype == HDR_STANDARD) {
		printf("MaxLat/MinGnt:          0x%02lx/%02lx\n",
			(values[15] & 0xff000000) >> 24, (values[15] & 0xff0000) >> 16);
	}
	else {
		printf("Expansion ROM BaseAddr: 0x%08lx\n",
			values[14]);
		printf("BridgeControl:          0x%04lx\n",
			(values[15] & 0xffff0000) >> 16);
	}

	printf("Interrupt Pin/Line:     0x%02lx/%02lx\n",
		(values[15] & 0xff00) >> 8, values[15] & 0xff);
}

char *PciHelp[] = {
	"PCI Config Interface",
	"-[b:d:f:i:v] {operation} [args]",
#if INCLUDE_VERBOSEHELP
	"Options:",
	" -b{###}   bus #", 
	" -d{###}   device #",
	" -f{###}   function #",
	" -i{###}   interface #",
	" -v        verbose",
	"Operations:",
	" scan, enum, bist, show, size {bar#}",
	" crd [reg#] [varname], cwr {reg#} {value}",
    "Note:",
	" bus, device, function & interface default to zero",
#endif
	0
};

/* PciCmd():
 * General purpose command to provide access to the config portion of
 * a PCI interface.  
 *
 * Notice that there is reference to an "interface number" as well as a
 * "bus number".  In most systems, there will be one host-to-pci interface.
 * and one pci bus.   Some targets will have more than one host-to-pci
 * interface (galileo 64260A, for example, has 2 distinct host-to-PCI
 * interface).  Some targets will have more than one bus (depends on whether
 * or not there is a pci-to-pci bridge hanging off the bus).
 * 
 */
int
PciCmd(int argc, char *argv[])
{
	ulong	value, bar;
	long	bus, device, interface, regno, func;
	int		enumerate, opt;

	bus = 0;
	func = 0;
	device = 0;
	enumerate = 0;
	interface = 0;
	pciVerbose = 0;
	while ((opt=getopt(argc,argv,"b:d:f:i:v")) != -1) {
		switch(opt) {
		case 'b':
			bus = atoi(optarg);
			break;
		case 'd':
			device = atoi(optarg);
			break;
		case 'f':
			func = atoi(optarg);
			break;
		case 'i':	/* Most systems will only have 1 interface */
			 interface = atoi(optarg);
			break;
		case 'v':
			 pciVerbose = 1;
			break;
		default:
			return(CMD_FAILURE);
		}
	}

	if (argc < optind+1)
		return(CMD_PARAM_ERROR);

	/* The "scan" and "enum" commands are very similar.  They both use
	 * the pciscan() function.
	 *
	 * Scan: look at the devices on the specified bus.
	 * Enum: a recursive scan... start with bus 0 and attempt to query
	 * all devices on all busses, making the necessary bus-number assignments
	 * along the way.
	 */

	/* For scan, the device number is ignored, all devices on a particular
	 * interface/bus are checked.  If ths bus number is something other than
	 * zero, then this function assumes that the appropriate pci-to-pci
	 * bridge device has already had its bus numbers assigned.
	 */
	if (!strcmp(argv[optind],"scan")) {
		if (argc != optind+1)
			return(CMD_PARAM_ERROR);

		pciscan(interface,bus,func,1,0);
		return(CMD_SUCCESS);
	}

	/* For enum, we start with bus 0, and attempt to enumerate all busses...
	 */
	if (!strcmp(argv[optind],"enum")) {
		if (argc != optind+1)
			return(CMD_PARAM_ERROR);

		pciscan(interface,0,func,1,1);
		return(CMD_SUCCESS);
	}

	if (!strcmp(argv[optind],"size")) { /* See pg 204 of PCI2.2 spec */
		int barnum;
		ulong implemented, sizehi, sizelo;

		if (argc != optind+2) 
			return(CMD_PARAM_ERROR);

		/* The argument to size is the BAR #.  The value can be a single
		 * digit or a range specification...
		 */
		printf(" Bar  Type Value      Size\n");
		for(barnum=0;barnum<6;barnum++) {
			if (inRange(argv[optind+1],barnum)) {
				/* Disable decoding through the command register:
				 * See section 6.2.2, pg 193.
				 */
				value = pciCfgRead(interface,bus,device,func,1);
				pciCfgWrite(interface,bus,device,0,1,
					value & ~(IO_SPACE | MEMORY_SPACE));

				bar = pciCfgRead(interface,bus,device,func,barnum+4);
				implemented = getBarInfo(interface,bus,device,func,
					barnum,&sizehi,&sizelo);
		
				printf(" %d    ",barnum);

				if (implemented) {
					printf("%s  0x%08lx ",
						implemented & BASEADDRESS_IO ? "io " : "mem", bar);
					if (implemented & TYPE_64) 
						printf("0x%08lx%08lx",sizehi,sizelo);
					else
						printf("0x%08lx",sizelo);
					if (implemented & PREFETCHABLE) 
						printf(" (prefetchable)");
					putchar('\n');
				}
				else
					printf("not implemented\n");
			}
		}
	}
	else if (!strcmp(argv[optind],"bist")) {
		if (argc != optind+1)
			return(CMD_PARAM_ERROR);

		value = pciCfgRead(interface,bus,device,func,3);

		if (value & BIST_CAPABLE) {
			/* Set the BIST_START bit to begin the test, then wait for
			 * the BIST_START bit to clear as an indication that the
			 * test has completed.
			 */
			pciCfgWrite(interface,bus,device,func,3,value | BIST_START);
			while(1) {
				value = pciCfgRead(interface,bus,device,func,3);
				if ((value & BIST_START) != BIST_START)
					break;
			}
			if ((value & BIST_COMPCODE_MASK) != 0)
				printf("BIST failed: 0x%lx\n",value & BIST_COMPCODE_MASK);
			else
				printf("BIST passed\n");
		}
		else {
			printf("Device %ld is not BIST-capable\n",device);
		}
	}
	else if (!strcmp(argv[optind],"crd")) {
		char *varname = (char *)0;

		if (argc == optind+3) {		/* varname specified ? */
			varname = argv[optind+2];
			argc--;
		}

		if (argc == optind+2) {
			dumpRawCfg(interface,bus,device,func,argv[optind+1],varname);
		}
		else if (argc == optind+1) {
			dumpConfig(interface,bus,device,func);
		}
		else
			return(CMD_PARAM_ERROR);
	}
	else if (!strcmp(argv[optind],"cwr")) {
		if (argc != optind+3)
			return(CMD_PARAM_ERROR);

		regno = atoi(argv[optind+1]);
		value = strtol(argv[optind+2],0,0);
		pciCfgWrite(interface,bus,device,func,regno,value);
	}
	else if (!strcmp(argv[optind],"init")) {
		pciCtrl(interface,PCICTRL_INIT,0,0);
	}
	else if (!strcmp(argv[optind],"show")) {
		pciShow(interface);
	}
	else
		return(CMD_PARAM_ERROR);
	return(CMD_SUCCESS);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -