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

📄 spdcmds.c

📁 MIPS处理器的bootloader,龙芯就是用的修改过的PMON2
💻 C
字号:
/*	$Id: spdcmds.c,v 1.1 2003/05/21 10:22:39 pefo Exp $ *//* * Copyright (c) 2003 Opsycon AB  (www.opsycon.se) *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by Opsycon AB, Sweden. * 4. The name of the author may not be used to endorse or promote products *    derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */#include <stdio.h>#include <termio.h>#include <string.h>#include <setjmp.h>#include <sys/endian.h>#include <ctype.h>#include <unistd.h>#include <stdlib.h>#include <fcntl.h>#ifdef _KERNEL#undef _KERNEL#include <sys/ioctl.h>#define _KERNEL#else#include <sys/ioctl.h>#endif#include <dev/pci/pcivar.h>#include <machine/pio.h>#include <machine/cpu.h>#include <pmon.h>#include "target/cm4.h"#include "pmon/dev/mpc107reg.h"int spd_cmd __P((int, char *[]));static int read_spd __P((int, char *, int, int));static int write_spd __P((int, char *, int, int));static void i2c_init __P((void));static int i2c_start __P((int, int));static void i2c_rstart __P((int, int));static void i2c_stop __P((void));static int i2c_wait __P((void));static void spd_enable __P((void));static void spd_disable __P((void));/* *  Target dependent version printout. *  Printout available target version information. */voidtgt_cmd_vers(){	char buf[256];	if(read_spd(0x50, buf, 0, 256) != 0) {		printf("SPD read error!\n");	}	else {		printf("%s %s\n", &buf[74], &buf[192]);	}}/* *  SPD  read/write */intspd_cmd(ac, av)	int ac;	char *av[];{	int32_t	devadr = 0x50;	int32_t	offs = 0;	char *madr;	register_t v;	char buf[256];	int c;	int dflag = 0;	int mflag = 0;	int wflag = 0;extern int optind;extern char *optarg;	optind = 0;	while ((c = getopt (ac, av, "a:dm:o:w")) != EOF) {		switch (c) {		case 'a':			if (!get_rsa (&devadr, optarg)) {				return (-1);			}			break;		case 'd':			dflag = 1;			break;		case 'm':			if (!get_rsa ((int32_t *)&madr, optarg)) {				return (-1);			}			mflag = 1;			break;		case 'o':			if (!get_rsa (&offs, optarg)) {				return (-1);			}			if(offs < 0 || offs > 255) {				printf("offset out of range!\n");				return(0);			}			break;		case 'w':			wflag = 1;			break;#ifdef POSSIBLE_EXTENSION		case 's':			serno = optarg;			break;		case 'p':			prodid = optarg;			break;#endif		default:			return (-1);		}	}	if (optind > ac) {		return (-1);	}	if (optind < ac) { /* command mode */		int nbytes = 0;		if(dflag || mflag) {			return(-1);		}		while(optind < ac) {			if (!get_rsa_reg (&v, av[optind++])) {				return (-1);			}			buf[nbytes++] = v;		}		if(write_spd(devadr, buf, offs, nbytes) != 0) {			printf("SPD write error!\n");		}	}	else if(mflag) {		if(dflag) {			return(-1);		}		if(write_spd(devadr, madr, 0, 256) != 0) {			printf("SPD write error!\n");		}	}	else if(dflag) { /* dump SPD contents */		int i, j;		if(read_spd(devadr, buf, 0, 256) != 0) {			printf("SPD read error!\n");			return(-1);		}		for(i = 0; i < 256; i += 16) {			printf("%04x  ", i);			for(j = i; j < i + 16; j++) {				printf("%02x ", buf[j]);			}			for(j = i; j < i + 16; j++) {				printf("%c", isprint(buf[j]) ? buf[j] : '.');			}			printf("\n");		}	}	else while(TRUE){ /* interactive mode */		char *p;		read_spd(devadr, buf, offs, 1);		printf ("%04x %02x ", offs, *buf);		line[0] = '\0'; get_line (line, 0);		for (p = line; *p == ' '; p++);		if (*p == '.') {			break;		}		else if (*p == '\0') {			offs++;		}		else if (*p == '^' || *p == '-') {			offs--;		}		else if (*p == '=') {			/* reread */;		}		else if(!wflag) {			printf("-w flag not given to allow modify!!\n");		}		else if(get_rsa_reg (&v, p)) {			buf[0] = v;			if(write_spd(devadr, buf, offs, 1) != 0) {				printf("SPD write error!\n");				return(0);			}			offs++;		}		offs &= 255;	/* Wrap offset */	}	return (0);}static intread_spd(devadr, buf, offset, nbytes)	int devadr;	char *buf;	int offset;	int nbytes;{	int csr;	int ccr;	i2c_init();	i2c_start(devadr, I2C_WRITE);	csr = i2c_wait();	if(csr & I2C_CSR_RXAK) {		i2c_stop();		return(-1);	}	out32rb(MPC107_I2C_CDR, offset);	csr = i2c_wait();	if(csr & I2C_CSR_RXAK) {		i2c_stop();		return(-1);	}	i2c_rstart(devadr, I2C_READ);	csr = i2c_wait();	if(csr & I2C_CSR_RXAK) {		i2c_stop();		return(-1);	}	ccr = in32rb(MPC107_I2C_CCR);	ccr &= ~(I2C_CCR_MTX|I2C_CCR_RSTA);	if(nbytes == 1) {		ccr |= I2C_CCR_TXAK;		/* TXAK to generate STOP */	}	out32rb(MPC107_I2C_CCR, ccr);	(void)in32rb(MPC107_I2C_CDR);		/* Dummy read */	while(nbytes--) {		csr = i2c_wait();		if(nbytes == 1) {			ccr |= I2C_CCR_TXAK;	/* TXAK to generate STOP */			out32rb(MPC107_I2C_CCR, ccr);		}		if(nbytes == 0) {			i2c_stop();		}		*buf++ = in32rb(MPC107_I2C_CDR);	}	return(0);}static intwrite_spd(devadr, buf, offset, nbytes)	int devadr;	char *buf;	int offset;	int nbytes;{	int csr;	int firstwrite = 1;	spd_enable();	i2c_init();	while(nbytes != 0) {		int blkcnt;		blkcnt = 4 - (offset & 3);		if(nbytes < blkcnt) {			blkcnt = nbytes;		}		nbytes -= blkcnt;		while(TRUE) {			i2c_start(devadr, I2C_WRITE);			csr = i2c_wait();			if((csr & I2C_CSR_RXAK) == 0) {				break;			}			i2c_stop();			if(firstwrite) {				return(-1);			}		}		out32rb(MPC107_I2C_CDR, offset);		csr = i2c_wait();		if(csr & I2C_CSR_RXAK) {			i2c_stop();			return(-1);		}		while(blkcnt--) {			out32rb(MPC107_I2C_CDR, *buf++);			csr = i2c_wait();			if(csr & I2C_CSR_RXAK) {				i2c_stop();				return(-1);			}			offset++;		}		i2c_stop();		firstwrite = 0;	}	/* Wait for last write to finish */	i2c_start(devadr, I2C_WRITE);	csr = i2c_wait();	i2c_stop();	spd_disable();	return(0);}static voidi2c_init(){	out32rb(MPC107_I2C_CCR, in32rb(MPC107_I2C_CCR) & ~I2C_CCR_MEN);	out32rb(MPC107_I2C_FDR, (in32rb(MPC107_I2C_FDR) & ~0x3f) | 0x28);	out32rb(MPC107_I2C_ADR, (in32rb(MPC107_I2C_ADR) & ~0x3f) | 0x02);}static inti2c_start(sadr, read)	int sadr;	int read;{	int ccr;	/* Check bus is idle */	out32rb(MPC107_I2C_CSR, 0);	if(in32rb(MPC107_I2C_CSR) & I2C_CSR_MBB) {		return(-1);	}	/* Setup address and generate start */	ccr =  I2C_CCR_MEN | I2C_CCR_MSTA | I2C_CCR_MTX;	out32rb(MPC107_I2C_CCR, ccr);	out32rb(MPC107_I2C_CDR, (sadr << 1) | read);	return(0);}static voidi2c_rstart(sadr, read)	int sadr;	int read;{	int ccr;	ccr = in32rb(MPC107_I2C_CCR);	ccr |= I2C_CCR_RSTA;	out32rb(MPC107_I2C_CCR, ccr);	out32rb(MPC107_I2C_CDR, (sadr << 1) | read);}static voidi2c_stop(){	int ccr;	ccr = in32rb(MPC107_I2C_CCR);	ccr &= ~I2C_CCR_MSTA;	out32rb(MPC107_I2C_CCR, ccr);}static inti2c_wait(){	int dly = 1000;	int csr;	while(dly > 0) {		if((csr = in32rb(MPC107_I2C_CSR)) & I2C_CSR_MIF) {			out32rb(MPC107_I2C_CSR, 0);			return(csr);		}		dly--;		delay(1);	}	return(-1);}static voidspd_enable(){	outb(CM4_SOP, inb(CM4_SOP) & ~CM4_SOP_WP_SPD);}static voidspd_disable(){	outb(CM4_SOP, inb(CM4_SOP) | CM4_SOP_WP_SPD);}static const Optdesc spd_opts[] = {	{"-a <adr>", "specify device address other than 0x50"},	{"-d", "dump SPD memory content"},	{"-m <madr>", "program SPD from memory area"},	{"-o <offs>", "start offset other than 0"},	{"-w", "yes i intend to write"},	{"Interactive Options", ""},	{"<hexval>", "set SPD, forward one"},	{"CR", "forward one, no change"},	{"^|-", "back one"},	{".", "quit"},	{0,0}};static const Cmd Cmds[] ={	{"Misc"},	{"spd",		"[-d][-w][-a adr][-o offs][data...]",			spd_opts,			"spd memory read/write",			spd_cmd, 1, 99, CMD_HIDE|CMD_REPEAT},	{0, 0}};static void init_cmd __P((void)) __attribute__ ((constructor));static voidinit_cmd(){	spd_disable();	cmdlist_expand(Cmds, 1);}

⌨️ 快捷键说明

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