From eaab50bb32edfe419eb472eacfdc82cbc3ecae8c Mon Sep 17 00:00:00 2001 From: "Ronald G. Minnich" Date: Fri, 12 Sep 2003 22:41:53 +0000 Subject: Changes from NIKI Corresponding to coreboot v1 svn r873. --- 82802ab.c | 7 +- 82802ab.h | 6 +- Makefile | 29 ++++-- am29f040b.c | 17 +++- am29f040b.h | 8 ++ flash.h | 30 +++---- flash_on.c | 5 +- flash_rom.c | 59 +++++++----- jedec.c | 7 +- jedec.h | 7 +- m29f400bt.c | 13 ++- m29f400bt.h | 15 +++- msys_doc.c | 289 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ msys_doc.h | 110 +++++++++++++++++++++++ mx29f002.c | 16 ++-- mx29f002.h | 8 ++ sst28sf040.c | 15 +++- sst28sf040.h | 8 ++ sst39sf020.c | 23 +++-- sst39sf020.h | 8 ++ w49f002u.c | 16 ++-- w49f002u.h | 8 ++ 22 files changed, 622 insertions(+), 82 deletions(-) create mode 100644 am29f040b.h create mode 100644 msys_doc.c create mode 100644 msys_doc.h create mode 100644 mx29f002.h create mode 100644 sst28sf040.h create mode 100644 sst39sf020.h create mode 100644 w49f002u.h diff --git a/82802ab.c b/82802ab.c index b41efccfc..c818e9215 100644 --- a/82802ab.c +++ b/82802ab.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "flash.h" #include "82802ab.h" @@ -145,11 +146,11 @@ int erase_82802ab_block(struct flashchip *flash, int offset) status = wait_82802ab(flash->virt_addr); //print_82802ab_status(status); printf("DONE BLOCK 0x%x\n", offset); + return(0); } int erase_82802ab (struct flashchip * flash) { int i; - volatile unsigned char * bios = flash->virt_addr; unsigned int total_size = flash->total_size * 1024; printf("total_size is %d; flash->page_size is %d\n", @@ -157,6 +158,7 @@ int erase_82802ab (struct flashchip * flash) for(i = 0; i < total_size; i += flash->page_size) erase_82802ab_block(flash, i); printf("DONE ERASE\n"); + return(0); } void write_page_82802ab (volatile char * bios, char * src, volatile char * dst, @@ -173,7 +175,7 @@ void write_page_82802ab (volatile char * bios, char * src, volatile char * dst, } -int write_82802ab (struct flashchip * flash, char * buf) +int write_82802ab (struct flashchip * flash, unsigned char * buf) { int i; int total_size = flash->total_size *1024, page_size = flash->page_size; @@ -193,4 +195,5 @@ int write_82802ab (struct flashchip * flash, char * buf) } printf("\n"); protect_82802ab (bios); + return(0); } diff --git a/82802ab.h b/82802ab.h index 3649704c3..61e7f100a 100644 --- a/82802ab.h +++ b/82802ab.h @@ -1,6 +1,9 @@ +#ifndef __82802AB_H__ +#define __82802AB_H__ 1 + extern int probe_82802ab (struct flashchip * flash); extern int erase_82802ab (struct flashchip * flash); -extern int write_82802ab (struct flashchip * flash, char * buf); +extern int write_82802ab (struct flashchip * flash, unsigned char * buf); extern __inline__ void toggle_ready_82802ab (volatile char * dst) { @@ -42,3 +45,4 @@ extern __inline__ void protect_82802ab (volatile char * bios) usleep(200); } +#endif /* !__82802AB_H__ */ diff --git a/Makefile b/Makefile index 3a308f68a..5c8ffe9d4 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,30 @@ OBJS = jedec.o sst28sf040.o am29f040b.o mx29f002.c sst39sf020.o m29f400bt.o \ - w49f002u.o -OBJS += 82802ab.o -CC = gcc -O2 -g + w49f002u.o 82802ab.o msys_doc.o +CC = gcc -O2 -g -Wall -Werror -all: ${OBJS} +all: flash_rom flash_on + +flash_rom: flash_rom.o ${OBJS} ${CC} -o flash_rom flash_rom.c ${OBJS} -lpci -# ${CC} -o flash_on flash_on.c + +flash_on: flash_on.c + ${CC} -o flash_on flash_on.c 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 +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 +w49f002u.o: w49f002u.c w49f002u.h jedec.h flash.h + +jedec.o: jedec.c jedec.h flash.h diff --git a/am29f040b.c b/am29f040b.c index 3603bb994..89cdff980 100644 --- a/am29f040b.c +++ b/am29f040b.c @@ -24,10 +24,11 @@ * $Id$ */ +#include #include "flash.h" #include "jedec.h" -static __inline__ erase_sector_29f040b (volatile char * bios, unsigned long address) +static __inline__ int erase_sector_29f040b (volatile char * bios, unsigned long address) { *(bios + 0x555) = 0xAA; *(bios + 0x2AA) = 0x55; @@ -40,15 +41,17 @@ static __inline__ erase_sector_29f040b (volatile char * bios, unsigned long addr /* wait for Toggle bit ready */ toggle_ready_jedec(bios + address); + + return(0); } -static __inline__ write_sector_29f040b(volatile char * bios, unsigned char * src, +static __inline__ int write_sector_29f040b(volatile char * bios, unsigned char * src, volatile unsigned char * dst, unsigned int page_size) { int i; for (i = 0; i < page_size; i++) { - printf("0x%08x", (unsigned long) dst - (unsigned long) bios); + printf("0x%08lx", (unsigned long) dst - (unsigned long) bios); *(bios + 0x555) = 0xAA; *(bios + 0x2AA) = 0x55; @@ -60,6 +63,8 @@ static __inline__ write_sector_29f040b(volatile char * bios, unsigned char * src printf("\b\b\b\b\b\b\b\b\b\b"); } + + return(0); } int probe_29f040b (struct flashchip * flash) @@ -98,9 +103,11 @@ int erase_29f040b (struct flashchip * flash) myusec_delay(10); toggle_ready_jedec(bios); + + return(0); } -int write_29f040b (struct flashchip * flash, char * buf) +int write_29f040b (struct flashchip * flash, unsigned char * buf) { int i; int total_size = flash->total_size * 1024, page_size = flash->page_size; @@ -118,4 +125,6 @@ int write_29f040b (struct flashchip * flash, char * buf) printf ("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); } printf("\n"); + + return(0); } diff --git a/am29f040b.h b/am29f040b.h new file mode 100644 index 000000000..dee8f629a --- /dev/null +++ b/am29f040b.h @@ -0,0 +1,8 @@ +#ifndef __AM29F040B_H__ +#define __AM29F040B_H__ 1 + +extern int probe_29f040b (struct flashchip * flash); +extern int erase_29f040b (struct flashchip * flash); +extern int write_29f040b (struct flashchip * flash, unsigned char * buf); + +#endif /* !__AM29F040B_H__ */ diff --git a/flash.h b/flash.h index 0fde00e7a..0e62b8975 100644 --- a/flash.h +++ b/flash.h @@ -1,3 +1,6 @@ +#ifndef __FLASH_H__ +#define __FLASH_H__ 1 + #include #include @@ -12,7 +15,9 @@ struct flashchip { int (*probe) (struct flashchip * flash); int (*erase) (struct flashchip * flash); - int (*write) (struct flashchip * flash, char * buf); + int (*write) (struct flashchip * flash, unsigned char * buf); + int (*read) (struct flashchip * flash, unsigned char * buf); + int fd_mem; volatile char *virt_addr_2; }; @@ -40,22 +45,11 @@ struct flashchip { #define ST_ID 0x20 #define ST_M29F400BT 0xD5 -extern int probe_28sf040 (struct flashchip * flash); -extern int erase_28sf040 (struct flashchip * flash); -extern int write_28sf040 (struct flashchip * flash, char * buf); - -extern int probe_39sf020 (struct flashchip * flash); -extern int erase_39sf020 (struct flashchip * flash); -extern int write_39sf020 (struct flashchip * flash, char * buf); - -extern int probe_29f040b (struct flashchip * flash); -extern int erase_29f040b (struct flashchip * flash); -extern int write_29f040b (struct flashchip * flash, char * buf); +#define MSYSTEMS_ID 0x156f +#define MSYSTEMS_MD2200 0xdb /* ? */ +#define MSYSTEMS_MD2800 0x30 /* hmm -- both 0x30 */ +#define MSYSTEMS_MD2802 0x30 /* hmm -- both 0x30 */ -extern int probe_29f002 (struct flashchip * flash); -extern int erase_29f002 (struct flashchip * flash); -extern int write_29f002 (struct flashchip * flash, char * buf); +extern void myusec_delay(int time); -extern int probe_49f002 (struct flashchip * flash); -extern int erase_49f002 (struct flashchip * flash); -extern int write_49f002 (struct flashchip * flash, char * buf); +#endif /* !__FLASH_H__ */ diff --git a/flash_on.c b/flash_on.c index c8952e208..a43f1da8c 100644 --- a/flash_on.c +++ b/flash_on.c @@ -33,8 +33,9 @@ #include #include #include +#include -main() +int main() { char b; @@ -71,4 +72,6 @@ main() outb(0x02, 0x2e); outb(0x02, 0x2f); + + return(0); } diff --git a/flash_rom.c b/flash_rom.c index e7d49a57e..a13d48bb5 100644 --- a/flash_rom.c +++ b/flash_rom.c @@ -30,43 +30,55 @@ #include #include #include +#include #include #include #include #include +#include #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 "mx29f002.h" struct flashchip flashchips[] = { {"Am29F040B", AMD_ID, AM_29F040B, NULL, 512, 64*1024, - probe_29f040b, erase_29f040b, write_29f040b}, + probe_29f040b, erase_29f040b, write_29f040b, NULL}, {"At29C040A", ATMEL_ID, AT_29C040A, NULL, 512, 256, - probe_jedec, erase_jedec, write_jedec}, + probe_jedec, erase_jedec, write_jedec, NULL}, {"Mx29f002", MX_ID, MX_29F002, NULL, 256, 64*1024, - probe_29f002, erase_29f002, write_29f002}, + probe_29f002, erase_29f002, write_29f002, NULL}, {"SST29EE020A", SST_ID, SST_29EE020A, NULL, 256, 128, - probe_jedec, erase_jedec, write_jedec}, + probe_jedec, erase_jedec, write_jedec, NULL}, {"SST28SF040A", SST_ID, SST_28SF040, NULL, 512, 256, - probe_28sf040, erase_28sf040, write_28sf040}, + probe_28sf040, erase_28sf040, write_28sf040, NULL}, {"SST39SF020A", SST_ID, SST_39SF020, NULL, 256, 4096, - probe_39sf020, erase_39sf020, write_39sf020}, + probe_39sf020, erase_39sf020, write_39sf020, NULL}, {"SST39VF020", SST_ID, SST_39VF020, NULL, 256, 4096, - probe_39sf020, erase_39sf020, write_39sf020}, + probe_39sf020, erase_39sf020, write_39sf020, NULL}, {"W29C011", WINBOND_ID, W_29C011, NULL, 128, 128, - probe_jedec, erase_jedec, write_jedec}, + probe_jedec, erase_jedec, write_jedec, NULL}, {"W29C020C", WINBOND_ID, W_29C020C, NULL, 256, 128, - probe_jedec, erase_jedec, write_jedec}, + probe_jedec, erase_jedec, write_jedec, NULL}, {"W49F002U", WINBOND_ID, W_49F002U, NULL, 256, 128, - probe_49f002, erase_49f002, write_49f002}, + probe_49f002, erase_49f002, write_49f002, NULL}, {"M29F400BT", ST_ID, ST_M29F400BT , NULL, 512, 64*1024, - probe_m29f400bt, erase_m29f400bt, write_linuxbios_m29f400bt}, + probe_m29f400bt, erase_m29f400bt, write_linuxbios_m29f400bt, NULL}, {"82802ab", 137, 173 , NULL, 512, 64*1024, - probe_82802ab, erase_82802ab, write_82802ab}, + probe_82802ab, erase_82802ab, write_82802ab, NULL}, {"82802ac", 137, 172 , NULL, 1024, 64*1024, - probe_82802ab, erase_82802ab, write_82802ab}, + 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,} }; @@ -208,7 +220,6 @@ enable_flash_vt8231(struct pci_dev *dev, char *name) { int enable_flash_cs5530(struct pci_dev *dev, char *name) { unsigned char new; - int ok; pci_write_byte(dev, 0x52, 0xee); @@ -225,7 +236,6 @@ enable_flash_cs5530(struct pci_dev *dev, char *name) { int enable_flash_sc1100(struct pci_dev *dev, char *name) { unsigned char new; - int ok; pci_write_byte(dev, 0x52, 0xee); @@ -280,6 +290,14 @@ struct flashchip * probe_flash(struct flashchip * flash) } printf("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 */ + if(getpagesize() > size) + { + size = getpagesize(); + printf("%s: warning: size: %d -> %ld\n", __FUNCTION__, + flash->total_size * 1024, (unsigned long)size); + } bios = mmap (0, size, PROT_WRITE | PROT_READ, MAP_SHARED, fd_mem, (off_t) (0 - size)); if (bios == MAP_FAILED) { @@ -291,7 +309,7 @@ struct flashchip * probe_flash(struct flashchip * flash) if (flash->probe(flash) == 1) { printf ("%s found at physical address: 0x%lx\n", - flash->name, (0 - size), bios); + flash->name, (0 - size)); return flash; } munmap ((void *) bios, size); @@ -332,7 +350,6 @@ void myusec_calibrate_delay() { int count = 1000; - volatile unsigned long i; unsigned long timeusec; struct timeval start, end; int ok = 0; @@ -356,7 +373,7 @@ myusec_calibrate_delay() // compute one microsecond. That will be count / time micro = count / timeusec; - fprintf(stderr, "%dM loops per second\n", micro); + fprintf(stderr, "%ldM loops per second\n", (unsigned long)micro); } @@ -391,7 +408,6 @@ enable_flash_write() { int i; struct pci_access *pacc; struct pci_dev *dev = 0; - unsigned int c; FLASH_ENABLE *enable = 0; pacc = pci_alloc(); /* Get the pci_access structure */ @@ -503,7 +519,10 @@ main (int argc, char * argv[]) exit(1); } printf("Reading Flash..."); - memcpy(buf, (const char *) flash->virt_addr, size); + if(flash->read == NULL) + memcpy(buf, (const char *) flash->virt_addr, size); + else + flash->read (flash, buf); fwrite(buf, sizeof(char), size, image); fclose(image); printf("done\n"); diff --git a/jedec.c b/jedec.c index e811959db..bb4a874ab 100644 --- a/jedec.c +++ b/jedec.c @@ -24,6 +24,7 @@ * $Id$ */ +#include #include "flash.h" #include "jedec.h" @@ -68,9 +69,11 @@ int erase_jedec (struct flashchip * flash) myusec_delay(10); toggle_ready_jedec(bios); + + return(0); } -int write_jedec (struct flashchip * flash, char * buf) +int write_jedec (struct flashchip * flash, unsigned char * buf) { int i; int total_size = flash->total_size *1024, page_size = flash->page_size; @@ -90,4 +93,6 @@ int write_jedec (struct flashchip * flash, char * buf) } printf("\n"); protect_jedec (bios); + + return(0); } diff --git a/jedec.h b/jedec.h index 18c5153c0..40261fd4f 100644 --- a/jedec.h +++ b/jedec.h @@ -1,6 +1,9 @@ +#ifndef __JEDEC_H__ +#define __JEDEC_H__ 1 + extern int probe_jedec (struct flashchip * flash); extern int erase_jedec (struct flashchip * flash); -extern int write_jedec (struct flashchip * flash, char * buf); +extern int write_jedec (struct flashchip * flash, unsigned char * buf); extern __inline__ void toggle_ready_jedec (volatile char * dst) { @@ -59,3 +62,5 @@ extern __inline__ void write_page_jedec (volatile char * bios, char * src, volat usleep(100); toggle_ready_jedec(dst-1); } + +#endif /* !__JEDEC_H__ */ diff --git a/m29f400bt.c b/m29f400bt.c index 73f921360..a19c8cd6c 100644 --- a/m29f400bt.c +++ b/m29f400bt.c @@ -70,6 +70,8 @@ int erase_m29f400bt (struct flashchip * flash) myusec_delay(10); toggle_ready_m29f400bt(bios); + + return(0); } int block_erase_m29f400bt (volatile char * bios ,volatile char * dst) @@ -86,9 +88,11 @@ int block_erase_m29f400bt (volatile char * bios ,volatile char * dst) myusec_delay(10); toggle_ready_m29f400bt(bios); + + return(0); } -int write_m29f400bt (struct flashchip * flash, char * buf) +int write_m29f400bt (struct flashchip * flash, unsigned char * buf) { int i; int total_size = flash->total_size *1024, page_size = flash->page_size; @@ -138,11 +142,12 @@ int write_m29f400bt (struct flashchip * flash, char * buf) printf("\n"); //protect_m29f400bt (bios); + + return(0); } -int write_linuxbios_m29f400bt (struct flashchip * flash, char * buf) +int write_linuxbios_m29f400bt (struct flashchip * flash, unsigned char * buf) { - int i; volatile char * bios = flash->virt_addr; printf ("Programming Page:\n "); @@ -179,4 +184,6 @@ int write_linuxbios_m29f400bt (struct flashchip * flash, char * buf) printf("\n"); //protect_m29f400bt (bios); + + return(0); } diff --git a/m29f400bt.h b/m29f400bt.h index a6458709e..3d1799f4e 100644 --- a/m29f400bt.h +++ b/m29f400bt.h @@ -1,8 +1,13 @@ +#ifndef __M29F400BT_H__ +#define __M29F400BT_H__ 1 + +#include + 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, char * buf); -extern int write_linuxbios_m29f400bt (struct flashchip * flash, char * buf); +extern int write_m29f400bt (struct flashchip * flash, unsigned char * buf); +extern int write_linuxbios_m29f400bt (struct flashchip * flash, unsigned char * buf); extern __inline__ void toggle_ready_m29f400bt (volatile char * dst) { @@ -20,7 +25,7 @@ extern __inline__ void toggle_ready_m29f400bt (volatile char * dst) } } -extern __inline__ void data_polling_m29f400bt (volatile char * dst, char data) +extern __inline__ void data_polling_m29f400bt (volatile char * dst, unsigned char data) { unsigned int i = 0; char tmp; @@ -59,9 +64,11 @@ extern __inline__ void write_page_m29f400bt (volatile char * bios, char * src, v //*(volatile char *) (bios) = 0xF0; //usleep(5); toggle_ready_m29f400bt(dst); - printf("Value in the flash at address %p = %#x, want %#x\n",dst-bios, *dst, *src); + printf("Value in the flash at address %p = %#x, want %#x\n",(char *)(dst-bios), *dst, *src); dst++; src++; } } + +#endif /* !__M29F400BT_H__ */ diff --git a/msys_doc.c b/msys_doc.c new file mode 100644 index 000000000..bfa4ecae9 --- /dev/null +++ b/msys_doc.c @@ -0,0 +1,289 @@ +/* + * msys_doc.c: driver for programming m-systems doc devices + * + * + * Copyright 2003 Niki W. Waibel + * + * 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 +#include +#include "flash.h" +#include "msys_doc.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); + + + + + +int +probe_md2802(struct flashchip * flash) +{ + volatile char *bios = flash->virt_addr; + unsigned char chipid; +#ifndef MSYSTEMS_DOC_NO_55AA_CHECKING + unsigned char 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__); + doc_write(0x85, bios, DOCControl); + doc_write(0x85, bios, DOCControl); + doc_read_4nop(bios); + if(doc_wait(bios, 5000)) + return(-1); + printf("%s: switching off reset mode ... done\n", __FUNCTION__); + printf("%s:\n", __FUNCTION__); + + printf("%s: switching off write protection ...\n", __FUNCTION__); + doc_write_cdsncontrol(bios, doc_read_cdsncontrol(bios)&(~0x08)); + printf("%s: switching off write protection ... done\n", __FUNCTION__); + printf("%s:\n", __FUNCTION__); + + + chipid = doc_read_chipid(bios); +#ifndef MSYSTEMS_DOC_NO_55AA_CHECKING + id_0x55 = doc_read(bios, IPL_0x0000); + id_0xAA = doc_read(bios, IPL_0x0001); +#endif /* !MSYSTEMS_DOC_NO_55AA_CHECKING */ + printf("%s: IPL_0x0000: 0x%02x\n", __FUNCTION__, id_0x55); + printf("%s: IPL_0x0001: 0x%02x\n", __FUNCTION__, id_0xAA); + printf("%s: IPL_0x0002: 0x%02x\n", __FUNCTION__, + doc_read(bios, IPL_0x0002)); + printf("%s: IPL_0x0003: 0x%02x\n", __FUNCTION__, + doc_read(bios, IPL_0x0003)); + printf("%s:\n", __FUNCTION__); + printf("%s: ChipID: 0x%02x\n", __FUNCTION__, chipid); + printf("%s: DOCStatus: 0x%02x\n", __FUNCTION__, + doc_read_docstatus(bios)); + printf("%s: FloorSelect: 0x%02x\n", __FUNCTION__, + doc_read(bios, FloorSelect)); + printf("%s: CDSNControl: 0x%02x\n", __FUNCTION__, + doc_read_cdsncontrol(bios)); + printf("%s: CDSNDeviceSelect: 0x%02x\n", __FUNCTION__, + doc_read(bios, CDSNDeviceSelect)); + printf("%s: ECCConfiguration: 0x%02x\n", __FUNCTION__, + doc_read(bios, ECCConfiguration)); + printf("%s: CDSNSlowIO: 0x%02x\n", __FUNCTION__, + doc_read(bios, CDSNSlowIO)); + printf("%s: ECCSyndrome0: 0x%02x\n", __FUNCTION__, + doc_read(bios, ECCSyndrome0)); + printf("%s: ECCSyndrome1: 0x%02x\n", __FUNCTION__, + doc_read(bios, ECCSyndrome1)); + printf("%s: ECCSyndrome2: 0x%02x\n", __FUNCTION__, + doc_read(bios, ECCSyndrome2)); + printf("%s: ECCSyndrome3: 0x%02x\n", __FUNCTION__, + doc_read(bios, ECCSyndrome3)); + printf("%s: ECCSyndrome4: 0x%02x\n", __FUNCTION__, + doc_read(bios, ECCSyndrome4)); + printf("%s: ECCSyndrome5: 0x%02x\n", __FUNCTION__, + doc_read(bios, ECCSyndrome5)); + printf("%s: AliasResolution: 0x%02x\n", __FUNCTION__, + doc_read(bios, AliasResolution)); + printf("%s: ConfigurationInput: 0x%02x\n", __FUNCTION__, + doc_read(bios, ConfigurationInput)); + printf("%s: ReadPipelineInitialization: 0x%02x\n", __FUNCTION__, + doc_read(bios, ReadPipelineInitialization)); + printf("%s: LastDataRead: 0x%02x\n", __FUNCTION__, + doc_read(bios, LastDataRead)); + printf("%s:\n", __FUNCTION__); + + printf("%s: checking ECCConfiguration toggle bit\n", __FUNCTION__); + printf("%s:", __FUNCTION__); + toggle_a = toggle_b = 0; + for(i=0; i<10; i++) + { + unsigned char toggle = doc_toggle(bios); + + printf(" 0x%02x", toggle); + + if(i%2) + toggle_a += toggle; + else + toggle_b += toggle; + } /* for(i=0; i<10; i++) */ + printf("\n%s: toggle result: %d/%d\n", __FUNCTION__, toggle_a, toggle_b); + + if(chipid == flash->model_id + && ((toggle_a==5 && toggle_b==0)||(toggle_a==0 && toggle_b==5)) +#ifndef MSYSTEMS_DOC_NO_55AA_CHECKING + && id_0x55 == 0x55 && id_0xAA == 0xaa +#endif /* !MSYSTEMS_DOC_NO_55AA_CHECKING */ + ) + { + return(1); + } + + return(0); +} /* int probe_md2802(struct flashchip *flash) */ + + + +int +read_md2802(struct flashchip *flash, unsigned char *buf) +{ + + return(0); +} /* int read_md2802(struct flashchip *flash, unsigned char *buf) */ + + + +int +erase_md2802(struct flashchip *flash) +{ + volatile char *bios = flash->virt_addr; + + return(1); + *(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) = 0x10; +} /* int erase_md2802(struct flashchip *flash) */ + + + +int +write_md2802(struct flashchip *flash, unsigned char *buf) +{ + int i; + int total_size = flash->total_size *1024, page_size = flash->page_size; + volatile unsigned char * bios = flash->virt_addr; + + return(1); + erase_md2802 (flash); + if (*bios != (unsigned char ) 0xff) { + printf("ERASE FAILED\n"); + return -1; + } + printf ("Programming Page: "); + for (i = 0; i < total_size/page_size; i++) { + printf ("%04d at address: 0x%08x", i, i * page_size); + //write_page_md2802(bios, buf + i * page_size, bios + i * page_size, page_size); + printf ("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"); + } + printf("\n"); + //protect_md2802(bios); + +} /* int write_md2802(struct flashchip *flash, char *buf) */ + + + + + + +/* + wait timeout msec for doc to become ready + return: + 0: ready + -1: timeout expired +*/ +static int +doc_wait(volatile char *bios, int timeout) +{ + int i = 20; + + doc_read_4nop(bios); + + while(_doc_busy(bios) && (i != 0)) + { + usleep(timeout*1000/20); + i--; + } + + doc_read_2nop(bios); + + if(_doc_busy(bios)) + { + doc_read_2nop(bios); + return(-1); + } + + return(0); +} /* static int doc_wait(volatile char *bios, int timeout) */ + + + +static unsigned char +doc_read_docstatus(volatile char *bios) +{ + doc_read(bios, CDSNSlowIO); + doc_read_2nop(bios); + + return(doc_read(bios, _DOCStatus)); +} /* static unsigned char doc_read_docstatus(volatile char *bios) */ + + + +static unsigned char +doc_read_chipid(volatile char *bios) +{ + doc_read(bios, CDSNSlowIO); + doc_read_2nop(bios); + + return(doc_read(bios, _ChipID)); +} /* static unsigned char doc_read_chipid(volatile char *bios) */ + + + +static unsigned char +doc_read_cdsncontrol(volatile char *bios) +{ + unsigned char value; + + /* the delays might be necessary when reading the busy bit, + but because a read to this reg reads the busy bit + anyway we better do this delays... */ + doc_read_4nop(bios); + value = doc_read(bios, _CDSNControl); + doc_read_2nop(bios); + + return(value); +} /* static unsigned char doc_read_chipid(volatile char *bios) */ + + + +static void +doc_write_cdsncontrol(volatile char *bios, unsigned char data) +{ + doc_write(data, bios, _CDSNControl); + doc_read_4nop(bios); +} /* static void doc_write_chipid(volatile char *bios, unsigned char data) */ diff --git a/msys_doc.h b/msys_doc.h new file mode 100644 index 000000000..9ea523cc4 --- /dev/null +++ b/msys_doc.h @@ -0,0 +1,110 @@ +/* + * msys_doc.h: header file of msys_doc.c + * + * + * Copyright 2003 Niki W. Waibel + * + * 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. + */ + + + +#ifndef __MSYS_DOC_H__ +#define __MSYS_DOC_H__ 1 + + + +/* idea from include/linux/mtd/doc2000.h */ +/* registers with __ should not be read/written directly */ +#define MSYSTEMS_DOC_R__ChipID 0x1000 +#define MSYSTEMS_DOC_R__DOCStatus 0x1001 +#define MSYSTEMS_DOC_W_DOCControl 0x1002 +#define MSYSTEMS_DOC_R_FloorSelect 0x1003 +#define MSYSTEMS_DOC_W_FloorSelect 0x1003 +#define MSYSTEMS_DOC_R__CDSNControl 0x1004 +#define MSYSTEMS_DOC_W__CDSNControl 0x1004 +#define MSYSTEMS_DOC_R_CDSNDeviceSelect 0x1005 +#define MSYSTEMS_DOC_W_CDSNDeviceSelect 0x1005 +#define MSYSTEMS_DOC_R_ECCConfiguration 0x1006 +#define MSYSTEMS_DOC_W_ECCConfiguration 0x1006 +#define MSYSTEMS_DOC_R_CDSNSlowIO 0x100d +#define MSYSTEMS_DOC_W_CDSNSlowIO 0x100d +#define MSYSTEMS_DOC_R_ECCSyndrome0 0x1010 +#define MSYSTEMS_DOC_R_ECCSyndrome1 0x1011 +#define MSYSTEMS_DOC_R_ECCSyndrome2 0x1012 +#define MSYSTEMS_DOC_R_ECCSyndrome3 0x1013 +#define MSYSTEMS_DOC_R_ECCSyndrome4 0x1014 +#define MSYSTEMS_DOC_R_ECCSyndrome5 0x1015 +#define MSYSTEMS_DOC_R_AliasResolution 0x101b +#define MSYSTEMS_DOC_W_AliasResolution 0x101b +#define MSYSTEMS_DOC_R_ConfigurationInput 0x101c +#define MSYSTEMS_DOC_W_ConfigurationInput 0x101c +#define MSYSTEMS_DOC_R_ReadPipelineInitialization 0x101d +#define MSYSTEMS_DOC_W_WritePipelineTermination 0x101e +#define MSYSTEMS_DOC_R_LastDataRead 0x101f +#define MSYSTEMS_DOC_W_LastDataRead 0x101f +#define MSYSTEMS_DOC_R_NOP 0x1020 +#define MSYSTEMS_DOC_W_NOP 0x1020 + +#define MSYSTEMS_DOC_R_IPL_0x0000 0x0000 +#define MSYSTEMS_DOC_R_IPL_0x0001 0x0001 +#define MSYSTEMS_DOC_R_IPL_0x0002 0x0002 +#define MSYSTEMS_DOC_R_IPL_0x0003 0x0003 + +#define MSYSTEMS_DOC_R_CDSNIO_BASE 0x0800 +#define MSYSTEMS_DOC_W_CDSNIO_BASE 0x0800 + + + +#define doc_read(base,reg) \ + (*(volatile unsigned char *)(base + MSYSTEMS_DOC_R_##reg)) + +#define doc_read_nop(base) \ + doc_read(base, NOP) + +#define doc_read_2nop(base) \ + { doc_read_nop(base); doc_read_nop(base); } + +#define doc_read_4nop(base) \ + { doc_read_2nop(base); doc_read_2nop(base); } + +#define doc_write(data,base,reg) \ + (*(volatile unsigned char *)(base + MSYSTEMS_DOC_W_##reg)) = data + +#define doc_write_nop(base) \ + doc_write(0, base, NOP) + +#define doc_write_2nop(base) \ + { doc_write_nop(base); doc_write_nop(base); } + +#define doc_write_4nop(base) \ + { doc_write_2nop(base); doc_write_2nop(base); } + +#define _doc_busy(base) /* 0: ready; -1: busy */ \ + ( ((doc_read(base, _CDSNControl) & 0x80) >> 7) - 1) + +#define doc_toggle(base) /* 0, 1, 0, 1, 0, 1, ... if a doc is present */ \ + ( (doc_read(base, ECCConfiguration) & 0x04) >> 2 ) + + + +extern int probe_md2802(struct flashchip *flash); +extern int read_md2802(struct flashchip *flash, unsigned char *buf); +extern int erase_md2802(struct flashchip *flash); +extern int write_md2802(struct flashchip *flash, unsigned char *buf); + + + +#endif /* !__MSYS_DOC_H__ */ diff --git a/mx29f002.c b/mx29f002.c index 4ff98a089..4c22cd43f 100644 --- a/mx29f002.c +++ b/mx29f002.c @@ -25,13 +25,15 @@ * $Id$ */ +#include #include "flash.h" #include "jedec.h" +#include "mx29f002.h" int probe_29f002 (struct flashchip * flash) { volatile char * bios = flash->virt_addr; - unsigned char id1, id2, id3; + unsigned char id1, id2; *(bios + 0x5555) = 0xAA; *(bios + 0x2AAA) = 0x55; @@ -55,7 +57,6 @@ int erase_29f002 (struct flashchip * flash) { volatile char * bios = flash->virt_addr; - again: *(bios + 0x555) = 0xF0; *(bios + 0x555) = 0xAA; *(bios + 0x2AA) = 0x55; @@ -80,14 +81,15 @@ int erase_29f002 (struct flashchip * flash) *(bios + 0x3bfff) = 0x30; #endif + return(0); } -int write_29f002 (struct flashchip * flash, char * buf) +int write_29f002 (struct flashchip * flash, unsigned char * buf) { int i; - int total_size = flash->total_size * 1024, page_size = flash->page_size; + int total_size = flash->total_size * 1024; volatile char * bios = flash->virt_addr; - volatile char * dst = bios, * src = buf; + volatile char * dst = bios; *bios = 0xF0; myusec_delay(10); @@ -98,7 +100,7 @@ int write_29f002 (struct flashchip * flash, char * buf) for (i = 0; i < total_size; i++) { /* write to the sector */ if ((i & 0xfff) == 0) - printf ("address: 0x%08lx", i); + printf ("address: 0x%08lx", (unsigned long)i); *(bios + 0x5555) = 0xAA; *(bios + 0x2AAA) = 0x55; *(bios + 0x5555) = 0xA0; @@ -112,4 +114,6 @@ int write_29f002 (struct flashchip * flash, char * buf) } #endif printf("\n"); + + return(0); } diff --git a/mx29f002.h b/mx29f002.h new file mode 100644 index 000000000..0d252bbe9 --- /dev/null +++ b/mx29f002.h @@ -0,0 +1,8 @@ +#ifndef __MX29F002_H__ +#define __MX29F002_H__ 1 + +extern int probe_29f002 (struct flashchip * flash); +extern int erase_29f002 (struct flashchip * flash); +extern int write_29f002 (struct flashchip * flash, unsigned char * buf); + +#endif /* !__MX29F002_H__ */ diff --git a/sst28sf040.c b/sst28sf040.c index d811988ca..ee49f7978 100644 --- a/sst28sf040.c +++ b/sst28sf040.c @@ -25,6 +25,7 @@ * $Id$ */ +#include #include "flash.h" #include "jedec.h" @@ -63,16 +64,18 @@ static __inline__ void unprotect_28sf040 (volatile char * bios) tmp = *(volatile unsigned char *) (bios + 0x041A); } -static __inline__ erase_sector_28sf040 (volatile char * bios, unsigned long address) +static __inline__ int erase_sector_28sf040 (volatile char * bios, unsigned long address) { *bios = AUTO_PG_ERASE1; *(bios + address) = AUTO_PG_ERASE2; /* wait for Toggle bit ready */ toggle_ready_jedec(bios); + + return(0); } -static __inline__ write_sector_28sf040(volatile char * bios, unsigned char * src, +static __inline__ int write_sector_28sf040(volatile char * bios, unsigned char * src, volatile unsigned char * dst, unsigned int page_size) { int i; @@ -91,6 +94,8 @@ static __inline__ write_sector_28sf040(volatile char * bios, unsigned char * src /* wait for Toggle bit ready */ toggle_ready_jedec(bios); } + + return(0); } int probe_28sf040 (struct flashchip * flash) @@ -133,9 +138,11 @@ int erase_28sf040 (struct flashchip * flash) myusec_delay(10); toggle_ready_jedec(bios); + + return(0); } -int write_28sf040 (struct flashchip * flash, char * buf) +int write_28sf040 (struct flashchip * flash, unsigned char * buf) { int i; int total_size = flash->total_size * 1024, page_size = flash->page_size; @@ -157,4 +164,6 @@ int write_28sf040 (struct flashchip * flash, char * buf) printf("\n"); protect_28sf040 (bios); + + return(0); } diff --git a/sst28sf040.h b/sst28sf040.h new file mode 100644 index 000000000..ab2641d32 --- /dev/null +++ b/sst28sf040.h @@ -0,0 +1,8 @@ +#ifndef __SST28SF040_H__ +#define __SST28SF040_H__ + +extern int probe_28sf040 (struct flashchip * flash); +extern int erase_28sf040 (struct flashchip * flash); +extern int write_28sf040 (struct flashchip * flash, unsigned char * buf); + +#endif /* !__SST28SF040_H__ */ diff --git a/sst39sf020.c b/sst39sf020.c index 80116aefe..65fc62382 100644 --- a/sst39sf020.c +++ b/sst39sf020.c @@ -25,9 +25,10 @@ * $Id$ */ +#include #include "flash.h" #include "jedec.h" -#include +#include "sst39sf020.h" #define AUTO_PG_ERASE1 0x20 #define AUTO_PG_ERASE2 0xD0 @@ -64,16 +65,18 @@ static __inline__ void unprotect_39sf020 (volatile char * bios) tmp = *(volatile unsigned char *) (bios + 0x041A); } -static __inline__ erase_sector_39sf020 (volatile char * bios, unsigned long address) +static __inline__ int erase_sector_39sf020 (volatile char * bios, unsigned long address) { *bios = AUTO_PG_ERASE1; *(bios + address) = AUTO_PG_ERASE2; /* wait for Toggle bit ready */ toggle_ready_jedec(bios); + + return(0); } -static __inline__ write_sector_39sf020(volatile char * bios, +static __inline__ int write_sector_39sf020(volatile char * bios, unsigned char * src, volatile unsigned char * dst, unsigned int page_size) @@ -84,7 +87,7 @@ static __inline__ write_sector_39sf020(volatile char * bios, for (i = 0; i < page_size; i++) { if (*dst != 0xff) { printf("FATAL: dst %p not erased (val 0x%x\n", dst, *dst); - return; + return(-1); } /* transfer data from source to destination */ if (*src == 0xFF) { @@ -101,10 +104,12 @@ static __inline__ write_sector_39sf020(volatile char * bios, *dst = *src; toggle_ready_jedec(bios); if (*dst != *src) - printf("BAD! dst 0x%x val 0x%x src 0x%x\n", - dst, *dst, *src); + printf("BAD! dst 0x%lx val 0x%x src 0x%x\n", + (unsigned long)dst, *dst, *src); dst++, src++; } + + return(0); } int probe_39sf020 (struct flashchip * flash) @@ -162,9 +167,11 @@ int erase_39sf020 (struct flashchip * flash) *Temp = 0x10; /* write data 0x55 to the address */ myusec_delay(50000); + + return(0); } -int write_39sf020 (struct flashchip * flash, char * buf) +int write_39sf020 (struct flashchip * flash, unsigned char * buf) { int i; int total_size = flash->total_size * 1024, page_size = flash->page_size; @@ -187,4 +194,6 @@ int write_39sf020 (struct flashchip * flash, char * buf) printf("\n"); // protect_39sf020 (bios); + + return(0); } diff --git a/sst39sf020.h b/sst39sf020.h new file mode 100644 index 000000000..dfbedfffc --- /dev/null +++ b/sst39sf020.h @@ -0,0 +1,8 @@ +#ifndef __SST39SF020_H__ +#define __SST39SF020_H__ 1 + +extern int probe_39sf020 (struct flashchip * flash); +extern int erase_39sf020 (struct flashchip * flash); +extern int write_39sf020 (struct flashchip * flash, unsigned char * buf); + +#endif /* !__SST39SF020_H__ */ diff --git a/w49f002u.c b/w49f002u.c index bf8feb4cc..b7c57eb25 100644 --- a/w49f002u.c +++ b/w49f002u.c @@ -25,13 +25,15 @@ * $Id */ +#include #include "flash.h" #include "jedec.h" +#include "w49f002u.h" int probe_49f002 (struct flashchip * flash) { volatile char * bios = flash->virt_addr; - unsigned char id1, id2, id3; + unsigned char id1, id2; *(bios + 0x5555) = 0xAA; *(bios + 0x2AAA) = 0x55; @@ -56,7 +58,6 @@ int erase_49f002 (struct flashchip * flash) { volatile char * bios = flash->virt_addr; - again: *(bios + 0x5555) = 0xAA; *(bios + 0x2AAA) = 0x55; *(bios + 0x5555) = 0x80; @@ -80,14 +81,15 @@ int erase_49f002 (struct flashchip * flash) *(bios + 0x3bfff) = 0x30; #endif + return(0); } -int write_49f002 (struct flashchip * flash, char * buf) +int write_49f002 (struct flashchip * flash, unsigned char * buf) { int i; - int total_size = flash->total_size * 1024, page_size = flash->page_size; + int total_size = flash->total_size * 1024; volatile char * bios = flash->virt_addr; - volatile char * dst = bios, * src = buf; + volatile char * dst = bios; *bios = 0xF0; myusec_delay(10); @@ -98,7 +100,7 @@ int write_49f002 (struct flashchip * flash, char * buf) for (i = 0; i < total_size; i++) { /* write to the sector */ if ((i & 0xfff) == 0) - printf ("address: 0x%08lx", i); + printf ("address: 0x%08lx", (unsigned long)i); *(bios + 0x5555) = 0xAA; *(bios + 0x2AAA) = 0x55; *(bios + 0x5555) = 0xA0; @@ -112,4 +114,6 @@ int write_49f002 (struct flashchip * flash, char * buf) } #endif printf("\n"); + + return(0); } diff --git a/w49f002u.h b/w49f002u.h new file mode 100644 index 000000000..9705d4247 --- /dev/null +++ b/w49f002u.h @@ -0,0 +1,8 @@ +#ifndef __W49F002U_H__ +#define __W49F002U_H__ 1 + +extern int probe_49f002 (struct flashchip * flash); +extern int erase_49f002 (struct flashchip * flash); +extern int write_49f002 (struct flashchip * flash, unsigned char * buf); + +#endif /* !__W49F002U_H__ */ -- cgit v1.2.3