Flashrom update from Stefan, resolve issue 21

Corresponding to flashrom svn r34 and coreboot v2 svn r2111.
diff --git a/82802ab.c b/82802ab.c
index 80945ad..27ce57d 100644
--- a/82802ab.c
+++ b/82802ab.c
@@ -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 @@
 
 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 @@
 	*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 @@
 	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 @@
 	*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 @@
 	//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 @@
 	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 @@
 
 }
 
-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) {
diff --git a/82802ab.h b/82802ab.h
index 0542068..7836f36 100644
--- a/82802ab.h
+++ b/82802ab.h
@@ -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 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 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);
 }
diff --git a/Makefile b/Makefile
index 9d4124f..9293fb8 100644
--- a/Makefile
+++ b/Makefile
@@ -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
 
-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
+.PHONY: all clean distclean dep 
+
+-include .dependencies
+
diff --git a/README b/README
index 48f6fb8..fab2b16 100644
--- a/README
+++ b/README
@@ -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
+--------------------------------------------
 
-Ollie
+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.
+
+
diff --git a/am29f040b.c b/am29f040b.c
index 3ebfe86..f67127d 100644
--- a/am29f040b.c
+++ b/am29f040b.c
@@ -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 @@
 	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 @@
 
 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 @@
 
 	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 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 @@
 	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++) {
diff --git a/am29f040b.h b/am29f040b.h
index 08c6c92..99efb67 100644
--- a/am29f040b.h
+++ b/am29f040b.h
@@ -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__ */
diff --git a/debug.h b/debug.h
new file mode 100644
index 0000000..7d540b5
--- /dev/null
+++ b/debug.h
@@ -0,0 +1,7 @@
+#ifndef __DEBUG_H__
+#define __DEBUG_H__ 1
+
+//#define printf_debug(x...) printf(x)
+#define printf_debug(x...) { }
+
+#endif
diff --git a/flash.h b/flash.h
index 3dfefe2..f477da5 100644
--- a/flash.h
+++ b/flash.h
@@ -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
 
diff --git a/flash_enable.c b/flash_enable.c
index 19fd9b0..582766f 100644
--- a/flash_enable.c
+++ b/flash_enable.c
@@ -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_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_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_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_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_cs5530(struct pci_dev *dev, char *name)
 {
-	unsigned char new;
+	uint8_t new;
 
 	pci_write_byte(dev, 0x52, 0xee);
 
@@ -174,12 +190,17 @@
 		       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_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_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_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 @@
         {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 @@
 	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++) {
diff --git a/flash_on.c b/flash_on.c
deleted file mode 100644
index f1e8aca..0000000
--- a/flash_on.c
+++ /dev/null
@@ -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);
-}
diff --git a/flash_rom.c b/flash_rom.c
index ceb56ad..7b38c8a 100644
--- a/flash_rom.c
+++ b/flash_rom.c
@@ -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 @@
 			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 @@
 	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 @@
 
 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 @@
 			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 @@
 	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 @@
 			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 @@
 		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;
 }
diff --git a/flashchips.c b/flashchips.c
new file mode 100644
index 0000000..823154a
--- /dev/null
+++ b/flashchips.c
@@ -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,}
+};
+
+
diff --git a/jedec.c b/jedec.c
index 353b17a..2a07b44 100644
--- a/jedec.c
+++ b/jedec.c
@@ -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 @@
 	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_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 @@
 	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 @@
 	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 @@
 
 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 @@
 	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 @@
 	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;
 	}
diff --git a/jedec.h b/jedec.h
index 2a9f977..210f9f9 100644
--- a/jedec.h
+++ b/jedec.h
@@ -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 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 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);
 }
diff --git a/layout.c b/layout.c
new file mode 100644
index 0000000..2219096
--- /dev/null
+++ b/layout.c
@@ -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;
+}
diff --git a/layout.h b/layout.h
new file mode 100644
index 0000000..ec1fd1b
--- /dev/null
+++ b/layout.h
@@ -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__ */
diff --git a/lbtable.c b/lbtable.c
new file mode 100644
index 0000000..f982672
--- /dev/null
+++ b/lbtable.c
@@ -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;
+}
diff --git a/lbtable.h b/lbtable.h
new file mode 100644
index 0000000..ed9768c
--- /dev/null
+++ b/lbtable.h
@@ -0,0 +1,8 @@
+#ifndef __LBTABLE_H__
+#define __LBTABLE_H__ 1
+
+int linuxbios_init(void);
+
+extern char *lb_part, *lb_vendor;
+
+#endif
diff --git a/m29f400bt.c b/m29f400bt.c
index 842e35d..aff4cd5 100644
--- a/m29f400bt.c
+++ b/m29f400bt.c
@@ -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 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 @@
 	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 @@
 	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 @@
 	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 ");
 	/*********************************
diff --git a/m29f400bt.h b/m29f400bt.h
index efe0953..30a7ee8 100644
--- a/m29f400bt.h
+++ b/m29f400bt.h
@@ -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 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 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 @@
 		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++;
 	}
diff --git a/msys_doc.c b/msys_doc.c
index 7e9ca9a..c9f4b4f 100644
--- a/msys_doc.c
+++ b/msys_doc.c
@@ -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 @@
 
 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 @@
 	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 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 @@
 	//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 @@
 		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 @@
 	}
 
 	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 @@
 	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) */
diff --git a/msys_doc.h b/msys_doc.h
index 3e2028b..02da23c 100644
--- a/msys_doc.h
+++ b/msys_doc.h
@@ -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);
 
 
 
diff --git a/mx29f002.c b/mx29f002.c
index b281528..263b592 100644
--- a/mx29f002.c
+++ b/mx29f002.c
@@ -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 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 @@
 	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);
diff --git a/mx29f002.h b/mx29f002.h
index 7d3cf20..d180fae 100644
--- a/mx29f002.h
+++ b/mx29f002.h
@@ -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__ */
diff --git a/pm49fl004.c b/pm49fl004.c
index afcd55a..baa80a8 100644
--- a/pm49fl004.c
+++ b/pm49fl004.c
@@ -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++) {
diff --git a/pm49fl004.h b/pm49fl004.h
index 21c880b..2abd7de 100644
--- a/pm49fl004.h
+++ b/pm49fl004.h
@@ -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
diff --git a/rom.layout b/rom.layout
new file mode 100644
index 0000000..3d7511a
--- /dev/null
+++ b/rom.layout
@@ -0,0 +1,3 @@
+00000000:00008fff gfxrom
+00009000:0003ffff normal
+00040000:0007ffff fallback
diff --git a/sst28sf040.c b/sst28sf040.c
index 1853f15..3de991d 100644
--- a/sst28sf040.c
+++ b/sst28sf040.c
@@ -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 @@
 	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 @@
 
 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 @@
 
 	*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 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 @@
 	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);
 
diff --git a/sst28sf040.h b/sst28sf040.h
index ca57eff..027e845 100644
--- a/sst28sf040.h
+++ b/sst28sf040.h
@@ -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__ */
diff --git a/sst39sf020.c b/sst39sf020.c
index 97e87a1..28aa16b 100644
--- a/sst39sf020.c
+++ b/sst39sf020.c
@@ -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 @@
 	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);
 
diff --git a/sst39sf020.h b/sst39sf020.h
index 698814c..aea62cc 100644
--- a/sst39sf020.h
+++ b/sst39sf020.h
@@ -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__ */
diff --git a/sst49lf040.c b/sst49lf040.c
index f19b91e..377b74f 100644
--- a/sst49lf040.c
+++ b/sst49lf040.c
@@ -35,7 +35,7 @@
         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 @@
 	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++) {
diff --git a/sst49lf040.h b/sst49lf040.h
index 79dfec9..3fefe57 100644
--- a/sst49lf040.h
+++ b/sst49lf040.h
@@ -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__ */
diff --git a/sst_fwhub.c b/sst_fwhub.c
index c064ed6..e835a1a 100644
--- a/sst_fwhub.c
+++ b/sst_fwhub.c
@@ -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 @@
 /* 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 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 @@
 	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;
diff --git a/sst_fwhub.h b/sst_fwhub.h
index eb2b364..66979bc 100644
--- a/sst_fwhub.h
+++ b/sst_fwhub.h
@@ -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__ */
diff --git a/udelay.c b/udelay.c
index 30b8dde..e2fd310 100644
--- a/udelay.c
+++ b/udelay.c
@@ -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 @@
 	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 @@
 	// 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);
 }
diff --git a/w49f002u.c b/w49f002u.c
index 02667cf..15df445 100644
--- a/w49f002u.c
+++ b/w49f002u.c
@@ -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);
 
diff --git a/w49f002u.h b/w49f002u.h
index 29320b7..1ea8377 100644
--- a/w49f002u.h
+++ b/w49f002u.h
@@ -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__ */