Commit cbbf1259 authored by Ollie Lho's avatar Ollie Lho
Browse files

Move utility functions into new source files

Corresponding to flashrom svn r6 and coreboot v2 svn r1428.
parent 3770a113
OBJS = jedec.o sst28sf040.o am29f040b.o mx29f002.c sst39sf020.o m29f400bt.o \
w49f002u.o 82802ab.o msys_doc.o pm49fl004.o sst49lf040.o
OBJS = flash_enable.o udelay.o jedec.o sst28sf040.o am29f040b.o mx29f002.c sst39sf020.o \
m29f400bt.o w49f002u.o 82802ab.o msys_doc.o pm49fl004.o sst49lf040.o
CC = gcc -O2 -g -Wall -Werror
all: flash_rom flash_on
......@@ -28,5 +28,6 @@ sst39sf020.o: sst39sf020.c sst39sf020.h jedec.h flash.h
sst49lf040.o: sst49lf040.c sst49lf040.h jedec.h flash.h
w49f002u.o: w49f002u.c w49f002u.h jedec.h flash.h
pm49fl004.o: pm49fl004.c pm49fl004.h jedec.h flash.h
flash_enable.o: flash_enable.c
udelay.o: udelay.c
jedec.o: jedec.c jedec.h flash.h
......@@ -55,5 +55,6 @@ struct flashchip {
#define MSYSTEMS_MD2802 0x30 /* hmm -- both 0x30 */
extern void myusec_delay(int time);
extern void myusec_calibrate_delay();
extern int enable_flash_write(void);
#endif /* !__FLASH_H__ */
#include <sys/io.h>
#include <stdio.h>
#include <pci/pci.h>
#include <stdlib.h>
static int enable_flash_sis630 (struct pci_dev *dev, char *name)
{
char b;
/* get io privilege access PCI configuration space */
if (iopl(3) != 0) {
perror("Can not set io priviliage");
exit(1);
}
/* Enable 0xFFF8000~0xFFFF0000 decoding on SiS 540/630 */
outl(0x80000840, 0x0cf8);
b = inb(0x0cfc) | 0x0b;
outb(b, 0xcfc);
/* Flash write enable on SiS 540/630 */
outl(0x80000845, 0x0cf8);
b = inb(0x0cfd) | 0x40;
outb(b, 0xcfd);
/* The same thing on SiS 950 SuperIO side */
outb(0x87, 0x2e);
outb(0x01, 0x2e);
outb(0x55, 0x2e);
outb(0x55, 0x2e);
if (inb(0x2f) != 0x87) {
outb(0x87, 0x4e);
outb(0x01, 0x4e);
outb(0x55, 0x4e);
outb(0xaa, 0x4e);
if (inb(0x4f) != 0x87) {
printf("Can not access SiS 950\n");
return -1;
}
outb(0x24, 0x4e);
b = inb(0x4f) | 0xfc;
outb(0x24, 0x4e);
outb(b, 0x4f);
outb(0x02, 0x4e);
outb(0x02, 0x4f);
}
outb(0x24, 0x2e);
printf("2f is %#x\n", inb(0x2f));
b = inb(0x2f) | 0xfc;
outb(0x24, 0x2e);
outb(b, 0x2f);
outb(0x02, 0x2e);
outb(0x02, 0x2f);
return 0;
}
static int enable_flash_e7500(struct pci_dev *dev, char *name)
{
/* register 4e.b gets or'ed with one */
unsigned char old, new;
/* if it fails, it fails. There are so many variations of broken mobos
* that it is hard to argue that we should quit at this point.
*/
old = pci_read_byte(dev, 0x4e);
new = old | 1;
if (new == old)
return 0;
pci_write_byte(dev, 0x4e, new);
if (pci_read_byte(dev, 0x4e) != new) {
printf("tried to set 0x%x to 0x%x on %s failed (WARNING ONLY)\n",
0x4e, new, name);
return -1;
}
return 0;
}
static int enable_flash_vt8235(struct pci_dev *dev, char *name)
{
unsigned char old, new, val;
unsigned int base;
int ok;
/* get io privilege access PCI configuration space */
if (iopl(3) != 0) {
perror("Can not set io priviliage");
exit(1);
}
old = pci_read_byte(dev, 0x40);
new = old | 0x10;
if (new == old)
return 0;
ok = pci_write_byte(dev, 0x40, new);
if (ok != 0) {
printf("tried to set 0x%x to 0x%x on %s failed (WARNING ONLY)\n",
old, new, name);
}
/* enable GPIO15 which is connected to write protect. */
base = ((pci_read_byte(dev, 0x88) & 0x80) | pci_read_byte(dev, 0x89) << 8);
val = inb(base + 0x4d);
val |= 0x80;
outb(val, base + 0x4d);
if (ok != 0) {
return -1;
} else {
return 0;
}
}
static int enable_flash_vt8231(struct pci_dev *dev, char *name)
{
unsigned char val;
val = pci_read_byte(dev, 0x40);
val |= 0x10;
pci_write_byte(dev, 0x40, val);
if (pci_read_byte(dev, 0x40) != val) {
printf("tried to set 0x%x to 0x%x on %s failed (WARNING ONLY)\n",
0x40, val, name);
return -1;
}
return 0;
}
static int enable_flash_cs5530(struct pci_dev *dev, char *name)
{
unsigned char new;
pci_write_byte(dev, 0x52, 0xee);
new = pci_read_byte(dev, 0x52);
if (new != 0xee) {
printf("tried to set register 0x%x to 0x%x on %s failed (WARNING ONLY)\n",
0x52, new, name);
return -1;
}
return 0;
}
static int enable_flash_sc1100(struct pci_dev *dev, char *name)
{
unsigned char new;
pci_write_byte(dev, 0x52, 0xee);
new = pci_read_byte(dev, 0x52);
if (new != 0xee) {
printf("tried to set register 0x%x to 0x%x on %s failed (WARNING ONLY)\n",
0x52, new, name);
return -1;
}
return 0;
}
static int enable_flash_sis5595(struct pci_dev *dev, char *name)
{
unsigned char new, newer;
new = pci_read_byte(dev, 0x45);
/* clear bit 5 */
new &= (~ 0x20);
/* set bit 2 */
new |= 0x4;
pci_write_byte(dev, 0x45, new);
newer = pci_read_byte(dev, 0x45);
if (newer != new) {
printf("tried to set register 0x%x to 0x%x on %s failed (WARNING ONLY)\n",
0x45, new, name);
printf("Stuck at 0x%x\n", newer);
return -1;
}
return 0;
}
static int enable_flash_amd8111(struct pci_dev *dev, char *name) {
/* register 4e.b gets or'ed with one */
unsigned char old, new;
/* if it fails, it fails. There are so many variations of broken mobos
* that it is hard to argue that we should quit at this point.
*/
//dump_pci_device(dev);
old = pci_read_byte(dev, 0x43);
new = old | 0x80;
if (new != old) {
pci_write_byte(dev, 0x43, new);
if (pci_read_byte(dev, 0x43) != new) {
printf("tried to set 0x%x to 0x%x on %s failed (WARNING ONLY)\n",
0x43, new, name);
}
}
old = pci_read_byte(dev, 0x40);
new = old | 0x01;
if (new == old)
return 0;
pci_write_byte(dev, 0x40, new);
if (pci_read_byte(dev, 0x40) != new) {
printf("tried to set 0x%x to 0x%x on %s failed (WARNING ONLY)\n",
0x40, new, name);
return -1;
}
return 0;
}
typedef struct penable {
unsigned short vendor, device;
char *name;
int (*doit)(struct pci_dev *dev, char *name);
} FLASH_ENABLE;
static FLASH_ENABLE enables[] = {
{0x1039, 0x0630, "sis630", enable_flash_sis630},
{0x8086, 0x2480, "E7500", enable_flash_e7500},
{0x1106, 0x8231, "VT8231", enable_flash_vt8231},
{0x1106, 0x3177, "VT8235", enable_flash_vt8235},
{0x1078, 0x0100, "CS5530", enable_flash_cs5530},
{0x100b, 0x0510, "SC1100", enable_flash_sc1100},
{0x1039, 0x0008, "SIS5595", enable_flash_sis5595},
{0x1022, 0x7468, "AMD8111", enable_flash_amd8111},
};
int enable_flash_write()
{
int i;
struct pci_access *pacc;
struct pci_dev *dev = 0;
FLASH_ENABLE *enable = 0;
pacc = pci_alloc(); /* Get the pci_access structure */
/* Set all options you want -- here we stick with the defaults */
pci_init(pacc); /* Initialize the PCI library */
pci_scan_bus(pacc); /* We want to get the list of devices */
/* now let's try to find the chipset we have ... */
for (i = 0; i < sizeof(enables)/sizeof(enables[0]) && (! dev); i++) {
struct pci_filter f;
struct pci_dev *z;
/* the first param is unused. */
pci_filter_init((struct pci_access *) 0, &f);
f.vendor = enables[i].vendor;
f.device = enables[i].device;
for (z=pacc->devices; z; z=z->next)
if (pci_filter_match(&f, z)) {
enable = &enables[i];
dev = z;
}
}
/* now do the deed. */
if (enable) {
printf("Enabling flash write on %s...", enable->name);
if (enable->doit(dev, enable->name) == 0)
printf("OK\n");
}
return 0;
}
This diff is collapsed.
......@@ -32,7 +32,7 @@
#define AUTO_PG_ERASE1 0x20
#define AUTO_PG_ERASE2 0xD0
#define AUTO_PGRM 0x10
#define AUTO_PGRM 0x10
#define CHIP_ERASE 0x30
#define RESET 0xFF
#define READ_ID 0x90
......
#include <sys/time.h>
#include <stdio.h>
// count to a billion. Time it. If it's < 1 sec, count to 10B, etc.
unsigned long micro = 1;
void myusec_delay(int time)
{
volatile unsigned long i;
for(i = 0; i < time * micro; i++)
;
}
void myusec_calibrate_delay()
{
int count = 1000;
unsigned long timeusec;
struct timeval start, end;
int ok = 0;
void myusec_delay(int time);
printf("Setting up microsecond timing loop\n");
while (!ok) {
//fprintf(stderr, "Try %d\n", count);
gettimeofday(&start, 0);
myusec_delay(count);
gettimeofday(&end, 0);
timeusec = 1000000 * (end.tv_sec - start.tv_sec ) +
(end.tv_usec - start.tv_usec);
//fprintf(stderr, "timeusec is %d\n", timeusec);
count *= 2;
if (timeusec < 1000000/4)
continue;
ok = 1;
}
// compute one microsecond. That will be count / time
micro = count / timeusec;
fprintf(stderr, "%ldM loops per second\n", (unsigned long)micro);
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment