Initial revision

This commit is contained in:
Michael Brown
2005-05-17 16:44:57 +00:00
parent 75a5374d79
commit 1097cf8685
164 changed files with 24592 additions and 0 deletions

View File

@@ -0,0 +1,9 @@
FILES = cromutil bromutil
INCLUDEDIR = /usr/include
CFLAGS = -O2 -fomit-frame-pointer -Wall -I$(INCLUDEDIR)
all: $(FILES)
clean:
rm -f $(FILES) *~ core

31
contrib/3c90xutil/README Normal file
View File

@@ -0,0 +1,31 @@
This utility was apparently writen by John Finlay and came to me
via Richard Schroeder who got it from Greg Beeley. John, if you want
to be credited with your full address or whatever in the Etherboot
documentation, please contact me (Etherboot maintainer).
1/18/2000 Marty Connor (mdc@thinguin.org) added code for the 3C905C
with AT49BV512 Flash memory, and created cromutil and bromutil to
differentiate the versions. cromutil is for 3C905C and bromutil is
for 3C905B.
Be careful. You can easily erase your Flash memory using these
utilities. Make *sure* to back them up first using the "read"
command. You must "erase" before using "prog" to program the chip with
Etherboot code. This code comes with NO WARRANTY, and you take sole
responsibility and liability for whatever it does. Read the
"romutil.txt" file for more information on commands.
That being said, if you are programming a 3C905C-TXM (for example)
you would do something like this:
$ cd etherboot-x.x.x/contrib
$ tar -zxvf n3c905xutil.tar.gz
$ cd n3c905xutil
$ make
# replace 0x6600 with whatever the IO Addr for your card is!!!!
$ ./cromutil 0x6600 read > 905cbackup.bin
$ ./cromutil 0x6600 erase
$ ./cromutil 0x6600 prog < 3c90x.lzrom
You should now have an Etherboot-enabled 3c905C-TXM.

View File

@@ -0,0 +1,169 @@
/*
* readutil.c - perform various control ops on the 3c509b bios rom
*
*/
#ifndef __i386__
# error "This program can't compile or run on non-intel computers"
#else
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#ifdef __FreeBSD__
#include <fcntl.h>
#include <machine/cpufunc.h>
#define OUTB(data, port) outb(port, data)
#define OUTW(data, port) outw(port, data)
#define OUTL(data, port) outl(port, data)
#else
#include <sys/io.h>
#define OUTB(data, port) outb(data, port)
#define OUTW(data, port) outw(data, port)
#define OUTL(data, port) outl(data, port)
#endif
int main(int argc, char **argv)
{
unsigned int i, j, n;
unsigned int ioaddr;
unsigned long recvrstat;
unsigned char buf[128];
unsigned char b;
if (argc != 3) {
printf("Usage: romid ioaddr [erase|protect|unprotect|id|read >file|prog <file]\n");
exit(-1);
}
#ifdef __FreeBSD__
/* get permissions for in/out{blw} */
open("/dev/io",O_RDONLY,0);
#else
setuid(0); /* if we're setuid, do it really */
if (iopl(3)) {
perror("iopl()");
exit(1);
}
#endif
sscanf(argv[1],"%x",&ioaddr);
/* Set the register window to 3 for the 3c905b */
OUTW(0x803, ioaddr+0xe);
recvrstat = inl(ioaddr); /* save the receiver status */
/* set the receiver type to MII so the full bios rom address space
can be accessed */
OUTL((recvrstat & 0xf00fffff)|0x00600000, ioaddr);
/* Set the register window to 0 for the 3c905b */
OUTW(0x800, ioaddr+0xe);
if (strcmp(argv[2], "erase") == 0) {
/* do the funky chicken to erase the rom contents */
OUTL(0x5555, ioaddr+0x4);
OUTB(0xaa, ioaddr+0x8);
OUTL(0x2aaa, ioaddr+0x4);
OUTB(0x55, ioaddr+0x8);
OUTL(0x5555, ioaddr+0x4);
OUTB(0x80, ioaddr+0x8);
OUTL(0x5555, ioaddr+0x4);
OUTB(0xaa, ioaddr+0x8);
OUTL(0x2aaa, ioaddr+0x4);
OUTB(0x55, ioaddr+0x8);
OUTL(0x5555, ioaddr+0x4);
OUTB(0x10, ioaddr+0x8);
printf("Bios ROM at %04x has been erased\n", ioaddr);
} else if (strcmp(argv[2], "protect") == 0) {
OUTL(0x5555, ioaddr+0x4);
OUTB(0xaa, ioaddr+0x8);
OUTL(0x2aaa, ioaddr+0x4);
OUTB(0x55, ioaddr+0x8);
OUTL(0x5555, ioaddr+0x4);
OUTB(0xa0, ioaddr+0x8);
printf("Software Data Protection for Bios ROM at %04x has been enabled\n",
ioaddr);
} else if (strcmp(argv[2], "unprotect") == 0) {
OUTL(0x5555, ioaddr+0x4);
OUTB(0xaa, ioaddr+0x8);
OUTL(0x2aaa, ioaddr+0x4);
OUTB(0x55, ioaddr+0x8);
OUTL(0x5555, ioaddr+0x4);
OUTB(0x80, ioaddr+0x8);
OUTL(0x5555, ioaddr+0x4);
OUTB(0xaa, ioaddr+0x8);
OUTL(0x2aaa, ioaddr+0x4);
OUTB(0x55, ioaddr+0x8);
OUTL(0x5555, ioaddr+0x4);
OUTB(0x20, ioaddr+0x8);
printf("Software Data Protection for Bios ROM at %04x has been disabled\n",
ioaddr);
} else if (strcmp(argv[2], "id") == 0) {
OUTL(0x5555, ioaddr+0x4);
OUTB(0xaa, ioaddr+0x8);
OUTL(0x2aaa, ioaddr+0x4);
OUTB(0x55, ioaddr+0x8);
OUTL(0x5555, ioaddr+0x4);
OUTB(0x90, ioaddr+0x8);
/* 10ms delay needed */
printf("Manufacturer ID - ");
/* manuf. id */
OUTL(0x0000, ioaddr+0x4);
printf("%02x\n", inb(ioaddr+0x8));
/* device id */
OUTL(0x0001, ioaddr+0x4);
printf("Device ID - %02x\n", inb(ioaddr+0x8));
/* undo the funky chicken */
OUTL(0x5555, ioaddr+0x4);
OUTB(0xaa, ioaddr+0x8);
OUTL(0x2aaa, ioaddr+0x4);
OUTB(0x55, ioaddr+0x8);
OUTL(0x5555, ioaddr+0x4);
OUTB(0xf0, ioaddr+0x8);
} else if (strcmp(argv[2], "read") == 0) {
for (i = 0; i < 65536; i++) {
OUTL(i, ioaddr+0x4);
b = inb(ioaddr+0x8);
write(1, &b, 1);
}
} else if (strcmp(argv[2], "prog") == 0) {
/* program the rom in 128 bute chunks */
for (i = 0, n = 0; i < 65536; i += n) {
n = read(0, buf, 128);
if (n == 0)
break;
if (n < 0) {
perror("File Error");
exit(-3);
}
/* disable SDP temporarily for programming a sector */
OUTL(0x5555, ioaddr+0x4);
OUTB(0xaa, ioaddr+0x8);
OUTL(0x2aaa, ioaddr+0x4);
OUTB(0x55, ioaddr+0x8);
OUTL(0x5555, ioaddr+0x4);
OUTB(0xa0, ioaddr+0x8);
for (j = 0; j < n; j++) {
OUTL(i+j, ioaddr+0x4);
OUTB(buf[j], ioaddr+0x8);
}
/* wait for the programming of this sector to coomplete */
while (inb(ioaddr+0x8) != buf[j-1])
;
}
}
/* Set the register window to 3 for the 3c905b */
OUTW(0x803, ioaddr+0xe);
/* restore the receiver status */
OUTL(recvrstat, ioaddr);
return 0;
}
#endif /* __i386__ */

View File

@@ -0,0 +1,103 @@
/*
* 3c905cutil.c - perform various control ops on the 3C905C bios rom
* which we assume to be an AT49BV512
*
*/
#ifndef __i386__
# error "This program can't compile or run on non-intel computers"
#else
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/io.h>
int main(int argc, char **argv)
{
unsigned int ioaddr, i, n;
unsigned char b;
setuid(0); /* if we're setuid, do it really */
if (argc != 3) {
printf("Usage: romid ioaddr [erase|id|read >file|prog <file]\n");
exit(-1);
}
if (iopl(3)) {
perror("iopl()");
exit(1);
}
sscanf(argv[1],"%x",&ioaddr);
/* Set the register window to 0 for the 3C905C */
outw(0x800, ioaddr+0xe);
if (strcmp(argv[2], "erase") == 0) {
/* do the funky chicken to erase the rom contents */
outl(0x5555, ioaddr+0x4);
outb(0xaa, ioaddr+0x8);
outl(0x2aaa, ioaddr+0x4);
outb(0x55, ioaddr+0x8);
outl(0x5555, ioaddr+0x4);
outb(0x80, ioaddr+0x8);
outl(0x5555, ioaddr+0x4);
outb(0xaa, ioaddr+0x8);
outl(0x2aaa, ioaddr+0x4);
outb(0x55, ioaddr+0x8);
outl(0x5555, ioaddr+0x4);
outb(0x10, ioaddr+0x8);
sleep (1);
printf("Bios ROM at %04x has been erased\n", ioaddr);
} else if (strcmp(argv[2], "id") == 0) {
outl(0x5555, ioaddr+0x4);
outb(0xaa, ioaddr+0x8);
outl(0x2aaa, ioaddr+0x4);
outb(0x55, ioaddr+0x8);
outl(0x5555, ioaddr+0x4);
outb(0x90, ioaddr+0x8);
/* 10ms delay needed */
printf("Manufacturer ID - ");
/* manuf. id */
outl(0x0000, ioaddr+0x4);
printf("%02x\n", inb(ioaddr+0x8));
/* device id */
outl(0x0001, ioaddr+0x4);
printf("Device ID - %02x\n", inb(ioaddr+0x8));
/* undo the funky chicken */
outl(0x5555, ioaddr+0x4);
outb(0xaa, ioaddr+0x8);
outl(0x2aaa, ioaddr+0x4);
outb(0x55, ioaddr+0x8);
outl(0x5555, ioaddr+0x4);
outb(0xf0, ioaddr+0x8);
} else if (strcmp(argv[2], "read") == 0) {
for (i = 0; i < 65536; i++) {
outl(i, ioaddr+0x4);
b = inb(ioaddr+0x8);
write(1, &b, 1);
}
} else if (strcmp(argv[2], "prog") == 0) {
for (i = 0; i < 65536; i++) {
n = read(0, &b, 1);
if (n == 0)
break;
if (n < 0) {
perror("File Error");
exit(-3);
}
outl(0x5555, ioaddr+0x4);
outb(0xaa, ioaddr+0x8);
outl(0x2aaa, ioaddr+0x4);
outb(0x55, ioaddr+0x8);
outl(0x5555, ioaddr+0x4);
outb(0xA0, ioaddr+0x8);
outl(i, ioaddr+0x4);
outb(b, ioaddr+0x8);
while (inb(ioaddr+0x8) != b)
;
}
}
return 0;
}
#endif /* __i386__ */

View File

@@ -0,0 +1,36 @@
I wrote the attached little util program to try out the basic approach
and thought that you might find it useful as well as providing some
simple testing. It isn't a final solution so the interface is rough. The
program must be run as root on an Intel based machine.
The key point is that the IO address needs to be entered - I grab it
from the dmesg output:
eth0: 3Com 3c905B Cyclone 100baseTx at 0xe400, 00:10:4b:d2:5e:0d, IRQ
11
or "cat /proc/pci" to find the "I/O at XXXXXX" for your 3Com Card.
Some example commands are:
romutil 0xe400 erase - erases the ROM contents
romutil 0xe400 protect - enables the Software Data Protection
on the ROM [3c905B only]
romutil 0xe400 unprotect - disables the Software Data Protection
on the ROM [3c905B only]
romutil 0xe400 id - displays the manufacturer and
device IDs
romutil 0xe400 read >file - writes the contents of the ROM to stdout
romutil 0xe400 prog <file - writes the contents of the stdin into the
ROM (<64k)
I tried reading and writing the ROM while doing large ftp transfers and
experienced no problems. I didn't spend much time worrying about the
possible race conditions. My system has lots of resources (450MHx P2,
128MB RAM) so it might not provide the best test candidate.
Let me know what results you get if you try it out.
Thanks
John