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:
Li-Ta Lo 2005-11-26 21:55:36 +00:00
parent f622d598db
commit 1a4f0707bb
38 changed files with 1098 additions and 511 deletions

View File

@ -34,9 +34,10 @@
#include "flash.h"
#include "82802ab.h"
#include "debug.h"
// 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 & 0x40 ? "BE SUSPEND:" : "BE RUN/FINISH:");
@ -49,13 +50,13 @@ void print_82802ab_status(unsigned char status)
int probe_82802ab(struct flashchip *flash)
{
volatile unsigned char *bios = flash->virt_addr;
unsigned char id1, id2;
volatile uint8_t *bios = flash->virt_addr;
uint8_t id1, id2;
#if 0
*(volatile unsigned char *) (bios + 0x5555) = 0xAA;
*(volatile unsigned char *) (bios + 0x2AAA) = 0x55;
*(volatile unsigned char *) (bios + 0x5555) = 0x90;
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
*(volatile uint8_t *) (bios + 0x5555) = 0x90;
#endif
*bios = 0xff;
@ -63,18 +64,18 @@ int probe_82802ab(struct flashchip *flash)
*bios = 0x90;
myusec_delay(10);
id1 = *(volatile unsigned char *) bios;
id2 = *(volatile unsigned char *) (bios + 0x01);
id1 = *(volatile uint8_t *) bios;
id2 = *(volatile uint8_t *) (bios + 0x01);
#if 1
*(volatile unsigned char *) (bios + 0x5555) = 0xAA;
*(volatile unsigned char *) (bios + 0x2AAA) = 0x55;
*(volatile unsigned char *) (bios + 0x5555) = 0xF0;
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
*(volatile uint8_t *) (bios + 0x5555) = 0xF0;
#endif
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) {
size_t size = flash->total_size * 1024;
@ -94,11 +95,11 @@ int probe_82802ab(struct flashchip *flash)
return 0;
}
unsigned char wait_82802ab(volatile unsigned char *bios)
uint8_t wait_82802ab(volatile uint8_t *bios)
{
unsigned char status;
unsigned char id1, id2;
uint8_t status;
uint8_t id1, id2;
*bios = 0x70;
if ((*bios & 0x80) == 0) { // it's busy
@ -112,22 +113,22 @@ unsigned char wait_82802ab(volatile unsigned char *bios)
*bios = 0x90;
myusec_delay(10);
id1 = *(volatile unsigned char *) bios;
id2 = *(volatile unsigned char *) (bios + 0x01);
id1 = *(volatile uint8_t *) bios;
id2 = *(volatile uint8_t *) (bios + 0x01);
// this is needed to jam it out of "read id" mode
*(volatile unsigned char *) (bios + 0x5555) = 0xAA;
*(volatile unsigned char *) (bios + 0x2AAA) = 0x55;
*(volatile unsigned char *) (bios + 0x5555) = 0xF0;
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
*(volatile uint8_t *) (bios + 0x5555) = 0xF0;
return status;
}
int erase_82802ab_block(struct flashchip *flash, int offset)
{
volatile unsigned char *bios = flash->virt_addr + offset;
volatile unsigned char *wrprotect =
volatile uint8_t *bios = flash->virt_addr + offset;
volatile uint8_t *wrprotect =
flash->virt_addr_2 + offset + 2;
unsigned char status;
uint8_t status;
// clear status register
*bios = 0x50;
@ -139,8 +140,8 @@ int erase_82802ab_block(struct flashchip *flash, int offset)
//printf("write protect is 0x%x\n", *(wrprotect));
// now start it
*(volatile unsigned char *) (bios) = 0x20;
*(volatile unsigned char *) (bios) = 0xd0;
*(volatile uint8_t *) (bios) = 0x20;
*(volatile uint8_t *) (bios) = 0xd0;
myusec_delay(10);
// now let's see what the register is
status = wait_82802ab(flash->virt_addr);
@ -161,7 +162,7 @@ int erase_82802ab(struct flashchip *flash)
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 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 total_size = flash->total_size * 1024, page_size =
flash->page_size;
volatile unsigned char *bios = flash->virt_addr;
volatile uint8_t *bios = flash->virt_addr;
erase_82802ab(flash);
if (*bios != 0xff) {

View File

@ -3,12 +3,12 @@
extern int probe_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;
char tmp1, tmp2;
uint8_t tmp1, tmp2;
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;
char tmp;
uint8_t tmp;
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 char *) (bios + 0x2AAA) = 0x55;
*(volatile char *) (bios + 0x5555) = 0xA0;
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
*(volatile uint8_t *) (bios + 0x5555) = 0xA0;
usleep(200);
}

View File

@ -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
CC = gcc -O2 -g -Wall -Werror
#
# Makefile for flash_rom
#
# redone by Stefan Reinauer <stepan@openbios.org>
#
all: flash_rom flash_on
PROGRAM = flashrom
flash_rom: flash_rom.o ${OBJS}
${CC} -o flash_rom flash_rom.c ${OBJS} -lpci
CC = gcc
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:
rm -f flash_rom flash_on *.o *~
rm -f *.o *~
flash_rom.o: flash_rom.c flash.h jedec.h \
82802ab.h am29f040b.h m29f400bt.h msys_doc.h mx29f002.h sst28sf040.h \
sst39sf020.h w49f002u.h sst49lf040.h
flash_on.o: flash_on.c
distclean: clean
rm -f $(PROGRAM) .dependencies
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

View File

@ -1,20 +1,69 @@
on the cs5530 southbridge,
This is the universal LinuxBIOS flash utility.
setpci -s 0:12.0 52.b=ee
setpci -x 0:12.0 5b.b= 0x20 (| with whatever is there)
usage: ./flashrom [-rwvE] [-V] [-c chipname]
[-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
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.
LinuxBIOS table and Mainboard identification
--------------------------------------------
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

View File

@ -18,17 +18,17 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
* Reference:
* AMD Am29F040B data sheet
* $Id$
*/
#include <stdio.h>
#include <stdint.h>
#include "flash.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)
{
*(bios + 0x555) = 0xAA;
@ -46,9 +46,9 @@ static __inline__ int erase_sector_29f040b(volatile char *bios,
return (0);
}
static __inline__ int write_sector_29f040b(volatile char *bios,
unsigned char *src,
volatile unsigned char *dst,
static __inline__ int write_sector_29f040b(volatile uint8_t *bios,
uint8_t *src,
volatile uint8_t *dst,
unsigned int page_size)
{
int i;
@ -73,8 +73,8 @@ static __inline__ int write_sector_29f040b(volatile char *bios,
int probe_29f040b(struct flashchip *flash)
{
volatile unsigned char *bios = flash->virt_addr;
unsigned char id1, id2;
volatile uint8_t *bios = flash->virt_addr;
uint8_t id1, id2;
*(bios + 0x555) = 0xAA;
*(bios + 0x2AA) = 0x55;
@ -87,7 +87,7 @@ int probe_29f040b(struct flashchip *flash)
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)
return 1;
@ -96,7 +96,7 @@ int probe_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 + 0x2AA) = 0x55;
@ -111,12 +111,12 @@ int erase_29f040b(struct flashchip *flash)
return (0);
}
int write_29f040b(struct flashchip *flash, unsigned char *buf)
int write_29f040b(struct flashchip *flash, uint8_t *buf)
{
int i;
int total_size = flash->total_size * 1024, page_size =
flash->page_size;
volatile char *bios = flash->virt_addr;
volatile uint8_t *bios = flash->virt_addr;
printf("Programming Page: ");
for (i = 0; i < total_size / page_size; i++) {

View File

@ -3,6 +3,6 @@
extern int probe_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__ */

7
util/flashrom/debug.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef __DEBUG_H__
#define __DEBUG_H__ 1
//#define printf_debug(x...) printf(x)
#define printf_debug(x...) { }
#endif

View File

@ -3,25 +3,28 @@
#include <sys/io.h>
#include <unistd.h>
#include <stdint.h>
struct flashchip {
char *name;
int manufacture_id;
int model_id;
volatile char *virt_addr;
volatile uint8_t *virt_addr;
int total_size;
int page_size;
int (*probe) (struct flashchip * flash);
int (*erase) (struct flashchip * flash);
int (*write) (struct flashchip * flash, unsigned char *buf);
int (*read) (struct flashchip * flash, unsigned char *buf);
int (*write) (struct flashchip * flash, uint8_t *buf);
int (*read) (struct flashchip * flash, uint8_t *buf);
int fd_mem;
volatile char *virt_addr_2;
volatile uint8_t *virt_addr_2;
};
extern struct flashchip flashchips[];
#define AMD_ID 0x01
#define AM_29F040B 0xA4

View File

@ -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 <stdio.h>
#include <pci/pci.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)
{
@ -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)
{
/* 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
* 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)
{
/* 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
* 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)
{
unsigned char old, new, val;
uint8_t old, new, val;
unsigned int base;
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)
{
unsigned char val;
uint8_t val;
val = pci_read_byte(dev, 0x40);
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)
{
unsigned char new;
uint8_t new;
pci_write_byte(dev, 0x52, 0xee);
@ -174,12 +190,17 @@ static int enable_flash_cs5530(struct pci_dev *dev, char *name)
0x52, new, name);
return -1;
}
new = pci_read_byte(dev, 0x5b) | 0x20;
pci_write_byte(dev, 0x5b, new);
return 0;
}
static int enable_flash_sc1100(struct pci_dev *dev, char *name)
{
unsigned char new;
uint8_t new;
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)
{
unsigned char new, newer;
uint8_t new, newer;
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)
{
/* 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
* 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)
{
/* 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
* 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.
};
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 i;
@ -317,6 +401,18 @@ int enable_flash_write()
pci_init(pacc); /* Initialize the PCI library */
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 ... */
for (i = 0; i < sizeof(enables) / sizeof(enables[0]) && (!dev);
i++) {

View File

@ -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);
}

View File

@ -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 2004 Tyan Corp
* 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
* it under the terms of the GNU General Public License as published by
* 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
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
* Reference:
* 1. SiS 630 Specification
* 2. SiS 950 Specification
*
* $Id$
*/
#include <errno.h>
@ -35,75 +31,19 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>
#include "flash.h"
#include "jedec.h"
#include "m29f400bt.h"
#include "82802ab.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,}
};
#include "lbtable.h"
#include "layout.h"
#include "debug.h"
char *chip_to_probe = NULL;
struct flashchip *probe_flash(struct flashchip *flash)
{
int fd_mem;
volatile char *bios;
volatile uint8_t *bios;
unsigned long size;
if ((fd_mem = open("/dev/mem", O_RDWR)) < 0) {
@ -116,7 +56,7 @@ struct flashchip *probe_flash(struct flashchip *flash)
flash++;
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;
/* BUG? what happens if getpagesize() > size!?
-> ``Error MMAP /dev/mem: Invalid argument'' NIKI */
@ -146,11 +86,11 @@ struct flashchip *probe_flash(struct flashchip *flash)
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 total_size = flash->total_size * 1024;
volatile char *bios = flash->virt_addr;
volatile uint8_t *bios = flash->virt_addr;
printf("Verifying address: ");
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)
{
printf("usage: %s [-rwv] [-c chipname] [-s exclude_start] [-e exclude_end] [file]\n", name);
printf("-r: read flash and save into file\n"
"-w: write file into flash (default when file is specified)\n"
"-v: verify flash against file\n"
"-c: probe only for specified flash chip\n"
"-s: exclude start position\n"
"-e: exclude end postion\n"
printf("usage: %s [-rwvE] [-V] [-c chipname] [-s exclude_start] [-e exclude_end] [file]\n", name);
printf(" -r | --read: read flash and save into file\n"
" -w | --write: write file into flash (default when file is specified)\n"
" -v | --verify: verify flash against file\n"
" -E | --erase: Erase flash device\n"
" -V | --verbose: more verbose output\n\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"
" is that flash info is dumped\n");
" is that flash info is dumped\n\n");
exit(1);
}
int exclude_start_page, exclude_end_page;
int force=0;
int main(int argc, char *argv[])
{
char *buf;
uint8_t *buf;
unsigned long size;
FILE *image;
struct flashchip *flash;
int opt;
int read_it = 0, write_it = 0, erase_it = 0, verify_it = 0,
verbose = 0;
int option_index = 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;
unsigned int exclude_start_position=0, exclude_end_position=0; // [x,y)
char *tempstr=NULL;
char *tempstr=NULL, *tempstr2=NULL;
if (argc > 1) {
/* Yes, print them. */
int i;
printf ("The arguments are:\n");
printf_debug ("The arguments are:\n");
for (i = 1; i < argc; ++i)
printf ("%s\n", argv[i]);
printf_debug ("%s\n", argv[i]);
}
setbuf(stdout, NULL);
while ((opt = getopt(argc, argv, "rwvVEc:s:e:")) != EOF) {
while ((opt = getopt_long(argc, argv, "rwvVEfc:s:e:m:l:i:h", long_options,
&option_index)) != EOF) {
switch (opt) {
case 'r':
read_it = 1;
@ -240,7 +210,30 @@ int main(int argc, char *argv[])
tempstr = strdup(optarg);
sscanf(tempstr,"%x",&exclude_end_position);
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:
usage(argv[0]);
break;
@ -255,28 +248,36 @@ int main(int argc, char *argv[])
if (optind < argc)
filename = argv[optind++];
printf("Calibrating timer since microsleep sucks ... takes a second\n");
printf("Calibrating delay loop... ");
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
* really need this to be done, etc., etc. It sucks.
* really need this to be done, etc., etc.
*/
(void) enable_flash_write();
if ((flash = probe_flash(flashchips)) == NULL) {
printf("EEPROM not found\n");
printf("No EEPROM/flash device found.\n");
exit(1);
}
printf("Part is %s\n", flash->name);
printf("Flash part is %s\n", flash->name);
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;
}
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) {
printf("Erasing flash chip\n");
flash->erase(flash);
@ -305,9 +306,18 @@ int main(int argc, char *argv[])
exit(1);
}
fread(buf, sizeof(char), size, image);
show_id(buf, size);
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)
memcpy(buf+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_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);
}
if (verify_it)
verify_flash(flash, buf, verbose);
return 0;
}

View File

@ -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,}
};

View File

@ -25,56 +25,58 @@
*/
#include <stdio.h>
#include <stdint.h>
#include "flash.h"
#include "jedec.h"
#include "debug.h"
int probe_jedec(struct flashchip *flash)
{
volatile unsigned char *bios = flash->virt_addr;
unsigned char id1, id2;
volatile uint8_t *bios = flash->virt_addr;
uint8_t id1, id2;
/* Issue JEDEC Product ID Entry command */
*(volatile char *) (bios + 0x5555) = 0xAA;
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
myusec_delay(10);
*(volatile char *) (bios + 0x2AAA) = 0x55;
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
myusec_delay(10);
*(volatile char *) (bios + 0x5555) = 0x90;
*(volatile uint8_t *) (bios + 0x5555) = 0x90;
myusec_delay(10);
/* Read product ID */
id1 = *(volatile unsigned char *) bios;
id2 = *(volatile unsigned char *) (bios + 0x01);
id1 = *(volatile uint8_t *) bios;
id2 = *(volatile uint8_t *) (bios + 0x01);
/* Issue JEDEC Product ID Exit command */
*(volatile char *) (bios + 0x5555) = 0xAA;
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
myusec_delay(10);
*(volatile char *) (bios + 0x2AAA) = 0x55;
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
myusec_delay(10);
*(volatile char *) (bios + 0x5555) = 0xF0;
*(volatile uint8_t *) (bios + 0x5555) = 0xF0;
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)
return 1;
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 */
*(volatile char *) (bios + 0x5555) = 0xAA;
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
myusec_delay(10);
*(volatile char *) (bios + 0x2AAA) = 0x55;
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
myusec_delay(10);
*(volatile char *) (bios + 0x5555) = 0x80;
*(volatile uint8_t *) (bios + 0x5555) = 0x80;
myusec_delay(10);
*(volatile char *) (bios + 0x5555) = 0xAA;
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
myusec_delay(10);
*(volatile char *) (bios + 0x2AAA) = 0x55;
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
myusec_delay(10);
*(volatile char *) (bios + page) = 0x30;
*(volatile uint8_t *) (bios + page) = 0x30;
myusec_delay(10);
/* wait for Toggle bit ready */
@ -83,21 +85,21 @@ int erase_sector_jedec(volatile unsigned char *bios, unsigned int page)
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 */
*(volatile char *) (bios + 0x5555) = 0xAA;
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
myusec_delay(10);
*(volatile char *) (bios + 0x2AAA) = 0x55;
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
myusec_delay(10);
*(volatile char *) (bios + 0x5555) = 0x80;
*(volatile uint8_t *) (bios + 0x5555) = 0x80;
myusec_delay(10);
*(volatile char *) (bios + 0x5555) = 0xAA;
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
myusec_delay(10);
*(volatile char *) (bios + 0x2AAA) = 0x55;
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
myusec_delay(10);
*(volatile char *) (bios + block) = 0x50;
*(volatile uint8_t *) (bios + block) = 0x50;
myusec_delay(10);
/* 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)
{
volatile unsigned char *bios = flash->virt_addr;
volatile uint8_t *bios = flash->virt_addr;
/* Issue the JEDEC Chip Erase command */
*(volatile char *) (bios + 0x5555) = 0xAA;
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
myusec_delay(10);
*(volatile char *) (bios + 0x2AAA) = 0x55;
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
myusec_delay(10);
*(volatile char *) (bios + 0x5555) = 0x80;
*(volatile uint8_t *) (bios + 0x5555) = 0x80;
myusec_delay(10);
*(volatile char *) (bios + 0x5555) = 0xAA;
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
myusec_delay(10);
*(volatile char *) (bios + 0x2AAA) = 0x55;
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
myusec_delay(10);
*(volatile char *) (bios + 0x5555) = 0x10;
*(volatile uint8_t *) (bios + 0x5555) = 0x10;
myusec_delay(10);
toggle_ready_jedec(bios);
@ -130,15 +132,15 @@ int erase_chip_jedec(struct flashchip *flash)
return (0);
}
int write_page_write_jedec(volatile unsigned char *bios, unsigned char *src,
volatile unsigned char *dst, int page_size)
int write_page_write_jedec(volatile uint8_t *bios, uint8_t *src,
volatile uint8_t *dst, int page_size)
{
int i;
/* Issue JEDEC Data Unprotect comand */
*(volatile unsigned char *) (bios + 0x5555) = 0xAA;
*(volatile unsigned char *) (bios + 0x2AAA) = 0x55;
*(volatile unsigned char *) (bios + 0x5555) = 0xA0;
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
*(volatile uint8_t *) (bios + 0x5555) = 0xA0;
/* transfer data from source to destination */
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;
}
int write_byte_program_jedec(volatile unsigned char *bios, unsigned char *src,
volatile unsigned char *dst)
int write_byte_program_jedec(volatile uint8_t *bios, uint8_t *src,
volatile uint8_t *dst)
{
int tried = 0;
@ -165,9 +167,9 @@ int write_byte_program_jedec(volatile unsigned char *bios, unsigned char *src,
retry:
/* Issue JEDEC Byte Program command */
*(volatile unsigned char *) (bios + 0x5555) = 0xAA;
*(volatile unsigned char *) (bios + 0x2AAA) = 0x55;
*(volatile unsigned char *) (bios + 0x5555) = 0xA0;
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
*(volatile uint8_t *) (bios + 0x5555) = 0xA0;
/* transfer data from source to destination */
*dst = *src;
@ -180,8 +182,8 @@ retry:
return 0;
}
int write_sector_jedec(volatile unsigned char *bios, unsigned char *src,
volatile unsigned char *dst, unsigned int page_size)
int write_sector_jedec(volatile uint8_t *bios, uint8_t *src,
volatile uint8_t *dst, unsigned int page_size)
{
int i;
@ -193,15 +195,15 @@ int write_sector_jedec(volatile unsigned char *bios, unsigned char *src,
return (0);
}
int write_jedec(struct flashchip *flash, unsigned char *buf)
int write_jedec(struct flashchip *flash, uint8_t *buf)
{
int i;
int total_size = flash->total_size * 1024;
int page_size = flash->page_size;
volatile unsigned char *bios = flash->virt_addr;
volatile uint8_t *bios = flash->virt_addr;
erase_chip_jedec(flash);
if (*bios != (unsigned char) 0xff) {
if (*bios != (uint8_t) 0xff) {
printf("ERASE FAILED\n");
return -1;
}

View File

@ -1,21 +1,21 @@
#ifndef __JEDEC_H__
#define __JEDEC_H__ 1
int write_byte_program_jedec(volatile unsigned char *bios, unsigned char *src,
volatile unsigned char *dst);
int write_byte_program_jedec(volatile uint8_t *bios, uint8_t *src,
volatile uint8_t *dst);
extern int probe_jedec(struct flashchip *flash);
extern int erase_chip_jedec(struct flashchip *flash);
extern int write_jedec(struct flashchip *flash, unsigned char *buf);
extern int erase_sector_jedec(volatile unsigned char *bios, unsigned int page);
extern int erase_block_jedec(volatile unsigned char *bios, unsigned int page);
extern int write_sector_jedec(volatile unsigned char *bios, unsigned char *src,
volatile unsigned char *dst,
extern int write_jedec(struct flashchip *flash, uint8_t *buf);
extern int erase_sector_jedec(volatile uint8_t *bios, unsigned int page);
extern int erase_block_jedec(volatile uint8_t *bios, unsigned int page);
extern int write_sector_jedec(volatile uint8_t *bios, uint8_t *src,
volatile uint8_t *dst,
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;
char tmp1, tmp2;
uint8_t tmp1, tmp2;
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;
char tmp;
uint8_t tmp;
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 char *) (bios + 0x2AAA) = 0x55;
*(volatile char *) (bios + 0x5555) = 0x80;
*(volatile char *) (bios + 0x5555) = 0xAA;
*(volatile char *) (bios + 0x2AAA) = 0x55;
*(volatile char *) (bios + 0x5555) = 0x20;
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
*(volatile uint8_t *) (bios + 0x5555) = 0x80;
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
*(volatile uint8_t *) (bios + 0x5555) = 0x20;
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 char *) (bios + 0x2AAA) = 0x55;
*(volatile char *) (bios + 0x5555) = 0xA0;
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
*(volatile uint8_t *) (bios + 0x5555) = 0xA0;
usleep(200);
}

170
util/flashrom/layout.c Normal file
View File

@ -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;
}

10
util/flashrom/layout.h Normal file
View File

@ -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__ */

193
util/flashrom/lbtable.c Normal file
View File

@ -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;
}

8
util/flashrom/lbtable.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef __LBTABLE_H__
#define __LBTABLE_H__ 1
int linuxbios_init(void);
extern char *lb_part, *lb_vendor;
#endif

View File

@ -26,28 +26,29 @@
#include "flash.h"
#include "m29f400bt.h"
#include "debug.h"
int probe_m29f400bt(struct flashchip *flash)
{
volatile char *bios = flash->virt_addr;
unsigned char id1, id2;
volatile uint8_t *bios = flash->virt_addr;
uint8_t id1, id2;
*(volatile char *) (bios + 0xAAA) = 0xAA;
*(volatile char *) (bios + 0x555) = 0x55;
*(volatile char *) (bios + 0xAAA) = 0x90;
*(volatile uint8_t *) (bios + 0xAAA) = 0xAA;
*(volatile uint8_t *) (bios + 0x555) = 0x55;
*(volatile uint8_t *) (bios + 0xAAA) = 0x90;
myusec_delay(10);
id1 = *(volatile unsigned char *) bios;
id2 = *(volatile unsigned char *) (bios + 0x02);
id1 = *(volatile uint8_t *) bios;
id2 = *(volatile uint8_t *) (bios + 0x02);
*(volatile char *) (bios + 0xAAA) = 0xAA;
*(volatile char *) (bios + 0x555) = 0x55;
*(volatile char *) (bios + 0xAAA) = 0xF0;
*(volatile uint8_t *) (bios + 0xAAA) = 0xAA;
*(volatile uint8_t *) (bios + 0x555) = 0x55;
*(volatile uint8_t *) (bios + 0xAAA) = 0xF0;
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)
@ -58,15 +59,15 @@ int probe_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 char *) (bios + 0x555) = 0x55;
*(volatile char *) (bios + 0xAAA) = 0x80;
*(volatile uint8_t *) (bios + 0xAAA) = 0xAA;
*(volatile uint8_t *) (bios + 0x555) = 0x55;
*(volatile uint8_t *) (bios + 0xAAA) = 0x80;
*(volatile char *) (bios + 0xAAA) = 0xAA;
*(volatile char *) (bios + 0x555) = 0x55;
*(volatile char *) (bios + 0xAAA) = 0x10;
*(volatile uint8_t *) (bios + 0xAAA) = 0xAA;
*(volatile uint8_t *) (bios + 0x555) = 0x55;
*(volatile uint8_t *) (bios + 0xAAA) = 0x10;
myusec_delay(10);
toggle_ready_m29f400bt(bios);
@ -74,16 +75,16 @@ int erase_m29f400bt(struct flashchip *flash)
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 char *) (bios + 0x555) = 0x55;
*(volatile char *) (bios + 0xAAA) = 0x80;
*(volatile uint8_t *) (bios + 0xAAA) = 0xAA;
*(volatile uint8_t *) (bios + 0x555) = 0x55;
*(volatile uint8_t *) (bios + 0xAAA) = 0x80;
*(volatile char *) (bios + 0xAAA) = 0xAA;
*(volatile char *) (bios + 0x555) = 0x55;
//*(volatile char *) (bios + 0xAAA) = 0x10;
*(volatile uint8_t *) (bios + 0xAAA) = 0xAA;
*(volatile uint8_t *) (bios + 0x555) = 0x55;
//*(volatile uint8_t *) (bios + 0xAAA) = 0x10;
*dst = 0x30;
myusec_delay(10);
@ -92,12 +93,12 @@ int block_erase_m29f400bt(volatile char *bios, volatile char *dst)
return (0);
}
int write_m29f400bt(struct flashchip *flash, unsigned char *buf)
int write_m29f400bt(struct flashchip *flash, uint8_t *buf)
{
int i;
int total_size = flash->total_size * 1024, page_size =
flash->page_size;
volatile char *bios = flash->virt_addr;
volatile uint8_t *bios = flash->virt_addr;
//erase_m29f400bt (flash);
printf("Programming Page:\n ");
@ -152,9 +153,9 @@ int write_m29f400bt(struct flashchip *flash, unsigned char *buf)
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 ");
/*********************************

View File

@ -5,15 +5,15 @@
extern int probe_m29f400bt(struct flashchip *flash);
extern int erase_m29f400bt(struct flashchip *flash);
extern int block_erase_m29f400bt(volatile char *bios, volatile char *dst);
extern int write_m29f400bt(struct flashchip *flash, unsigned char *buf);
extern int block_erase_m29f400bt(volatile uint8_t *bios, volatile uint8_t *dst);
extern int write_m29f400bt(struct flashchip *flash, uint8_t *buf);
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;
char tmp1, tmp2;
uint8_t tmp1, tmp2;
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,
unsigned char data)
extern __inline__ void data_polling_m29f400bt(volatile uint8_t *dst,
uint8_t data)
{
unsigned int i = 0;
char tmp;
uint8_t tmp;
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 char *) (bios + 0x555) = 0x55;
*(volatile char *) (bios + 0xAAA) = 0xA0;
*(volatile uint8_t *) (bios + 0xAAA) = 0xAA;
*(volatile uint8_t *) (bios + 0x555) = 0x55;
*(volatile uint8_t *) (bios + 0xAAA) = 0xA0;
usleep(200);
}
extern __inline__ void write_page_m29f400bt(volatile char *bios, char *src,
volatile char *dst,
extern __inline__ void write_page_m29f400bt(volatile uint8_t *bios, uint8_t *src,
volatile uint8_t *dst,
int page_size)
{
int i;
for (i = 0; i < page_size; i++) {
*(volatile char *) (bios + 0xAAA) = 0xAA;
*(volatile char *) (bios + 0x555) = 0x55;
*(volatile char *) (bios + 0xAAA) = 0xA0;
*(volatile uint8_t *) (bios + 0xAAA) = 0xAA;
*(volatile uint8_t *) (bios + 0x555) = 0x55;
*(volatile uint8_t *) (bios + 0xAAA) = 0xA0;
/* transfer data from source to destination */
*dst = *src;
@ -69,7 +69,7 @@ extern __inline__ void write_page_m29f400bt(volatile char *bios, char *src,
toggle_ready_m29f400bt(dst);
printf
("Value in the flash at address %p = %#x, want %#x\n",
(char *) (dst - bios), *dst, *src);
(uint8_t *) (dst - bios), *dst, *src);
dst++;
src++;
}

View File

@ -25,16 +25,16 @@
#include <unistd.h>
#include "flash.h"
#include "msys_doc.h"
#include "debug.h"
static int doc_wait(volatile char *bios, int timeout);
static unsigned char doc_read_chipid(volatile char *bios);
static unsigned char doc_read_docstatus(volatile char *bios);
static unsigned char doc_read_cdsncontrol(volatile char *bios);
static void doc_write_cdsncontrol(volatile char *bios, unsigned char data);
static int doc_wait(volatile uint8_t *bios, int timeout);
static uint8_t doc_read_chipid(volatile uint8_t *bios);
static uint8_t doc_read_docstatus(volatile uint8_t *bios);
static uint8_t doc_read_cdsncontrol(volatile uint8_t *bios);
static void doc_write_cdsncontrol(volatile uint8_t *bios, uint8_t data);
@ -42,26 +42,26 @@ static void doc_write_cdsncontrol(volatile char *bios, unsigned char data);
int probe_md2802(struct flashchip *flash)
{
volatile char *bios = flash->virt_addr;
unsigned char chipid;
volatile uint8_t *bios = flash->virt_addr;
uint8_t chipid;
#ifndef MSYSTEMS_DOC_NO_55AA_CHECKING
unsigned char id_0x55, id_0xAA;
uint8_t id_0x55, id_0xAA;
#endif /* !MSYSTEMS_DOC_NO_55AA_CHECKING */
int i, toggle_a, toggle_b;
printf("%s:\n", __FUNCTION__);
printf("%s: *******************************\n", __FUNCTION__);
printf("%s: * THIS IS A PRE ALPHA VERSION *\n", __FUNCTION__);
printf("%s: * IN THE DEVELOPEMENT *********\n", __FUNCTION__);
printf("%s: * PROCESS RIGHT NOW. **********\n", __FUNCTION__);
printf("%s: *******************************\n", __FUNCTION__);
printf("%s: * IF YOU ARE NOT A DEVELOPER **\n", __FUNCTION__);
printf("%s: * THEN DO NOT TRY TO READ OR **\n", __FUNCTION__);
printf("%s: * WRITE TO THIS DEVICE ********\n", __FUNCTION__);
printf("%s: *******************************\n", __FUNCTION__);
printf("%s:\n", __FUNCTION__);
printf_debug("%s:\n", __FUNCTION__);
printf_debug("%s: *******************************\n", __FUNCTION__);
printf_debug("%s: * THIS IS A PRE ALPHA VERSION *\n", __FUNCTION__);
printf_debug("%s: * IN THE DEVELOPEMENT *********\n", __FUNCTION__);
printf_debug("%s: * PROCESS RIGHT NOW. **********\n", __FUNCTION__);
printf_debug("%s: *******************************\n", __FUNCTION__);
printf_debug("%s: * IF YOU ARE NOT A DEVELOPER **\n", __FUNCTION__);
printf_debug("%s: * THEN DO NOT TRY TO READ OR **\n", __FUNCTION__);
printf_debug("%s: * WRITE TO THIS DEVICE ********\n", __FUNCTION__);
printf_debug("%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_read_4nop(bios);
@ -128,7 +128,7 @@ int probe_md2802(struct flashchip *flash)
printf("%s:", __FUNCTION__);
toggle_a = toggle_b = 0;
for (i = 0; i < 10; i++) {
unsigned char toggle = doc_toggle(bios);
uint8_t toggle = doc_toggle(bios);
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);
} /* int read_md2802(struct flashchip *flash, unsigned char *buf) */
} /* int read_md2802(struct flashchip *flash, uint8_t *buf) */
int erase_md2802(struct flashchip *flash)
{
volatile char *bios = flash->virt_addr;
volatile uint8_t *bios = flash->virt_addr;
return (1);
*(volatile char *) (bios + 0x5555) = 0xAA;
*(volatile char *) (bios + 0x2AAA) = 0x55;
*(volatile char *) (bios + 0x5555) = 0x80;
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
*(volatile uint8_t *) (bios + 0x5555) = 0x80;
*(volatile char *) (bios + 0x5555) = 0xAA;
*(volatile char *) (bios + 0x2AAA) = 0x55;
*(volatile char *) (bios + 0x5555) = 0x10;
*(volatile uint8_t *) (bios + 0x5555) = 0xAA;
*(volatile uint8_t *) (bios + 0x2AAA) = 0x55;
*(volatile uint8_t *) (bios + 0x5555) = 0x10;
} /* 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 total_size = flash->total_size * 1024, page_size =
flash->page_size;
volatile unsigned char *bios = flash->virt_addr;
volatile uint8_t *bios = flash->virt_addr;
return (1);
erase_md2802(flash);
if (*bios != (unsigned char) 0xff) {
if (*bios != (uint8_t) 0xff) {
printf("ERASE FAILED\n");
return -1;
}
@ -203,7 +203,7 @@ int write_md2802(struct flashchip *flash, unsigned char *buf)
//protect_md2802(bios);
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
-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;
@ -235,33 +235,33 @@ static int doc_wait(volatile char *bios, int timeout)
}
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_2nop(bios);
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_2nop(bios);
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,
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);
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_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) */

View File

@ -69,7 +69,7 @@
#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) \
doc_read(base, NOP)
@ -81,7 +81,7 @@
{ doc_read_2nop(base); doc_read_2nop(base); }
#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) \
doc_write(0, base, NOP)
@ -101,9 +101,9 @@
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 write_md2802(struct flashchip *flash, unsigned char *buf);
extern int write_md2802(struct flashchip *flash, uint8_t *buf);

View File

@ -26,27 +26,29 @@
*/
#include <stdio.h>
#include <stdint.h>
#include "flash.h"
#include "jedec.h"
#include "mx29f002.h"
#include "debug.h"
int probe_29f002(struct flashchip *flash)
{
volatile char *bios = flash->virt_addr;
unsigned char id1, id2;
volatile uint8_t *bios = flash->virt_addr;
uint8_t id1, id2;
*(bios + 0x5555) = 0xAA;
*(bios + 0x2AAA) = 0x55;
*(bios + 0x5555) = 0x90;
id1 = *(volatile unsigned char *) bios;
id2 = *(volatile unsigned char *) (bios + 0x01);
id1 = *(volatile uint8_t *) bios;
id2 = *(volatile uint8_t *) (bios + 0x01);
*bios = 0xF0;
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)
return 1;
@ -55,7 +57,7 @@ int probe_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) = 0xAA;
@ -84,12 +86,12 @@ int erase_29f002(struct flashchip *flash)
return (0);
}
int write_29f002(struct flashchip *flash, unsigned char *buf)
int write_29f002(struct flashchip *flash, uint8_t *buf)
{
int i;
int total_size = flash->total_size * 1024;
volatile char *bios = flash->virt_addr;
volatile char *dst = bios;
volatile uint8_t *bios = flash->virt_addr;
volatile uint8_t *dst = bios;
*bios = 0xF0;
myusec_delay(10);

View File

@ -3,6 +3,6 @@
extern int probe_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__ */

View File

@ -29,12 +29,12 @@
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 total_size = flash->total_size * 1024, page_size =
flash->page_size;
volatile char *bios = flash->virt_addr;
volatile uint8_t *bios = flash->virt_addr;
printf("Programming Page: ");
for (i = 0; i < total_size / page_size; i++) {

View File

@ -3,6 +3,6 @@
extern int probe_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

3
util/flashrom/rom.layout Normal file
View File

@ -0,0 +1,3 @@
00000000:00008fff gfxrom
00009000:0003ffff normal
00040000:0007ffff fallback

View File

@ -3,6 +3,7 @@
*
*
* 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
* it under the terms of the GNU General Public License as published by
@ -22,12 +23,13 @@
* Reference:
* 4 MEgabit (512K x 8) SuperFlash EEPROM, SST28SF040 data sheet
*
* $Id$
*/
#include <stdio.h>
#include <stdint.h>
#include "flash.h"
#include "jedec.h"
#include "debug.h"
#define AUTO_PG_ERASE1 0x20
#define AUTO_PG_ERASE2 0xD0
@ -36,35 +38,35 @@
#define RESET 0xFF
#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 */
volatile unsigned char tmp;
volatile uint8_t tmp;
tmp = *(volatile unsigned char *) (bios + 0x1823);
tmp = *(volatile unsigned char *) (bios + 0x1820);
tmp = *(volatile unsigned char *) (bios + 0x1822);
tmp = *(volatile unsigned char *) (bios + 0x0418);
tmp = *(volatile unsigned char *) (bios + 0x041B);
tmp = *(volatile unsigned char *) (bios + 0x0419);
tmp = *(volatile unsigned char *) (bios + 0x040A);
tmp = *(volatile uint8_t *) (bios + 0x1823);
tmp = *(volatile uint8_t *) (bios + 0x1820);
tmp = *(volatile uint8_t *) (bios + 0x1822);
tmp = *(volatile uint8_t *) (bios + 0x0418);
tmp = *(volatile uint8_t *) (bios + 0x041B);
tmp = *(volatile uint8_t *) (bios + 0x0419);
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 */
volatile unsigned char tmp;
volatile uint8_t tmp;
tmp = *(volatile unsigned char *) (bios + 0x1823);
tmp = *(volatile unsigned char *) (bios + 0x1820);
tmp = *(volatile unsigned char *) (bios + 0x1822);
tmp = *(volatile unsigned char *) (bios + 0x0418);
tmp = *(volatile unsigned char *) (bios + 0x041B);
tmp = *(volatile unsigned char *) (bios + 0x0419);
tmp = *(volatile unsigned char *) (bios + 0x041A);
tmp = *(volatile uint8_t *) (bios + 0x1823);
tmp = *(volatile uint8_t *) (bios + 0x1820);
tmp = *(volatile uint8_t *) (bios + 0x1822);
tmp = *(volatile uint8_t *) (bios + 0x0418);
tmp = *(volatile uint8_t *) (bios + 0x041B);
tmp = *(volatile uint8_t *) (bios + 0x0419);
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)
{
*bios = AUTO_PG_ERASE1;
@ -76,9 +78,9 @@ static __inline__ int erase_sector_28sf040(volatile char *bios,
return (0);
}
static __inline__ int write_sector_28sf040(volatile char *bios,
unsigned char *src,
volatile unsigned char *dst,
static __inline__ int write_sector_28sf040(volatile uint8_t *bios,
uint8_t *src,
volatile uint8_t *dst,
unsigned int page_size)
{
int i;
@ -103,8 +105,8 @@ static __inline__ int write_sector_28sf040(volatile char *bios,
int probe_28sf040(struct flashchip *flash)
{
volatile char *bios = flash->virt_addr;
unsigned char id1, id2, tmp;
volatile uint8_t *bios = flash->virt_addr;
uint8_t id1, id2, tmp;
/* save the value at the beginning of the Flash */
tmp = *bios;
@ -114,14 +116,14 @@ int probe_28sf040(struct flashchip *flash)
*bios = READ_ID;
myusec_delay(10);
id1 = *(volatile unsigned char *) bios;
id1 = *(volatile uint8_t *) bios;
myusec_delay(10);
id2 = *(volatile unsigned char *) (bios + 0x01);
id2 = *(volatile uint8_t *) (bios + 0x01);
*bios = RESET;
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)
return 1;
@ -132,7 +134,7 @@ int probe_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);
*bios = CHIP_ERASE;
@ -145,12 +147,12 @@ int erase_28sf040(struct flashchip *flash)
return (0);
}
int write_28sf040(struct flashchip *flash, unsigned char *buf)
int write_28sf040(struct flashchip *flash, uint8_t *buf)
{
int i;
int total_size = flash->total_size * 1024, page_size =
flash->page_size;
volatile char *bios = flash->virt_addr;
volatile uint8_t *bios = flash->virt_addr;
unprotect_28sf040(bios);

View File

@ -3,6 +3,6 @@
extern int probe_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__ */

View File

@ -28,6 +28,7 @@
*/
#include <stdio.h>
#include <stdint.h>
#include "flash.h"
#include "jedec.h"
#include "sst39sf020.h"
@ -35,7 +36,7 @@
#define AUTO_PG_ERASE1 0x20
#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)
{
*bios = AUTO_PG_ERASE1;
@ -47,12 +48,12 @@ static __inline__ int erase_sector_39sf020(volatile char *bios,
return (0);
}
int write_39sf020(struct flashchip *flash, unsigned char *buf)
int write_39sf020(struct flashchip *flash, uint8_t *buf)
{
int i;
int total_size = flash->total_size * 1024, page_size =
flash->page_size;
volatile char *bios = flash->virt_addr;
volatile uint8_t *bios = flash->virt_addr;
erase_chip_jedec(flash);

View File

@ -2,6 +2,6 @@
#define __SST39SF020_H__ 1
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__ */

View File

@ -35,7 +35,7 @@ int erase_49lf040(struct flashchip *flash)
int i;
int total_size = flash->total_size * 1024;
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++) {
/* Chip erase only works in parallel programming mode
@ -45,12 +45,12 @@ int erase_49lf040(struct flashchip *flash)
return 0;
}
int write_49lf040(struct flashchip *flash, unsigned char *buf)
int write_49lf040(struct flashchip *flash, uint8_t *buf)
{
int i;
int total_size = flash->total_size * 1024;
int page_size = flash->page_size;
volatile char *bios = flash->virt_addr;
volatile uint8_t *bios = flash->virt_addr;
printf("Programming Page: ");
for (i = 0; i < total_size / page_size; i++) {

View File

@ -2,6 +2,6 @@
#define __SST49LF040_H__ 1
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__ */

View File

@ -18,8 +18,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
* $Id$
*/
#include <errno.h>
@ -35,7 +33,7 @@
#include "sst_fwhub.h"
// 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 & 0x40 ? "BE SUSPEND:" : "BE RUN/FINISH:");
@ -49,7 +47,7 @@ void print_sst_fwhub_status(unsigned char status)
/* probe_jedec works fine for probing */
int probe_sst_fwhub(struct flashchip *flash)
{
volatile unsigned char *bios;
volatile uint8_t *bios;
size_t size = flash->total_size * 1024;
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)
{
volatile unsigned char *wrprotect = flash->virt_addr_2 + offset + 2;
volatile uint8_t *wrprotect = flash->virt_addr_2 + offset + 2;
// clear write protect
*(wrprotect) = 0;
@ -90,14 +88,17 @@ int erase_sst_fwhub(struct flashchip *flash)
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 total_size = flash->total_size * 1024, 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);
// FIXME: This test is not sufficient!
if (*bios != 0xff) {
printf("ERASE FAILED\n");
return -1;

View File

@ -3,6 +3,6 @@
extern int probe_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__ */

View File

@ -1,5 +1,6 @@
#include <sys/time.h>
#include <stdio.h>
#include "debug.h"
// count to a billion. Time it. If it's < 1 sec, count to 10B, etc.
unsigned long micro = 1;
@ -17,7 +18,7 @@ void myusec_calibrate_delay()
struct timeval start, end;
int ok = 0;
printf("Setting up microsecond timing loop\n");
printf_debug("Setting up microsecond timing loop\n");
while (!ok) {
gettimeofday(&start, 0);
myusec_delay(count);
@ -33,5 +34,5 @@ void myusec_calibrate_delay()
// compute one microsecond. That will be count / time
micro = count / timeusec;
fprintf(stderr, "%ldM loops per second\n", (unsigned long) micro);
printf_debug("%ldM loops per second\n", (unsigned long) micro);
}

View File

@ -32,12 +32,12 @@
#include "jedec.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 total_size = flash->total_size * 1024, page_size =
flash->page_size;
volatile char *bios = flash->virt_addr;
volatile uint8_t *bios = flash->virt_addr;
erase_chip_jedec(flash);

View File

@ -1,6 +1,6 @@
#ifndef __W49F002U_H__
#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__ */