📄 spdcmds.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 + -