flasrom update from Stefan, resovle issue 21
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@2111 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
parent
f622d598db
commit
1a4f0707bb
|
@ -34,9 +34,10 @@
|
||||||
|
|
||||||
#include "flash.h"
|
#include "flash.h"
|
||||||
#include "82802ab.h"
|
#include "82802ab.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
// I need that Berkeley bit-map printer
|
// I need that Berkeley bit-map printer
|
||||||
void print_82802ab_status(unsigned char status)
|
void print_82802ab_status(uint8_t status)
|
||||||
{
|
{
|
||||||
printf("%s", status & 0x80 ? "Ready:" : "Busy:");
|
printf("%s", status & 0x80 ? "Ready:" : "Busy:");
|
||||||
printf("%s", status & 0x40 ? "BE SUSPEND:" : "BE RUN/FINISH:");
|
printf("%s", status & 0x40 ? "BE SUSPEND:" : "BE RUN/FINISH:");
|
||||||
|
@ -49,13 +50,13 @@ void print_82802ab_status(unsigned char status)
|
||||||
|
|
||||||
int probe_82802ab(struct flashchip *flash)
|
int probe_82802ab(struct flashchip *flash)
|
||||||
{
|
{
|
||||||
volatile unsigned char *bios = flash->virt_addr;
|
volatile uint8_t *bios = flash->virt_addr;
|
||||||
unsigned char id1, id2;
|
uint8_t id1, id2;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
*(volatile unsigned char *) (bios + 0x5555) = 0xAA;
|
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
|
||||||
*(volatile unsigned char *) (bios + 0x2AAA) = 0x55;
|
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
|
||||||
*(volatile unsigned char *) (bios + 0x5555) = 0x90;
|
*(volatile uint8_t *) (bios + 0x5555) = 0x90;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
*bios = 0xff;
|
*bios = 0xff;
|
||||||
|
@ -63,18 +64,18 @@ int probe_82802ab(struct flashchip *flash)
|
||||||
*bios = 0x90;
|
*bios = 0x90;
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
|
|
||||||
id1 = *(volatile unsigned char *) bios;
|
id1 = *(volatile uint8_t *) bios;
|
||||||
id2 = *(volatile unsigned char *) (bios + 0x01);
|
id2 = *(volatile uint8_t *) (bios + 0x01);
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
*(volatile unsigned char *) (bios + 0x5555) = 0xAA;
|
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
|
||||||
*(volatile unsigned char *) (bios + 0x2AAA) = 0x55;
|
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
|
||||||
*(volatile unsigned char *) (bios + 0x5555) = 0xF0;
|
*(volatile uint8_t *) (bios + 0x5555) = 0xF0;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
|
|
||||||
printf("%s: id1 0x%x, id2 0x%x\n", __FUNCTION__, id1, id2);
|
printf_debug("%s: id1 0x%x, id2 0x%x\n", __FUNCTION__, id1, id2);
|
||||||
|
|
||||||
if (id1 == flash->manufacture_id && id2 == flash->model_id) {
|
if (id1 == flash->manufacture_id && id2 == flash->model_id) {
|
||||||
size_t size = flash->total_size * 1024;
|
size_t size = flash->total_size * 1024;
|
||||||
|
@ -94,11 +95,11 @@ int probe_82802ab(struct flashchip *flash)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char wait_82802ab(volatile unsigned char *bios)
|
uint8_t wait_82802ab(volatile uint8_t *bios)
|
||||||
{
|
{
|
||||||
|
|
||||||
unsigned char status;
|
uint8_t status;
|
||||||
unsigned char id1, id2;
|
uint8_t id1, id2;
|
||||||
|
|
||||||
*bios = 0x70;
|
*bios = 0x70;
|
||||||
if ((*bios & 0x80) == 0) { // it's busy
|
if ((*bios & 0x80) == 0) { // it's busy
|
||||||
|
@ -112,22 +113,22 @@ unsigned char wait_82802ab(volatile unsigned char *bios)
|
||||||
*bios = 0x90;
|
*bios = 0x90;
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
|
|
||||||
id1 = *(volatile unsigned char *) bios;
|
id1 = *(volatile uint8_t *) bios;
|
||||||
id2 = *(volatile unsigned char *) (bios + 0x01);
|
id2 = *(volatile uint8_t *) (bios + 0x01);
|
||||||
|
|
||||||
// this is needed to jam it out of "read id" mode
|
// this is needed to jam it out of "read id" mode
|
||||||
*(volatile unsigned char *) (bios + 0x5555) = 0xAA;
|
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
|
||||||
*(volatile unsigned char *) (bios + 0x2AAA) = 0x55;
|
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
|
||||||
*(volatile unsigned char *) (bios + 0x5555) = 0xF0;
|
*(volatile uint8_t *) (bios + 0x5555) = 0xF0;
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
}
|
}
|
||||||
int erase_82802ab_block(struct flashchip *flash, int offset)
|
int erase_82802ab_block(struct flashchip *flash, int offset)
|
||||||
{
|
{
|
||||||
volatile unsigned char *bios = flash->virt_addr + offset;
|
volatile uint8_t *bios = flash->virt_addr + offset;
|
||||||
volatile unsigned char *wrprotect =
|
volatile uint8_t *wrprotect =
|
||||||
flash->virt_addr_2 + offset + 2;
|
flash->virt_addr_2 + offset + 2;
|
||||||
unsigned char status;
|
uint8_t status;
|
||||||
|
|
||||||
// clear status register
|
// clear status register
|
||||||
*bios = 0x50;
|
*bios = 0x50;
|
||||||
|
@ -139,8 +140,8 @@ int erase_82802ab_block(struct flashchip *flash, int offset)
|
||||||
//printf("write protect is 0x%x\n", *(wrprotect));
|
//printf("write protect is 0x%x\n", *(wrprotect));
|
||||||
|
|
||||||
// now start it
|
// now start it
|
||||||
*(volatile unsigned char *) (bios) = 0x20;
|
*(volatile uint8_t *) (bios) = 0x20;
|
||||||
*(volatile unsigned char *) (bios) = 0xd0;
|
*(volatile uint8_t *) (bios) = 0xd0;
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
// now let's see what the register is
|
// now let's see what the register is
|
||||||
status = wait_82802ab(flash->virt_addr);
|
status = wait_82802ab(flash->virt_addr);
|
||||||
|
@ -161,7 +162,7 @@ int erase_82802ab(struct flashchip *flash)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_page_82802ab(volatile char *bios, char *src, volatile char *dst,
|
void write_page_82802ab(volatile uint8_t *bios, uint8_t *src, volatile uint8_t *dst,
|
||||||
int page_size)
|
int page_size)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -175,12 +176,12 @@ void write_page_82802ab(volatile char *bios, char *src, volatile char *dst,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int write_82802ab(struct flashchip *flash, unsigned char *buf)
|
int write_82802ab(struct flashchip *flash, uint8_t *buf)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int total_size = flash->total_size * 1024, page_size =
|
int total_size = flash->total_size * 1024, page_size =
|
||||||
flash->page_size;
|
flash->page_size;
|
||||||
volatile unsigned char *bios = flash->virt_addr;
|
volatile uint8_t *bios = flash->virt_addr;
|
||||||
|
|
||||||
erase_82802ab(flash);
|
erase_82802ab(flash);
|
||||||
if (*bios != 0xff) {
|
if (*bios != 0xff) {
|
||||||
|
|
|
@ -3,12 +3,12 @@
|
||||||
|
|
||||||
extern int probe_82802ab(struct flashchip *flash);
|
extern int probe_82802ab(struct flashchip *flash);
|
||||||
extern int erase_82802ab(struct flashchip *flash);
|
extern int erase_82802ab(struct flashchip *flash);
|
||||||
extern int write_82802ab(struct flashchip *flash, unsigned char *buf);
|
extern int write_82802ab(struct flashchip *flash, uint8_t *buf);
|
||||||
|
|
||||||
extern __inline__ void toggle_ready_82802ab(volatile char *dst)
|
extern __inline__ void toggle_ready_82802ab(volatile uint8_t *dst)
|
||||||
{
|
{
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
char tmp1, tmp2;
|
uint8_t tmp1, tmp2;
|
||||||
|
|
||||||
tmp1 = *dst & 0x40;
|
tmp1 = *dst & 0x40;
|
||||||
|
|
||||||
|
@ -21,10 +21,10 @@ extern __inline__ void toggle_ready_82802ab(volatile char *dst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern __inline__ void data_polling_82802ab(volatile char *dst, char data)
|
extern __inline__ void data_polling_82802ab(volatile uint8_t *dst, uint8_t data)
|
||||||
{
|
{
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
char tmp;
|
uint8_t tmp;
|
||||||
|
|
||||||
data &= 0x80;
|
data &= 0x80;
|
||||||
|
|
||||||
|
@ -36,11 +36,11 @@ extern __inline__ void data_polling_82802ab(volatile char *dst, char data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern __inline__ void protect_82802ab(volatile char *bios)
|
extern __inline__ void protect_82802ab(volatile uint8_t *bios)
|
||||||
{
|
{
|
||||||
*(volatile char *) (bios + 0x5555) = 0xAA;
|
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
|
||||||
*(volatile char *) (bios + 0x2AAA) = 0x55;
|
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
|
||||||
*(volatile char *) (bios + 0x5555) = 0xA0;
|
*(volatile uint8_t *) (bios + 0x5555) = 0xA0;
|
||||||
|
|
||||||
usleep(200);
|
usleep(200);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,33 +1,38 @@
|
||||||
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 sst_fwhub.o
|
# Makefile for flash_rom
|
||||||
CC = gcc -O2 -g -Wall -Werror
|
#
|
||||||
|
# redone by Stefan Reinauer <stepan@openbios.org>
|
||||||
|
#
|
||||||
|
|
||||||
all: flash_rom flash_on
|
PROGRAM = flashrom
|
||||||
|
|
||||||
flash_rom: flash_rom.o ${OBJS}
|
CC = gcc
|
||||||
${CC} -o flash_rom flash_rom.c ${OBJS} -lpci
|
STRIP = strip
|
||||||
|
#CFLAGS = -O2 -g -Wall -Werror
|
||||||
|
CFLAGS = -Os -Wall -Werror -DDISABLE_DOC
|
||||||
|
LDFLAGS = -lpci -static
|
||||||
|
|
||||||
flash_on: flash_on.c
|
|
||||||
${CC} -o flash_on flash_on.c
|
OBJS = flash_enable.o udelay.o jedec.o sst28sf040.o am29f040b.o mx29f002.o \
|
||||||
|
sst39sf020.o m29f400bt.o w49f002u.o 82802ab.o msys_doc.o pm49fl004.o \
|
||||||
|
sst49lf040.o sst_fwhub.o layout.o lbtable.o flashchips.o flash_rom.o
|
||||||
|
|
||||||
|
all: dep $(PROGRAM)
|
||||||
|
|
||||||
|
$(PROGRAM): $(OBJS)
|
||||||
|
$(CC) -o $(PROGRAM) $(OBJS) $(LDFLAGS)
|
||||||
|
$(STRIP) -s $(PROGRAM)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f flash_rom flash_on *.o *~
|
rm -f *.o *~
|
||||||
|
|
||||||
flash_rom.o: flash_rom.c flash.h jedec.h \
|
distclean: clean
|
||||||
82802ab.h am29f040b.h m29f400bt.h msys_doc.h mx29f002.h sst28sf040.h \
|
rm -f $(PROGRAM) .dependencies
|
||||||
sst39sf020.h w49f002u.h sst49lf040.h
|
|
||||||
flash_on.o: flash_on.c
|
dep:
|
||||||
|
@$(CC) -MM *.c > .dependencies
|
||||||
|
|
||||||
|
.PHONY: all clean distclean dep
|
||||||
|
|
||||||
|
-include .dependencies
|
||||||
|
|
||||||
82802ab.o: 82802ab.c 82802ab.h flash.h
|
|
||||||
am29f040b.o: am29f040b.c am29f040b.h jedec.h flash.h
|
|
||||||
m29f400bt.o: m29f400bt.c m29f400bt.h flash.h
|
|
||||||
msys_doc.o: msys_doc.c msys_doc.h flash.h
|
|
||||||
mx29f002.o: mx29f002.c mx29f002.h jedec.h flash.h
|
|
||||||
sst28sf040.o: sst28sf040.c sst28sf040.h jedec.h flash.h
|
|
||||||
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
|
|
||||||
|
|
|
@ -1,20 +1,69 @@
|
||||||
on the cs5530 southbridge,
|
This is the universal LinuxBIOS flash utility.
|
||||||
|
|
||||||
setpci -s 0:12.0 52.b=ee
|
usage: ./flashrom [-rwvE] [-V] [-c chipname]
|
||||||
setpci -x 0:12.0 5b.b= 0x20 (| with whatever is there)
|
[-s exclude_start] [-e exclude_end] [file]
|
||||||
|
|
||||||
I am making this a general-purpose userland flash burner -- RGM
|
-r | --read: read flash and save into file
|
||||||
|
-w | --write: write file into flash (default when file is specified)
|
||||||
|
-v | --verify: verify flash against file
|
||||||
|
-E | --erase: Erase flash device
|
||||||
|
-V | --verbose: more verbose output
|
||||||
|
|
||||||
Earlier notes from Ollie:
|
-c | --chip <chipname>: probe only for specified flash chip
|
||||||
|
-s | --estart <addr>: exclude start position
|
||||||
|
-e | --eend <addr>: exclude end postion
|
||||||
|
-m | --mainboard <vendor:part>: override mainboard settings
|
||||||
|
-l | --layout <file.layout>: read rom layout from file
|
||||||
|
-i | --image <name>: only flash image name from flash layout
|
||||||
|
|
||||||
Here is some utilities for using/programming flash ROM on SiS 630/950 M/Bs
|
If no file is specified, then all that happens
|
||||||
|
is that flash info is dumped and the flash chip is set to writable.
|
||||||
|
|
||||||
1. flash_on, turnning on the flash writer enable for 630/950 M/Bs,
|
|
||||||
you have to run this before load DoC drivers.
|
|
||||||
|
|
||||||
2. flash_rom, use your 630/950 M/Bs as a flash programmer for some
|
LinuxBIOS table and Mainboard identification
|
||||||
flash parts. This utility is made as modular as possible. If
|
--------------------------------------------
|
||||||
you find your flash part is not supported, you can add a driver
|
|
||||||
your own. Or sending me the data sheet.
|
flashrom reads the LinuxBIOS table to determine the current mainboard.
|
||||||
|
(Parse DMI as well in future?) If no LinuxBIOS table could be read
|
||||||
|
or if you want to override these values, you can to specify -m ie.:
|
||||||
|
|
||||||
|
flashrom -w --mainboard ISLAND:ARUMA island_aruma.rom
|
||||||
|
|
||||||
|
|
||||||
|
rom layout support
|
||||||
|
------------------
|
||||||
|
|
||||||
|
flashrom supports rom layouts. This allows to flash certain parts of
|
||||||
|
the flash chip only. A rom layout file looks like follows:
|
||||||
|
|
||||||
|
00000000:00008fff gfxrom
|
||||||
|
00009000:0003ffff normal
|
||||||
|
00040000:0007ffff fallback
|
||||||
|
|
||||||
|
i.e.:
|
||||||
|
startaddr:endaddr name
|
||||||
|
|
||||||
|
all addresses are offsets within the file, not absolute addresses!
|
||||||
|
|
||||||
|
If you only want to update the normal image in a rom you can say:
|
||||||
|
|
||||||
|
flashrom -w --layout rom.layout --image normal island_aruma.rom
|
||||||
|
|
||||||
|
To update normal and fallback but leave the vga bios alone, say:
|
||||||
|
|
||||||
|
flashrom -w -l rom.layout -i normal -i fallback island_aruma.rom
|
||||||
|
|
||||||
|
Currently overlapping sections are not spported.
|
||||||
|
|
||||||
|
rom layouts should replace the -s and -e option since they are more
|
||||||
|
flexible and they should lead to a rom update file format with the
|
||||||
|
rom layout and the rom image in one file (cpio, zip or something?)
|
||||||
|
|
||||||
|
|
||||||
|
DOC support
|
||||||
|
-----------
|
||||||
|
|
||||||
|
DISK on Chip support is currently disabled since it is considered unstable.
|
||||||
|
Change CFLAGS in the Makefile to enable it.
|
||||||
|
|
||||||
|
|
||||||
Ollie
|
|
||||||
|
|
|
@ -18,17 +18,17 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* Reference:
|
* Reference:
|
||||||
* AMD Am29F040B data sheet
|
* AMD Am29F040B data sheet
|
||||||
* $Id$
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include "flash.h"
|
#include "flash.h"
|
||||||
#include "jedec.h"
|
#include "jedec.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
static __inline__ int erase_sector_29f040b(volatile char *bios,
|
static __inline__ int erase_sector_29f040b(volatile uint8_t *bios,
|
||||||
unsigned long address)
|
unsigned long address)
|
||||||
{
|
{
|
||||||
*(bios + 0x555) = 0xAA;
|
*(bios + 0x555) = 0xAA;
|
||||||
|
@ -46,9 +46,9 @@ static __inline__ int erase_sector_29f040b(volatile char *bios,
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline__ int write_sector_29f040b(volatile char *bios,
|
static __inline__ int write_sector_29f040b(volatile uint8_t *bios,
|
||||||
unsigned char *src,
|
uint8_t *src,
|
||||||
volatile unsigned char *dst,
|
volatile uint8_t *dst,
|
||||||
unsigned int page_size)
|
unsigned int page_size)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -73,8 +73,8 @@ static __inline__ int write_sector_29f040b(volatile char *bios,
|
||||||
|
|
||||||
int probe_29f040b(struct flashchip *flash)
|
int probe_29f040b(struct flashchip *flash)
|
||||||
{
|
{
|
||||||
volatile unsigned char *bios = flash->virt_addr;
|
volatile uint8_t *bios = flash->virt_addr;
|
||||||
unsigned char id1, id2;
|
uint8_t id1, id2;
|
||||||
|
|
||||||
*(bios + 0x555) = 0xAA;
|
*(bios + 0x555) = 0xAA;
|
||||||
*(bios + 0x2AA) = 0x55;
|
*(bios + 0x2AA) = 0x55;
|
||||||
|
@ -87,7 +87,7 @@ int probe_29f040b(struct flashchip *flash)
|
||||||
|
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
|
|
||||||
printf("%s: id1 0x%x, id2 0x%x\n", __FUNCTION__, id1, id2);
|
printf_debug("%s: id1 0x%x, id2 0x%x\n", __FUNCTION__, id1, id2);
|
||||||
if (id1 == flash->manufacture_id && id2 == flash->model_id)
|
if (id1 == flash->manufacture_id && id2 == flash->model_id)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ int probe_29f040b(struct flashchip *flash)
|
||||||
|
|
||||||
int erase_29f040b(struct flashchip *flash)
|
int erase_29f040b(struct flashchip *flash)
|
||||||
{
|
{
|
||||||
volatile unsigned char *bios = flash->virt_addr;
|
volatile uint8_t *bios = flash->virt_addr;
|
||||||
|
|
||||||
*(bios + 0x555) = 0xAA;
|
*(bios + 0x555) = 0xAA;
|
||||||
*(bios + 0x2AA) = 0x55;
|
*(bios + 0x2AA) = 0x55;
|
||||||
|
@ -111,12 +111,12 @@ int erase_29f040b(struct flashchip *flash)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int write_29f040b(struct flashchip *flash, unsigned char *buf)
|
int write_29f040b(struct flashchip *flash, uint8_t *buf)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int total_size = flash->total_size * 1024, page_size =
|
int total_size = flash->total_size * 1024, page_size =
|
||||||
flash->page_size;
|
flash->page_size;
|
||||||
volatile char *bios = flash->virt_addr;
|
volatile uint8_t *bios = flash->virt_addr;
|
||||||
|
|
||||||
printf("Programming Page: ");
|
printf("Programming Page: ");
|
||||||
for (i = 0; i < total_size / page_size; i++) {
|
for (i = 0; i < total_size / page_size; i++) {
|
||||||
|
|
|
@ -3,6 +3,6 @@
|
||||||
|
|
||||||
extern int probe_29f040b(struct flashchip *flash);
|
extern int probe_29f040b(struct flashchip *flash);
|
||||||
extern int erase_29f040b(struct flashchip *flash);
|
extern int erase_29f040b(struct flashchip *flash);
|
||||||
extern int write_29f040b(struct flashchip *flash, unsigned char *buf);
|
extern int write_29f040b(struct flashchip *flash, uint8_t *buf);
|
||||||
|
|
||||||
#endif /* !__AM29F040B_H__ */
|
#endif /* !__AM29F040B_H__ */
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
#ifndef __DEBUG_H__
|
||||||
|
#define __DEBUG_H__ 1
|
||||||
|
|
||||||
|
//#define printf_debug(x...) printf(x)
|
||||||
|
#define printf_debug(x...) { }
|
||||||
|
|
||||||
|
#endif
|
|
@ -3,25 +3,28 @@
|
||||||
|
|
||||||
#include <sys/io.h>
|
#include <sys/io.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
struct flashchip {
|
struct flashchip {
|
||||||
char *name;
|
char *name;
|
||||||
int manufacture_id;
|
int manufacture_id;
|
||||||
int model_id;
|
int model_id;
|
||||||
|
|
||||||
volatile char *virt_addr;
|
volatile uint8_t *virt_addr;
|
||||||
int total_size;
|
int total_size;
|
||||||
int page_size;
|
int page_size;
|
||||||
|
|
||||||
int (*probe) (struct flashchip * flash);
|
int (*probe) (struct flashchip * flash);
|
||||||
int (*erase) (struct flashchip * flash);
|
int (*erase) (struct flashchip * flash);
|
||||||
int (*write) (struct flashchip * flash, unsigned char *buf);
|
int (*write) (struct flashchip * flash, uint8_t *buf);
|
||||||
int (*read) (struct flashchip * flash, unsigned char *buf);
|
int (*read) (struct flashchip * flash, uint8_t *buf);
|
||||||
|
|
||||||
int fd_mem;
|
int fd_mem;
|
||||||
volatile char *virt_addr_2;
|
volatile uint8_t *virt_addr_2;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern struct flashchip flashchips[];
|
||||||
|
|
||||||
#define AMD_ID 0x01
|
#define AMD_ID 0x01
|
||||||
#define AM_29F040B 0xA4
|
#define AM_29F040B 0xA4
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,23 @@
|
||||||
|
/*
|
||||||
|
* flash rom utility: enable flash writes
|
||||||
|
*
|
||||||
|
* Copyright (C) 2000-2004 ???
|
||||||
|
* Copyright (C) 2005 coresystems GmbH <stepan@openbios.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* version 2
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
#include <sys/io.h>
|
#include <sys/io.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <pci/pci.h>
|
#include <pci/pci.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "lbtable.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
static int enable_flash_sis630(struct pci_dev *dev, char *name)
|
static int enable_flash_sis630(struct pci_dev *dev, char *name)
|
||||||
{
|
{
|
||||||
|
@ -60,7 +76,7 @@ static int enable_flash_sis630(struct pci_dev *dev, char *name)
|
||||||
static int enable_flash_e7500(struct pci_dev *dev, char *name)
|
static int enable_flash_e7500(struct pci_dev *dev, char *name)
|
||||||
{
|
{
|
||||||
/* register 4e.b gets or'ed with one */
|
/* register 4e.b gets or'ed with one */
|
||||||
unsigned char old, new;
|
uint8_t old, new;
|
||||||
/* if it fails, it fails. There are so many variations of broken mobos
|
/* 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.
|
* that it is hard to argue that we should quit at this point.
|
||||||
*/
|
*/
|
||||||
|
@ -85,7 +101,7 @@ static int enable_flash_e7500(struct pci_dev *dev, char *name)
|
||||||
static int enable_flash_ich4(struct pci_dev *dev, char *name)
|
static int enable_flash_ich4(struct pci_dev *dev, char *name)
|
||||||
{
|
{
|
||||||
/* register 4e.b gets or'ed with one */
|
/* register 4e.b gets or'ed with one */
|
||||||
unsigned char old, new;
|
uint8_t old, new;
|
||||||
/* if it fails, it fails. There are so many variations of broken mobos
|
/* 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.
|
* that it is hard to argue that we should quit at this point.
|
||||||
*/
|
*/
|
||||||
|
@ -109,7 +125,7 @@ static int enable_flash_ich4(struct pci_dev *dev, char *name)
|
||||||
|
|
||||||
static int enable_flash_vt8235(struct pci_dev *dev, char *name)
|
static int enable_flash_vt8235(struct pci_dev *dev, char *name)
|
||||||
{
|
{
|
||||||
unsigned char old, new, val;
|
uint8_t old, new, val;
|
||||||
unsigned int base;
|
unsigned int base;
|
||||||
int ok;
|
int ok;
|
||||||
|
|
||||||
|
@ -147,7 +163,7 @@ static int enable_flash_vt8235(struct pci_dev *dev, char *name)
|
||||||
|
|
||||||
static int enable_flash_vt8231(struct pci_dev *dev, char *name)
|
static int enable_flash_vt8231(struct pci_dev *dev, char *name)
|
||||||
{
|
{
|
||||||
unsigned char val;
|
uint8_t val;
|
||||||
|
|
||||||
val = pci_read_byte(dev, 0x40);
|
val = pci_read_byte(dev, 0x40);
|
||||||
val |= 0x10;
|
val |= 0x10;
|
||||||
|
@ -163,7 +179,7 @@ static int enable_flash_vt8231(struct pci_dev *dev, char *name)
|
||||||
|
|
||||||
static int enable_flash_cs5530(struct pci_dev *dev, char *name)
|
static int enable_flash_cs5530(struct pci_dev *dev, char *name)
|
||||||
{
|
{
|
||||||
unsigned char new;
|
uint8_t new;
|
||||||
|
|
||||||
pci_write_byte(dev, 0x52, 0xee);
|
pci_write_byte(dev, 0x52, 0xee);
|
||||||
|
|
||||||
|
@ -174,12 +190,17 @@ static int enable_flash_cs5530(struct pci_dev *dev, char *name)
|
||||||
0x52, new, name);
|
0x52, new, name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
new = pci_read_byte(dev, 0x5b) | 0x20;
|
||||||
|
pci_write_byte(dev, 0x5b, new);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int enable_flash_sc1100(struct pci_dev *dev, char *name)
|
static int enable_flash_sc1100(struct pci_dev *dev, char *name)
|
||||||
{
|
{
|
||||||
unsigned char new;
|
uint8_t new;
|
||||||
|
|
||||||
pci_write_byte(dev, 0x52, 0xee);
|
pci_write_byte(dev, 0x52, 0xee);
|
||||||
|
|
||||||
|
@ -195,7 +216,7 @@ static int enable_flash_sc1100(struct pci_dev *dev, char *name)
|
||||||
|
|
||||||
static int enable_flash_sis5595(struct pci_dev *dev, char *name)
|
static int enable_flash_sis5595(struct pci_dev *dev, char *name)
|
||||||
{
|
{
|
||||||
unsigned char new, newer;
|
uint8_t new, newer;
|
||||||
|
|
||||||
new = pci_read_byte(dev, 0x45);
|
new = pci_read_byte(dev, 0x45);
|
||||||
|
|
||||||
|
@ -219,7 +240,7 @@ static int enable_flash_sis5595(struct pci_dev *dev, char *name)
|
||||||
static int enable_flash_amd8111(struct pci_dev *dev, char *name)
|
static int enable_flash_amd8111(struct pci_dev *dev, char *name)
|
||||||
{
|
{
|
||||||
/* register 4e.b gets or'ed with one */
|
/* register 4e.b gets or'ed with one */
|
||||||
unsigned char old, new;
|
uint8_t old, new;
|
||||||
/* if it fails, it fails. There are so many variations of broken mobos
|
/* 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.
|
* that it is hard to argue that we should quit at this point.
|
||||||
*/
|
*/
|
||||||
|
@ -253,7 +274,7 @@ static int enable_flash_amd8111(struct pci_dev *dev, char *name)
|
||||||
static int enable_flash_ck804(struct pci_dev *dev, char *name)
|
static int enable_flash_ck804(struct pci_dev *dev, char *name)
|
||||||
{
|
{
|
||||||
/* register 4e.b gets or'ed with one */
|
/* register 4e.b gets or'ed with one */
|
||||||
unsigned char old, new;
|
uint8_t old, new;
|
||||||
/* if it fails, it fails. There are so many variations of broken mobos
|
/* 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.
|
* that it is hard to argue that we should quit at this point.
|
||||||
*/
|
*/
|
||||||
|
@ -305,6 +326,69 @@ static FLASH_ENABLE enables[] = {
|
||||||
{0x10de, 0x00d3, "NVIDIA CK804", enable_flash_ck804}, // Slave, should not be here, to fix known bug for A01.
|
{0x10de, 0x00d3, "NVIDIA CK804", enable_flash_ck804}, // Slave, should not be here, to fix known bug for A01.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int mbenable_island_aruma(void)
|
||||||
|
{
|
||||||
|
#define EFIR 0x2e // Exteneded function index register, either 0x2e or 0x4e
|
||||||
|
#define EFDR EFIR + 1 // Extended function data register, one plus the index reg.
|
||||||
|
char b;
|
||||||
|
// Disable the flash write protect. The flash write protect is
|
||||||
|
// connected to the WinBond w83627hf GPIO 24.
|
||||||
|
|
||||||
|
/* get io privilege access winbond config space */
|
||||||
|
if (iopl(3) != 0) {
|
||||||
|
perror("Can not set io priviliage");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Disabling mainboard flash write protection.\n");
|
||||||
|
|
||||||
|
outb(0x87, EFIR); // sequence to unlock extended functions
|
||||||
|
outb(0x87, EFIR);
|
||||||
|
|
||||||
|
outb(0x20, EFIR); // SIO device ID register
|
||||||
|
b = inb(EFDR);
|
||||||
|
printf_debug("W83627HF device ID = 0x%x\n",b);
|
||||||
|
|
||||||
|
if (b != 0x52) {
|
||||||
|
perror("Incorrect device ID, aborting write protect disable\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
outb(0x2b, EFIR); // GPIO multiplexed pin reg.
|
||||||
|
b = inb(EFDR) | 0x10;
|
||||||
|
outb(0x2b, EFIR);
|
||||||
|
outb(b, EFDR); // select GPIO 24 instead of WDTO
|
||||||
|
|
||||||
|
outb(0x7, EFIR); // logical device select
|
||||||
|
outb(0x8, EFDR); // point to device 8, GPIO port 2
|
||||||
|
|
||||||
|
outb(0x30, EFIR); // logic device activation control
|
||||||
|
outb(0x1, EFDR); // activate
|
||||||
|
|
||||||
|
outb(0xf0, EFIR); // GPIO 20-27 I/O selection register
|
||||||
|
b = inb(EFDR) & ~0x10;
|
||||||
|
outb(0xf0, EFIR);
|
||||||
|
outb(b, EFDR); // set GPIO 24 as an output
|
||||||
|
|
||||||
|
outb(0xf1, EFIR); // GPIO 20-27 data register
|
||||||
|
b = inb(EFDR) | 0x10;
|
||||||
|
outb(0xf1, EFIR);
|
||||||
|
outb(b, EFDR); // set GPIO 24
|
||||||
|
|
||||||
|
outb(0xaa, EFIR); // command to exit extended functions
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct mbenable {
|
||||||
|
char *vendor, *part;
|
||||||
|
int (*doit)(void);
|
||||||
|
} MAINBOARD_ENABLE;
|
||||||
|
|
||||||
|
static MAINBOARD_ENABLE mbenables[] = {
|
||||||
|
{ "ISLAND", "ARUMA", mbenable_island_aruma },
|
||||||
|
};
|
||||||
|
|
||||||
int enable_flash_write()
|
int enable_flash_write()
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -317,6 +401,18 @@ int enable_flash_write()
|
||||||
pci_init(pacc); /* Initialize the PCI library */
|
pci_init(pacc); /* Initialize the PCI library */
|
||||||
pci_scan_bus(pacc); /* We want to get the list of devices */
|
pci_scan_bus(pacc); /* We want to get the list of devices */
|
||||||
|
|
||||||
|
|
||||||
|
/* First look whether we have to do something for this
|
||||||
|
* motherboard.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < sizeof(mbenables) / sizeof(mbenables[0]); i++) {
|
||||||
|
if(lb_vendor && !strcmp(mbenables[i].vendor, lb_vendor) &&
|
||||||
|
lb_part && !strcmp(mbenables[i].part, lb_part)) {
|
||||||
|
mbenables[i].doit();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* now let's try to find the chipset we have ... */
|
/* now let's try to find the chipset we have ... */
|
||||||
for (i = 0; i < sizeof(enables) / sizeof(enables[0]) && (!dev);
|
for (i = 0; i < sizeof(enables) / sizeof(enables[0]) && (!dev);
|
||||||
i++) {
|
i++) {
|
||||||
|
|
|
@ -1,77 +0,0 @@
|
||||||
/*
|
|
||||||
* flash_rom.c: Turnning on Flash Write Enable for SiS 630/950 M/Bs,
|
|
||||||
* use this program before loading DoC drivers.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Copyright 2000 Silicon Integrated System Corporation
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Reference:
|
|
||||||
* 1. SiS 630 Specification
|
|
||||||
* 2. SiS 950 Specification
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <sys/io.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
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) {
|
|
||||||
printf("Can not access SiS 950\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
outb(0x24, 0x2e);
|
|
||||||
b = inb(0x2f) | 0xfc;
|
|
||||||
outb(0x24, 0x2e);
|
|
||||||
outb(b, 0x2f);
|
|
||||||
|
|
||||||
outb(0x02, 0x2e);
|
|
||||||
outb(0x02, 0x2f);
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
|
@ -1,11 +1,13 @@
|
||||||
/*
|
/*
|
||||||
* flash_rom.c: Flash programming utility for SiS 630/950 M/Bs
|
* flash_rom.c: Flash programming utility
|
||||||
*
|
|
||||||
*
|
*
|
||||||
* Copyright 2000 Silicon Integrated System Corporation
|
* Copyright 2000 Silicon Integrated System Corporation
|
||||||
* Copyright 2004 Tyan Corp
|
* Copyright 2004 Tyan Corp
|
||||||
* yhlu yhlu@tyan.com add exclude start and end option
|
* yhlu yhlu@tyan.com add exclude start and end option
|
||||||
*
|
* Copyright 2005 coresystems GmbH
|
||||||
|
* Stefan Reinauer <stepan@core-systems.de> added rom layout
|
||||||
|
* support, and checking for suitable rom image
|
||||||
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
@ -20,12 +22,6 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* Reference:
|
|
||||||
* 1. SiS 630 Specification
|
|
||||||
* 2. SiS 950 Specification
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -35,75 +31,19 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
|
||||||
#include "flash.h"
|
#include "flash.h"
|
||||||
#include "jedec.h"
|
#include "lbtable.h"
|
||||||
#include "m29f400bt.h"
|
#include "layout.h"
|
||||||
#include "82802ab.h"
|
#include "debug.h"
|
||||||
#include "msys_doc.h"
|
|
||||||
#include "am29f040b.h"
|
|
||||||
#include "sst28sf040.h"
|
|
||||||
#include "w49f002u.h"
|
|
||||||
#include "sst39sf020.h"
|
|
||||||
#include "sst49lf040.h"
|
|
||||||
#include "pm49fl004.h"
|
|
||||||
#include "mx29f002.h"
|
|
||||||
#include "sst_fwhub.h"
|
|
||||||
|
|
||||||
struct flashchip flashchips[] = {
|
|
||||||
{"Am29F040B", AMD_ID, AM_29F040B, NULL, 512, 64 * 1024,
|
|
||||||
probe_29f040b, erase_29f040b, write_29f040b, NULL},
|
|
||||||
{"At29C040A", ATMEL_ID, AT_29C040A, NULL, 512, 256,
|
|
||||||
probe_jedec, erase_chip_jedec, write_jedec, NULL},
|
|
||||||
{"Mx29f002", MX_ID, MX_29F002, NULL, 256, 64 * 1024,
|
|
||||||
probe_29f002, erase_29f002, write_29f002, NULL},
|
|
||||||
{"SST29EE020A", SST_ID, SST_29EE020A, NULL, 256, 128,
|
|
||||||
probe_jedec, erase_chip_jedec, write_jedec, NULL},
|
|
||||||
{"SST28SF040A", SST_ID, SST_28SF040, NULL, 512, 256,
|
|
||||||
probe_28sf040, erase_28sf040, write_28sf040, NULL},
|
|
||||||
{"SST39SF020A", SST_ID, SST_39SF020, NULL, 256, 4096,
|
|
||||||
probe_jedec, erase_chip_jedec, write_39sf020,NULL},
|
|
||||||
{"SST39VF020", SST_ID, SST_39VF020, NULL, 256, 4096,
|
|
||||||
probe_jedec, erase_chip_jedec, write_39sf020,NULL},
|
|
||||||
{"SST49LF040", SST_ID, SST_49LF040, NULL, 512, 4096,
|
|
||||||
probe_jedec, erase_49lf040, write_49lf040,NULL},
|
|
||||||
{"SST49LF080A", SST_ID, SST_49LF080A, NULL, 1024, 4096,
|
|
||||||
probe_jedec, erase_chip_jedec, write_49lf040,NULL},
|
|
||||||
{"SST49LF002A/B", SST_ID, SST_49LF002A, NULL, 256, 16 * 1024,
|
|
||||||
probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub, NULL},
|
|
||||||
{"SST49LF003A/B", SST_ID, SST_49LF003A, NULL, 384, 64 * 1024,
|
|
||||||
probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub,NULL},
|
|
||||||
{"SST49LF004A/B", SST_ID, SST_49LF004A, NULL, 512, 64 * 1024,
|
|
||||||
probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub,NULL},
|
|
||||||
{"SST49LF008A", SST_ID, SST_49LF008A, NULL, 1024, 64 * 1024 ,
|
|
||||||
probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub, NULL},
|
|
||||||
{"Pm49FL004", PMC_ID, PMC_49FL004, NULL, 512, 64 * 1024,
|
|
||||||
probe_jedec, erase_chip_jedec, write_49fl004,NULL},
|
|
||||||
{"W29C011", WINBOND_ID, W_29C011, NULL, 128, 128,
|
|
||||||
probe_jedec, erase_chip_jedec, write_jedec, NULL},
|
|
||||||
{"W29C020C", WINBOND_ID, W_29C020C, NULL, 256, 128,
|
|
||||||
probe_jedec, erase_chip_jedec, write_jedec, NULL},
|
|
||||||
{"W49F002U", WINBOND_ID, W_49F002U, NULL, 256, 128,
|
|
||||||
probe_jedec, erase_chip_jedec, write_49f002, NULL},
|
|
||||||
{"M29F400BT", ST_ID, ST_M29F400BT, NULL, 512, 64 * 1024,
|
|
||||||
probe_m29f400bt, erase_m29f400bt, write_linuxbios_m29f400bt, NULL},
|
|
||||||
{"82802ab", 137, 173, NULL, 512, 64 * 1024,
|
|
||||||
probe_82802ab, erase_82802ab, write_82802ab, NULL},
|
|
||||||
{"82802ac", 137, 172, NULL, 1024, 64 * 1024,
|
|
||||||
probe_82802ab, erase_82802ab, write_82802ab, NULL},
|
|
||||||
{"MD-2802 (M-Systems DiskOnChip Millennium Module)",
|
|
||||||
MSYSTEMS_ID, MSYSTEMS_MD2802,
|
|
||||||
NULL, 8, 8 * 1024,
|
|
||||||
probe_md2802, erase_md2802, write_md2802, read_md2802},
|
|
||||||
{NULL,}
|
|
||||||
};
|
|
||||||
|
|
||||||
char *chip_to_probe = NULL;
|
char *chip_to_probe = NULL;
|
||||||
|
|
||||||
struct flashchip *probe_flash(struct flashchip *flash)
|
struct flashchip *probe_flash(struct flashchip *flash)
|
||||||
{
|
{
|
||||||
int fd_mem;
|
int fd_mem;
|
||||||
volatile char *bios;
|
volatile uint8_t *bios;
|
||||||
unsigned long size;
|
unsigned long size;
|
||||||
|
|
||||||
if ((fd_mem = open("/dev/mem", O_RDWR)) < 0) {
|
if ((fd_mem = open("/dev/mem", O_RDWR)) < 0) {
|
||||||
|
@ -116,7 +56,7 @@ struct flashchip *probe_flash(struct flashchip *flash)
|
||||||
flash++;
|
flash++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
printf("Trying %s, %d KB\n", flash->name, flash->total_size);
|
printf_debug("Trying %s, %d KB\n", flash->name, flash->total_size);
|
||||||
size = flash->total_size * 1024;
|
size = flash->total_size * 1024;
|
||||||
/* BUG? what happens if getpagesize() > size!?
|
/* BUG? what happens if getpagesize() > size!?
|
||||||
-> ``Error MMAP /dev/mem: Invalid argument'' NIKI */
|
-> ``Error MMAP /dev/mem: Invalid argument'' NIKI */
|
||||||
|
@ -146,11 +86,11 @@ struct flashchip *probe_flash(struct flashchip *flash)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int verify_flash(struct flashchip *flash, char *buf, int verbose)
|
int verify_flash(struct flashchip *flash, uint8_t *buf, int verbose)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int total_size = flash->total_size * 1024;
|
int total_size = flash->total_size * 1024;
|
||||||
volatile char *bios = flash->virt_addr;
|
volatile uint8_t *bios = flash->virt_addr;
|
||||||
|
|
||||||
printf("Verifying address: ");
|
printf("Verifying address: ");
|
||||||
for (i = 0; i < total_size; i++) {
|
for (i = 0; i < total_size; i++) {
|
||||||
|
@ -173,46 +113,76 @@ int verify_flash(struct flashchip *flash, char *buf, int verbose)
|
||||||
|
|
||||||
void usage(const char *name)
|
void usage(const char *name)
|
||||||
{
|
{
|
||||||
printf("usage: %s [-rwv] [-c chipname] [-s exclude_start] [-e exclude_end] [file]\n", name);
|
printf("usage: %s [-rwvE] [-V] [-c chipname] [-s exclude_start] [-e exclude_end] [file]\n", name);
|
||||||
printf("-r: read flash and save into file\n"
|
printf(" -r | --read: read flash and save into file\n"
|
||||||
"-w: write file into flash (default when file is specified)\n"
|
" -w | --write: write file into flash (default when file is specified)\n"
|
||||||
"-v: verify flash against file\n"
|
" -v | --verify: verify flash against file\n"
|
||||||
"-c: probe only for specified flash chip\n"
|
" -E | --erase: Erase flash device\n"
|
||||||
"-s: exclude start position\n"
|
" -V | --verbose: more verbose output\n\n"
|
||||||
"-e: exclude end postion\n"
|
" -c | --chip <chipname>: probe only for specified flash chip\n"
|
||||||
|
" -s | --estart <addr>: exclude start position\n"
|
||||||
|
" -e | --eend <addr>: exclude end postion\n"
|
||||||
|
" -m | --mainboard <vendor:part>: override mainboard settings\n"
|
||||||
|
" -f | --force: force write without checking image\n"
|
||||||
|
" -l | --layout <file.layout>: read rom layout from file\n"
|
||||||
|
" -i | --image <name>: only flash image name from flash layout\n"
|
||||||
|
"\n"
|
||||||
" If no file is specified, then all that happens\n"
|
" If no file is specified, then all that happens\n"
|
||||||
" is that flash info is dumped\n");
|
" is that flash info is dumped\n\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int exclude_start_page, exclude_end_page;
|
int exclude_start_page, exclude_end_page;
|
||||||
|
int force=0;
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
char *buf;
|
uint8_t *buf;
|
||||||
unsigned long size;
|
unsigned long size;
|
||||||
FILE *image;
|
FILE *image;
|
||||||
struct flashchip *flash;
|
struct flashchip *flash;
|
||||||
int opt;
|
int opt;
|
||||||
int read_it = 0, write_it = 0, erase_it = 0, verify_it = 0,
|
int option_index = 0;
|
||||||
verbose = 0;
|
int read_it = 0,
|
||||||
|
write_it = 0,
|
||||||
|
erase_it = 0,
|
||||||
|
verify_it = 0;
|
||||||
|
int verbose = 0;
|
||||||
|
|
||||||
|
static struct option long_options[]= {
|
||||||
|
{ "read", 0, 0, 'r' },
|
||||||
|
{ "write", 0, 0, 'w' },
|
||||||
|
{ "erase", 0, 0, 'E' },
|
||||||
|
{ "verify", 0, 0, 'v' },
|
||||||
|
{ "chip", 1, 0, 'c' },
|
||||||
|
{ "estart", 1, 0, 's' },
|
||||||
|
{ "eend", 1, 0, 'e' },
|
||||||
|
{ "mainboard", 1, 0, 'm' },
|
||||||
|
{ "verbose", 0, 0, 'V' },
|
||||||
|
{ "force", 0, 0, 'f' },
|
||||||
|
{ "layout", 1, 0, 'l' },
|
||||||
|
{ "image", 1, 0, 'i' },
|
||||||
|
{ "help", 0, 0, 'h' },
|
||||||
|
{ 0, 0, 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
char *filename = NULL;
|
char *filename = NULL;
|
||||||
|
|
||||||
|
|
||||||
unsigned int exclude_start_position=0, exclude_end_position=0; // [x,y)
|
unsigned int exclude_start_position=0, exclude_end_position=0; // [x,y)
|
||||||
char *tempstr=NULL;
|
char *tempstr=NULL, *tempstr2=NULL;
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
/* Yes, print them. */
|
/* Yes, print them. */
|
||||||
int i;
|
int i;
|
||||||
printf ("The arguments are:\n");
|
printf_debug ("The arguments are:\n");
|
||||||
for (i = 1; i < argc; ++i)
|
for (i = 1; i < argc; ++i)
|
||||||
printf ("%s\n", argv[i]);
|
printf_debug ("%s\n", argv[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
setbuf(stdout, NULL);
|
setbuf(stdout, NULL);
|
||||||
|
while ((opt = getopt_long(argc, argv, "rwvVEfc:s:e:m:l:i:h", long_options,
|
||||||
while ((opt = getopt(argc, argv, "rwvVEc:s:e:")) != EOF) {
|
&option_index)) != EOF) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'r':
|
case 'r':
|
||||||
read_it = 1;
|
read_it = 1;
|
||||||
|
@ -240,7 +210,30 @@ int main(int argc, char *argv[])
|
||||||
tempstr = strdup(optarg);
|
tempstr = strdup(optarg);
|
||||||
sscanf(tempstr,"%x",&exclude_end_position);
|
sscanf(tempstr,"%x",&exclude_end_position);
|
||||||
break;
|
break;
|
||||||
|
case 'm':
|
||||||
|
tempstr = strdup(optarg);
|
||||||
|
strtok(tempstr, ":");
|
||||||
|
tempstr2=strtok(NULL, ":");
|
||||||
|
if (tempstr2) {
|
||||||
|
lb_vendor=tempstr;
|
||||||
|
lb_part=tempstr2;
|
||||||
|
} else {
|
||||||
|
printf("warning: ignored wrong format of"
|
||||||
|
" mainboard: %s\n", tempstr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
force=1;
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
tempstr=strdup(optarg);
|
||||||
|
read_romlayout(tempstr);
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
tempstr=strdup(optarg);
|
||||||
|
find_romentry(tempstr);
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
default:
|
default:
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
break;
|
break;
|
||||||
|
@ -255,28 +248,36 @@ int main(int argc, char *argv[])
|
||||||
if (optind < argc)
|
if (optind < argc)
|
||||||
filename = argv[optind++];
|
filename = argv[optind++];
|
||||||
|
|
||||||
printf("Calibrating timer since microsleep sucks ... takes a second\n");
|
printf("Calibrating delay loop... ");
|
||||||
myusec_calibrate_delay();
|
myusec_calibrate_delay();
|
||||||
printf("OK, calibrated, now do the deed\n");
|
printf("ok\n");
|
||||||
|
|
||||||
|
/* We look at the lbtable first to see if we need a
|
||||||
|
* mainboard specific flash enable sequence.
|
||||||
|
*/
|
||||||
|
linuxbios_init();
|
||||||
|
|
||||||
/* try to enable it. Failure IS an option, since not all motherboards
|
/* try to enable it. Failure IS an option, since not all motherboards
|
||||||
* really need this to be done, etc., etc. It sucks.
|
* really need this to be done, etc., etc.
|
||||||
*/
|
*/
|
||||||
(void) enable_flash_write();
|
(void) enable_flash_write();
|
||||||
|
|
||||||
if ((flash = probe_flash(flashchips)) == NULL) {
|
if ((flash = probe_flash(flashchips)) == NULL) {
|
||||||
printf("EEPROM not found\n");
|
printf("No EEPROM/flash device found.\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Part is %s\n", flash->name);
|
printf("Flash part is %s\n", flash->name);
|
||||||
|
|
||||||
if (!filename && !erase_it) {
|
if (!filename && !erase_it) {
|
||||||
printf("OK, only ENABLING flash write, but NOT FLASHING\n");
|
// FIXME: Do we really want this feature implicitly?
|
||||||
|
printf("OK, only ENABLING flash write, but NOT FLASHING.\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
size = flash->total_size * 1024;
|
|
||||||
buf = (char *) calloc(size, sizeof(char));
|
|
||||||
|
|
||||||
|
size = flash->total_size * 1024;
|
||||||
|
buf = (uint8_t *) calloc(size, sizeof(char));
|
||||||
|
|
||||||
if (erase_it) {
|
if (erase_it) {
|
||||||
printf("Erasing flash chip\n");
|
printf("Erasing flash chip\n");
|
||||||
flash->erase(flash);
|
flash->erase(flash);
|
||||||
|
@ -305,9 +306,18 @@ int main(int argc, char *argv[])
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
fread(buf, sizeof(char), size, image);
|
fread(buf, sizeof(char), size, image);
|
||||||
|
show_id(buf, size);
|
||||||
fclose(image);
|
fclose(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* exclude range stuff. Nice idea, but at the moment it is only
|
||||||
|
* supported in hardware by the pm49fl004 chips.
|
||||||
|
* Instead of implementing this for all chips I suggest advancing
|
||||||
|
* it to the rom layout feature below and drop exclude range
|
||||||
|
* completely once all flash chips can do rom layouts. stepan
|
||||||
|
*/
|
||||||
|
|
||||||
|
// ////////////////////////////////////////////////////////////
|
||||||
if (exclude_end_position - exclude_start_position > 0)
|
if (exclude_end_position - exclude_start_position > 0)
|
||||||
memcpy(buf+exclude_start_position,
|
memcpy(buf+exclude_start_position,
|
||||||
(const char *) flash->virt_addr+exclude_start_position,
|
(const char *) flash->virt_addr+exclude_start_position,
|
||||||
|
@ -318,11 +328,19 @@ int main(int argc, char *argv[])
|
||||||
exclude_start_page++;
|
exclude_start_page++;
|
||||||
}
|
}
|
||||||
exclude_end_page = exclude_end_position/flash->page_size;
|
exclude_end_page = exclude_end_position/flash->page_size;
|
||||||
|
// ////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
if (write_it || (!read_it && !verify_it)) {
|
// This should be moved into each flash part's code to do it
|
||||||
|
// cleanly. This does the job.
|
||||||
|
handle_romentries(buf, (uint8_t *)flash->virt_addr);
|
||||||
|
|
||||||
|
// ////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
if (write_it)
|
||||||
flash->write(flash, buf);
|
flash->write(flash, buf);
|
||||||
}
|
|
||||||
if (verify_it)
|
if (verify_it)
|
||||||
verify_flash(flash, buf, verbose);
|
verify_flash(flash, buf, verbose);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
* flashchips.c: flash programming utility - flash devices
|
||||||
|
*
|
||||||
|
* Copyright 2000 Silicon Integrated System Corporation
|
||||||
|
* Copyright 2004 Tyan Corp
|
||||||
|
* yhlu yhlu@tyan.com add exclude start and end option
|
||||||
|
* Copyright 2005 coresystems GmbH <stepan@openbios.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "flash.h"
|
||||||
|
#include "jedec.h"
|
||||||
|
#include "m29f400bt.h"
|
||||||
|
#include "82802ab.h"
|
||||||
|
#ifndef DISABLE_DOC
|
||||||
|
#include "msys_doc.h"
|
||||||
|
#endif
|
||||||
|
#include "am29f040b.h"
|
||||||
|
#include "sst28sf040.h"
|
||||||
|
#include "w49f002u.h"
|
||||||
|
#include "sst39sf020.h"
|
||||||
|
#include "sst49lf040.h"
|
||||||
|
#include "pm49fl004.h"
|
||||||
|
#include "mx29f002.h"
|
||||||
|
#include "sst_fwhub.h"
|
||||||
|
|
||||||
|
struct flashchip flashchips[] = {
|
||||||
|
{"Am29F040B", AMD_ID, AM_29F040B, NULL, 512, 64 * 1024,
|
||||||
|
probe_29f040b, erase_29f040b, write_29f040b, NULL},
|
||||||
|
{"At29C040A", ATMEL_ID, AT_29C040A, NULL, 512, 256,
|
||||||
|
probe_jedec, erase_chip_jedec, write_jedec, NULL},
|
||||||
|
{"Mx29f002", MX_ID, MX_29F002, NULL, 256, 64 * 1024,
|
||||||
|
probe_29f002, erase_29f002, write_29f002, NULL},
|
||||||
|
{"SST29EE020A", SST_ID, SST_29EE020A, NULL, 256, 128,
|
||||||
|
probe_jedec, erase_chip_jedec, write_jedec, NULL},
|
||||||
|
{"SST28SF040A", SST_ID, SST_28SF040, NULL, 512, 256,
|
||||||
|
probe_28sf040, erase_28sf040, write_28sf040, NULL},
|
||||||
|
{"SST39SF020A", SST_ID, SST_39SF020, NULL, 256, 4096,
|
||||||
|
probe_jedec, erase_chip_jedec, write_39sf020,NULL},
|
||||||
|
{"SST39VF020", SST_ID, SST_39VF020, NULL, 256, 4096,
|
||||||
|
probe_jedec, erase_chip_jedec, write_39sf020,NULL},
|
||||||
|
{"SST49LF040", SST_ID, SST_49LF040, NULL, 512, 4096,
|
||||||
|
probe_jedec, erase_49lf040, write_49lf040,NULL},
|
||||||
|
{"SST49LF080A", SST_ID, SST_49LF080A, NULL, 1024, 4096,
|
||||||
|
probe_jedec, erase_chip_jedec, write_49lf040,NULL},
|
||||||
|
{"SST49LF002A/B", SST_ID, SST_49LF002A, NULL, 256, 16 * 1024,
|
||||||
|
probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub, NULL},
|
||||||
|
{"SST49LF003A/B", SST_ID, SST_49LF003A, NULL, 384, 64 * 1024,
|
||||||
|
probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub,NULL},
|
||||||
|
{"SST49LF004A/B", SST_ID, SST_49LF004A, NULL, 512, 64 * 1024,
|
||||||
|
probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub,NULL},
|
||||||
|
{"SST49LF008A", SST_ID, SST_49LF008A, NULL, 1024, 64 * 1024 ,
|
||||||
|
probe_sst_fwhub, erase_sst_fwhub, write_sst_fwhub, NULL},
|
||||||
|
{"Pm49FL004", PMC_ID, PMC_49FL004, NULL, 512, 64 * 1024,
|
||||||
|
probe_jedec, erase_chip_jedec, write_49fl004,NULL},
|
||||||
|
{"W29C011", WINBOND_ID, W_29C011, NULL, 128, 128,
|
||||||
|
probe_jedec, erase_chip_jedec, write_jedec, NULL},
|
||||||
|
{"W29C020C", WINBOND_ID, W_29C020C, NULL, 256, 128,
|
||||||
|
probe_jedec, erase_chip_jedec, write_jedec, NULL},
|
||||||
|
{"W49F002U", WINBOND_ID, W_49F002U, NULL, 256, 128,
|
||||||
|
probe_jedec, erase_chip_jedec, write_49f002, NULL},
|
||||||
|
{"M29F400BT", ST_ID, ST_M29F400BT, NULL, 512, 64 * 1024,
|
||||||
|
probe_m29f400bt, erase_m29f400bt, write_linuxbios_m29f400bt, NULL},
|
||||||
|
{"82802ab", 137, 173, NULL, 512, 64 * 1024,
|
||||||
|
probe_82802ab, erase_82802ab, write_82802ab, NULL},
|
||||||
|
{"82802ac", 137, 172, NULL, 1024, 64 * 1024,
|
||||||
|
probe_82802ab, erase_82802ab, write_82802ab, NULL},
|
||||||
|
#ifndef DISABLE_DOC
|
||||||
|
{"MD-2802 (M-Systems DiskOnChip Millennium Module)",
|
||||||
|
MSYSTEMS_ID, MSYSTEMS_MD2802,
|
||||||
|
NULL, 8, 8 * 1024,
|
||||||
|
probe_md2802, erase_md2802, write_md2802, read_md2802},
|
||||||
|
#endif
|
||||||
|
{NULL,}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
|
@ -25,56 +25,58 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include "flash.h"
|
#include "flash.h"
|
||||||
#include "jedec.h"
|
#include "jedec.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
int probe_jedec(struct flashchip *flash)
|
int probe_jedec(struct flashchip *flash)
|
||||||
{
|
{
|
||||||
volatile unsigned char *bios = flash->virt_addr;
|
volatile uint8_t *bios = flash->virt_addr;
|
||||||
unsigned char id1, id2;
|
uint8_t id1, id2;
|
||||||
|
|
||||||
/* Issue JEDEC Product ID Entry command */
|
/* Issue JEDEC Product ID Entry command */
|
||||||
*(volatile char *) (bios + 0x5555) = 0xAA;
|
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
*(volatile char *) (bios + 0x2AAA) = 0x55;
|
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
*(volatile char *) (bios + 0x5555) = 0x90;
|
*(volatile uint8_t *) (bios + 0x5555) = 0x90;
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
|
|
||||||
/* Read product ID */
|
/* Read product ID */
|
||||||
id1 = *(volatile unsigned char *) bios;
|
id1 = *(volatile uint8_t *) bios;
|
||||||
id2 = *(volatile unsigned char *) (bios + 0x01);
|
id2 = *(volatile uint8_t *) (bios + 0x01);
|
||||||
|
|
||||||
/* Issue JEDEC Product ID Exit command */
|
/* Issue JEDEC Product ID Exit command */
|
||||||
*(volatile char *) (bios + 0x5555) = 0xAA;
|
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
*(volatile char *) (bios + 0x2AAA) = 0x55;
|
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
*(volatile char *) (bios + 0x5555) = 0xF0;
|
*(volatile uint8_t *) (bios + 0x5555) = 0xF0;
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
|
|
||||||
printf("%s: id1 0x%x, id2 0x%x\n", __FUNCTION__, id1, id2);
|
printf_debug("%s: id1 0x%x, id2 0x%x\n", __FUNCTION__, id1, id2);
|
||||||
if (id1 == flash->manufacture_id && id2 == flash->model_id)
|
if (id1 == flash->manufacture_id && id2 == flash->model_id)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int erase_sector_jedec(volatile unsigned char *bios, unsigned int page)
|
int erase_sector_jedec(volatile uint8_t *bios, unsigned int page)
|
||||||
{
|
{
|
||||||
/* Issue the Sector Erase command */
|
/* Issue the Sector Erase command */
|
||||||
*(volatile char *) (bios + 0x5555) = 0xAA;
|
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
*(volatile char *) (bios + 0x2AAA) = 0x55;
|
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
*(volatile char *) (bios + 0x5555) = 0x80;
|
*(volatile uint8_t *) (bios + 0x5555) = 0x80;
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
|
|
||||||
*(volatile char *) (bios + 0x5555) = 0xAA;
|
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
*(volatile char *) (bios + 0x2AAA) = 0x55;
|
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
*(volatile char *) (bios + page) = 0x30;
|
*(volatile uint8_t *) (bios + page) = 0x30;
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
|
|
||||||
/* wait for Toggle bit ready */
|
/* wait for Toggle bit ready */
|
||||||
|
@ -83,21 +85,21 @@ int erase_sector_jedec(volatile unsigned char *bios, unsigned int page)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int erase_block_jedec(volatile unsigned char *bios, unsigned int block)
|
int erase_block_jedec(volatile uint8_t *bios, unsigned int block)
|
||||||
{
|
{
|
||||||
/* Issue the Sector Erase command */
|
/* Issue the Sector Erase command */
|
||||||
*(volatile char *) (bios + 0x5555) = 0xAA;
|
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
*(volatile char *) (bios + 0x2AAA) = 0x55;
|
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
*(volatile char *) (bios + 0x5555) = 0x80;
|
*(volatile uint8_t *) (bios + 0x5555) = 0x80;
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
|
|
||||||
*(volatile char *) (bios + 0x5555) = 0xAA;
|
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
*(volatile char *) (bios + 0x2AAA) = 0x55;
|
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
*(volatile char *) (bios + block) = 0x50;
|
*(volatile uint8_t *) (bios + block) = 0x50;
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
|
|
||||||
/* wait for Toggle bit ready */
|
/* wait for Toggle bit ready */
|
||||||
|
@ -108,21 +110,21 @@ int erase_block_jedec(volatile unsigned char *bios, unsigned int block)
|
||||||
|
|
||||||
int erase_chip_jedec(struct flashchip *flash)
|
int erase_chip_jedec(struct flashchip *flash)
|
||||||
{
|
{
|
||||||
volatile unsigned char *bios = flash->virt_addr;
|
volatile uint8_t *bios = flash->virt_addr;
|
||||||
|
|
||||||
/* Issue the JEDEC Chip Erase command */
|
/* Issue the JEDEC Chip Erase command */
|
||||||
*(volatile char *) (bios + 0x5555) = 0xAA;
|
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
*(volatile char *) (bios + 0x2AAA) = 0x55;
|
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
*(volatile char *) (bios + 0x5555) = 0x80;
|
*(volatile uint8_t *) (bios + 0x5555) = 0x80;
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
|
|
||||||
*(volatile char *) (bios + 0x5555) = 0xAA;
|
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
*(volatile char *) (bios + 0x2AAA) = 0x55;
|
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
*(volatile char *) (bios + 0x5555) = 0x10;
|
*(volatile uint8_t *) (bios + 0x5555) = 0x10;
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
|
|
||||||
toggle_ready_jedec(bios);
|
toggle_ready_jedec(bios);
|
||||||
|
@ -130,15 +132,15 @@ int erase_chip_jedec(struct flashchip *flash)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int write_page_write_jedec(volatile unsigned char *bios, unsigned char *src,
|
int write_page_write_jedec(volatile uint8_t *bios, uint8_t *src,
|
||||||
volatile unsigned char *dst, int page_size)
|
volatile uint8_t *dst, int page_size)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Issue JEDEC Data Unprotect comand */
|
/* Issue JEDEC Data Unprotect comand */
|
||||||
*(volatile unsigned char *) (bios + 0x5555) = 0xAA;
|
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
|
||||||
*(volatile unsigned char *) (bios + 0x2AAA) = 0x55;
|
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
|
||||||
*(volatile unsigned char *) (bios + 0x5555) = 0xA0;
|
*(volatile uint8_t *) (bios + 0x5555) = 0xA0;
|
||||||
|
|
||||||
/* transfer data from source to destination */
|
/* transfer data from source to destination */
|
||||||
for (i = 0; i < page_size; i++) {
|
for (i = 0; i < page_size; i++) {
|
||||||
|
@ -153,8 +155,8 @@ int write_page_write_jedec(volatile unsigned char *bios, unsigned char *src,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int write_byte_program_jedec(volatile unsigned char *bios, unsigned char *src,
|
int write_byte_program_jedec(volatile uint8_t *bios, uint8_t *src,
|
||||||
volatile unsigned char *dst)
|
volatile uint8_t *dst)
|
||||||
{
|
{
|
||||||
int tried = 0;
|
int tried = 0;
|
||||||
|
|
||||||
|
@ -165,9 +167,9 @@ int write_byte_program_jedec(volatile unsigned char *bios, unsigned char *src,
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
/* Issue JEDEC Byte Program command */
|
/* Issue JEDEC Byte Program command */
|
||||||
*(volatile unsigned char *) (bios + 0x5555) = 0xAA;
|
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
|
||||||
*(volatile unsigned char *) (bios + 0x2AAA) = 0x55;
|
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
|
||||||
*(volatile unsigned char *) (bios + 0x5555) = 0xA0;
|
*(volatile uint8_t *) (bios + 0x5555) = 0xA0;
|
||||||
|
|
||||||
/* transfer data from source to destination */
|
/* transfer data from source to destination */
|
||||||
*dst = *src;
|
*dst = *src;
|
||||||
|
@ -180,8 +182,8 @@ retry:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int write_sector_jedec(volatile unsigned char *bios, unsigned char *src,
|
int write_sector_jedec(volatile uint8_t *bios, uint8_t *src,
|
||||||
volatile unsigned char *dst, unsigned int page_size)
|
volatile uint8_t *dst, unsigned int page_size)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -193,15 +195,15 @@ int write_sector_jedec(volatile unsigned char *bios, unsigned char *src,
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int write_jedec(struct flashchip *flash, unsigned char *buf)
|
int write_jedec(struct flashchip *flash, uint8_t *buf)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int total_size = flash->total_size * 1024;
|
int total_size = flash->total_size * 1024;
|
||||||
int page_size = flash->page_size;
|
int page_size = flash->page_size;
|
||||||
volatile unsigned char *bios = flash->virt_addr;
|
volatile uint8_t *bios = flash->virt_addr;
|
||||||
|
|
||||||
erase_chip_jedec(flash);
|
erase_chip_jedec(flash);
|
||||||
if (*bios != (unsigned char) 0xff) {
|
if (*bios != (uint8_t) 0xff) {
|
||||||
printf("ERASE FAILED\n");
|
printf("ERASE FAILED\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
#ifndef __JEDEC_H__
|
#ifndef __JEDEC_H__
|
||||||
#define __JEDEC_H__ 1
|
#define __JEDEC_H__ 1
|
||||||
int write_byte_program_jedec(volatile unsigned char *bios, unsigned char *src,
|
int write_byte_program_jedec(volatile uint8_t *bios, uint8_t *src,
|
||||||
volatile unsigned char *dst);
|
volatile uint8_t *dst);
|
||||||
|
|
||||||
extern int probe_jedec(struct flashchip *flash);
|
extern int probe_jedec(struct flashchip *flash);
|
||||||
extern int erase_chip_jedec(struct flashchip *flash);
|
extern int erase_chip_jedec(struct flashchip *flash);
|
||||||
extern int write_jedec(struct flashchip *flash, unsigned char *buf);
|
extern int write_jedec(struct flashchip *flash, uint8_t *buf);
|
||||||
extern int erase_sector_jedec(volatile unsigned char *bios, unsigned int page);
|
extern int erase_sector_jedec(volatile uint8_t *bios, unsigned int page);
|
||||||
extern int erase_block_jedec(volatile unsigned char *bios, unsigned int page);
|
extern int erase_block_jedec(volatile uint8_t *bios, unsigned int page);
|
||||||
extern int write_sector_jedec(volatile unsigned char *bios, unsigned char *src,
|
extern int write_sector_jedec(volatile uint8_t *bios, uint8_t *src,
|
||||||
volatile unsigned char *dst,
|
volatile uint8_t *dst,
|
||||||
unsigned int page_size);
|
unsigned int page_size);
|
||||||
|
|
||||||
extern __inline__ void toggle_ready_jedec(volatile char *dst)
|
extern __inline__ void toggle_ready_jedec(volatile uint8_t *dst)
|
||||||
{
|
{
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
char tmp1, tmp2;
|
uint8_t tmp1, tmp2;
|
||||||
|
|
||||||
tmp1 = *dst & 0x40;
|
tmp1 = *dst & 0x40;
|
||||||
|
|
||||||
|
@ -28,10 +28,10 @@ extern __inline__ void toggle_ready_jedec(volatile char *dst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern __inline__ void data_polling_jedec(volatile char *dst, char data)
|
extern __inline__ void data_polling_jedec(volatile uint8_t *dst, uint8_t data)
|
||||||
{
|
{
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
char tmp;
|
uint8_t tmp;
|
||||||
|
|
||||||
data &= 0x80;
|
data &= 0x80;
|
||||||
|
|
||||||
|
@ -43,23 +43,23 @@ extern __inline__ void data_polling_jedec(volatile char *dst, char data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern __inline__ void unprotect_jedec(volatile char *bios)
|
extern __inline__ void unprotect_jedec(volatile uint8_t *bios)
|
||||||
{
|
{
|
||||||
*(volatile char *) (bios + 0x5555) = 0xAA;
|
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
|
||||||
*(volatile char *) (bios + 0x2AAA) = 0x55;
|
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
|
||||||
*(volatile char *) (bios + 0x5555) = 0x80;
|
*(volatile uint8_t *) (bios + 0x5555) = 0x80;
|
||||||
*(volatile char *) (bios + 0x5555) = 0xAA;
|
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
|
||||||
*(volatile char *) (bios + 0x2AAA) = 0x55;
|
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
|
||||||
*(volatile char *) (bios + 0x5555) = 0x20;
|
*(volatile uint8_t *) (bios + 0x5555) = 0x20;
|
||||||
|
|
||||||
usleep(200);
|
usleep(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern __inline__ void protect_jedec(volatile char *bios)
|
extern __inline__ void protect_jedec(volatile uint8_t *bios)
|
||||||
{
|
{
|
||||||
*(volatile char *) (bios + 0x5555) = 0xAA;
|
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
|
||||||
*(volatile char *) (bios + 0x2AAA) = 0x55;
|
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
|
||||||
*(volatile char *) (bios + 0x5555) = 0xA0;
|
*(volatile uint8_t *) (bios + 0x5555) = 0xA0;
|
||||||
|
|
||||||
usleep(200);
|
usleep(200);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,170 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "layout.h"
|
||||||
|
#include "lbtable.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
char * mainboard_vendor=NULL;
|
||||||
|
char * mainboard_part=NULL;
|
||||||
|
int romimages=0;
|
||||||
|
|
||||||
|
extern int force;
|
||||||
|
|
||||||
|
#define MAX_ROMLAYOUT 16
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned int start;
|
||||||
|
unsigned int end;
|
||||||
|
unsigned int included;
|
||||||
|
char name[256];
|
||||||
|
} romlayout_t;
|
||||||
|
|
||||||
|
romlayout_t rom_entries[MAX_ROMLAYOUT];
|
||||||
|
|
||||||
|
static char *def_name = "DEFAULT";
|
||||||
|
|
||||||
|
|
||||||
|
int show_id(uint8_t *bios, int size)
|
||||||
|
{
|
||||||
|
unsigned int *walk;
|
||||||
|
|
||||||
|
|
||||||
|
walk=(unsigned int *)(bios+size-0x10);
|
||||||
|
walk--;
|
||||||
|
|
||||||
|
if((*walk)==0 || ((*walk)&0x3ff) != 0) {
|
||||||
|
/* We might have an Nvidia chipset bios
|
||||||
|
* which stores the id information at a
|
||||||
|
* different location.
|
||||||
|
*/
|
||||||
|
walk=(unsigned int *)(bios+size-0x80);
|
||||||
|
walk--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((*walk)==0 || ((*walk)&0x3ff) != 0) {
|
||||||
|
printf("Flash image seems to be a legacy BIOS. Disabling checks.\n");
|
||||||
|
mainboard_vendor=def_name;
|
||||||
|
mainboard_part=def_name;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("LinuxBIOS image size=%d\n", *walk);
|
||||||
|
|
||||||
|
walk--; mainboard_part=strdup((const char *)(bios+size-*walk));
|
||||||
|
walk--; mainboard_vendor=strdup((const char *)(bios+size-*walk));
|
||||||
|
printf("MANUFACTURER: %s\n", mainboard_vendor);
|
||||||
|
printf("MAINBOARD ID: %s\n", mainboard_part);
|
||||||
|
if(lb_vendor && !strcmp(mainboard_vendor, lb_vendor) &&
|
||||||
|
lb_part && !strcmp(mainboard_part, lb_part)) {
|
||||||
|
printf ("This firmware image matches "
|
||||||
|
"this motherboard.\n");
|
||||||
|
} else {
|
||||||
|
if(force) {
|
||||||
|
printf("WARNING: This firmware image does not "
|
||||||
|
"fit to this machine - forcing it.\n");
|
||||||
|
} else {
|
||||||
|
printf("ERROR: This firmware image does not "
|
||||||
|
"fit to this machine\nOverride with -m if"
|
||||||
|
"you know exactly what you are doing.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int read_romlayout(char *name)
|
||||||
|
{
|
||||||
|
FILE *romlayout;
|
||||||
|
char tempstr[256];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
romlayout=fopen (name, "r");
|
||||||
|
|
||||||
|
if(!romlayout) {
|
||||||
|
printf("Error while opening rom layout.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(!feof(romlayout)) {
|
||||||
|
char *tstr1, *tstr2;
|
||||||
|
fscanf(romlayout,"%s %s\n", tempstr, rom_entries[romimages].name);
|
||||||
|
#if 0
|
||||||
|
// fscanf does not like arbitrary comments like that :( later
|
||||||
|
if (tempstr[0]=='#') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
tstr1=strtok(tempstr,":");
|
||||||
|
tstr2=strtok(NULL,":");
|
||||||
|
rom_entries[romimages].start=strtol(tstr1, (char **)NULL, 16);
|
||||||
|
rom_entries[romimages].end=strtol(tstr2, (char **)NULL, 16);
|
||||||
|
rom_entries[romimages].included=0;
|
||||||
|
romimages++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=0; i<romimages; i++) {
|
||||||
|
printf("romlayout %08x - %08x named %s\n",
|
||||||
|
rom_entries[i].start,
|
||||||
|
rom_entries[i].end,
|
||||||
|
rom_entries[i].name);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(romlayout);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int find_romentry(char *name)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if(!romimages) return -1;
|
||||||
|
|
||||||
|
printf("Looking for \"%s\"... ", name);
|
||||||
|
|
||||||
|
for (i=0; i<romimages; i++) {
|
||||||
|
if(!strcmp(rom_entries[i].name, name)) {
|
||||||
|
rom_entries[i].included=1;
|
||||||
|
printf("found.\n");
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("not found.\n");
|
||||||
|
// Not found. Error.
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int handle_romentries(uint8_t *buffer, uint8_t *content)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// This function does not safe flash write cycles.
|
||||||
|
//
|
||||||
|
// Also it does not cope with overlapping rom layout
|
||||||
|
// sections.
|
||||||
|
// example:
|
||||||
|
// 00000000:00008fff gfxrom
|
||||||
|
// 00009000:0003ffff normal
|
||||||
|
// 00040000:0007ffff fallback
|
||||||
|
// 00000000:0007ffff all
|
||||||
|
//
|
||||||
|
// If you'd specify -i all the included flag of all other
|
||||||
|
// sections is still 0, so no changes will be made to the
|
||||||
|
// flash. Same thing if you specify -i normal -i all only
|
||||||
|
// normal will be updated and the rest will be kept.
|
||||||
|
|
||||||
|
|
||||||
|
for (i=0; i<romimages; i++) {
|
||||||
|
|
||||||
|
if (rom_entries[i].included)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
memcpy (buffer+rom_entries[i].start,
|
||||||
|
content+rom_entries[i].start,
|
||||||
|
rom_entries[i].end-rom_entries[i].start);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
#ifndef __LAYOUT_H__
|
||||||
|
#define __LAYOUT_H__ 1
|
||||||
|
|
||||||
|
int show_id(uint8_t *bios, int size);
|
||||||
|
int read_romlayout(char *name);
|
||||||
|
int find_romentry(char *name);
|
||||||
|
int handle_romentries(uint8_t *buffer, uint8_t *content);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* !__LAYOUT_H__ */
|
|
@ -0,0 +1,193 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include "../../src/include/boot/linuxbios_tables.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
char *lb_part=NULL, *lb_vendor=NULL;
|
||||||
|
|
||||||
|
static unsigned long compute_checksum(void *addr, unsigned long length)
|
||||||
|
{
|
||||||
|
uint8_t *ptr;
|
||||||
|
volatile union {
|
||||||
|
uint8_t byte[2];
|
||||||
|
uint16_t word;
|
||||||
|
} value;
|
||||||
|
unsigned long sum;
|
||||||
|
unsigned long i;
|
||||||
|
/* In the most straight forward way possible,
|
||||||
|
* compute an ip style checksum.
|
||||||
|
*/
|
||||||
|
sum = 0;
|
||||||
|
ptr = addr;
|
||||||
|
for(i = 0; i < length; i++) {
|
||||||
|
unsigned long value;
|
||||||
|
value = ptr[i];
|
||||||
|
if (i & 1) {
|
||||||
|
value <<= 8;
|
||||||
|
}
|
||||||
|
/* Add the new value */
|
||||||
|
sum += value;
|
||||||
|
/* Wrap around the carry */
|
||||||
|
if (sum > 0xFFFF) {
|
||||||
|
sum = (sum + (sum >> 16)) & 0xFFFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
value.byte[0] = sum & 0xff;
|
||||||
|
value.byte[1] = (sum >> 8) & 0xff;
|
||||||
|
return (~value.word) & 0xFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define for_each_lbrec(head, rec) \
|
||||||
|
for(rec = (struct lb_record *)(((char *)head) + sizeof(*head)); \
|
||||||
|
(((char *)rec) < (((char *)head) + sizeof(*head) + head->table_bytes)) && \
|
||||||
|
(rec->size >= 1) && \
|
||||||
|
((((char *)rec) + rec->size) <= (((char *)head) + sizeof(*head) + head->table_bytes)); \
|
||||||
|
rec = (struct lb_record *)(((char *)rec) + rec->size))
|
||||||
|
|
||||||
|
|
||||||
|
static int count_lb_records(struct lb_header *head)
|
||||||
|
{
|
||||||
|
struct lb_record *rec;
|
||||||
|
int count;
|
||||||
|
count = 0;
|
||||||
|
for_each_lbrec(head, rec) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct lb_header *find_lb_table(void *base, unsigned long start, unsigned long end)
|
||||||
|
{
|
||||||
|
unsigned long addr;
|
||||||
|
/* For now be stupid.... */
|
||||||
|
for(addr = start; addr < end; addr += 16) {
|
||||||
|
struct lb_header *head = (struct lb_header *)(((char*)base) + addr);
|
||||||
|
struct lb_record *recs = (struct lb_record *)(((char*)base) + addr + sizeof(*head));
|
||||||
|
if (memcmp(head->signature, "LBIO", 4) != 0)
|
||||||
|
continue;
|
||||||
|
printf_debug( "Found canidate at: %08lx-%08lx\n",
|
||||||
|
addr, addr + head->table_bytes);
|
||||||
|
if (head->header_bytes != sizeof(*head)) {
|
||||||
|
fprintf(stderr, "Header bytes of %d are incorrect\n",
|
||||||
|
head->header_bytes);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (count_lb_records(head) != head->table_entries) {
|
||||||
|
fprintf(stderr, "bad record count: %d\n",
|
||||||
|
head->table_entries);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (compute_checksum((uint8_t *)head, sizeof(*head)) != 0) {
|
||||||
|
fprintf(stderr, "bad header checksum\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (compute_checksum(recs, head->table_bytes)
|
||||||
|
!= head->table_checksum) {
|
||||||
|
fprintf(stderr, "bad table checksum: %04x\n",
|
||||||
|
head->table_checksum);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
fprintf(stdout, "Found LinuxBIOS table at: %08lx\n", addr);
|
||||||
|
return head;
|
||||||
|
|
||||||
|
};
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void find_mainboard(struct lb_record *ptr, unsigned long addr)
|
||||||
|
{
|
||||||
|
struct lb_mainboard *rec;
|
||||||
|
int max_size;
|
||||||
|
char vendor[256], part[256];
|
||||||
|
rec = (struct lb_mainboard *)ptr;
|
||||||
|
max_size = rec->size - sizeof(*rec);
|
||||||
|
printf("vendor id: %.*s part id: %.*s\n",
|
||||||
|
max_size - rec->vendor_idx,
|
||||||
|
rec->strings + rec->vendor_idx,
|
||||||
|
max_size - rec->part_number_idx,
|
||||||
|
rec->strings + rec->part_number_idx);
|
||||||
|
snprintf(vendor, 255, "%.*s", max_size - rec->vendor_idx,
|
||||||
|
rec->strings + rec->vendor_idx);
|
||||||
|
snprintf(part, 255, "%.*s", max_size - rec->part_number_idx,
|
||||||
|
rec->strings + rec->part_number_idx);
|
||||||
|
|
||||||
|
if(lb_part) {
|
||||||
|
printf("overwritten by command line, vendor id: %s part id: %s\n",
|
||||||
|
lb_vendor, lb_part);
|
||||||
|
} else {
|
||||||
|
lb_part=strdup(part);
|
||||||
|
lb_vendor=strdup(vendor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct lb_record *next_record(struct lb_record *rec)
|
||||||
|
{
|
||||||
|
return (struct lb_record *)(((char *)rec) + rec->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void search_lb_records(struct lb_record *rec, struct lb_record *last,
|
||||||
|
unsigned long addr)
|
||||||
|
{
|
||||||
|
struct lb_record *next;
|
||||||
|
int count;
|
||||||
|
count = 0;
|
||||||
|
|
||||||
|
for(next = next_record(rec); (rec < last) && (next <= last);
|
||||||
|
rec = next, addr += rec->size) {
|
||||||
|
next = next_record(rec);
|
||||||
|
count++;
|
||||||
|
if(rec->tag == LB_TAG_MAINBOARD) {
|
||||||
|
find_mainboard(rec,addr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int linuxbios_init(void)
|
||||||
|
{
|
||||||
|
uint8_t *low_1MB;
|
||||||
|
struct lb_header *lb_table;
|
||||||
|
struct lb_record *rec, *last;
|
||||||
|
|
||||||
|
int fd;
|
||||||
|
fd = open("/dev/mem", O_RDONLY);
|
||||||
|
if (fd < 0) {
|
||||||
|
fprintf(stderr, "Can not open /dev/mem\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
low_1MB = mmap(0, 1024*1024, PROT_READ, MAP_SHARED, fd, 0x00000000);
|
||||||
|
if (low_1MB == ((void *) -1)) {
|
||||||
|
fprintf(stderr, "Can not mmap /dev/mem at %08lx errno(%d):%s\n",
|
||||||
|
0x00000000UL, errno, strerror(errno));
|
||||||
|
exit(-2);
|
||||||
|
}
|
||||||
|
lb_table = 0;
|
||||||
|
if (!lb_table)
|
||||||
|
lb_table = find_lb_table(low_1MB, 0x00000, 0x1000);
|
||||||
|
if (!lb_table)
|
||||||
|
lb_table = find_lb_table(low_1MB, 0xf0000, 1024*1024);
|
||||||
|
if (lb_table) {
|
||||||
|
unsigned long addr;
|
||||||
|
addr = ((char *)lb_table) - ((char *)low_1MB);
|
||||||
|
printf_debug("lb_table found at address %p\n", lb_table);
|
||||||
|
rec = (struct lb_record *)(((char *)lb_table) + lb_table->header_bytes);
|
||||||
|
last = (struct lb_record *)(((char *)rec) + lb_table->table_bytes);
|
||||||
|
printf_debug("LinuxBIOS header(%d) checksum: %04x table(%d) checksum: %04x entries: %d\n",
|
||||||
|
lb_table->header_bytes, lb_table->header_checksum,
|
||||||
|
lb_table->table_bytes, lb_table->table_checksum, lb_table->table_entries);
|
||||||
|
search_lb_records(rec, last, addr + lb_table->header_bytes);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("No LinuxBIOS table found.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef __LBTABLE_H__
|
||||||
|
#define __LBTABLE_H__ 1
|
||||||
|
|
||||||
|
int linuxbios_init(void);
|
||||||
|
|
||||||
|
extern char *lb_part, *lb_vendor;
|
||||||
|
|
||||||
|
#endif
|
|
@ -26,28 +26,29 @@
|
||||||
|
|
||||||
#include "flash.h"
|
#include "flash.h"
|
||||||
#include "m29f400bt.h"
|
#include "m29f400bt.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
int probe_m29f400bt(struct flashchip *flash)
|
int probe_m29f400bt(struct flashchip *flash)
|
||||||
{
|
{
|
||||||
volatile char *bios = flash->virt_addr;
|
volatile uint8_t *bios = flash->virt_addr;
|
||||||
unsigned char id1, id2;
|
uint8_t id1, id2;
|
||||||
|
|
||||||
*(volatile char *) (bios + 0xAAA) = 0xAA;
|
*(volatile uint8_t *) (bios + 0xAAA) = 0xAA;
|
||||||
*(volatile char *) (bios + 0x555) = 0x55;
|
*(volatile uint8_t *) (bios + 0x555) = 0x55;
|
||||||
*(volatile char *) (bios + 0xAAA) = 0x90;
|
*(volatile uint8_t *) (bios + 0xAAA) = 0x90;
|
||||||
|
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
|
|
||||||
id1 = *(volatile unsigned char *) bios;
|
id1 = *(volatile uint8_t *) bios;
|
||||||
id2 = *(volatile unsigned char *) (bios + 0x02);
|
id2 = *(volatile uint8_t *) (bios + 0x02);
|
||||||
|
|
||||||
*(volatile char *) (bios + 0xAAA) = 0xAA;
|
*(volatile uint8_t *) (bios + 0xAAA) = 0xAA;
|
||||||
*(volatile char *) (bios + 0x555) = 0x55;
|
*(volatile uint8_t *) (bios + 0x555) = 0x55;
|
||||||
*(volatile char *) (bios + 0xAAA) = 0xF0;
|
*(volatile uint8_t *) (bios + 0xAAA) = 0xF0;
|
||||||
|
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
|
|
||||||
printf("%s: id1 0x%x, id2 0x%x\n", __FUNCTION__, id1, id2);
|
printf_debug("%s: id1 0x%x, id2 0x%x\n", __FUNCTION__, id1, id2);
|
||||||
|
|
||||||
|
|
||||||
if (id1 == flash->manufacture_id && id2 == flash->model_id)
|
if (id1 == flash->manufacture_id && id2 == flash->model_id)
|
||||||
|
@ -58,15 +59,15 @@ int probe_m29f400bt(struct flashchip *flash)
|
||||||
|
|
||||||
int erase_m29f400bt(struct flashchip *flash)
|
int erase_m29f400bt(struct flashchip *flash)
|
||||||
{
|
{
|
||||||
volatile char *bios = flash->virt_addr;
|
volatile uint8_t *bios = flash->virt_addr;
|
||||||
|
|
||||||
*(volatile char *) (bios + 0xAAA) = 0xAA;
|
*(volatile uint8_t *) (bios + 0xAAA) = 0xAA;
|
||||||
*(volatile char *) (bios + 0x555) = 0x55;
|
*(volatile uint8_t *) (bios + 0x555) = 0x55;
|
||||||
*(volatile char *) (bios + 0xAAA) = 0x80;
|
*(volatile uint8_t *) (bios + 0xAAA) = 0x80;
|
||||||
|
|
||||||
*(volatile char *) (bios + 0xAAA) = 0xAA;
|
*(volatile uint8_t *) (bios + 0xAAA) = 0xAA;
|
||||||
*(volatile char *) (bios + 0x555) = 0x55;
|
*(volatile uint8_t *) (bios + 0x555) = 0x55;
|
||||||
*(volatile char *) (bios + 0xAAA) = 0x10;
|
*(volatile uint8_t *) (bios + 0xAAA) = 0x10;
|
||||||
|
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
toggle_ready_m29f400bt(bios);
|
toggle_ready_m29f400bt(bios);
|
||||||
|
@ -74,16 +75,16 @@ int erase_m29f400bt(struct flashchip *flash)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int block_erase_m29f400bt(volatile char *bios, volatile char *dst)
|
int block_erase_m29f400bt(volatile uint8_t *bios, volatile uint8_t *dst)
|
||||||
{
|
{
|
||||||
|
|
||||||
*(volatile char *) (bios + 0xAAA) = 0xAA;
|
*(volatile uint8_t *) (bios + 0xAAA) = 0xAA;
|
||||||
*(volatile char *) (bios + 0x555) = 0x55;
|
*(volatile uint8_t *) (bios + 0x555) = 0x55;
|
||||||
*(volatile char *) (bios + 0xAAA) = 0x80;
|
*(volatile uint8_t *) (bios + 0xAAA) = 0x80;
|
||||||
|
|
||||||
*(volatile char *) (bios + 0xAAA) = 0xAA;
|
*(volatile uint8_t *) (bios + 0xAAA) = 0xAA;
|
||||||
*(volatile char *) (bios + 0x555) = 0x55;
|
*(volatile uint8_t *) (bios + 0x555) = 0x55;
|
||||||
//*(volatile char *) (bios + 0xAAA) = 0x10;
|
//*(volatile uint8_t *) (bios + 0xAAA) = 0x10;
|
||||||
*dst = 0x30;
|
*dst = 0x30;
|
||||||
|
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
|
@ -92,12 +93,12 @@ int block_erase_m29f400bt(volatile char *bios, volatile char *dst)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int write_m29f400bt(struct flashchip *flash, unsigned char *buf)
|
int write_m29f400bt(struct flashchip *flash, uint8_t *buf)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int total_size = flash->total_size * 1024, page_size =
|
int total_size = flash->total_size * 1024, page_size =
|
||||||
flash->page_size;
|
flash->page_size;
|
||||||
volatile char *bios = flash->virt_addr;
|
volatile uint8_t *bios = flash->virt_addr;
|
||||||
|
|
||||||
//erase_m29f400bt (flash);
|
//erase_m29f400bt (flash);
|
||||||
printf("Programming Page:\n ");
|
printf("Programming Page:\n ");
|
||||||
|
@ -152,9 +153,9 @@ int write_m29f400bt(struct flashchip *flash, unsigned char *buf)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int write_linuxbios_m29f400bt(struct flashchip *flash, unsigned char *buf)
|
int write_linuxbios_m29f400bt(struct flashchip *flash, uint8_t *buf)
|
||||||
{
|
{
|
||||||
volatile char *bios = flash->virt_addr;
|
volatile uint8_t *bios = flash->virt_addr;
|
||||||
|
|
||||||
printf("Programming Page:\n ");
|
printf("Programming Page:\n ");
|
||||||
/*********************************
|
/*********************************
|
||||||
|
|
|
@ -5,15 +5,15 @@
|
||||||
|
|
||||||
extern int probe_m29f400bt(struct flashchip *flash);
|
extern int probe_m29f400bt(struct flashchip *flash);
|
||||||
extern int erase_m29f400bt(struct flashchip *flash);
|
extern int erase_m29f400bt(struct flashchip *flash);
|
||||||
extern int block_erase_m29f400bt(volatile char *bios, volatile char *dst);
|
extern int block_erase_m29f400bt(volatile uint8_t *bios, volatile uint8_t *dst);
|
||||||
extern int write_m29f400bt(struct flashchip *flash, unsigned char *buf);
|
extern int write_m29f400bt(struct flashchip *flash, uint8_t *buf);
|
||||||
extern int write_linuxbios_m29f400bt(struct flashchip *flash,
|
extern int write_linuxbios_m29f400bt(struct flashchip *flash,
|
||||||
unsigned char *buf);
|
uint8_t *buf);
|
||||||
|
|
||||||
extern __inline__ void toggle_ready_m29f400bt(volatile char *dst)
|
extern __inline__ void toggle_ready_m29f400bt(volatile uint8_t *dst)
|
||||||
{
|
{
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
char tmp1, tmp2;
|
uint8_t tmp1, tmp2;
|
||||||
|
|
||||||
tmp1 = *dst & 0x40;
|
tmp1 = *dst & 0x40;
|
||||||
|
|
||||||
|
@ -26,11 +26,11 @@ extern __inline__ void toggle_ready_m29f400bt(volatile char *dst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern __inline__ void data_polling_m29f400bt(volatile char *dst,
|
extern __inline__ void data_polling_m29f400bt(volatile uint8_t *dst,
|
||||||
unsigned char data)
|
uint8_t data)
|
||||||
{
|
{
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
char tmp;
|
uint8_t tmp;
|
||||||
|
|
||||||
data &= 0x80;
|
data &= 0x80;
|
||||||
|
|
||||||
|
@ -42,25 +42,25 @@ extern __inline__ void data_polling_m29f400bt(volatile char *dst,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern __inline__ void protect_m29f400bt(volatile char *bios)
|
extern __inline__ void protect_m29f400bt(volatile uint8_t *bios)
|
||||||
{
|
{
|
||||||
*(volatile char *) (bios + 0xAAA) = 0xAA;
|
*(volatile uint8_t *) (bios + 0xAAA) = 0xAA;
|
||||||
*(volatile char *) (bios + 0x555) = 0x55;
|
*(volatile uint8_t *) (bios + 0x555) = 0x55;
|
||||||
*(volatile char *) (bios + 0xAAA) = 0xA0;
|
*(volatile uint8_t *) (bios + 0xAAA) = 0xA0;
|
||||||
|
|
||||||
usleep(200);
|
usleep(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern __inline__ void write_page_m29f400bt(volatile char *bios, char *src,
|
extern __inline__ void write_page_m29f400bt(volatile uint8_t *bios, uint8_t *src,
|
||||||
volatile char *dst,
|
volatile uint8_t *dst,
|
||||||
int page_size)
|
int page_size)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < page_size; i++) {
|
for (i = 0; i < page_size; i++) {
|
||||||
*(volatile char *) (bios + 0xAAA) = 0xAA;
|
*(volatile uint8_t *) (bios + 0xAAA) = 0xAA;
|
||||||
*(volatile char *) (bios + 0x555) = 0x55;
|
*(volatile uint8_t *) (bios + 0x555) = 0x55;
|
||||||
*(volatile char *) (bios + 0xAAA) = 0xA0;
|
*(volatile uint8_t *) (bios + 0xAAA) = 0xA0;
|
||||||
|
|
||||||
/* transfer data from source to destination */
|
/* transfer data from source to destination */
|
||||||
*dst = *src;
|
*dst = *src;
|
||||||
|
@ -69,7 +69,7 @@ extern __inline__ void write_page_m29f400bt(volatile char *bios, char *src,
|
||||||
toggle_ready_m29f400bt(dst);
|
toggle_ready_m29f400bt(dst);
|
||||||
printf
|
printf
|
||||||
("Value in the flash at address %p = %#x, want %#x\n",
|
("Value in the flash at address %p = %#x, want %#x\n",
|
||||||
(char *) (dst - bios), *dst, *src);
|
(uint8_t *) (dst - bios), *dst, *src);
|
||||||
dst++;
|
dst++;
|
||||||
src++;
|
src++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,16 +25,16 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "flash.h"
|
#include "flash.h"
|
||||||
#include "msys_doc.h"
|
#include "msys_doc.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int doc_wait(volatile uint8_t *bios, int timeout);
|
||||||
static int doc_wait(volatile char *bios, int timeout);
|
static uint8_t doc_read_chipid(volatile uint8_t *bios);
|
||||||
static unsigned char doc_read_chipid(volatile char *bios);
|
static uint8_t doc_read_docstatus(volatile uint8_t *bios);
|
||||||
static unsigned char doc_read_docstatus(volatile char *bios);
|
static uint8_t doc_read_cdsncontrol(volatile uint8_t *bios);
|
||||||
static unsigned char doc_read_cdsncontrol(volatile char *bios);
|
static void doc_write_cdsncontrol(volatile uint8_t *bios, uint8_t data);
|
||||||
static void doc_write_cdsncontrol(volatile char *bios, unsigned char data);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,26 +42,26 @@ static void doc_write_cdsncontrol(volatile char *bios, unsigned char data);
|
||||||
|
|
||||||
int probe_md2802(struct flashchip *flash)
|
int probe_md2802(struct flashchip *flash)
|
||||||
{
|
{
|
||||||
volatile char *bios = flash->virt_addr;
|
volatile uint8_t *bios = flash->virt_addr;
|
||||||
unsigned char chipid;
|
uint8_t chipid;
|
||||||
#ifndef MSYSTEMS_DOC_NO_55AA_CHECKING
|
#ifndef MSYSTEMS_DOC_NO_55AA_CHECKING
|
||||||
unsigned char id_0x55, id_0xAA;
|
uint8_t id_0x55, id_0xAA;
|
||||||
#endif /* !MSYSTEMS_DOC_NO_55AA_CHECKING */
|
#endif /* !MSYSTEMS_DOC_NO_55AA_CHECKING */
|
||||||
int i, toggle_a, toggle_b;
|
int i, toggle_a, toggle_b;
|
||||||
|
|
||||||
printf("%s:\n", __FUNCTION__);
|
printf_debug("%s:\n", __FUNCTION__);
|
||||||
printf("%s: *******************************\n", __FUNCTION__);
|
printf_debug("%s: *******************************\n", __FUNCTION__);
|
||||||
printf("%s: * THIS IS A PRE ALPHA VERSION *\n", __FUNCTION__);
|
printf_debug("%s: * THIS IS A PRE ALPHA VERSION *\n", __FUNCTION__);
|
||||||
printf("%s: * IN THE DEVELOPEMENT *********\n", __FUNCTION__);
|
printf_debug("%s: * IN THE DEVELOPEMENT *********\n", __FUNCTION__);
|
||||||
printf("%s: * PROCESS RIGHT NOW. **********\n", __FUNCTION__);
|
printf_debug("%s: * PROCESS RIGHT NOW. **********\n", __FUNCTION__);
|
||||||
printf("%s: *******************************\n", __FUNCTION__);
|
printf_debug("%s: *******************************\n", __FUNCTION__);
|
||||||
printf("%s: * IF YOU ARE NOT A DEVELOPER **\n", __FUNCTION__);
|
printf_debug("%s: * IF YOU ARE NOT A DEVELOPER **\n", __FUNCTION__);
|
||||||
printf("%s: * THEN DO NOT TRY TO READ OR **\n", __FUNCTION__);
|
printf_debug("%s: * THEN DO NOT TRY TO READ OR **\n", __FUNCTION__);
|
||||||
printf("%s: * WRITE TO THIS DEVICE ********\n", __FUNCTION__);
|
printf_debug("%s: * WRITE TO THIS DEVICE ********\n", __FUNCTION__);
|
||||||
printf("%s: *******************************\n", __FUNCTION__);
|
printf_debug("%s: *******************************\n", __FUNCTION__);
|
||||||
printf("%s:\n", __FUNCTION__);
|
printf_debug("%s:\n", __FUNCTION__);
|
||||||
|
|
||||||
printf("%s: switching off reset mode ...\n", __FUNCTION__);
|
printf_debug("%s: switching off reset mode ...\n", __FUNCTION__);
|
||||||
doc_write(0x85, bios, DOCControl);
|
doc_write(0x85, bios, DOCControl);
|
||||||
doc_write(0x85, bios, DOCControl);
|
doc_write(0x85, bios, DOCControl);
|
||||||
doc_read_4nop(bios);
|
doc_read_4nop(bios);
|
||||||
|
@ -128,7 +128,7 @@ int probe_md2802(struct flashchip *flash)
|
||||||
printf("%s:", __FUNCTION__);
|
printf("%s:", __FUNCTION__);
|
||||||
toggle_a = toggle_b = 0;
|
toggle_a = toggle_b = 0;
|
||||||
for (i = 0; i < 10; i++) {
|
for (i = 0; i < 10; i++) {
|
||||||
unsigned char toggle = doc_toggle(bios);
|
uint8_t toggle = doc_toggle(bios);
|
||||||
|
|
||||||
printf(" 0x%02x", toggle);
|
printf(" 0x%02x", toggle);
|
||||||
|
|
||||||
|
@ -155,40 +155,40 @@ int probe_md2802(struct flashchip *flash)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int read_md2802(struct flashchip *flash, unsigned char *buf)
|
int read_md2802(struct flashchip *flash, uint8_t *buf)
|
||||||
{
|
{
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
} /* int read_md2802(struct flashchip *flash, unsigned char *buf) */
|
} /* int read_md2802(struct flashchip *flash, uint8_t *buf) */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int erase_md2802(struct flashchip *flash)
|
int erase_md2802(struct flashchip *flash)
|
||||||
{
|
{
|
||||||
volatile char *bios = flash->virt_addr;
|
volatile uint8_t *bios = flash->virt_addr;
|
||||||
|
|
||||||
return (1);
|
return (1);
|
||||||
*(volatile char *) (bios + 0x5555) = 0xAA;
|
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
|
||||||
*(volatile char *) (bios + 0x2AAA) = 0x55;
|
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
|
||||||
*(volatile char *) (bios + 0x5555) = 0x80;
|
*(volatile uint8_t *) (bios + 0x5555) = 0x80;
|
||||||
|
|
||||||
*(volatile char *) (bios + 0x5555) = 0xAA;
|
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
|
||||||
*(volatile char *) (bios + 0x2AAA) = 0x55;
|
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
|
||||||
*(volatile char *) (bios + 0x5555) = 0x10;
|
*(volatile uint8_t *) (bios + 0x5555) = 0x10;
|
||||||
} /* int erase_md2802(struct flashchip *flash) */
|
} /* int erase_md2802(struct flashchip *flash) */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int write_md2802(struct flashchip *flash, unsigned char *buf)
|
int write_md2802(struct flashchip *flash, uint8_t *buf)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int total_size = flash->total_size * 1024, page_size =
|
int total_size = flash->total_size * 1024, page_size =
|
||||||
flash->page_size;
|
flash->page_size;
|
||||||
volatile unsigned char *bios = flash->virt_addr;
|
volatile uint8_t *bios = flash->virt_addr;
|
||||||
|
|
||||||
return (1);
|
return (1);
|
||||||
erase_md2802(flash);
|
erase_md2802(flash);
|
||||||
if (*bios != (unsigned char) 0xff) {
|
if (*bios != (uint8_t) 0xff) {
|
||||||
printf("ERASE FAILED\n");
|
printf("ERASE FAILED\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -203,7 +203,7 @@ int write_md2802(struct flashchip *flash, unsigned char *buf)
|
||||||
//protect_md2802(bios);
|
//protect_md2802(bios);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
} /* int write_md2802(struct flashchip *flash, char *buf) */
|
} /* int write_md2802(struct flashchip *flash, uint8_t *buf) */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ int write_md2802(struct flashchip *flash, unsigned char *buf)
|
||||||
0: ready
|
0: ready
|
||||||
-1: timeout expired
|
-1: timeout expired
|
||||||
*/
|
*/
|
||||||
static int doc_wait(volatile char *bios, int timeout)
|
static int doc_wait(volatile uint8_t *bios, int timeout)
|
||||||
{
|
{
|
||||||
int i = 20;
|
int i = 20;
|
||||||
|
|
||||||
|
@ -235,33 +235,33 @@ static int doc_wait(volatile char *bios, int timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
} /* static int doc_wait(volatile char *bios, int timeout) */
|
} /* static int doc_wait(volatile uint8_t *bios, int timeout) */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned char doc_read_docstatus(volatile char *bios)
|
static uint8_t doc_read_docstatus(volatile uint8_t *bios)
|
||||||
{
|
{
|
||||||
doc_read(bios, CDSNSlowIO);
|
doc_read(bios, CDSNSlowIO);
|
||||||
doc_read_2nop(bios);
|
doc_read_2nop(bios);
|
||||||
|
|
||||||
return (doc_read(bios, _DOCStatus));
|
return (doc_read(bios, _DOCStatus));
|
||||||
} /* static unsigned char doc_read_docstatus(volatile char *bios) */
|
} /* static uint8_t doc_read_docstatus(volatile uint8_t *bios) */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned char doc_read_chipid(volatile char *bios)
|
static uint8_t doc_read_chipid(volatile uint8_t *bios)
|
||||||
{
|
{
|
||||||
doc_read(bios, CDSNSlowIO);
|
doc_read(bios, CDSNSlowIO);
|
||||||
doc_read_2nop(bios);
|
doc_read_2nop(bios);
|
||||||
|
|
||||||
return (doc_read(bios, _ChipID));
|
return (doc_read(bios, _ChipID));
|
||||||
} /* static unsigned char doc_read_chipid(volatile char *bios) */
|
} /* static uint8_t doc_read_chipid(volatile uint8_t *bios) */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned char doc_read_cdsncontrol(volatile char *bios)
|
static uint8_t doc_read_cdsncontrol(volatile uint8_t *bios)
|
||||||
{
|
{
|
||||||
unsigned char value;
|
uint8_t value;
|
||||||
|
|
||||||
/* the delays might be necessary when reading the busy bit,
|
/* the delays might be necessary when reading the busy bit,
|
||||||
but because a read to this reg reads the busy bit
|
but because a read to this reg reads the busy bit
|
||||||
|
@ -271,12 +271,12 @@ static unsigned char doc_read_cdsncontrol(volatile char *bios)
|
||||||
doc_read_2nop(bios);
|
doc_read_2nop(bios);
|
||||||
|
|
||||||
return (value);
|
return (value);
|
||||||
} /* static unsigned char doc_read_chipid(volatile char *bios) */
|
} /* static uint8_t doc_read_chipid(volatile char *bios) */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void doc_write_cdsncontrol(volatile char *bios, unsigned char data)
|
static void doc_write_cdsncontrol(volatile uint8_t *bios, uint8_t data)
|
||||||
{
|
{
|
||||||
doc_write(data, bios, _CDSNControl);
|
doc_write(data, bios, _CDSNControl);
|
||||||
doc_read_4nop(bios);
|
doc_read_4nop(bios);
|
||||||
} /* static void doc_write_chipid(volatile char *bios, unsigned char data) */
|
} /* static void doc_write_chipid(volatile char *bios, uint8_t data) */
|
||||||
|
|
|
@ -69,7 +69,7 @@
|
||||||
|
|
||||||
|
|
||||||
#define doc_read(base,reg) \
|
#define doc_read(base,reg) \
|
||||||
(*(volatile unsigned char *)(base + MSYSTEMS_DOC_R_##reg))
|
(*(volatile uint8_t *)(base + MSYSTEMS_DOC_R_##reg))
|
||||||
|
|
||||||
#define doc_read_nop(base) \
|
#define doc_read_nop(base) \
|
||||||
doc_read(base, NOP)
|
doc_read(base, NOP)
|
||||||
|
@ -81,7 +81,7 @@
|
||||||
{ doc_read_2nop(base); doc_read_2nop(base); }
|
{ doc_read_2nop(base); doc_read_2nop(base); }
|
||||||
|
|
||||||
#define doc_write(data,base,reg) \
|
#define doc_write(data,base,reg) \
|
||||||
(*(volatile unsigned char *)(base + MSYSTEMS_DOC_W_##reg)) = data
|
(*(volatile uint8_t *)(base + MSYSTEMS_DOC_W_##reg)) = data
|
||||||
|
|
||||||
#define doc_write_nop(base) \
|
#define doc_write_nop(base) \
|
||||||
doc_write(0, base, NOP)
|
doc_write(0, base, NOP)
|
||||||
|
@ -101,9 +101,9 @@
|
||||||
|
|
||||||
|
|
||||||
extern int probe_md2802(struct flashchip *flash);
|
extern int probe_md2802(struct flashchip *flash);
|
||||||
extern int read_md2802(struct flashchip *flash, unsigned char *buf);
|
extern int read_md2802(struct flashchip *flash, uint8_t *buf);
|
||||||
extern int erase_md2802(struct flashchip *flash);
|
extern int erase_md2802(struct flashchip *flash);
|
||||||
extern int write_md2802(struct flashchip *flash, unsigned char *buf);
|
extern int write_md2802(struct flashchip *flash, uint8_t *buf);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,27 +26,29 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include "flash.h"
|
#include "flash.h"
|
||||||
#include "jedec.h"
|
#include "jedec.h"
|
||||||
#include "mx29f002.h"
|
#include "mx29f002.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
int probe_29f002(struct flashchip *flash)
|
int probe_29f002(struct flashchip *flash)
|
||||||
{
|
{
|
||||||
volatile char *bios = flash->virt_addr;
|
volatile uint8_t *bios = flash->virt_addr;
|
||||||
unsigned char id1, id2;
|
uint8_t id1, id2;
|
||||||
|
|
||||||
*(bios + 0x5555) = 0xAA;
|
*(bios + 0x5555) = 0xAA;
|
||||||
*(bios + 0x2AAA) = 0x55;
|
*(bios + 0x2AAA) = 0x55;
|
||||||
*(bios + 0x5555) = 0x90;
|
*(bios + 0x5555) = 0x90;
|
||||||
|
|
||||||
id1 = *(volatile unsigned char *) bios;
|
id1 = *(volatile uint8_t *) bios;
|
||||||
id2 = *(volatile unsigned char *) (bios + 0x01);
|
id2 = *(volatile uint8_t *) (bios + 0x01);
|
||||||
|
|
||||||
*bios = 0xF0;
|
*bios = 0xF0;
|
||||||
|
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
|
|
||||||
printf("%s: id1 0x%x, id2 0x%x\n", __FUNCTION__, id1, id2);
|
printf_debug("%s: id1 0x%x, id2 0x%x\n", __FUNCTION__, id1, id2);
|
||||||
if (id1 == flash->manufacture_id && id2 == flash->model_id)
|
if (id1 == flash->manufacture_id && id2 == flash->model_id)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
@ -55,7 +57,7 @@ int probe_29f002(struct flashchip *flash)
|
||||||
|
|
||||||
int erase_29f002(struct flashchip *flash)
|
int erase_29f002(struct flashchip *flash)
|
||||||
{
|
{
|
||||||
volatile char *bios = flash->virt_addr;
|
volatile uint8_t *bios = flash->virt_addr;
|
||||||
|
|
||||||
*(bios + 0x555) = 0xF0;
|
*(bios + 0x555) = 0xF0;
|
||||||
*(bios + 0x555) = 0xAA;
|
*(bios + 0x555) = 0xAA;
|
||||||
|
@ -84,12 +86,12 @@ int erase_29f002(struct flashchip *flash)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int write_29f002(struct flashchip *flash, unsigned char *buf)
|
int write_29f002(struct flashchip *flash, uint8_t *buf)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int total_size = flash->total_size * 1024;
|
int total_size = flash->total_size * 1024;
|
||||||
volatile char *bios = flash->virt_addr;
|
volatile uint8_t *bios = flash->virt_addr;
|
||||||
volatile char *dst = bios;
|
volatile uint8_t *dst = bios;
|
||||||
|
|
||||||
*bios = 0xF0;
|
*bios = 0xF0;
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
|
|
|
@ -3,6 +3,6 @@
|
||||||
|
|
||||||
extern int probe_29f002(struct flashchip *flash);
|
extern int probe_29f002(struct flashchip *flash);
|
||||||
extern int erase_29f002(struct flashchip *flash);
|
extern int erase_29f002(struct flashchip *flash);
|
||||||
extern int write_29f002(struct flashchip *flash, unsigned char *buf);
|
extern int write_29f002(struct flashchip *flash, uint8_t *buf);
|
||||||
|
|
||||||
#endif /* !__MX29F002_H__ */
|
#endif /* !__MX29F002_H__ */
|
||||||
|
|
|
@ -29,12 +29,12 @@
|
||||||
|
|
||||||
extern int exclude_start_page, exclude_end_page;
|
extern int exclude_start_page, exclude_end_page;
|
||||||
|
|
||||||
int write_49fl004(struct flashchip *flash, unsigned char *buf)
|
int write_49fl004(struct flashchip *flash, uint8_t *buf)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int total_size = flash->total_size * 1024, page_size =
|
int total_size = flash->total_size * 1024, page_size =
|
||||||
flash->page_size;
|
flash->page_size;
|
||||||
volatile char *bios = flash->virt_addr;
|
volatile uint8_t *bios = flash->virt_addr;
|
||||||
|
|
||||||
printf("Programming Page: ");
|
printf("Programming Page: ");
|
||||||
for (i = 0; i < total_size / page_size; i++) {
|
for (i = 0; i < total_size / page_size; i++) {
|
||||||
|
|
|
@ -3,6 +3,6 @@
|
||||||
|
|
||||||
extern int probe_49fl004(struct flashchip *flash);
|
extern int probe_49fl004(struct flashchip *flash);
|
||||||
extern int erase_49fl004(struct flashchip *flash);
|
extern int erase_49fl004(struct flashchip *flash);
|
||||||
extern int write_49fl004(struct flashchip *flash, unsigned char *buf);
|
extern int write_49fl004(struct flashchip *flash, uint8_t *buf);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
00000000:00008fff gfxrom
|
||||||
|
00009000:0003ffff normal
|
||||||
|
00040000:0007ffff fallback
|
|
@ -3,6 +3,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Copyright 2000 Silicon Integrated System Corporation
|
* Copyright 2000 Silicon Integrated System Corporation
|
||||||
|
* Copyright 2005 coresystems GmbH <stepan@openbios.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -22,12 +23,13 @@
|
||||||
* Reference:
|
* Reference:
|
||||||
* 4 MEgabit (512K x 8) SuperFlash EEPROM, SST28SF040 data sheet
|
* 4 MEgabit (512K x 8) SuperFlash EEPROM, SST28SF040 data sheet
|
||||||
*
|
*
|
||||||
* $Id$
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include "flash.h"
|
#include "flash.h"
|
||||||
#include "jedec.h"
|
#include "jedec.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
#define AUTO_PG_ERASE1 0x20
|
#define AUTO_PG_ERASE1 0x20
|
||||||
#define AUTO_PG_ERASE2 0xD0
|
#define AUTO_PG_ERASE2 0xD0
|
||||||
|
@ -36,35 +38,35 @@
|
||||||
#define RESET 0xFF
|
#define RESET 0xFF
|
||||||
#define READ_ID 0x90
|
#define READ_ID 0x90
|
||||||
|
|
||||||
static __inline__ void protect_28sf040(volatile char *bios)
|
static __inline__ void protect_28sf040(volatile uint8_t *bios)
|
||||||
{
|
{
|
||||||
/* ask compiler not to optimize this */
|
/* ask compiler not to optimize this */
|
||||||
volatile unsigned char tmp;
|
volatile uint8_t tmp;
|
||||||
|
|
||||||
tmp = *(volatile unsigned char *) (bios + 0x1823);
|
tmp = *(volatile uint8_t *) (bios + 0x1823);
|
||||||
tmp = *(volatile unsigned char *) (bios + 0x1820);
|
tmp = *(volatile uint8_t *) (bios + 0x1820);
|
||||||
tmp = *(volatile unsigned char *) (bios + 0x1822);
|
tmp = *(volatile uint8_t *) (bios + 0x1822);
|
||||||
tmp = *(volatile unsigned char *) (bios + 0x0418);
|
tmp = *(volatile uint8_t *) (bios + 0x0418);
|
||||||
tmp = *(volatile unsigned char *) (bios + 0x041B);
|
tmp = *(volatile uint8_t *) (bios + 0x041B);
|
||||||
tmp = *(volatile unsigned char *) (bios + 0x0419);
|
tmp = *(volatile uint8_t *) (bios + 0x0419);
|
||||||
tmp = *(volatile unsigned char *) (bios + 0x040A);
|
tmp = *(volatile uint8_t *) (bios + 0x040A);
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline__ void unprotect_28sf040(volatile char *bios)
|
static __inline__ void unprotect_28sf040(volatile uint8_t *bios)
|
||||||
{
|
{
|
||||||
/* ask compiler not to optimize this */
|
/* ask compiler not to optimize this */
|
||||||
volatile unsigned char tmp;
|
volatile uint8_t tmp;
|
||||||
|
|
||||||
tmp = *(volatile unsigned char *) (bios + 0x1823);
|
tmp = *(volatile uint8_t *) (bios + 0x1823);
|
||||||
tmp = *(volatile unsigned char *) (bios + 0x1820);
|
tmp = *(volatile uint8_t *) (bios + 0x1820);
|
||||||
tmp = *(volatile unsigned char *) (bios + 0x1822);
|
tmp = *(volatile uint8_t *) (bios + 0x1822);
|
||||||
tmp = *(volatile unsigned char *) (bios + 0x0418);
|
tmp = *(volatile uint8_t *) (bios + 0x0418);
|
||||||
tmp = *(volatile unsigned char *) (bios + 0x041B);
|
tmp = *(volatile uint8_t *) (bios + 0x041B);
|
||||||
tmp = *(volatile unsigned char *) (bios + 0x0419);
|
tmp = *(volatile uint8_t *) (bios + 0x0419);
|
||||||
tmp = *(volatile unsigned char *) (bios + 0x041A);
|
tmp = *(volatile uint8_t *) (bios + 0x041A);
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline__ int erase_sector_28sf040(volatile char *bios,
|
static __inline__ int erase_sector_28sf040(volatile uint8_t *bios,
|
||||||
unsigned long address)
|
unsigned long address)
|
||||||
{
|
{
|
||||||
*bios = AUTO_PG_ERASE1;
|
*bios = AUTO_PG_ERASE1;
|
||||||
|
@ -76,9 +78,9 @@ static __inline__ int erase_sector_28sf040(volatile char *bios,
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline__ int write_sector_28sf040(volatile char *bios,
|
static __inline__ int write_sector_28sf040(volatile uint8_t *bios,
|
||||||
unsigned char *src,
|
uint8_t *src,
|
||||||
volatile unsigned char *dst,
|
volatile uint8_t *dst,
|
||||||
unsigned int page_size)
|
unsigned int page_size)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -103,8 +105,8 @@ static __inline__ int write_sector_28sf040(volatile char *bios,
|
||||||
|
|
||||||
int probe_28sf040(struct flashchip *flash)
|
int probe_28sf040(struct flashchip *flash)
|
||||||
{
|
{
|
||||||
volatile char *bios = flash->virt_addr;
|
volatile uint8_t *bios = flash->virt_addr;
|
||||||
unsigned char id1, id2, tmp;
|
uint8_t id1, id2, tmp;
|
||||||
|
|
||||||
/* save the value at the beginning of the Flash */
|
/* save the value at the beginning of the Flash */
|
||||||
tmp = *bios;
|
tmp = *bios;
|
||||||
|
@ -114,14 +116,14 @@ int probe_28sf040(struct flashchip *flash)
|
||||||
|
|
||||||
*bios = READ_ID;
|
*bios = READ_ID;
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
id1 = *(volatile unsigned char *) bios;
|
id1 = *(volatile uint8_t *) bios;
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
id2 = *(volatile unsigned char *) (bios + 0x01);
|
id2 = *(volatile uint8_t *) (bios + 0x01);
|
||||||
|
|
||||||
*bios = RESET;
|
*bios = RESET;
|
||||||
myusec_delay(10);
|
myusec_delay(10);
|
||||||
|
|
||||||
printf("%s: id1 0x%x, id2 0x%x\n", __FUNCTION__, id1, id2);
|
printf_debug("%s: id1 0x%x, id2 0x%x\n", __FUNCTION__, id1, id2);
|
||||||
if (id1 == flash->manufacture_id && id2 == flash->model_id)
|
if (id1 == flash->manufacture_id && id2 == flash->model_id)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
@ -132,7 +134,7 @@ int probe_28sf040(struct flashchip *flash)
|
||||||
|
|
||||||
int erase_28sf040(struct flashchip *flash)
|
int erase_28sf040(struct flashchip *flash)
|
||||||
{
|
{
|
||||||
volatile char *bios = flash->virt_addr;
|
volatile uint8_t *bios = flash->virt_addr;
|
||||||
|
|
||||||
unprotect_28sf040(bios);
|
unprotect_28sf040(bios);
|
||||||
*bios = CHIP_ERASE;
|
*bios = CHIP_ERASE;
|
||||||
|
@ -145,12 +147,12 @@ int erase_28sf040(struct flashchip *flash)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int write_28sf040(struct flashchip *flash, unsigned char *buf)
|
int write_28sf040(struct flashchip *flash, uint8_t *buf)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int total_size = flash->total_size * 1024, page_size =
|
int total_size = flash->total_size * 1024, page_size =
|
||||||
flash->page_size;
|
flash->page_size;
|
||||||
volatile char *bios = flash->virt_addr;
|
volatile uint8_t *bios = flash->virt_addr;
|
||||||
|
|
||||||
unprotect_28sf040(bios);
|
unprotect_28sf040(bios);
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,6 @@
|
||||||
|
|
||||||
extern int probe_28sf040(struct flashchip *flash);
|
extern int probe_28sf040(struct flashchip *flash);
|
||||||
extern int erase_28sf040(struct flashchip *flash);
|
extern int erase_28sf040(struct flashchip *flash);
|
||||||
extern int write_28sf040(struct flashchip *flash, unsigned char *buf);
|
extern int write_28sf040(struct flashchip *flash, uint8_t *buf);
|
||||||
|
|
||||||
#endif /* !__SST28SF040_H__ */
|
#endif /* !__SST28SF040_H__ */
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include "flash.h"
|
#include "flash.h"
|
||||||
#include "jedec.h"
|
#include "jedec.h"
|
||||||
#include "sst39sf020.h"
|
#include "sst39sf020.h"
|
||||||
|
@ -35,7 +36,7 @@
|
||||||
#define AUTO_PG_ERASE1 0x20
|
#define AUTO_PG_ERASE1 0x20
|
||||||
#define AUTO_PG_ERASE2 0xD0
|
#define AUTO_PG_ERASE2 0xD0
|
||||||
|
|
||||||
static __inline__ int erase_sector_39sf020(volatile char *bios,
|
static __inline__ int erase_sector_39sf020(volatile uint8_t *bios,
|
||||||
unsigned long address)
|
unsigned long address)
|
||||||
{
|
{
|
||||||
*bios = AUTO_PG_ERASE1;
|
*bios = AUTO_PG_ERASE1;
|
||||||
|
@ -47,12 +48,12 @@ static __inline__ int erase_sector_39sf020(volatile char *bios,
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int write_39sf020(struct flashchip *flash, unsigned char *buf)
|
int write_39sf020(struct flashchip *flash, uint8_t *buf)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int total_size = flash->total_size * 1024, page_size =
|
int total_size = flash->total_size * 1024, page_size =
|
||||||
flash->page_size;
|
flash->page_size;
|
||||||
volatile char *bios = flash->virt_addr;
|
volatile uint8_t *bios = flash->virt_addr;
|
||||||
|
|
||||||
erase_chip_jedec(flash);
|
erase_chip_jedec(flash);
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,6 @@
|
||||||
#define __SST39SF020_H__ 1
|
#define __SST39SF020_H__ 1
|
||||||
|
|
||||||
extern int probe_39sf020(struct flashchip *flash);
|
extern int probe_39sf020(struct flashchip *flash);
|
||||||
extern int write_39sf020(struct flashchip *flash, unsigned char *buf);
|
extern int write_39sf020(struct flashchip *flash, uint8_t *buf);
|
||||||
|
|
||||||
#endif /* !__SST39SF020_H__ */
|
#endif /* !__SST39SF020_H__ */
|
||||||
|
|
|
@ -35,7 +35,7 @@ int erase_49lf040(struct flashchip *flash)
|
||||||
int i;
|
int i;
|
||||||
int total_size = flash->total_size * 1024;
|
int total_size = flash->total_size * 1024;
|
||||||
int page_size = flash->page_size;
|
int page_size = flash->page_size;
|
||||||
volatile char *bios = flash->virt_addr;
|
volatile uint8_t *bios = flash->virt_addr;
|
||||||
|
|
||||||
for (i = 0; i < total_size / page_size; i++) {
|
for (i = 0; i < total_size / page_size; i++) {
|
||||||
/* Chip erase only works in parallel programming mode
|
/* Chip erase only works in parallel programming mode
|
||||||
|
@ -45,12 +45,12 @@ int erase_49lf040(struct flashchip *flash)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int write_49lf040(struct flashchip *flash, unsigned char *buf)
|
int write_49lf040(struct flashchip *flash, uint8_t *buf)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int total_size = flash->total_size * 1024;
|
int total_size = flash->total_size * 1024;
|
||||||
int page_size = flash->page_size;
|
int page_size = flash->page_size;
|
||||||
volatile char *bios = flash->virt_addr;
|
volatile uint8_t *bios = flash->virt_addr;
|
||||||
|
|
||||||
printf("Programming Page: ");
|
printf("Programming Page: ");
|
||||||
for (i = 0; i < total_size / page_size; i++) {
|
for (i = 0; i < total_size / page_size; i++) {
|
||||||
|
|
|
@ -2,6 +2,6 @@
|
||||||
#define __SST49LF040_H__ 1
|
#define __SST49LF040_H__ 1
|
||||||
|
|
||||||
extern int erase_49lf040(struct flashchip *flash);
|
extern int erase_49lf040(struct flashchip *flash);
|
||||||
extern int write_49lf040(struct flashchip *flash, unsigned char *buf);
|
extern int write_49lf040(struct flashchip *flash, uint8_t *buf);
|
||||||
|
|
||||||
#endif /* !__SST49LF040_H__ */
|
#endif /* !__SST49LF040_H__ */
|
||||||
|
|
|
@ -18,8 +18,6 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -35,7 +33,7 @@
|
||||||
#include "sst_fwhub.h"
|
#include "sst_fwhub.h"
|
||||||
|
|
||||||
// I need that Berkeley bit-map printer
|
// I need that Berkeley bit-map printer
|
||||||
void print_sst_fwhub_status(unsigned char status)
|
void print_sst_fwhub_status(uint8_t status)
|
||||||
{
|
{
|
||||||
printf("%s", status & 0x80 ? "Ready:" : "Busy:");
|
printf("%s", status & 0x80 ? "Ready:" : "Busy:");
|
||||||
printf("%s", status & 0x40 ? "BE SUSPEND:" : "BE RUN/FINISH:");
|
printf("%s", status & 0x40 ? "BE SUSPEND:" : "BE RUN/FINISH:");
|
||||||
|
@ -49,7 +47,7 @@ void print_sst_fwhub_status(unsigned char status)
|
||||||
/* probe_jedec works fine for probing */
|
/* probe_jedec works fine for probing */
|
||||||
int probe_sst_fwhub(struct flashchip *flash)
|
int probe_sst_fwhub(struct flashchip *flash)
|
||||||
{
|
{
|
||||||
volatile unsigned char *bios;
|
volatile uint8_t *bios;
|
||||||
size_t size = flash->total_size * 1024;
|
size_t size = flash->total_size * 1024;
|
||||||
|
|
||||||
if (probe_jedec(flash) == 0)
|
if (probe_jedec(flash) == 0)
|
||||||
|
@ -69,7 +67,7 @@ int probe_sst_fwhub(struct flashchip *flash)
|
||||||
|
|
||||||
int erase_sst_fwhub_block(struct flashchip *flash, int offset)
|
int erase_sst_fwhub_block(struct flashchip *flash, int offset)
|
||||||
{
|
{
|
||||||
volatile unsigned char *wrprotect = flash->virt_addr_2 + offset + 2;
|
volatile uint8_t *wrprotect = flash->virt_addr_2 + offset + 2;
|
||||||
|
|
||||||
// clear write protect
|
// clear write protect
|
||||||
*(wrprotect) = 0;
|
*(wrprotect) = 0;
|
||||||
|
@ -90,14 +88,17 @@ int erase_sst_fwhub(struct flashchip *flash)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int write_sst_fwhub(struct flashchip *flash, unsigned char *buf)
|
int write_sst_fwhub(struct flashchip *flash, uint8_t *buf)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int total_size = flash->total_size * 1024, page_size =
|
int total_size = flash->total_size * 1024, page_size =
|
||||||
flash->page_size;
|
flash->page_size;
|
||||||
volatile unsigned char *bios = flash->virt_addr;
|
volatile uint8_t *bios = flash->virt_addr;
|
||||||
|
|
||||||
|
// Do we want block wide erase?
|
||||||
erase_sst_fwhub(flash);
|
erase_sst_fwhub(flash);
|
||||||
|
|
||||||
|
// FIXME: This test is not sufficient!
|
||||||
if (*bios != 0xff) {
|
if (*bios != 0xff) {
|
||||||
printf("ERASE FAILED\n");
|
printf("ERASE FAILED\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -3,6 +3,6 @@
|
||||||
|
|
||||||
extern int probe_sst_fwhub(struct flashchip *flash);
|
extern int probe_sst_fwhub(struct flashchip *flash);
|
||||||
extern int erase_sst_fwhub(struct flashchip *flash);
|
extern int erase_sst_fwhub(struct flashchip *flash);
|
||||||
extern int write_sst_fwhub(struct flashchip *flash, unsigned char *buf);
|
extern int write_sst_fwhub(struct flashchip *flash, uint8_t *buf);
|
||||||
|
|
||||||
#endif /* !__SST_FWHUB_H__ */
|
#endif /* !__SST_FWHUB_H__ */
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
// count to a billion. Time it. If it's < 1 sec, count to 10B, etc.
|
// count to a billion. Time it. If it's < 1 sec, count to 10B, etc.
|
||||||
unsigned long micro = 1;
|
unsigned long micro = 1;
|
||||||
|
@ -17,7 +18,7 @@ void myusec_calibrate_delay()
|
||||||
struct timeval start, end;
|
struct timeval start, end;
|
||||||
int ok = 0;
|
int ok = 0;
|
||||||
|
|
||||||
printf("Setting up microsecond timing loop\n");
|
printf_debug("Setting up microsecond timing loop\n");
|
||||||
while (!ok) {
|
while (!ok) {
|
||||||
gettimeofday(&start, 0);
|
gettimeofday(&start, 0);
|
||||||
myusec_delay(count);
|
myusec_delay(count);
|
||||||
|
@ -33,5 +34,5 @@ void myusec_calibrate_delay()
|
||||||
// compute one microsecond. That will be count / time
|
// compute one microsecond. That will be count / time
|
||||||
micro = count / timeusec;
|
micro = count / timeusec;
|
||||||
|
|
||||||
fprintf(stderr, "%ldM loops per second\n", (unsigned long) micro);
|
printf_debug("%ldM loops per second\n", (unsigned long) micro);
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,12 +32,12 @@
|
||||||
#include "jedec.h"
|
#include "jedec.h"
|
||||||
#include "w49f002u.h"
|
#include "w49f002u.h"
|
||||||
|
|
||||||
int write_49f002(struct flashchip *flash, unsigned char *buf)
|
int write_49f002(struct flashchip *flash, uint8_t *buf)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int total_size = flash->total_size * 1024, page_size =
|
int total_size = flash->total_size * 1024, page_size =
|
||||||
flash->page_size;
|
flash->page_size;
|
||||||
volatile char *bios = flash->virt_addr;
|
volatile uint8_t *bios = flash->virt_addr;
|
||||||
|
|
||||||
erase_chip_jedec(flash);
|
erase_chip_jedec(flash);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#ifndef __W49F002U_H__
|
#ifndef __W49F002U_H__
|
||||||
#define __W49F002U_H__ 1
|
#define __W49F002U_H__ 1
|
||||||
|
|
||||||
extern int write_49f002(struct flashchip *flash, unsigned char *buf);
|
extern int write_49f002(struct flashchip *flash, uint8_t *buf);
|
||||||
|
|
||||||
#endif /* !__W49F002U_H__ */
|
#endif /* !__W49F002U_H__ */
|
||||||
|
|
Loading…
Reference in New Issue