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

📄 pcicmds.c

📁 MIPS处理器的bootloader,龙芯就是用的修改过的PMON2
💻 C
📖 第 1 页 / 共 2 页
字号:
	char *tp, *p;	int c;extern int optind;extern char *optarg;	optind = 0;	while ((c = getopt (ac, av, "b:d:")) != EOF) {		switch (c) {		case 'b':			if(!get_rsa(&busno, optarg)) {				return(-1);			}			if(busno < 0 || busno > 255) {				return(-1);			}			break;		case 'd':			if(!get_rsa(&devno, optarg)) {				return(-1);			}			if(devno < 0 || devno > 30) {				return(-1);			}			break;		default:			return (-1);		}	}	if (optind >= ac) { /* No ethernet address given, display */		do {			csrbase = probe_dev(busno, devno & 255);			if(csrbase != 0) {				if(devno > 255) {					if(busno != 0) {						printf("bus %d ", busno);					}					printf("device %2d ", devno & 255);				}				read_eeprom(csrbase, (u_int16_t *)&ee_init_data, 0, 14);				printf("ethernet address = %02x", ee_init_data[0]);				for(i = 1; i < 6; i++) {					printf(":%02x", ee_init_data[i]);				}				printf("\n");			}			else if(devno < 256) {				printf("No fxp on bus %d slot %d\n", busno, devno);			}			if(++devno > 256+30) {				devno = 0;			}		} while(devno > 256);		return(0);	}	/*	 * Arguments given, validate that the given dev is a fxp.	 * Then try to decode an ethernet address from input data.	 */	if(devno < 0 || devno > 31) {		return(-1);	}	csrbase = probe_dev(busno, devno);	if(csrbase == 0) {		printf("No fxp on bus %d slot %d\n", busno, devno);		return(0);	}	bcopy((const char *)ee_init_proto, ee_init_data, sizeof(ee_init_proto));	p = av[optind];	for (i = 0 ; p; i++) {		tp = p;		while(*p && *p != ':') {			p++;		}		if(*p) {			*p++ = 0;		}		else {			p = 0;		}					if(!get_rsa(&rv, tp)) {			return(-1);		}		ee_init_data[i] = rv;	}	if(i != 6) {		printf("badly formed ethernet address!\n");		return(0);	}	write_eeprom(csrbase, (u_int16_t *)&ee_init_data, 0, 14);	return(0);}static intprobe_dev(busno, devno)	int busno;	int devno;{	pcitag_t tag;	pcireg_t preg;	bus_addr_t iobase;	bus_size_t iosize;	bus_addr_t vaddr;	tag = _pci_make_tag(busno, devno, 0);	preg = _pci_conf_read(tag, PCI_ID_REG);	switch (PCI_PRODUCT(preg)) {	case PCI_PRODUCT_INTEL_82557:	case PCI_PRODUCT_INTEL_82559:	case PCI_PRODUCT_INTEL_82559ER:		if (pci_io_find(NULL, tag, FXP_PCI_IOBA, &iobase, &iosize)) { 			printf(": can't find i/o space\n");			return(-1);		}		if (bus_space_map(&bus_iot, iobase, iosize, 0, &vaddr)) {			printf(": can't map i/o space\n");			return(-1);		}		return((int)vaddr);	}	return (0);}/* * Read from the serial EEPROM. Basically, you manually shift in * the read opcode (one bit at a time) and then shift in the address, * and then you shift out the data (all of this one bit at a time). * The word size is 16 bits, so you have to provide the address for * every 16 bits of data. */static voidread_eeprom(csrbase, data, offset, words)	int csrbase;	u_int16_t *data;	int offset;	int words;{	u_int16_t reg;	int i, x;	for (i = 0; i < words; i++) {		CSR_W_2(&bus_iot, csrbase, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);		/*		 * Shift in read opcode.		 */		for (x = 3; x > 0; x--) {			if (FXP_EEPROM_OPC_READ & (1 << (x - 1))) {				reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI;			} else {				reg = FXP_EEPROM_EECS;			}			CSR_W_2(&bus_iot, csrbase, FXP_CSR_EEPROMCONTROL, reg);			CSR_W_2(&bus_iot, csrbase, FXP_CSR_EEPROMCONTROL,			    reg | FXP_EEPROM_EESK);			delay(1);			CSR_W_2(&bus_iot, csrbase, FXP_CSR_EEPROMCONTROL, reg);			delay(1);		}		/*		 * Shift in address.		 */		for (x = 6; x > 0; x--) {			if ((i + offset) & (1 << (x - 1))) {				reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI;			} else {				reg = FXP_EEPROM_EECS;			}			CSR_W_2(&bus_iot, csrbase, FXP_CSR_EEPROMCONTROL, reg);			CSR_W_2(&bus_iot, csrbase, FXP_CSR_EEPROMCONTROL,			    reg | FXP_EEPROM_EESK);			delay(1);			CSR_W_2(&bus_iot, csrbase, FXP_CSR_EEPROMCONTROL, reg);			delay(1);		}		reg = FXP_EEPROM_EECS;		data[i] = 0;		/*		 * Shift out data.		 */		for (x = 16; x > 0; x--) {			CSR_W_2(&bus_iot, csrbase, FXP_CSR_EEPROMCONTROL,			    reg | FXP_EEPROM_EESK);			delay(1);			if (CSR_R_2(&bus_iot, csrbase, FXP_CSR_EEPROMCONTROL) &			    FXP_EEPROM_EEDO)				data[i] |= (1 << (x - 1));			CSR_W_2(&bus_iot, csrbase, FXP_CSR_EEPROMCONTROL, reg);			delay(1);		}		data[i] = htole16(data[i]);		CSR_W_2(&bus_iot, csrbase, FXP_CSR_EEPROMCONTROL, 0);		delay(1);	}}/* * Write to the serial EEPROM. */voidwrite_eeprom(csrbase, data, offset, words)	int csrbase;	u_int16_t *data;	int offset;	int words;{	u_int16_t reg;	int i, x;	int d;	/*	 * Enable writing.	 */	d = (FXP_EEPROM_OPC_WRITENB << 4);	x = 0x100;	while (x != 0) {		if (d & x) {			reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI;		} else {			reg = FXP_EEPROM_EECS;		}		CSR_W_2(&bus_iot, csrbase, FXP_CSR_EEPROMCONTROL, reg);		CSR_W_2(&bus_iot, csrbase, FXP_CSR_EEPROMCONTROL,		    reg | FXP_EEPROM_EESK);		delay(1);		CSR_W_2(&bus_iot, csrbase, FXP_CSR_EEPROMCONTROL, reg);		delay(1);		x >>= 1;	}/* XXXX Need data sheet to verify if raise CS is enough! (pefo) */	CSR_W_2(&bus_iot, csrbase, FXP_CSR_EEPROMCONTROL, 0);	delay(1);	CSR_W_2(&bus_iot, csrbase, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EESK);	delay(1);	CSR_W_2(&bus_iot, csrbase, FXP_CSR_EEPROMCONTROL, 0);	delay(1);	/*	 * Now write the data words.	 */	for (i = 0; i < words; i++) {		CSR_W_2(&bus_iot, csrbase, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);		/*		 * Shift in write command, address and data.		 */		d = (FXP_EEPROM_OPC_WRITE << 6) | ((i + offset) & 0x3f);		d = d << 16 | htole16(data[i]);		x = 0x1000000;		while (x != 0) {			if (d & x) {				reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI;			} else {				reg = FXP_EEPROM_EECS;			}			CSR_W_2(&bus_iot, csrbase, FXP_CSR_EEPROMCONTROL, reg);			CSR_W_2(&bus_iot, csrbase, FXP_CSR_EEPROMCONTROL,			    reg | FXP_EEPROM_EESK);			delay(1);			CSR_W_2(&bus_iot, csrbase, FXP_CSR_EEPROMCONTROL, reg);			delay(1);			x >>= 1;		}		CSR_W_2(&bus_iot, csrbase, FXP_CSR_EEPROMCONTROL, 0);		delay(1);		CSR_W_2(&bus_iot, csrbase, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EESK);		delay(1);		CSR_W_2(&bus_iot, csrbase, FXP_CSR_EEPROMCONTROL, 0);		delay(1);		delay(200000);  /* Let write settle */	}	/*	 * Disable writing.	 */	d = (FXP_EEPROM_OPC_WRITDIS << 4);	x = 0x100;	while (x != 0) {		if (d & x) {			reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI;		} else {			reg = FXP_EEPROM_EECS;		}		CSR_W_2(&bus_iot, csrbase, FXP_CSR_EEPROMCONTROL, reg);		CSR_W_2(&bus_iot, csrbase, FXP_CSR_EEPROMCONTROL,		    reg | FXP_EEPROM_EESK);		delay(1);		CSR_W_2(&bus_iot, csrbase, FXP_CSR_EEPROMCONTROL, reg);		delay(1);		x >>= 1;	}	CSR_W_2(&bus_iot, csrbase, FXP_CSR_EEPROMCONTROL, 0);	delay(1);	CSR_W_2(&bus_iot, csrbase, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EESK);	delay(1);	CSR_W_2(&bus_iot, csrbase, FXP_CSR_EEPROMCONTROL, 0);	delay(1);}#endifstatic const Cmd Cmds[] ={	{"Pci"},	{"pcicfg",	"bus device[:func] reg",			0,			"pci config space",			cmd_pcicfg, 3, 4, 0},	{"pcfg",	"",			0,			"pcicfg",			cmd_pcicfg, 3, 4, CMD_ALIAS},	{"pciscan",	"[-b <bus>][-d <dev>]",			cmd_pciscan_opts,			"scan pci bus",			cmd_pciscan, 1, 5, 0},#ifdef ENABLE_FXPETH	{"fxpeth",	"[-b <bus>][-d <dev>][addr]",			cmd_fxp_opts,			"fxp address read/set",			cmd_fxp_eth, 1, 6, CMD_HIDE},#endif	{0, 0}};static void init_cmd __P((void)) __attribute__ ((constructor));static voidinit_cmd(){	cmdlist_expand(Cmds, 1);}

⌨️ 快捷键说明

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