diff options
author | Ollie Lho <ollie@sis.com.tw> | 2005-11-26 21:55:36 +0000 |
---|---|---|
committer | Ollie Lho <ollie@sis.com.tw> | 2005-11-26 21:55:36 +0000 |
commit | 09f43e5e2c3ec7e3e96ab030d683b4bcbed89a6f (patch) | |
tree | 730168012ceeb517f9c3d14e02f21be6c75cf107 | |
parent | f18077019037c248e2fa80f9b66aef534525f823 (diff) | |
download | flashrom-09f43e5e2c3ec7e3e96ab030d683b4bcbed89a6f.zip flashrom-09f43e5e2c3ec7e3e96ab030d683b4bcbed89a6f.tar.gz |
Flashrom update from Stefan, resolve issue 21
Corresponding to flashrom svn r34 and coreboot v2 svn r2111.
-rw-r--r-- | 82802ab.c | 57 | ||||
-rw-r--r-- | 82802ab.h | 18 | ||||
-rw-r--r-- | Makefile | 61 | ||||
-rw-r--r-- | README | 75 | ||||
-rw-r--r-- | am29f040b.c | 24 | ||||
-rw-r--r-- | am29f040b.h | 2 | ||||
-rw-r--r-- | debug.h | 7 | ||||
-rw-r--r-- | flash.h | 11 | ||||
-rw-r--r-- | flash_enable.c | 114 | ||||
-rw-r--r-- | flash_on.c | 77 | ||||
-rw-r--r-- | flash_rom.c | 220 | ||||
-rw-r--r-- | flashchips.c | 91 | ||||
-rw-r--r-- | jedec.c | 96 | ||||
-rw-r--r-- | jedec.h | 44 | ||||
-rw-r--r-- | layout.c | 170 | ||||
-rw-r--r-- | layout.h | 10 | ||||
-rw-r--r-- | lbtable.c | 193 | ||||
-rw-r--r-- | lbtable.h | 8 | ||||
-rw-r--r-- | m29f400bt.c | 59 | ||||
-rw-r--r-- | m29f400bt.h | 36 | ||||
-rw-r--r-- | msys_doc.c | 94 | ||||
-rw-r--r-- | msys_doc.h | 8 | ||||
-rw-r--r-- | mx29f002.c | 20 | ||||
-rw-r--r-- | mx29f002.h | 2 | ||||
-rw-r--r-- | pm49fl004.c | 4 | ||||
-rw-r--r-- | pm49fl004.h | 2 | ||||
-rw-r--r-- | rom.layout | 3 | ||||
-rw-r--r-- | sst28sf040.c | 68 | ||||
-rw-r--r-- | sst28sf040.h | 2 | ||||
-rw-r--r-- | sst39sf020.c | 7 | ||||
-rw-r--r-- | sst39sf020.h | 2 | ||||
-rw-r--r-- | sst49lf040.c | 6 | ||||
-rw-r--r-- | sst49lf040.h | 2 | ||||
-rw-r--r-- | sst_fwhub.c | 15 | ||||
-rw-r--r-- | sst_fwhub.h | 2 | ||||
-rw-r--r-- | udelay.c | 5 | ||||
-rw-r--r-- | w49f002u.c | 4 | ||||
-rw-r--r-- | w49f002u.h | 2 |
38 files changed, 1104 insertions, 517 deletions
@@ -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) { @@ -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); } @@ -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 *~ - -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 - -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 + rm -f *.o *~ + +distclean: clean + rm -f $(PROGRAM) .dependencies + +dep: + @$(CC) -MM *.c > .dependencies + +.PHONY: all clean distclean dep + +-include .dependencies + @@ -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 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 @@ 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++) { 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__ */ @@ -0,0 +1,7 @@ +#ifndef __DEBUG_H__ +#define __DEBUG_H__ 1 + +//#define printf_debug(x...) printf(x) +#define printf_debug(x...) { } + +#endif @@ -3,25 +3,28 @@ #include <sys/io.h> #include <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_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++) { 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 @@ 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; } 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,} +}; + + @@ -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; } @@ -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); } 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 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 "); /********************************* 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 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++; } @@ -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("%s: switching off reset mode ...\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_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) */ @@ -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); @@ -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); @@ -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; - - 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); + volatile uint8_t tmp; + + 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; - - 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); + volatile uint8_t tmp; + + 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); 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 @@ 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); 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 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++) { 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 @@ 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; 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__ */ @@ -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); } @@ -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); @@ -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__ */ |