You can subscribe to this list here.
2001 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(79) |
Aug
(27) |
Sep
(64) |
Oct
(202) |
Nov
(31) |
Dec
(59) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2002 |
Jan
(125) |
Feb
(173) |
Mar
(13) |
Apr
(140) |
May
(75) |
Jun
(1) |
Jul
(37) |
Aug
(14) |
Sep
|
Oct
(20) |
Nov
(9) |
Dec
(2) |
2003 |
Jan
(51) |
Feb
(12) |
Mar
(18) |
Apr
(24) |
May
(1) |
Jun
|
Jul
|
Aug
(72) |
Sep
(12) |
Oct
(18) |
Nov
(60) |
Dec
(26) |
2004 |
Jan
(1) |
Feb
(40) |
Mar
(3) |
Apr
(3) |
May
|
Jun
(1) |
Jul
(4) |
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
(1) |
2005 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
(1) |
Dec
(5) |
2006 |
Jan
(13) |
Feb
(5) |
Mar
(8) |
Apr
(13) |
May
(7) |
Jun
(6) |
Jul
(10) |
Aug
(6) |
Sep
(6) |
Oct
(35) |
Nov
(20) |
Dec
(10) |
2007 |
Jan
(13) |
Feb
(9) |
Mar
(2) |
Apr
(1) |
May
(1) |
Jun
(2) |
Jul
(2) |
Aug
(3) |
Sep
(1) |
Oct
|
Nov
(1) |
Dec
(1) |
2008 |
Jan
|
Feb
|
Mar
(1) |
Apr
(4) |
May
(1) |
Jun
|
Jul
|
Aug
(2) |
Sep
(1) |
Oct
|
Nov
|
Dec
|
2009 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(54) |
Jun
(78) |
Jul
(35) |
Aug
(21) |
Sep
(21) |
Oct
(29) |
Nov
(10) |
Dec
(5) |
2010 |
Jan
|
Feb
|
Mar
(26) |
Apr
(55) |
May
(73) |
Jun
(63) |
Jul
(38) |
Aug
(39) |
Sep
(19) |
Oct
(2) |
Nov
(1) |
Dec
(1) |
2011 |
Jan
(2) |
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2013 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
|
Dec
|
From: Erik M. <er...@us...> - 2001-10-24 12:28:28
|
Update of /cvsroot/blob/blob/src/blob In directory usw-pr-cvs1:/tmp/cvs-serv13224/src/blob Modified Files: flash.c main.c Log Message: More flash cleanup. This includes the new flash write algorithm. Next is static flash partition support. Index: flash.c =================================================================== RCS file: /cvsroot/blob/blob/src/blob/flash.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- flash.c 2001/10/21 21:36:15 1.5 +++ flash.c 2001/10/24 12:28:25 1.6 @@ -11,6 +11,7 @@ /* * flash.c: Flash I/O functions for blob * + * Copyright (C) 2001 Erik Mouw (J.A...@it...) * Copyright (C) 1999 Jan-Derk Bakker (J.D...@it...) * * This program is free software; you can redistribute it and/or modify @@ -48,7 +49,7 @@ /* this is enough for a 16MB flash with 128kB blocks */ -#define NEW_NUM_FLASH_BLOCKS (128) +#define NUM_FLASH_BLOCKS (128) typedef struct { @@ -58,7 +59,7 @@ } flash_block_t; -static flash_block_t flash_blocks[NEW_NUM_FLASH_BLOCKS]; +static flash_block_t flash_blocks[NUM_FLASH_BLOCKS]; static int num_flash_blocks; flash_descriptor_t *flash_descriptors; @@ -113,7 +114,7 @@ num_flash_blocks++; - if(num_flash_blocks >= NEW_NUM_FLASH_BLOCKS) { + if(num_flash_blocks >= NUM_FLASH_BLOCKS) { printerrprefix(); SerialOutputString("not enough flash_blocks\n"); break; @@ -155,14 +156,21 @@ cur = start; end = start + nwords; +#if BLOB_DEBUG + SerialOutputString(__FUNCTION__ "(): erasing 0x"); + SerialOutputHex(nwords); + SerialOutputString(" ("); + SerialOutputDec(nwords); + SerialOutputString(") words at 0x"); + SerialOutputHex((u32)start); + SerialOutputByte('\n'); +#endif while(cur < end) { if(*cur != 0xffffffff) { - -#ifdef BLOB_DEBUG - SerialOutputString(__FUNCTION__ "(): erasing dirty block at 0x"); + SerialOutputString("erasing dirty block at 0x"); SerialOutputHex((u32)cur); SerialOutputByte('\n'); -#endif + /* dirty block */ rv = flash_driver->flash_erase(cur); @@ -184,189 +192,107 @@ + +/* Write a flash region with a minimum number of erase operations. + * + * Flash chips wear from erase operations (that's why flash lifetime + * is specified in erase cycles), so we try to limit the number of + * erase operations in this function. Luckily the flash helps us a + * little bit with this, because it only allows you to change a '1' + * bit into a '0' during a write operation. This means that 0xffff can + * be changed into 0x1010, and 0x1010 into 0x0000, but 0x0000 can't be + * changed into anything else anymore because there are no '1' bits + * left. + */ int flash_write_region(u32 *dst, const u32 *src, u32 nwords) { - u32 *cur; - u32 *end; int rv; + u32 nerrors = 0; + u32 i = 0; - cur = dst; - end = dst + nwords; + u32 nerase = 0; + u32 nwrite = 0; + u32 nscandown = 0; + u32 nskip = 0; -#ifdef BLOB_DEBUG +#if BLOB_DEBUG SerialOutputString(__FUNCTION__ "(): flashing 0x"); SerialOutputHex(nwords); - SerialOutputString(" words from 0x"); + SerialOutputString(" ("); + SerialOutputDec(nwords); + SerialOutputString(") words from 0x"); SerialOutputHex((u32)src); SerialOutputString(" to 0x"); SerialOutputHex((u32)dst); SerialOutputByte('\n'); #endif - - while(cur < end) { - if((u32)cur % (16 * 1024) == 0) { - SerialOutputByte('.'); - led_toggle(); - } - - rv = flash_driver->flash_write(cur, src); - if(rv < 0) { - printerrprefix(); - SerialOutputString("flash write error at 0x"); - SerialOutputHex((u32)cur); - SerialOutputByte('\n'); - return rv; + while(i < nwords) { + /* nothing to write */ + if(dst[i] == src[i]) { + i++; + nskip++; + continue; } - - cur ++; - src ++; - } - - return 0; -} - - - - -/* -------- OLD ---------------------------------------------------- */ - - - - -/* Static function defs */ -static u32 EraseOne(const char *whichOne); - - + /* different, so write to this location */ + rv = flash_driver->flash_write(&dst[i], &src[i]); + nwrite++; + + if(rv == 0) { + i++; + } else { + nerrors++; + + SerialOutputString("erasing at 0x"); + SerialOutputHex((u32)&dst[i]); + SerialOutputString("..."); -void EraseBlocks(tBlockType which) -{ - char *thisBlock; - int numBlocks, i; + /* erase block at current location */ + rv = flash_driver->flash_erase(&dst[i]); + nerase++; + if(rv < 0) { + /* something is obviously wrong */ + return rv; + } + + SerialOutputString(" scanning down..."); - switch(which) { - case blBlob: - thisBlock = (char *)BLOB_START; - numBlocks = NUM_BLOB_BLOCKS; - break; + /* scan down until we find the first + non-erased location and restart writing + again from that location */ + while((i > 0) && + ((dst[i] != src[i]) || (dst[i] == 0xffffffff))) { + i--; + nscandown++; + } -#ifdef PARAM_START - case blParam: - thisBlock = (char *)PARAM_START; - numBlocks = NUM_PARAM_BLOCKS; - break; -#endif + SerialOutputString(" resume writing at 0x"); + SerialOutputHex((u32)&dst[i]); + SerialOutputByte('\n'); + } - case blKernel: - thisBlock = (char *)KERNEL_START; - numBlocks = NUM_KERNEL_BLOCKS; - break; - - case blRamdisk: - thisBlock = (char *)INITRD_START; - numBlocks = NUM_INITRD_BLOCKS; - break; - - default: - /* this should not happen */ - return; - } - - for(i = 0; i < numBlocks; i++, thisBlock += MAIN_BLOCK_SIZE) { - SerialOutputByte('.'); - led_toggle(); - if(EraseOne(thisBlock) != 0) { + /* there is something seriously wrong if this is true */ + if(nerrors > 2 * nwords) { printerrprefix(); - SerialOutputString("erase error at address 0x"); - SerialOutputHex((u32)thisBlock); - SerialOutputByte('\n'); - return; + SerialOutputString("too many flash errors, probably hardware error\n"); + return -EFLASHPGM; } } -} /* EraseBlocks */ - - - -void WriteBlocksFromMem(tBlockType type, const u32 *source, int length) -{ - u32 *flashBase; - int maxLength; - - if((u32)source & 0x03) { - printerror(EALIGN, NULL); #ifdef BLOB_DEBUG - printerrprefix(); - SerialOutputString("Address = 0x"); - SerialOutputHex((u32)source); - SerialOutputByte('\n'); -#endif - return; - } - - if(length & 0x03) - length += 0x04; - length &= ~((u32) 0x03); - - switch(type) { - case blBlob: - flashBase = (u32 *)BLOB_START; - maxLength = BLOB_LEN; - break; - -#ifdef PARAM_START - case blParam: - flashBase = (u32 *)PARAM_START; - maxLength = PARAM_LEN; - break; -#endif - - case blKernel: - flashBase = (u32 *)KERNEL_START; - maxLength = KERNEL_LEN; - break; - - case blRamdisk: - flashBase = (u32 *)INITRD_START; - maxLength = INITRD_LEN; - break; - - default: - /* this should not happen */ - return; - } - - length = (length + 3) / 4; - maxLength /= 4; - - if(length > maxLength) - length = maxLength; - -#ifdef BLOB_DEBUG - SerialOutputString(__FUNCTION__ "(): Flashing 0x"); - SerialOutputHex((u32)length); - SerialOutputString(" words from 0x"); - SerialOutputHex((u32)source); - SerialOutputString(" to 0x"); - SerialOutputHex((u32)flashBase); + SerialOutputDec(nwords); + SerialOutputString(" words source image\n"); + SerialOutputDec(nwrite); + SerialOutputString(" words written to flash\n"); + SerialOutputDec(nskip); + SerialOutputString(" words skipped\n"); + SerialOutputDec(nerase); + SerialOutputString(" erase operations\n"); + SerialOutputDec(nscandown); + SerialOutputString(" words scanned down\n"); SerialOutputByte('\n'); #endif - - flash_write_region(flashBase, source, length); -} /* WriteBlocksFromMem */ - - - -static u32 EraseOne(const char *whichOne) -{ - int rv; - - rv = flash_erase_region((u32 *)whichOne, MAIN_BLOCK_SIZE / 4); - - if(rv < 0) - return 1; - else - return 0; -} /* EraseOne */ + return 0; +} Index: main.c =================================================================== RCS file: /cvsroot/blob/blob/src/blob/main.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- main.c 2001/10/14 20:24:32 1.3 +++ main.c 2001/10/24 12:28:25 1.4 @@ -131,13 +131,7 @@ #ifdef BLOB_DEBUG /* print some information */ - SerialOutputString("Running from "); - if(RunningFromInternal()) - SerialOutputString("internal"); - else - SerialOutputString("external"); - - SerialOutputString(" flash, blockSize = 0x"); + SerialOutputString("Flash blockSize = 0x"); SerialOutputHex(blockSize); SerialOutputByte('\n'); #endif @@ -271,38 +265,40 @@ static int Flash(int argc, char *argv[]) { - u32 startAddress = 0; - tBlockType block; - int numBytes = 0; - int maxSize = 0; + u32 *src; + u32 *dst; + u32 numBytes = 0; + u32 maxSize = 0; + u32 nwords; block_source_t type = fromFlash; + if(argc < 2) return -ENOPARAMS; if(strncmp(argv[1], "blob", 4) == 0) { - startAddress = BLOB_RAM_BASE; - block = blBlob; - numBytes = blob_status.blobSize; + src = (u32 *)BLOB_RAM_BASE; + dst = (u32 *)BLOB_START; maxSize = BLOB_LEN; + numBytes = blob_status.blobSize; type = blob_status.blobType; #ifdef PARAM_START } else if(strncmp(argv[1], "param", 5) == 0) { - startAddress = PARAM_RAM_BASE; - block = blParam; - numBytes = blob_status.paramSize; + src = (u32 *)PARAM_RAM_BASE; + dst = (u32 *)PARAM_START; maxSize = PARAM_LEN; + numBytes = blob_status.paramSize; type = blob_status.paramType; #endif } else if(strncmp(argv[1], "kernel", 6) == 0) { - startAddress = KERNEL_RAM_BASE; - block = blKernel; + src = (u32 *)KERNEL_RAM_BASE; + dst = (u32 *)KERNEL_START; numBytes = blob_status.kernelSize; maxSize = KERNEL_LEN; type = blob_status.kernelType; } else if(strncmp(argv[1], "ramdisk", 7) == 0) { - startAddress = RAMDISK_RAM_BASE; - block = blRamdisk; + src = (u32 *)RAMDISK_RAM_BASE; + dst = (u32 *)INITRD_START; numBytes = blob_status.ramdiskSize; maxSize = INITRD_LEN; type = blob_status.ramdiskType; @@ -312,7 +308,6 @@ } if(type == fromFlash) { - /* error */ printerrprefix(); SerialOutputString(argv[1]); SerialOutputString(" not downloaded\n"); @@ -330,13 +325,14 @@ return -ETOOLONG; } + nwords = (numBytes + sizeof(u32) - 1) / sizeof(u32); + SerialOutputString("Saving "); SerialOutputString(argv[1]); - SerialOutputString(" to flash "); - EraseBlocks(block); - SerialOutputByte(' '); - WriteBlocksFromMem(block, (u32 *)startAddress, numBytes); - SerialOutputString(" done\n"); + SerialOutputString(" to flash\n"); + + + flash_write_region(dst, src, nwords); return 0; } @@ -407,12 +403,6 @@ { SerialOutputString("Bootloader : " PACKAGE "\n"); SerialOutputString("Version : " VERSION "\n"); - - SerialOutputString("Running from : "); - if(RunningFromInternal()) - SerialOutputString("internal"); - else - SerialOutputString("external"); SerialOutputString(" flash\nBlocksize : 0x"); SerialOutputHex(blob_status.blockSize); |
From: Erik M. <er...@us...> - 2001-10-24 12:28:28
|
Update of /cvsroot/blob/blob/include/blob In directory usw-pr-cvs1:/tmp/cvs-serv13224/include/blob Modified Files: flash.h Log Message: More flash cleanup. This includes the new flash write algorithm. Next is static flash partition support. Index: flash.h =================================================================== RCS file: /cvsroot/blob/blob/include/blob/flash.h,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- flash.h 2001/10/21 21:36:15 1.4 +++ flash.h 2001/10/24 12:28:25 1.5 @@ -75,16 +75,6 @@ /* -------- OLD ---------------------------------------------------- */ -#define NUM_FLASH_BLOCKS (31) -#define FLASH_BLOCK_BASE ((u32 *) 0x020000) -#define FLASH_BLOCK_SIZE ((u32) 0x020000) -#define BLOCK_NAME_LEN (64) -#define NO_BLOCK ((u8) 0xFF) -#define BLOCK_HDR_SIG ((u32) 'LART') -#define BLOCK_EMPTY_SIG ((u32) 0xFFFFFFFF) - -#define BLOCK_IN_USE(x) (x.signature == BLOCK_HDR_SIG) - typedef enum { blBlob, blParam, @@ -92,20 +82,9 @@ blRamdisk } tBlockType; -static inline int RunningFromInternal(void) { - - if(((*(u32 *)0xA0000010) & 0x04) == 0) - return 1; - else - return 0; -} - #define MAIN_BLOCK_SIZE (32768 * 4) - -#define CS0_BASE (0x00000000) -#define CS1_BASE (0x08000000) -#define INT_FLASH_BASE (RunningFromInternal() ? CS0_BASE : CS1_BASE) +#define INT_FLASH_BASE 0x00000000 #ifdef ASSABET // Assabet settings come from linux/drivers/block/flash_mem.h #define BLOB_START 0x00000 @@ -144,10 +123,6 @@ #define NUM_INITRD_BLOCKS (24) #define INITRD_LEN (NUM_INITRD_BLOCKS * MAIN_BLOCK_SIZE) #endif - - -void EraseBlocks(tBlockType which); -void WriteBlocksFromMem(tBlockType type, const u32 *source, int length); #endif |
From: Erik M. <er...@us...> - 2001-10-21 21:45:07
|
Update of /cvsroot/blob/blob In directory usw-pr-cvs1:/tmp/cvs-serv18706 Modified Files: configure.in Log Message: Fix a typo Index: configure.in =================================================================== RCS file: /cvsroot/blob/blob/configure.in,v retrieving revision 1.19 retrieving revision 1.20 diff -u -d -r1.19 -r1.20 --- configure.in 2001/10/21 21:37:07 1.19 +++ configure.in 2001/10/21 21:45:04 1.20 @@ -274,7 +274,7 @@ LCD="lcd.o" AC_DEFINE(CONFIG_LCD_SUPPORT) else - AC_MSG_WARN([No LCD suport for ${board_name}, disabling]) + AC_MSG_WARN([No LCD support for ${board_name}, disabling]) LCD="" lcd_flag="no" fi |
From: Erik M. <er...@us...> - 2001-10-21 21:42:11
|
Update of /cvsroot/blob/blob/src/blob In directory usw-pr-cvs1:/tmp/cvs-serv18128 Modified Files: nullflash.c Log Message: Oops, fix compiler warnings Index: nullflash.c =================================================================== RCS file: /cvsroot/blob/blob/src/blob/nullflash.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- nullflash.c 2001/10/21 21:35:11 1.1 +++ nullflash.c 2001/10/21 21:42:09 1.2 @@ -26,8 +26,9 @@ #endif #include <blob/errno.h> +#include <blob/error.h> #include <blob/flash.h> -#include <blob/util.h> +#include <blob/serial.h> |
From: Erik M. <er...@us...> - 2001-10-21 21:38:37
|
Update of /cvsroot/blob/blob/src/blob In directory usw-pr-cvs1:/tmp/cvs-serv17396 Modified Files: assabet.c brutus.c clart.c lart.c nesa.c pleb.c shannon.c system3.c Log Message: The architectures now use the new flash driver functionality. This greatly reduces the amount of code replication. (Ok now, Russ?) Index: assabet.c =================================================================== RCS file: /cvsroot/blob/blob/src/blob/assabet.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- assabet.c 2001/10/15 21:54:17 1.2 +++ assabet.c 2001/10/21 21:38:34 1.3 @@ -25,15 +25,15 @@ # include <blob/config.h> #endif -#include <blob/arch.h> -#include <blob/errno.h> #include <blob/flash.h> -#include <blob/util.h> +#include <blob/init.h> + + /* flash descriptor for Assabet flash */ /* 2x Intel 28F128J3A strataflash (16MB) */ -flash_descriptor_t flash_descriptors[] = +static flash_descriptor_t assabet_flash_descriptors[] = { { size: 2 * 128 * 1024, @@ -47,81 +47,11 @@ - -/* flash commands for two 16 bit intel flash chips */ -#define READ_ARRAY 0x00FF00FF -#define ERASE_SETUP 0x00200020 -#define ERASE_CONFIRM 0x00D000D0 -#define PGM_SETUP 0x00400040 -#define STATUS_READ 0x00700070 -#define STATUS_CLEAR 0x00500050 -#define STATUS_BUSY 0x00800080 -#define STATUS_ERASE_ERR 0x00200020 -#define STATUS_PGM_ERR 0x00100010 - - - -int erase_flash(u32 *addr) +static void init_assabet_flash_driver(void) { - u32 result; - - /* prepare for erase */ - *addr = data_to_flash(ERASE_SETUP); - barrier(); - - /* erase block */ - *addr = data_to_flash(ERASE_CONFIRM); - barrier(); - - /* status check */ - do { - *addr = data_to_flash(STATUS_READ); - barrier(); - result = data_from_flash(*addr); - barrier(); - } while((~result & STATUS_BUSY) != 0); - - /* put flash back into Read Array mode */ - *addr = data_to_flash(READ_ARRAY); - barrier(); - - if((result & STATUS_ERASE_ERR) != 0) - return -EFLASHERASE; - - return 0; + flash_descriptors = assabet_flash_descriptors; + flash_driver = &intel32_flash_driver; } - - - -int write_flash(u32 *dst, const u32* src) -{ - u32 result; - - /* setup flash for writing */ - *dst = data_to_flash(PGM_SETUP); - barrier(); - - /* write data */ - *dst = *src; - barrier(); - - /* status check */ - do { - *dst = data_to_flash(STATUS_READ); - barrier(); - - result = data_from_flash(*dst); - barrier(); - } while((~result & STATUS_BUSY) != 0); - - /* put flash back into Read Array mode */ - *dst = data_to_flash(READ_ARRAY); - barrier(); - - if(((result & STATUS_PGM_ERR) != 0) || (*dst != *src)) - return -EFLASHPGM; - - return 0; -} +__initlist(init_assabet_flash_driver, INIT_LEVEL_OTHER_STUFF); Index: brutus.c =================================================================== RCS file: /cvsroot/blob/blob/src/blob/brutus.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- brutus.c 2001/10/15 21:55:38 1.2 +++ brutus.c 2001/10/21 21:38:34 1.3 @@ -25,19 +25,17 @@ # include <blob/config.h> #endif -#include <blob/arch.h> -#include <blob/errno.h> #include <blob/flash.h> -#include <blob/util.h> +#include <blob/init.h> -#warning "Please verify Brutus flash layout" /* flash descriptor for Brutus flash. */ /* I have *really* no idea what kind of flash Brutus uses */ -flash_descriptor_t flash_descriptors[] = +static flash_descriptor_t brutus_flash_descriptors[] = { +#warning "Please verify Brutus flash layout" { /* NULL block */ }, @@ -45,19 +43,12 @@ - -#warning "Please verify Brutus flash functions" -int erase_flash(u32 *addr) +static void init_brutus_flash_driver(void) { - return -EFLASHERASE; + flash_descriptors = brutus_flash_descriptors; +#warning "Please add a proper Brutus flash driver" + flash_driver = &null_flash_driver; } - - - -/* write a flash block at a given location */ -int write_flash(u32 *dst, const u32* src) -{ - return -EFLASHPGM; -} +__initlist(init_brutus_flash_driver, INIT_LEVEL_OTHER_STUFF); Index: clart.c =================================================================== RCS file: /cvsroot/blob/blob/src/blob/clart.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- clart.c 2001/10/15 21:54:17 1.2 +++ clart.c 2001/10/21 21:38:34 1.3 @@ -25,17 +25,15 @@ # include <blob/config.h> #endif -#include <blob/arch.h> -#include <blob/errno.h> #include <blob/flash.h> -#include <blob/util.h> +#include <blob/init.h> /* flash descriptor for CreditLART flash */ /* 1x Intel 28F256J3A strataflash (16MB) */ -flash_descriptor_t flash_descriptors[] = +static flash_descriptor_t clart_flash_descriptors[] = { { size: 128 * 1024, @@ -49,85 +47,11 @@ - -/* flash commands for a single 16 bit intel flash chip */ -#define READ_ARRAY 0x000000FF -#define ERASE_SETUP 0x00000020 -#define ERASE_CONFIRM 0x000000D0 -#define PGM_SETUP 0x00000040 -#define STATUS_READ 0x00000070 -#define STATUS_CLEAR 0x00000050 -#define STATUS_BUSY 0x00000080 -#define STATUS_ERASE_ERR 0x00000020 -#define STATUS_PGM_ERR 0x00000010 - - - - -/* the next two functions should work for all Intel flashes */ -/* erases a flash block at the given address */ -int erase_flash(u32 *addr) +static void init_clart_flash_driver(void) { - u32 result; - - /* prepare for erase */ - *addr = data_to_flash(ERASE_SETUP); - barrier(); - - /* erase block */ - *addr = data_to_flash(ERASE_CONFIRM); - barrier(); - - /* status check */ - do { - *addr = data_to_flash(STATUS_READ); - barrier(); - result = data_from_flash(*addr); - barrier(); - } while((~result & STATUS_BUSY) != 0); - - /* put flash back into Read Array mode */ - *addr = data_to_flash(READ_ARRAY); - barrier(); - - if((result & STATUS_ERASE_ERR) != 0) - return -EFLASHERASE; - - return 0; + flash_descriptors = clart_flash_descriptors; + flash_driver = &intel16_flash_driver; } - - - - -/* write a flash block at a given location */ -int write_flash(u32 *dst, const u32* src) -{ - u32 result; - - /* setup flash for writing */ - *dst = data_to_flash(PGM_SETUP); - barrier(); - - /* write data */ - *dst = *src; - barrier(); - - /* status check */ - do { - *dst = data_to_flash(STATUS_READ); - barrier(); - - result = data_from_flash(*dst); - barrier(); - } while((~result & STATUS_BUSY) != 0); - - /* put flash back into Read Array mode */ - *dst = data_to_flash(READ_ARRAY); - barrier(); - if(((result & STATUS_PGM_ERR) != 0) || (*dst != *src)) - return -EFLASHPGM; - - return 0; -} +__initlist(init_clart_flash_driver, INIT_LEVEL_OTHER_STUFF); Index: lart.c =================================================================== RCS file: /cvsroot/blob/blob/src/blob/lart.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- lart.c 2001/10/15 21:54:17 1.2 +++ lart.c 2001/10/21 21:38:34 1.3 @@ -25,17 +25,15 @@ # include <blob/config.h> #endif -#include <blob/arch.h> -#include <blob/errno.h> #include <blob/flash.h> -#include <blob/util.h> +#include <blob/init.h> /* flash descriptor for LART flash */ /* 2x Intel 28F160F3B fast boot block flash (4MB) */ -flash_descriptor_t flash_descriptors[] = +static flash_descriptor_t lart_flash_descriptors[] = { { size: 2 * 8 * 1024, @@ -58,83 +56,16 @@ -/* flash commands for two 16 bit intel flash chips */ -#define READ_ARRAY 0x00FF00FF -#define ERASE_SETUP 0x00200020 -#define ERASE_CONFIRM 0x00D000D0 -#define PGM_SETUP 0x00400040 -#define STATUS_READ 0x00700070 -#define STATUS_CLEAR 0x00500050 -#define STATUS_BUSY 0x00800080 -#define STATUS_ERASE_ERR 0x00200020 -#define STATUS_PGM_ERR 0x00100010 - - - - -/* the next two functions should work for all Intel flashes */ - -/* erases a flash block at the given address */ -int erase_flash(u32 *addr) +static void init_lart_flash_driver(void) { - u32 result; - - /* prepare for erase */ - *addr = data_to_flash(ERASE_SETUP); - barrier(); - - /* erase block */ - *addr = data_to_flash(ERASE_CONFIRM); - barrier(); - - /* status check */ - do { - *addr = data_to_flash(STATUS_READ); - barrier(); - result = data_from_flash(*addr); - barrier(); - } while((~result & STATUS_BUSY) != 0); - - /* put flash back into Read Array mode */ - *addr = data_to_flash(READ_ARRAY); - barrier(); - - if((result & STATUS_ERASE_ERR) != 0) - return -EFLASHERASE; + /* we could do funky detection over here, because the LART can + * have both internal and external flash with different + * properties. for the time being we just ignore that fact. + * -- Erik + */ - return 0; + flash_descriptors = lart_flash_descriptors; + flash_driver = &intel32_flash_driver; } - - -/* write a flash block at a given location */ -int write_flash(u32 *dst, const u32* src) -{ - u32 result; - - /* setup flash for writing */ - *dst = data_to_flash(PGM_SETUP); - barrier(); - - /* write data */ - *dst = *src; - barrier(); - - /* status check */ - do { - *dst = data_to_flash(STATUS_READ); - barrier(); - - result = data_from_flash(*dst); - barrier(); - } while((~result & STATUS_BUSY) != 0); - - /* put flash back into Read Array mode */ - *dst = data_to_flash(READ_ARRAY); - barrier(); - - if(((result & STATUS_PGM_ERR) != 0) || (*dst != *src)) - return -EFLASHPGM; - - return 0; -} +__initlist(init_lart_flash_driver, INIT_LEVEL_OTHER_STUFF); Index: nesa.c =================================================================== RCS file: /cvsroot/blob/blob/src/blob/nesa.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- nesa.c 2001/10/15 21:56:37 1.2 +++ nesa.c 2001/10/21 21:38:34 1.3 @@ -25,20 +25,17 @@ # include <blob/config.h> #endif -#include <blob/arch.h> -#include <blob/errno.h> #include <blob/flash.h> -#include <blob/util.h> - +#include <blob/init.h> -#warning "Please fix NESA flash descriptor" /* flash descriptor for NESA flash */ /* 2x AMD *whatever* flash (4MB) */ -flash_descriptor_t flash_descriptors[] = +static flash_descriptor_t nesa_flash_descriptors[] = { +#warning "Please fix NESA flash descriptor" { size: 2 * 8 * 1024, num: 8, @@ -55,154 +52,10 @@ -/* flash commands for two 16 bit AMD flash chips */ -#define READ_ARRAY 0x00F000F0 -#define UNLOCK1 0x00AA00AA -#define UNLOCK2 0x00550055 -#define ERASE_SETUP 0x00800080 -#define ERASE_CONFIRM 0x00300030 -#define PGM_SETUP 0x00A000A0 -#define UNLOCK_BYPASS 0x00200020 -#define FLASH_ADDR1 (0x00000555 << 2) -#define FLASH_ADDR2 (0x000002AA << 2) -#define ERASE_DONE 0x00800080 -#define RDY_MASK 0x00800080 -#define STATUS_PGM_ERR 0x00200020 -#define STATUS_ERASE_ERR 0x00000001 - -#define READY 1 -#define ERR 2 - - - - -#warning "Please check NESA flash code" - -/* the next two functions should work for all 2x 16 bit AMD flashes */ - -int erase_flash(u32 *addr) +static void init_nesa_flash_driver(void) { - u32 result; - int chip1, chip2; - - /* prepare for erase */ - *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK1); - barrier(); - *(u32 *)FLASH_ADDR2 = data_to_flash(UNLOCK2); - barrier(); - *(u32 *)FLASH_ADDR1 = data_to_flash(ERASE_SETUP); - barrier(); - - /* erase command */ - *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK1); - barrier(); - *(u32 *)FLASH_ADDR2 = data_to_flash(UNLOCK2); - barrier(); - *addr = data_to_flash(ERASE_CONFIRM); - - /* I just can't find clean ways of dealing with this flash... - * The error bit is a *set* bit, so if its read, and bit 7 is 0, - * but bit 5 is 1, its an error, however, after these status reads - * are done, erased flash goes to 0xff...sooo...each chip has to - * be caught where the bits are the status bits -- Russ */ - - /* Russ, why don't you do this like the LART does? Just check - * the status of chips with a single compare. -- Erik */ - chip1 = chip2 = 0; - - do { - result = data_from_flash(*addr); - barrier(); - - if (!chip1 && (result & 0xFFFF) & ERASE_DONE) - chip1 = READY; - - if (!chip1 && (result & 0xFFFF) & STATUS_PGM_ERR) - chip1 = ERR; - - if (!chip2 && (result >> 16) & ERASE_DONE) - chip2 = READY; - - if (!chip2 && (result >> 16) & STATUS_PGM_ERR) - chip2 = ERR; - - } while(!chip1 || !chip2); - - /* put flash back into Read Array mode */ - *(u32 *)FLASH_ADDR1 = data_to_flash(READ_ARRAY); - barrier(); - - if (chip1 == ERR || chip2 == ERR) - return -EFLASHERASE; - - return 0; + flash_descriptors = nesa_flash_descriptors; + flash_driver = &amd32_flash_driver; } - - - - -int write_flash(u32 *dst, const u32* src) -{ - u32 result; - int chip1, chip2; - - *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK1); - barrier(); - *(u32 *)FLASH_ADDR2 = data_to_flash(UNLOCK2); - barrier(); - *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK_BYPASS); - barrier(); - - *dst = data_to_flash(PGM_SETUP); - barrier(); - *dst = *src; - barrier(); - - /* This is a pretty similar situation to the erasing status below - * Bit 7 is ~(data bit 7) until the flash is complete. If bit 5 - * gets set before this happens, there is an error, but this could - * happen near the clock edge, and bit 5 could be the actual data - * before bit 7 changes, so we have to read again. -- Russ - */ - - chip1 = chip2 = 0; - do { - result = data_from_flash(*dst); - barrier(); - - if (!chip1 && ((result & 0x80) == (*src & 0x80))) - chip1 = READY; - - if (!chip1 && ((result & 0xFFFF) & STATUS_PGM_ERR)) { - result = data_from_flash(*dst); - barrier(); - - if ((result & 0x80) == (*src & 0x80)) - chip1 = READY; - else - chip1 = ERR; - } - - if (!chip2 && ((result & (0x80 << 16)) == (*src & (0x80 << 16)))) - chip2 = READY; - - if (!chip2 && ((result >> 16) & STATUS_PGM_ERR)) { - result = data_from_flash(*dst); - barrier(); - - if ((result & (0x80 << 16)) == (*src & (0x80 << 16))) - chip2 = READY; - else - chip2 = ERR; - } - - } while (!chip1 || !chip2); - - *(u32 *)FLASH_ADDR1 = data_to_flash(READ_ARRAY); - barrier(); - - if (chip1 == ERR || chip2 == ERR || *dst != *src) - return -EFLASHPGM; - return 0; -} +__initlist(init_nesa_flash_driver, INIT_LEVEL_OTHER_STUFF); Index: pleb.c =================================================================== RCS file: /cvsroot/blob/blob/src/blob/pleb.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- pleb.c 2001/10/15 21:56:37 1.2 +++ pleb.c 2001/10/21 21:38:34 1.3 @@ -25,14 +25,13 @@ # include <blob/config.h> #endif -#include <blob/arch.h> -#include <blob/errno.h> #include <blob/flash.h> #include <blob/init.h> #include <blob/led.h> -#include <blob/util.h> + + /* the LED should always be on or otherwise the serial transmitter * doesn't work */ @@ -43,17 +42,17 @@ led_lock(); } + /* do this just after the initial hardware has been initialised */ __initlist(lock_pleb_led, INIT_LEVEL_INITIAL_HARDWARE + 1); -#warning "Please verify PLEB flash layout" - /* flash descriptor for PLEB flash. */ -flash_descriptor_t flash_descriptors[] = +static flash_descriptor_t pleb_flash_descriptors[] = { +#warning "Please add PLEB flash layout" { /* NULL block */ }, @@ -62,17 +61,11 @@ -#warning "Please verify PLEB flash functions" - -int erase_flash(u32 *addr) +static void init_pleb_flash_driver(void) { - return -EFLASHERASE; + flash_descriptors = pleb_flash_descriptors; +#warning "Please add a proper PLEB flash driver" + flash_driver = &null_flash_driver; } - - -/* write a flash block at a given location */ -int write_flash(u32 *dst, const u32* src) -{ - return -EFLASHPGM; -} +__initlist(init_pleb_flash_driver, INIT_LEVEL_OTHER_STUFF); Index: shannon.c =================================================================== RCS file: /cvsroot/blob/blob/src/blob/shannon.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- shannon.c 2001/10/15 21:56:37 1.2 +++ shannon.c 2001/10/21 21:38:34 1.3 @@ -25,20 +25,17 @@ # include <blob/config.h> #endif -#include <blob/arch.h> -#include <blob/errno.h> #include <blob/flash.h> -#include <blob/util.h> - +#include <blob/init.h> -#warning "Please fix SHANNON flash descriptor" /* flash descriptor for SHANNON flash */ /* 2x AMD *whatever* flash (4MB) */ -flash_descriptor_t flash_descriptors[] = +static flash_descriptor_t shannon_flash_descriptors[] = { +#warning "Please fix SHANNON flash descriptor" { size: 2 * 8 * 1024, num: 8, @@ -54,153 +51,11 @@ - -/* flash commands for two 16 bit AMD flash chips */ -#define READ_ARRAY 0x00F000F0 -#define UNLOCK1 0x00AA00AA -#define UNLOCK2 0x00550055 -#define ERASE_SETUP 0x00800080 -#define ERASE_CONFIRM 0x00300030 -#define PGM_SETUP 0x00A000A0 -#define UNLOCK_BYPASS 0x00200020 -#define FLASH_ADDR1 (0x00000555 << 2) -#define FLASH_ADDR2 (0x000002AA << 2) -#define ERASE_DONE 0x00800080 -#define RDY_MASK 0x00800080 -#define STATUS_PGM_ERR 0x00200020 -#define STATUS_ERASE_ERR 0x00000001 - -#define READY 1 -#define ERR 2 - - - -#warning "Please check SHANNON flash code" - -int erase_flash(u32 *addr) +static void init_shannon_flash_driver(void) { - u32 result; - int chip1, chip2; - - /* prepare for erase */ - *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK1); - barrier(); - *(u32 *)FLASH_ADDR2 = data_to_flash(UNLOCK2); - barrier(); - *(u32 *)FLASH_ADDR1 = data_to_flash(ERASE_SETUP); - barrier(); - - /* erase command */ - *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK1); - barrier(); - *(u32 *)FLASH_ADDR2 = data_to_flash(UNLOCK2); - barrier(); - *addr = data_to_flash(ERASE_CONFIRM); - - /* I just can't find clean ways of dealing with this flash... - * The error bit is a *set* bit, so if its read, and bit 7 is 0, - * but bit 5 is 1, its an error, however, after these status reads - * are done, erased flash goes to 0xff...sooo...each chip has to - * be caught where the bits are the status bits -- Russ */ - - /* Russ, why don't you do this like the LART does? Just check - * the status of chips with a single compare. -- Erik */ - chip1 = chip2 = 0; - - do { - result = data_from_flash(*addr); - barrier(); - - if (!chip1 && (result & 0xFFFF) & ERASE_DONE) - chip1 = READY; - - if (!chip1 && (result & 0xFFFF) & STATUS_PGM_ERR) - chip1 = ERR; - - if (!chip2 && (result >> 16) & ERASE_DONE) - chip2 = READY; - - if (!chip2 && (result >> 16) & STATUS_PGM_ERR) - chip2 = ERR; - - } while(!chip1 || !chip2); - - /* put flash back into Read Array mode */ - *(u32 *)FLASH_ADDR1 = data_to_flash(READ_ARRAY); - barrier(); - - if (chip1 == ERR || chip2 == ERR) - return -EFLASHERASE; - - return 0; + flash_descriptors = shannon_flash_descriptors; + flash_driver = &amd32_flash_driver; } - - - - -int write_flash(u32 *dst, const u32* src) -{ - u32 result; - int chip1, chip2; - - *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK1); - barrier(); - *(u32 *)FLASH_ADDR2 = data_to_flash(UNLOCK2); - barrier(); - *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK_BYPASS); - barrier(); - - *dst = data_to_flash(PGM_SETUP); - barrier(); - *dst = *src; - barrier(); - - /* This is a pretty similar situation to the erasing status below - * Bit 7 is ~(data bit 7) until the flash is complete. If bit 5 - * gets set before this happens, there is an error, but this could - * happen near the clock edge, and bit 5 could be the actual data - * before bit 7 changes, so we have to read again. -- Russ - */ - chip1 = chip2 = 0; - do { - result = data_from_flash(*dst); - barrier(); - - if (!chip1 && ((result & 0x80) == (*src & 0x80))) - chip1 = READY; - - if (!chip1 && ((result & 0xFFFF) & STATUS_PGM_ERR)) { - result = data_from_flash(*dst); - barrier(); - - if ((result & 0x80) == (*src & 0x80)) - chip1 = READY; - else - chip1 = ERR; - } - - if (!chip2 && ((result & (0x80 << 16)) == (*src & (0x80 << 16)))) - chip2 = READY; - - if (!chip2 && ((result >> 16) & STATUS_PGM_ERR)) { - result = data_from_flash(*dst); - barrier(); - - if ((result & (0x80 << 16)) == (*src & (0x80 << 16))) - chip2 = READY; - else - chip2 = ERR; - } - - } while (!chip1 || !chip2); - - *(u32 *)FLASH_ADDR1 = data_to_flash(READ_ARRAY); - barrier(); - - if (chip1 == ERR || chip2 == ERR || *dst != *src) - return -EFLASHPGM; - - return 0; -} +__initlist(init_shannon_flash_driver, INIT_LEVEL_OTHER_STUFF); Index: system3.c =================================================================== RCS file: /cvsroot/blob/blob/src/blob/system3.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- system3.c 2001/10/15 21:56:37 1.2 +++ system3.c 2001/10/21 21:38:34 1.3 @@ -25,19 +25,17 @@ # include <blob/config.h> #endif -#include <blob/arch.h> -#include <blob/errno.h> #include <blob/flash.h> -#include <blob/util.h> +#include <blob/init.h> -#warning "Please verify System3 flash layout" /* flash descriptor for System3 flash. */ /* I have *really* no idea what kind of flash System3 uses */ -flash_descriptor_t flash_descriptors[] = +static flash_descriptor_t system3_flash_descriptors[] = { +#warning "Please add System3 flash layout" { /* NULL block */ }, @@ -45,19 +43,12 @@ - -#warning "Please verify System3 flash functions" -int erase_flash(u32 *addr) +static void init_system3_flash_driver(void) { - return -EFLASHERASE; + flash_descriptors = system3_flash_descriptors; +#warning "Please add a proper System3 flash driver" + flash_driver = &null_flash_driver; } - - - -/* write a flash block at a given location */ -int write_flash(u32 *dst, const u32* src) -{ - return -EFLASHPGM; -} +__initlist(init_system3_flash_driver, INIT_LEVEL_OTHER_STUFF); |
From: Erik M. <er...@us...> - 2001-10-21 21:37:10
|
Update of /cvsroot/blob/blob/src/blob In directory usw-pr-cvs1:/tmp/cvs-serv17173/src/blob Modified Files: Makefile.am Log Message: Flash type is set at configure time Makefile.am knows about the new flash driver files Index: Makefile.am =================================================================== RCS file: /cvsroot/blob/blob/src/blob/Makefile.am,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- Makefile.am 2001/10/14 22:36:11 1.6 +++ Makefile.am 2001/10/21 21:37:07 1.7 @@ -93,6 +93,10 @@ chkmem.c \ clock.c \ debug.c \ + amd32.c \ + intel16.c \ + intel32.c \ + nullflash.c \ assabet.c \ brutus.c \ clart.c \ @@ -105,6 +109,7 @@ blob_rest_elf32_DEPENDENCIES = \ @BLOB_PLATFORM_OBJ@ \ + @BLOB_FLASH_OBJS@ \ @CHKMEM@ \ @DEBUG@ \ @CLOCK@ @@ -116,6 +121,7 @@ blob_rest_elf32_LDADD += \ @BLOB_PLATFORM_OBJ@ \ + @BLOB_FLASH_OBJS@ \ @CHKMEM@ \ @DEBUG@ \ @CLOCK@ \ |
From: Erik M. <er...@us...> - 2001-10-21 21:37:09
|
Update of /cvsroot/blob/blob In directory usw-pr-cvs1:/tmp/cvs-serv17173 Modified Files: configure.in Log Message: Flash type is set at configure time Makefile.am knows about the new flash driver files Index: configure.in =================================================================== RCS file: /cvsroot/blob/blob/configure.in,v retrieving revision 1.18 retrieving revision 1.19 diff -u -d -r1.18 -r1.19 --- configure.in 2001/10/14 14:49:41 1.18 +++ configure.in 2001/10/21 21:37:07 1.19 @@ -83,6 +83,7 @@ AC_DEFINE(ASSABET) AC_DEFINE(USE_SERIAL1) BLOB_PLATFORM_OBJ="assabet.o" + BLOB_FLASH_OBJS="intel32.o" use_cpu="sa1110" use_lcd="no" ;; @@ -91,6 +92,8 @@ AC_DEFINE(BRUTUS) AC_DEFINE(USE_SERIAL3) BLOB_PLATFORM_OBJ="brutus.o" + AC_MSG_WARN([Please check Brutus flash]) + BLOB_FLASH_OBJS="nullflash.o" use_cpu="sa1100" use_lcd="no" ;; @@ -99,6 +102,7 @@ AC_DEFINE(CLART) AC_DEFINE(USE_SERIAL3) BLOB_PLATFORM_OBJ="clart.o" + BLOB_FLASH_OBJS="intel16.o" use_cpu="sa1110" use_lcd="no" ;; @@ -107,6 +111,7 @@ AC_DEFINE(LART) AC_DEFINE(USE_SERIAL3) BLOB_PLATFORM_OBJ="lart.o" + BLOB_FLASH_OBJS="intel32.o" use_cpu="sa1100" use_lcd="no" ;; @@ -115,6 +120,7 @@ AC_DEFINE(NESA) AC_DEFINE(USE_SERIAL3) BLOB_PLATFORM_OBJ="nesa.o" + BLOB_FLASH_OBJS="amd32.o" use_cpu="sa1100" use_lcd="no" ;; @@ -123,6 +129,8 @@ AC_DEFINE(PLEB) AC_DEFINE(USE_SERIAL3) BLOB_PLATFORM_OBJ="pleb.o" + AC_MSG_WARN([Please check PLEB flash]) + BLOB_FLASH_OBJS="nullflash.o" use_cpu="sa1100" use_lcd="no" ;; @@ -131,6 +139,7 @@ AC_DEFINE(SHANNON) AC_DEFINE(USE_SERIAL3) BLOB_PLATFORM_OBJ="shannon.o" + BLOB_FLASH_OBJS="amd32.o" use_cpu="sa1100" use_lcd="no" ;; @@ -139,17 +148,15 @@ AC_DEFINE(PT_SYSTEM3) AC_DEFINE(USE_SERIAL1) BLOB_PLATFORM_OBJ="system3.o" + AC_MSG_WARN([Please check System3 flash]) + BLOB_FLASH_OBJS="nullflash.o" DIAG_PLATFORM_OBJ="system3.o" use_cpu="sa1110" use_lcd="yes" ;; *) AC_MSG_RESULT(unknown) - AC_MSG_WARN([Unknown board name, assuming SA1100 with serial 3]) - AC_DEFINE(USE_SERIAL3) - BLOB_PLATFORM_OBJ="unknown.o" - use_cpu="sa1100" - use_lcd="no" + AC_MSG_ERROR([Unknown board name, bailing out]) ;; esac @@ -278,6 +285,7 @@ dnl Check wether or not additional platform source code dnl for is needed +AC_SUBST(BLOB_FLASH_OBJS) AC_SUBST(BLOB_PLATFORM_OBJ) AC_SUBST(DIAG_PLATFORM_OBJ) |
From: Erik M. <er...@us...> - 2001-10-21 21:36:17
|
Update of /cvsroot/blob/blob/src/blob In directory usw-pr-cvs1:/tmp/cvs-serv17049/src/blob Modified Files: flash.c Log Message: Flash driver can use the new functions Index: flash.c =================================================================== RCS file: /cvsroot/blob/blob/src/blob/flash.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- flash.c 2001/10/15 21:52:09 1.4 +++ flash.c 2001/10/21 21:36:15 1.5 @@ -61,6 +61,9 @@ static flash_block_t flash_blocks[NEW_NUM_FLASH_BLOCKS]; static int num_flash_blocks; +flash_descriptor_t *flash_descriptors; +flash_driver_t *flash_driver; + /* initialise the flash blocks table */ @@ -70,6 +73,20 @@ int j; u32 start = 0; +#ifdef BLOB_DEBUG + if(flash_descriptors == NULL) { + printerrprefix(); + SerialOutputString("undefined flash_descriptors\n"); + return; + } + + if(flash_driver == NULL) { + printerrprefix(); + SerialOutputString("undefined flash_driver\n"); + return; + } +#endif + num_flash_blocks = 0; while(flash_descriptors[i].size != 0) { @@ -126,7 +143,7 @@ } -__initlist(init_flash, INIT_LEVEL_OTHER_STUFF); +__initlist(init_flash, INIT_LEVEL_OTHER_STUFF + 1); int flash_erase_region(u32 *start, u32 nwords) @@ -147,7 +164,7 @@ SerialOutputByte('\n'); #endif /* dirty block */ - rv = erase_flash(cur); + rv = flash_driver->flash_erase(cur); if(rv < 0) { printerrprefix(); @@ -192,7 +209,7 @@ led_toggle(); } - rv = write_flash(cur, src); + rv = flash_driver->flash_write(cur, src); if(rv < 0) { printerrprefix(); |
From: Erik M. <er...@us...> - 2001-10-21 21:36:17
|
Update of /cvsroot/blob/blob/include/blob In directory usw-pr-cvs1:/tmp/cvs-serv17049/include/blob Modified Files: flash.h Log Message: Flash driver can use the new functions Index: flash.h =================================================================== RCS file: /cvsroot/blob/blob/include/blob/flash.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- flash.h 2001/10/15 21:52:09 1.3 +++ flash.h 2001/10/21 21:36:15 1.4 @@ -42,16 +42,31 @@ int lockable; } flash_descriptor_t; + +typedef int (*flash_erase_func_t)(u32 *); +typedef int (*flash_write_func_t)(u32 *, const u32 *); + +typedef struct { + flash_erase_func_t flash_erase; + flash_write_func_t flash_write; +} flash_driver_t; + +/* implemented flash drivers */ +extern flash_driver_t amd32_flash_driver; +extern flash_driver_t intel16_flash_driver; +extern flash_driver_t intel32_flash_driver; +extern flash_driver_t null_flash_driver; + + /* should be filled out by the architecture dependent files */ -extern flash_descriptor_t flash_descriptors[]; +extern flash_descriptor_t *flash_descriptors; +extern flash_driver_t *flash_driver; -/* should be provided by the architecture dependent files */ -int erase_flash(u32 *addr); -int write_flash(u32 *dst, const u32* src); /* flash data mangle functions */ u32 data_from_flash(u32 what); u32 data_to_flash(u32 what); + /* exported functions */ int flash_erase_region(u32 *start, u32 nwords); |
From: Erik M. <er...@us...> - 2001-10-21 21:35:14
|
Update of /cvsroot/blob/blob/src/blob In directory usw-pr-cvs1:/tmp/cvs-serv16865 Added Files: intel16.c intel32.c amd32.c nullflash.c Log Message: New flash functions per flash type --- NEW FILE: intel16.c --- /* * intel16.c: Intel 16 bit flash driver * * Copyright (C) 2001 Erik Mouw (J.A...@it...) * Copyright (C) 1999 Jan-Derk Bakker (J.D...@it...) * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ident "$Id: intel16.c,v 1.1 2001/10/21 21:35:11 erikm Exp $" #ifdef HAVE_CONFIG_H # include <blob/config.h> #endif #include <blob/errno.h> #include <blob/flash.h> #include <blob/util.h> /* flash commands for a single 16 bit intel flash chip */ #define READ_ARRAY 0x000000FF #define ERASE_SETUP 0x00000020 #define ERASE_CONFIRM 0x000000D0 #define PGM_SETUP 0x00000040 #define STATUS_READ 0x00000070 #define STATUS_CLEAR 0x00000050 #define STATUS_BUSY 0x00000080 #define STATUS_ERASE_ERR 0x00000020 #define STATUS_PGM_ERR 0x00000010 static int do_erase(u16 *addr) { u16 result; /* prepare for erase */ *addr = ERASE_SETUP; barrier(); /* erase block */ *addr = ERASE_CONFIRM; barrier(); /* status check */ do { *addr = STATUS_READ; barrier(); result = *addr; barrier(); } while((~result & STATUS_BUSY) != 0); /* put flash back into Read Array mode */ *addr = READ_ARRAY; barrier(); if((result & STATUS_ERASE_ERR) != 0) return -EFLASHERASE; return 0; } static int do_write(u16 *dst, const u16* src) { u16 result; /* setup flash for writing */ *dst = PGM_SETUP; barrier(); /* write data */ *dst = *src; barrier(); /* status check */ do { *dst = STATUS_READ; barrier(); result = *dst; barrier(); } while((~result & STATUS_BUSY) != 0); /* put flash back into Read Array mode */ *dst = READ_ARRAY; barrier(); if(((result & STATUS_PGM_ERR) != 0) || (*dst != *src)) return -EFLASHPGM; return 0; } /* erases a flash block at the given address */ /* we have to break this up in two erases at 16 bit aligned addresses * (if necessary) */ static int flash_erase_intel16(u32 *addr) { int result; u16 *addr16 = (u16*)addr; /* erase first block */ result = do_erase(addr16); if(result != 0) return result; addr16++; /* if the second address is not erased, also erase it */ if(*addr16 != 0xffff) result = do_erase(addr16); if(result != 0) return result; return 0; } /* write a flash block at a given location */ /* this has to be broken up into two consectutive 16 bit writes */ static int flash_write_intel16(u32 *dst, const u32* src) { u16 *dst16 = (u16 *)dst; u16 *src16 = (u16 *)src; int result; result = do_write(dst16, src16); if(result != 0) return result; dst16++; src16++; result = do_write(dst16, src16); if(result != 0) return result; return 0; } /* flash driver structure */ flash_driver_t intel16_flash_driver = { flash_erase: flash_erase_intel16, flash_write: flash_write_intel16, }; --- NEW FILE: intel32.c --- /* * intel32.c: Intel 32 bit (2x 16 bit) flash driver * * Copyright (C) 2001 Erik Mouw (J.A...@it...) * Copyright (C) 1999 Jan-Derk Bakker (J.D...@it...) * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ident "$Id: intel32.c,v 1.1 2001/10/21 21:35:11 erikm Exp $" #ifdef HAVE_CONFIG_H # include <blob/config.h> #endif #include <blob/errno.h> #include <blob/flash.h> #include <blob/util.h> /* flash commands for two 16 bit intel flash chips */ #define READ_ARRAY 0x00FF00FF #define ERASE_SETUP 0x00200020 #define ERASE_CONFIRM 0x00D000D0 #define PGM_SETUP 0x00400040 #define STATUS_READ 0x00700070 #define STATUS_CLEAR 0x00500050 #define STATUS_BUSY 0x00800080 #define STATUS_ERASE_ERR 0x00200020 #define STATUS_PGM_ERR 0x00100010 /* erases a flash block at the given address */ static int flash_erase_intel32(u32 *addr) { u32 result; /* prepare for erase */ *addr = data_to_flash(ERASE_SETUP); barrier(); /* erase block */ *addr = data_to_flash(ERASE_CONFIRM); barrier(); /* status check */ do { *addr = data_to_flash(STATUS_READ); barrier(); result = data_from_flash(*addr); barrier(); } while((~result & STATUS_BUSY) != 0); /* put flash back into Read Array mode */ *addr = data_to_flash(READ_ARRAY); barrier(); if((result & STATUS_ERASE_ERR) != 0) return -EFLASHERASE; return 0; } /* write a flash block at a given location */ static int flash_write_intel32(u32 *dst, const u32* src) { u32 result; /* setup flash for writing */ *dst = data_to_flash(PGM_SETUP); barrier(); /* write data */ *dst = *src; barrier(); /* status check */ do { *dst = data_to_flash(STATUS_READ); barrier(); result = data_from_flash(*dst); barrier(); } while((~result & STATUS_BUSY) != 0); /* put flash back into Read Array mode */ *dst = data_to_flash(READ_ARRAY); barrier(); if(((result & STATUS_PGM_ERR) != 0) || (*dst != *src)) return -EFLASHPGM; return 0; } /* flash driver structure */ flash_driver_t intel32_flash_driver = { flash_erase: flash_erase_intel32, flash_write: flash_write_intel32, }; --- NEW FILE: amd32.c --- /* * amd32.c: AMD 32 bit (2x 16 bit) flash driver * * Copyright (C) 2001 Erik Mouw (J.A...@it...) * Copyright (C) 2001 Russ Dill (Rus...@as...) * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ident "$Id: amd32.c,v 1.1 2001/10/21 21:35:11 erikm Exp $" #ifdef HAVE_CONFIG_H # include <blob/config.h> #endif #include <blob/errno.h> #include <blob/flash.h> #include <blob/util.h> /* flash commands for two 16 bit AMD flash chips */ #define READ_ARRAY 0x00F000F0 #define UNLOCK1 0x00AA00AA #define UNLOCK2 0x00550055 #define ERASE_SETUP 0x00800080 #define ERASE_CONFIRM 0x00300030 #define PGM_SETUP 0x00A000A0 #define UNLOCK_BYPASS 0x00200020 #define FLASH_ADDR1 (0x00000555 << 2) #define FLASH_ADDR2 (0x000002AA << 2) #define ERASE_DONE 0x00800080 #define RDY_MASK 0x00800080 #define STATUS_PGM_ERR 0x00200020 #define STATUS_ERASE_ERR 0x00000001 #define READY 1 #define ERR 2 #warning "Please check AMD flash code" static int flash_erase_amd32(u32 *addr) { u32 result; int chip1, chip2; /* prepare for erase */ *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK1); barrier(); *(u32 *)FLASH_ADDR2 = data_to_flash(UNLOCK2); barrier(); *(u32 *)FLASH_ADDR1 = data_to_flash(ERASE_SETUP); barrier(); /* erase command */ *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK1); barrier(); *(u32 *)FLASH_ADDR2 = data_to_flash(UNLOCK2); barrier(); *addr = data_to_flash(ERASE_CONFIRM); /* I just can't find clean ways of dealing with this flash... * The error bit is a *set* bit, so if its read, and bit 7 is 0, * but bit 5 is 1, its an error, however, after these status reads * are done, erased flash goes to 0xff...sooo...each chip has to * be caught where the bits are the status bits -- Russ */ /* Russ, why don't you do this like the LART does? Just check * the status of chips with a single compare. -- Erik */ chip1 = chip2 = 0; do { result = data_from_flash(*addr); barrier(); if (!chip1 && (result & 0xFFFF) & ERASE_DONE) chip1 = READY; if (!chip1 && (result & 0xFFFF) & STATUS_PGM_ERR) chip1 = ERR; if (!chip2 && (result >> 16) & ERASE_DONE) chip2 = READY; if (!chip2 && (result >> 16) & STATUS_PGM_ERR) chip2 = ERR; } while(!chip1 || !chip2); /* put flash back into Read Array mode */ *(u32 *)FLASH_ADDR1 = data_to_flash(READ_ARRAY); barrier(); if (chip1 == ERR || chip2 == ERR) return -EFLASHERASE; return 0; } static int flash_write_amd32(u32 *dst, const u32* src) { u32 result; int chip1, chip2; *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK1); barrier(); *(u32 *)FLASH_ADDR2 = data_to_flash(UNLOCK2); barrier(); *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK_BYPASS); barrier(); *dst = data_to_flash(PGM_SETUP); barrier(); *dst = *src; barrier(); /* This is a pretty similar situation to the erasing status below * Bit 7 is ~(data bit 7) until the flash is complete. If bit 5 * gets set before this happens, there is an error, but this could * happen near the clock edge, and bit 5 could be the actual data * before bit 7 changes, so we have to read again. -- Russ */ chip1 = chip2 = 0; do { result = data_from_flash(*dst); barrier(); if (!chip1 && ((result & 0x80) == (*src & 0x80))) chip1 = READY; if (!chip1 && ((result & 0xFFFF) & STATUS_PGM_ERR)) { result = data_from_flash(*dst); barrier(); if ((result & 0x80) == (*src & 0x80)) chip1 = READY; else chip1 = ERR; } if (!chip2 && ((result & (0x80 << 16)) == (*src & (0x80 << 16)))) chip2 = READY; if (!chip2 && ((result >> 16) & STATUS_PGM_ERR)) { result = data_from_flash(*dst); barrier(); if ((result & (0x80 << 16)) == (*src & (0x80 << 16))) chip2 = READY; else chip2 = ERR; } } while (!chip1 || !chip2); *(u32 *)FLASH_ADDR1 = data_to_flash(READ_ARRAY); barrier(); if (chip1 == ERR || chip2 == ERR || *dst != *src) return -EFLASHPGM; return 0; } /* flash driver structure */ flash_driver_t amd32_flash_driver = { flash_erase: flash_erase_amd32, flash_write: flash_write_amd32, }; --- NEW FILE: nullflash.c --- /* * nullflash.c: NULL flash driver * * Copyright (C) 2001 Erik Mouw (J.A...@it...) * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ident "$Id: nullflash.c,v 1.1 2001/10/21 21:35:11 erikm Exp $" #ifdef HAVE_CONFIG_H # include <blob/config.h> #endif #include <blob/errno.h> #include <blob/flash.h> #include <blob/util.h> static int flash_erase_null(u32 *addr) { #ifdef BLOB_DEBUG printerrprefix(); SerialOutputString("No flash_erase() function\n"); #endif return -EFLASHERASE; } static int flash_write_null(u32 *dst, const u32* src) { #ifdef BLOB_DEBUG printerrprefix(); SerialOutputString("No flash_write() function\n"); #endif return -EFLASHPGM; } /* flash driver structure */ flash_driver_t null_flash_driver = { flash_erase: flash_erase_null, flash_write: flash_write_null, }; |
From: Erik M. <J.A...@IT...> - 2001-10-15 22:50:10
|
On Mon, Oct 15, 2001 at 03:34:20PM -0700, Russ Dill wrote: > On Mon, 2001-10-15 at 15:20, Erik Mouw wrote: > > Looking at your comments in the code, the AMD flashes are a bit more > > difficult to handle, so I doubt it's really worth it. I really want to > > avoid recreating the complete MTD functionality in blob. > > The code could probably be cleaned up to support 1x 16. The amount of > code duplication involved in the current method just seems excessive. Agreed. I'll look into this tomorrow. Erik [sleep(7*3600) or so] -- J.A.K. (Erik) Mouw, Information and Communication Theory Group, Department of Electrical Engineering, Faculty of Information Technology and Systems, Delft University of Technology, PO BOX 5031, 2600 GA Delft, The Netherlands Phone: +31-15-2783635 Fax: +31-15-2781843 Email: J.A...@it... WWW: http://www-ict.its.tudelft.nl/~erik/ |
From: Russ D. <Rus...@as...> - 2001-10-15 22:31:16
|
On Mon, 2001-10-15 at 15:20, Erik Mouw wrote: > On Mon, Oct 15, 2001 at 03:05:52PM -0700, Russ Dill wrote: > > You should really break this out a bit more, as both the nesa and > > shannon have identical flash (probably true with other platforms as > > well). Maybe there should be an amd.c, and an intel.c. Each would > > contain functions for erasing and writing the flash. <arch.c> would set > > the proper write function, as well as an optional read32/write32 (for > > plaiting). If no erase/write function was set, then flashing would barf. > > Well, yes and no. The Intel flashes should be easy to do, because 1x 16 > bit and 2x 16 bit flashes can be done with the same code (only the > commands and error codes differ). > > Looking at your comments in the code, the AMD flashes are a bit more > difficult to handle, so I doubt it's really worth it. I really want to > avoid recreating the complete MTD functionality in blob. > > Anyway, at least it cleans up the flash code a lot, and I'll clean it > up even more when I start implementing the flash partitioning. The code could probably be cleaned up to support 1x 16. The amount of code duplication involved in the current method just seems excessive. |
From: Erik M. <J.A...@IT...> - 2001-10-15 22:20:25
|
On Mon, Oct 15, 2001 at 03:05:52PM -0700, Russ Dill wrote: > You should really break this out a bit more, as both the nesa and > shannon have identical flash (probably true with other platforms as > well). Maybe there should be an amd.c, and an intel.c. Each would > contain functions for erasing and writing the flash. <arch.c> would set > the proper write function, as well as an optional read32/write32 (for > plaiting). If no erase/write function was set, then flashing would barf. Well, yes and no. The Intel flashes should be easy to do, because 1x 16 bit and 2x 16 bit flashes can be done with the same code (only the commands and error codes differ). Looking at your comments in the code, the AMD flashes are a bit more difficult to handle, so I doubt it's really worth it. I really want to avoid recreating the complete MTD functionality in blob. Anyway, at least it cleans up the flash code a lot, and I'll clean it up even more when I start implementing the flash partitioning. Erik -- J.A.K. (Erik) Mouw, Information and Communication Theory Group, Department of Electrical Engineering, Faculty of Information Technology and Systems, Delft University of Technology, PO BOX 5031, 2600 GA Delft, The Netherlands Phone: +31-15-2783635 Fax: +31-15-2781843 Email: J.A...@it... WWW: http://www-ict.its.tudelft.nl/~erik/ |
From: Erik M. <J.A...@IT...> - 2001-10-15 22:09:57
|
On Mon, Oct 15, 2001 at 02:56:39PM -0700, Erik Mouw wrote: > Modified Files: > nesa.c pleb.c shannon.c system3.c > Log Message: > Nesa flash functions. Not tested, but they should work. Please test, Russ. Grrrr, I hate following up to my own messages. My intention was to commit each file with a separate CVS commit. Anyway, here is the rest of the log: Pleb flash functions should still be fleshed out. Pleb turns the LED on and locks it early in the boot process, so the LED shouldn't go off anymore, and hence the serial port should remain working. Shannon flash functions are not tested but they should work. Please fill out the correct flash table. Please test, Russ and Tim. PT System3 flash functions should be fleshed out. Stefan? Note that the flash descriptions are currently not used in the erase and write functions, but I want to use them for the flash partitioning support (which should become easier right now). Erik -- J.A.K. (Erik) Mouw, Information and Communication Theory Group, Department of Electrical Engineering, Faculty of Information Technology and Systems, Delft University of Technology, PO BOX 5031, 2600 GA Delft, The Netherlands Phone: +31-15-2783635 Fax: +31-15-2781843 Email: J.A...@it... WWW: http://www-ict.its.tudelft.nl/~erik/ |
From: Russ D. <Rus...@as...> - 2001-10-15 22:02:36
|
On Mon, 2001-10-15 at 14:56, Erik Mouw wrote: > Update of /cvsroot/blob/blob/src/blob > In directory usw-pr-cvs1:/tmp/cvs-serv21169 > > Modified Files: > nesa.c pleb.c shannon.c system3.c > Log Message: > Nesa flash functions. Not tested, but they should work. Please test, Russ. You should really break this out a bit more, as both the nesa and shannon have identical flash (probably true with other platforms as well). Maybe there should be an amd.c, and an intel.c. Each would contain functions for erasing and writing the flash. <arch.c> would set the proper write function, as well as an optional read32/write32 (for plaiting). If no erase/write function was set, then flashing would barf. |
From: Erik M. <er...@us...> - 2001-10-15 21:56:40
|
Update of /cvsroot/blob/blob/src/blob In directory usw-pr-cvs1:/tmp/cvs-serv21169 Modified Files: nesa.c pleb.c shannon.c system3.c Log Message: Nesa flash functions. Not tested, but they should work. Please test, Russ. Index: nesa.c =================================================================== RCS file: /cvsroot/blob/blob/src/blob/nesa.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- nesa.c 2001/10/14 22:36:11 1.1 +++ nesa.c 2001/10/15 21:56:37 1.2 @@ -26,4 +26,183 @@ #endif #include <blob/arch.h> +#include <blob/errno.h> +#include <blob/flash.h> +#include <blob/util.h> + + + + +#warning "Please fix NESA flash descriptor" + +/* flash descriptor for NESA flash */ +/* 2x AMD *whatever* flash (4MB) */ +flash_descriptor_t flash_descriptors[] = +{ + { + size: 2 * 8 * 1024, + num: 8, + }, + { + size: 2 * 64 * 1024, + num: 31, + }, + { + /* NULL block */ + }, +}; + + + + +/* flash commands for two 16 bit AMD flash chips */ +#define READ_ARRAY 0x00F000F0 +#define UNLOCK1 0x00AA00AA +#define UNLOCK2 0x00550055 +#define ERASE_SETUP 0x00800080 +#define ERASE_CONFIRM 0x00300030 +#define PGM_SETUP 0x00A000A0 +#define UNLOCK_BYPASS 0x00200020 +#define FLASH_ADDR1 (0x00000555 << 2) +#define FLASH_ADDR2 (0x000002AA << 2) +#define ERASE_DONE 0x00800080 +#define RDY_MASK 0x00800080 +#define STATUS_PGM_ERR 0x00200020 +#define STATUS_ERASE_ERR 0x00000001 + +#define READY 1 +#define ERR 2 + + + + +#warning "Please check NESA flash code" + +/* the next two functions should work for all 2x 16 bit AMD flashes */ + +int erase_flash(u32 *addr) +{ + u32 result; + int chip1, chip2; + + /* prepare for erase */ + *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK1); + barrier(); + *(u32 *)FLASH_ADDR2 = data_to_flash(UNLOCK2); + barrier(); + *(u32 *)FLASH_ADDR1 = data_to_flash(ERASE_SETUP); + barrier(); + + /* erase command */ + *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK1); + barrier(); + *(u32 *)FLASH_ADDR2 = data_to_flash(UNLOCK2); + barrier(); + *addr = data_to_flash(ERASE_CONFIRM); + + /* I just can't find clean ways of dealing with this flash... + * The error bit is a *set* bit, so if its read, and bit 7 is 0, + * but bit 5 is 1, its an error, however, after these status reads + * are done, erased flash goes to 0xff...sooo...each chip has to + * be caught where the bits are the status bits -- Russ */ + + /* Russ, why don't you do this like the LART does? Just check + * the status of chips with a single compare. -- Erik */ + chip1 = chip2 = 0; + + do { + result = data_from_flash(*addr); + barrier(); + + if (!chip1 && (result & 0xFFFF) & ERASE_DONE) + chip1 = READY; + if (!chip1 && (result & 0xFFFF) & STATUS_PGM_ERR) + chip1 = ERR; + + if (!chip2 && (result >> 16) & ERASE_DONE) + chip2 = READY; + + if (!chip2 && (result >> 16) & STATUS_PGM_ERR) + chip2 = ERR; + + } while(!chip1 || !chip2); + + /* put flash back into Read Array mode */ + *(u32 *)FLASH_ADDR1 = data_to_flash(READ_ARRAY); + barrier(); + + if (chip1 == ERR || chip2 == ERR) + return -EFLASHERASE; + + return 0; +} + + + + +int write_flash(u32 *dst, const u32* src) +{ + u32 result; + int chip1, chip2; + + *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK1); + barrier(); + *(u32 *)FLASH_ADDR2 = data_to_flash(UNLOCK2); + barrier(); + *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK_BYPASS); + barrier(); + + *dst = data_to_flash(PGM_SETUP); + barrier(); + *dst = *src; + barrier(); + + /* This is a pretty similar situation to the erasing status below + * Bit 7 is ~(data bit 7) until the flash is complete. If bit 5 + * gets set before this happens, there is an error, but this could + * happen near the clock edge, and bit 5 could be the actual data + * before bit 7 changes, so we have to read again. -- Russ + */ + + chip1 = chip2 = 0; + do { + result = data_from_flash(*dst); + barrier(); + + if (!chip1 && ((result & 0x80) == (*src & 0x80))) + chip1 = READY; + + if (!chip1 && ((result & 0xFFFF) & STATUS_PGM_ERR)) { + result = data_from_flash(*dst); + barrier(); + + if ((result & 0x80) == (*src & 0x80)) + chip1 = READY; + else + chip1 = ERR; + } + + if (!chip2 && ((result & (0x80 << 16)) == (*src & (0x80 << 16)))) + chip2 = READY; + + if (!chip2 && ((result >> 16) & STATUS_PGM_ERR)) { + result = data_from_flash(*dst); + barrier(); + + if ((result & (0x80 << 16)) == (*src & (0x80 << 16))) + chip2 = READY; + else + chip2 = ERR; + } + + } while (!chip1 || !chip2); + + *(u32 *)FLASH_ADDR1 = data_to_flash(READ_ARRAY); + barrier(); + + if (chip1 == ERR || chip2 == ERR || *dst != *src) + return -EFLASHPGM; + + return 0; +} Index: pleb.c =================================================================== RCS file: /cvsroot/blob/blob/src/blob/pleb.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- pleb.c 2001/10/14 22:36:11 1.1 +++ pleb.c 2001/10/15 21:56:37 1.2 @@ -26,4 +26,53 @@ #endif #include <blob/arch.h> +#include <blob/errno.h> +#include <blob/flash.h> +#include <blob/init.h> +#include <blob/led.h> +#include <blob/util.h> + +/* the LED should always be on or otherwise the serial transmitter + * doesn't work + */ +static void lock_pleb_led(void) +{ + led_unlock(); + led_on(); + led_lock(); +} + +/* do this just after the initial hardware has been initialised */ +__initlist(lock_pleb_led, INIT_LEVEL_INITIAL_HARDWARE + 1); + + + + +#warning "Please verify PLEB flash layout" + +/* flash descriptor for PLEB flash. */ +flash_descriptor_t flash_descriptors[] = +{ + { + /* NULL block */ + }, +}; + + + + +#warning "Please verify PLEB flash functions" + +int erase_flash(u32 *addr) +{ + return -EFLASHERASE; +} + + + +/* write a flash block at a given location */ +int write_flash(u32 *dst, const u32* src) +{ + return -EFLASHPGM; +} Index: shannon.c =================================================================== RCS file: /cvsroot/blob/blob/src/blob/shannon.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- shannon.c 2001/10/14 22:36:11 1.1 +++ shannon.c 2001/10/15 21:56:37 1.2 @@ -26,4 +26,181 @@ #endif #include <blob/arch.h> +#include <blob/errno.h> +#include <blob/flash.h> +#include <blob/util.h> + + + +#warning "Please fix SHANNON flash descriptor" + +/* flash descriptor for SHANNON flash */ +/* 2x AMD *whatever* flash (4MB) */ +flash_descriptor_t flash_descriptors[] = +{ + { + size: 2 * 8 * 1024, + num: 8, + }, + { + size: 2 * 64 * 1024, + num: 31, + }, + { + /* NULL block */ + }, +}; + + + + +/* flash commands for two 16 bit AMD flash chips */ +#define READ_ARRAY 0x00F000F0 +#define UNLOCK1 0x00AA00AA +#define UNLOCK2 0x00550055 +#define ERASE_SETUP 0x00800080 +#define ERASE_CONFIRM 0x00300030 +#define PGM_SETUP 0x00A000A0 +#define UNLOCK_BYPASS 0x00200020 +#define FLASH_ADDR1 (0x00000555 << 2) +#define FLASH_ADDR2 (0x000002AA << 2) +#define ERASE_DONE 0x00800080 +#define RDY_MASK 0x00800080 +#define STATUS_PGM_ERR 0x00200020 +#define STATUS_ERASE_ERR 0x00000001 + +#define READY 1 +#define ERR 2 + + + + +#warning "Please check SHANNON flash code" + +int erase_flash(u32 *addr) +{ + u32 result; + int chip1, chip2; + + /* prepare for erase */ + *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK1); + barrier(); + *(u32 *)FLASH_ADDR2 = data_to_flash(UNLOCK2); + barrier(); + *(u32 *)FLASH_ADDR1 = data_to_flash(ERASE_SETUP); + barrier(); + + /* erase command */ + *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK1); + barrier(); + *(u32 *)FLASH_ADDR2 = data_to_flash(UNLOCK2); + barrier(); + *addr = data_to_flash(ERASE_CONFIRM); + + /* I just can't find clean ways of dealing with this flash... + * The error bit is a *set* bit, so if its read, and bit 7 is 0, + * but bit 5 is 1, its an error, however, after these status reads + * are done, erased flash goes to 0xff...sooo...each chip has to + * be caught where the bits are the status bits -- Russ */ + + /* Russ, why don't you do this like the LART does? Just check + * the status of chips with a single compare. -- Erik */ + chip1 = chip2 = 0; + + do { + result = data_from_flash(*addr); + barrier(); + + if (!chip1 && (result & 0xFFFF) & ERASE_DONE) + chip1 = READY; + + if (!chip1 && (result & 0xFFFF) & STATUS_PGM_ERR) + chip1 = ERR; + + if (!chip2 && (result >> 16) & ERASE_DONE) + chip2 = READY; + + if (!chip2 && (result >> 16) & STATUS_PGM_ERR) + chip2 = ERR; + + } while(!chip1 || !chip2); + + /* put flash back into Read Array mode */ + *(u32 *)FLASH_ADDR1 = data_to_flash(READ_ARRAY); + barrier(); + + if (chip1 == ERR || chip2 == ERR) + return -EFLASHERASE; + + return 0; +} + + + + +int write_flash(u32 *dst, const u32* src) +{ + u32 result; + int chip1, chip2; + + *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK1); + barrier(); + *(u32 *)FLASH_ADDR2 = data_to_flash(UNLOCK2); + barrier(); + *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK_BYPASS); + barrier(); + + *dst = data_to_flash(PGM_SETUP); + barrier(); + *dst = *src; + barrier(); + + /* This is a pretty similar situation to the erasing status below + * Bit 7 is ~(data bit 7) until the flash is complete. If bit 5 + * gets set before this happens, there is an error, but this could + * happen near the clock edge, and bit 5 could be the actual data + * before bit 7 changes, so we have to read again. -- Russ + */ + + chip1 = chip2 = 0; + do { + result = data_from_flash(*dst); + barrier(); + + if (!chip1 && ((result & 0x80) == (*src & 0x80))) + chip1 = READY; + + if (!chip1 && ((result & 0xFFFF) & STATUS_PGM_ERR)) { + result = data_from_flash(*dst); + barrier(); + + if ((result & 0x80) == (*src & 0x80)) + chip1 = READY; + else + chip1 = ERR; + } + + if (!chip2 && ((result & (0x80 << 16)) == (*src & (0x80 << 16)))) + chip2 = READY; + + if (!chip2 && ((result >> 16) & STATUS_PGM_ERR)) { + result = data_from_flash(*dst); + barrier(); + + if ((result & (0x80 << 16)) == (*src & (0x80 << 16))) + chip2 = READY; + else + chip2 = ERR; + } + + } while (!chip1 || !chip2); + + *(u32 *)FLASH_ADDR1 = data_to_flash(READ_ARRAY); + barrier(); + + if (chip1 == ERR || chip2 == ERR || *dst != *src) + return -EFLASHPGM; + + return 0; +} Index: system3.c =================================================================== RCS file: /cvsroot/blob/blob/src/blob/system3.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- system3.c 2001/10/14 22:36:11 1.1 +++ system3.c 2001/10/15 21:56:37 1.2 @@ -26,4 +26,38 @@ #endif #include <blob/arch.h> +#include <blob/errno.h> +#include <blob/flash.h> +#include <blob/util.h> + + + +#warning "Please verify System3 flash layout" + +/* flash descriptor for System3 flash. */ +/* I have *really* no idea what kind of flash System3 uses */ +flash_descriptor_t flash_descriptors[] = +{ + { + /* NULL block */ + }, +}; + + + +#warning "Please verify System3 flash functions" + +int erase_flash(u32 *addr) +{ + return -EFLASHERASE; +} + + + + +/* write a flash block at a given location */ +int write_flash(u32 *dst, const u32* src) +{ + return -EFLASHPGM; +} |
From: Erik M. <er...@us...> - 2001-10-15 21:55:41
|
Update of /cvsroot/blob/blob/src/blob In directory usw-pr-cvs1:/tmp/cvs-serv20495 Modified Files: brutus.c Log Message: Empty flash functions for Brutus. I have really no idea about the Brutus flash chips. With this stuff you can at least load kernels and run them. Index: brutus.c =================================================================== RCS file: /cvsroot/blob/blob/src/blob/brutus.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- brutus.c 2001/10/14 22:36:11 1.1 +++ brutus.c 2001/10/15 21:55:38 1.2 @@ -26,4 +26,38 @@ #endif #include <blob/arch.h> +#include <blob/errno.h> +#include <blob/flash.h> +#include <blob/util.h> + + + +#warning "Please verify Brutus flash layout" + +/* flash descriptor for Brutus flash. */ +/* I have *really* no idea what kind of flash Brutus uses */ +flash_descriptor_t flash_descriptors[] = +{ + { + /* NULL block */ + }, +}; + + + +#warning "Please verify Brutus flash functions" + +int erase_flash(u32 *addr) +{ + return -EFLASHERASE; +} + + + + +/* write a flash block at a given location */ +int write_flash(u32 *dst, const u32* src) +{ + return -EFLASHPGM; +} |
From: Erik M. <er...@us...> - 2001-10-15 21:54:20
|
Update of /cvsroot/blob/blob/src/blob In directory usw-pr-cvs1:/tmp/cvs-serv20208 Modified Files: lart.c clart.c assabet.c Log Message: Machine specific flash functions. These three are either tested (LART), or otherwise I'm pretty sure they work (Assabet, CreditLART). Index: lart.c =================================================================== RCS file: /cvsroot/blob/blob/src/blob/lart.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- lart.c 2001/10/14 22:36:11 1.1 +++ lart.c 2001/10/15 21:54:17 1.2 @@ -26,4 +26,115 @@ #endif #include <blob/arch.h> +#include <blob/errno.h> +#include <blob/flash.h> +#include <blob/util.h> + + + + +/* flash descriptor for LART flash */ +/* 2x Intel 28F160F3B fast boot block flash (4MB) */ +flash_descriptor_t flash_descriptors[] = +{ + { + size: 2 * 8 * 1024, + num: 2, + lockable: 1 + }, + { + size: 2 * 8 * 1024, + num: 6, + }, + { + size: 2 * 64 * 1024, + num: 31, + }, + { + /* NULL block */ + }, +}; + + + + +/* flash commands for two 16 bit intel flash chips */ +#define READ_ARRAY 0x00FF00FF +#define ERASE_SETUP 0x00200020 +#define ERASE_CONFIRM 0x00D000D0 +#define PGM_SETUP 0x00400040 +#define STATUS_READ 0x00700070 +#define STATUS_CLEAR 0x00500050 +#define STATUS_BUSY 0x00800080 +#define STATUS_ERASE_ERR 0x00200020 +#define STATUS_PGM_ERR 0x00100010 + + + + +/* the next two functions should work for all Intel flashes */ + +/* erases a flash block at the given address */ +int erase_flash(u32 *addr) +{ + u32 result; + + /* prepare for erase */ + *addr = data_to_flash(ERASE_SETUP); + barrier(); + /* erase block */ + *addr = data_to_flash(ERASE_CONFIRM); + barrier(); + + /* status check */ + do { + *addr = data_to_flash(STATUS_READ); + barrier(); + result = data_from_flash(*addr); + barrier(); + } while((~result & STATUS_BUSY) != 0); + + /* put flash back into Read Array mode */ + *addr = data_to_flash(READ_ARRAY); + barrier(); + + if((result & STATUS_ERASE_ERR) != 0) + return -EFLASHERASE; + + return 0; +} + + + +/* write a flash block at a given location */ +int write_flash(u32 *dst, const u32* src) +{ + u32 result; + + /* setup flash for writing */ + *dst = data_to_flash(PGM_SETUP); + barrier(); + + /* write data */ + *dst = *src; + barrier(); + + /* status check */ + do { + *dst = data_to_flash(STATUS_READ); + barrier(); + + result = data_from_flash(*dst); + barrier(); + } while((~result & STATUS_BUSY) != 0); + + /* put flash back into Read Array mode */ + *dst = data_to_flash(READ_ARRAY); + barrier(); + + if(((result & STATUS_PGM_ERR) != 0) || (*dst != *src)) + return -EFLASHPGM; + + return 0; +} Index: clart.c =================================================================== RCS file: /cvsroot/blob/blob/src/blob/clart.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- clart.c 2001/10/14 22:36:11 1.1 +++ clart.c 2001/10/15 21:54:17 1.2 @@ -26,4 +26,108 @@ #endif #include <blob/arch.h> +#include <blob/errno.h> +#include <blob/flash.h> +#include <blob/util.h> + + + + +/* flash descriptor for CreditLART flash */ +/* 1x Intel 28F256J3A strataflash (16MB) */ +flash_descriptor_t flash_descriptors[] = +{ + { + size: 128 * 1024, + num: 128, + lockable: 1 + }, + { + /* NULL block */ + }, +}; + + + + +/* flash commands for a single 16 bit intel flash chip */ +#define READ_ARRAY 0x000000FF +#define ERASE_SETUP 0x00000020 +#define ERASE_CONFIRM 0x000000D0 +#define PGM_SETUP 0x00000040 +#define STATUS_READ 0x00000070 +#define STATUS_CLEAR 0x00000050 +#define STATUS_BUSY 0x00000080 +#define STATUS_ERASE_ERR 0x00000020 +#define STATUS_PGM_ERR 0x00000010 + + + + +/* the next two functions should work for all Intel flashes */ + +/* erases a flash block at the given address */ +int erase_flash(u32 *addr) +{ + u32 result; + + /* prepare for erase */ + *addr = data_to_flash(ERASE_SETUP); + barrier(); + + /* erase block */ + *addr = data_to_flash(ERASE_CONFIRM); + barrier(); + /* status check */ + do { + *addr = data_to_flash(STATUS_READ); + barrier(); + result = data_from_flash(*addr); + barrier(); + } while((~result & STATUS_BUSY) != 0); + + /* put flash back into Read Array mode */ + *addr = data_to_flash(READ_ARRAY); + barrier(); + + if((result & STATUS_ERASE_ERR) != 0) + return -EFLASHERASE; + + return 0; +} + + + + +/* write a flash block at a given location */ +int write_flash(u32 *dst, const u32* src) +{ + u32 result; + + /* setup flash for writing */ + *dst = data_to_flash(PGM_SETUP); + barrier(); + + /* write data */ + *dst = *src; + barrier(); + + /* status check */ + do { + *dst = data_to_flash(STATUS_READ); + barrier(); + + result = data_from_flash(*dst); + barrier(); + } while((~result & STATUS_BUSY) != 0); + + /* put flash back into Read Array mode */ + *dst = data_to_flash(READ_ARRAY); + barrier(); + + if(((result & STATUS_PGM_ERR) != 0) || (*dst != *src)) + return -EFLASHPGM; + + return 0; +} Index: assabet.c =================================================================== RCS file: /cvsroot/blob/blob/src/blob/assabet.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- assabet.c 2001/10/14 22:36:11 1.1 +++ assabet.c 2001/10/15 21:54:17 1.2 @@ -26,4 +26,102 @@ #endif #include <blob/arch.h> +#include <blob/errno.h> +#include <blob/flash.h> +#include <blob/util.h> + + +/* flash descriptor for Assabet flash */ +/* 2x Intel 28F128J3A strataflash (16MB) */ +flash_descriptor_t flash_descriptors[] = +{ + { + size: 2 * 128 * 1024, + num: 64, + lockable: 1 + }, + { + /* NULL block */ + }, +}; + + + + +/* flash commands for two 16 bit intel flash chips */ +#define READ_ARRAY 0x00FF00FF +#define ERASE_SETUP 0x00200020 +#define ERASE_CONFIRM 0x00D000D0 +#define PGM_SETUP 0x00400040 +#define STATUS_READ 0x00700070 +#define STATUS_CLEAR 0x00500050 +#define STATUS_BUSY 0x00800080 +#define STATUS_ERASE_ERR 0x00200020 +#define STATUS_PGM_ERR 0x00100010 + + + + +int erase_flash(u32 *addr) +{ + u32 result; + + /* prepare for erase */ + *addr = data_to_flash(ERASE_SETUP); + barrier(); + + /* erase block */ + *addr = data_to_flash(ERASE_CONFIRM); + barrier(); + + /* status check */ + do { + *addr = data_to_flash(STATUS_READ); + barrier(); + result = data_from_flash(*addr); + barrier(); + } while((~result & STATUS_BUSY) != 0); + + /* put flash back into Read Array mode */ + *addr = data_to_flash(READ_ARRAY); + barrier(); + + if((result & STATUS_ERASE_ERR) != 0) + return -EFLASHERASE; + return 0; +} + + + + +int write_flash(u32 *dst, const u32* src) +{ + u32 result; + + /* setup flash for writing */ + *dst = data_to_flash(PGM_SETUP); + barrier(); + + /* write data */ + *dst = *src; + barrier(); + + /* status check */ + do { + *dst = data_to_flash(STATUS_READ); + barrier(); + + result = data_from_flash(*dst); + barrier(); + } while((~result & STATUS_BUSY) != 0); + + /* put flash back into Read Array mode */ + *dst = data_to_flash(READ_ARRAY); + barrier(); + + if(((result & STATUS_PGM_ERR) != 0) || (*dst != *src)) + return -EFLASHPGM; + + return 0; +} |
From: Erik M. <er...@us...> - 2001-10-15 21:52:12
|
Update of /cvsroot/blob/blob/src/blob In directory usw-pr-cvs1:/tmp/cvs-serv19896/src/blob Modified Files: flash.c Log Message: First cleanup of the flash code Index: flash.c =================================================================== RCS file: /cvsroot/blob/blob/src/blob/flash.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- flash.c 2001/10/14 20:24:32 1.3 +++ flash.c 2001/10/15 21:52:09 1.4 @@ -43,107 +43,185 @@ #include <blob/serial.h> #include <blob/flash.h> -/* define for advanced flash functionality (not that it works) -- Erik */ -/* #define ADVANCED_FLASH 1 */ +#include <blob/init.h> +#include <blob/command.h> +/* this is enough for a 16MB flash with 128kB blocks */ +#define NEW_NUM_FLASH_BLOCKS (128) -/* Static function defs */ -static u32 EraseOne(const char *whichOne); -#ifdef ADVANCED_FLASH -static void GetBlockOrder(tBlkInfo *blocksInfo, u8 which, - u8 blockOrder[NUM_FLASH_BLOCKS]); -#endif +typedef struct { + u32 start; + u32 size; + int lockable; +} flash_block_t; + +static flash_block_t flash_blocks[NEW_NUM_FLASH_BLOCKS]; +static int num_flash_blocks; -#ifdef ADVANCED_FLASH -void ScanFlash(tBlkInfo *blocksInfo) +/* initialise the flash blocks table */ +static void init_flash(void) { -/* Scans the flash for headers in the main blocks. Maybe in the future we will - put the headers in one of the parameter blocks. */ - int i,j; + int i = 0; + int j; + u32 start = 0; - j = 0; - for(i = 0; i < NUM_FLASH_BLOCKS; i++) { - MyMemCpy((u32 *) &(blocksInfo->headers[i]), - FLASH_BLOCK_BASE + i * FLASH_BLOCK_SIZE, - sizeof(tBlkHdr) / 4); - /* Is this a 'first' block ? */ - if(BLOCK_IN_USE(blocksInfo->headers[i]) - && (blocksInfo->headers[i].seqNum == 0)) - blocksInfo->firstBlockIndex[j++] = i; + num_flash_blocks = 0; + + while(flash_descriptors[i].size != 0) { +#ifdef BLOB_DEBUG + SerialOutputDec(flash_descriptors[i].num); + SerialOutputString("x 0x"); + SerialOutputHex(flash_descriptors[i].size); + SerialOutputString(", "); + + if(!flash_descriptors[i].lockable) + SerialOutputString("not "); + + SerialOutputString("lockable\n"); +#endif + + for(j = 0; j < flash_descriptors[i].num; j++) { + flash_blocks[num_flash_blocks].start = start; + flash_blocks[num_flash_blocks].size = + flash_descriptors[i].size; + flash_blocks[num_flash_blocks].lockable = + flash_descriptors[i].lockable; + + start += flash_descriptors[i].size; + + num_flash_blocks++; + + if(num_flash_blocks >= NEW_NUM_FLASH_BLOCKS) { + printerrprefix(); + SerialOutputString("not enough flash_blocks\n"); + break; + } + } + + i++; } - - for(; j < NUM_FLASH_BLOCKS; j++) - blocksInfo->firstBlockIndex[j] = NO_BLOCK; -} /* ScanFlash */ -#endif +#ifdef BLOB_DEBUG + SerialOutputString("Flash map:\n"); + for(i = 0; i < num_flash_blocks; i++) { + SerialOutputString(" 0x"); + SerialOutputHex(flash_blocks[i].size); + SerialOutputString(" @ 0x"); + SerialOutputHex(flash_blocks[i].start); + SerialOutputString(" ("); + SerialOutputDec(flash_blocks[i].size / 1024); + SerialOutputString(" kB), "); + if(!flash_blocks[i].lockable) + SerialOutputString("not "); + + SerialOutputString("lockable\n"); + } +#endif +} -#ifdef ADVANCED_FLASH -void LoadBlocksToMem(tBlkInfo *blocksInfo, u8 which, u32 *baseAddr) +__initlist(init_flash, INIT_LEVEL_OTHER_STUFF); + + +int flash_erase_region(u32 *start, u32 nwords) { -/* Load a series of blocks to memory */ - u8 blockOrder[NUM_FLASH_BLOCKS]; - int numBlocks = blocksInfo->headers[which].totSeq; - int i; - u32 *srcAddr, *dstAddr = baseAddr; - - /* If the block isn't in use, fail silently. */ - if(!BLOCK_IN_USE(blocksInfo->headers[which])) - return; - - GetBlockOrder(blocksInfo, which, blockOrder); - - for(i = 0; i < numBlocks; i++) { - srcAddr = FLASH_BLOCK_BASE + - blockOrder[i] * FLASH_BLOCK_SIZE + sizeof(tBlkHdr); - MyMemCpy(dstAddr, srcAddr, blocksInfo->headers[i].bytesInBlock / 4); - dstAddr += blocksInfo->headers[i].bytesInBlock / 4; + u32 *cur; + u32 *end; + int rv; + + cur = start; + end = start + nwords; + + while(cur < end) { + if(*cur != 0xffffffff) { + +#ifdef BLOB_DEBUG + SerialOutputString(__FUNCTION__ "(): erasing dirty block at 0x"); + SerialOutputHex((u32)cur); + SerialOutputByte('\n'); +#endif + /* dirty block */ + rv = erase_flash(cur); + + if(rv < 0) { + printerrprefix(); + SerialOutputString("flash erase error at 0x"); + SerialOutputHex((u32)cur); + SerialOutputByte('\n'); + return rv; + } + + continue; + } + cur ++; } -} /* LoadBlocksToMem */ + + return 0; +} + + + +int flash_write_region(u32 *dst, const u32 *src, u32 nwords) +{ + u32 *cur; + u32 *end; + int rv; + + cur = dst; + end = dst + nwords; + +#ifdef BLOB_DEBUG + SerialOutputString(__FUNCTION__ "(): flashing 0x"); + SerialOutputHex(nwords); + SerialOutputString(" words from 0x"); + SerialOutputHex((u32)src); + SerialOutputString(" to 0x"); + SerialOutputHex((u32)dst); + SerialOutputByte('\n'); #endif + while(cur < end) { + if((u32)cur % (16 * 1024) == 0) { + SerialOutputByte('.'); + led_toggle(); + } + rv = write_flash(cur, src); + if(rv < 0) { + printerrprefix(); + SerialOutputString("flash write error at 0x"); + SerialOutputHex((u32)cur); + SerialOutputByte('\n'); + return rv; + } -/* The spooky functions that write to the same flash that we're executing from */ + cur ++; + src ++; + } -u32 data_from_flash(u32 what); -u32 data_to_flash(u32 what); + return 0; +} -#if defined SHANNON || defined NESA -#define READ_ARRAY 0x00F000F0 -#define UNLOCK1 0x00AA00AA -#define UNLOCK2 0x00550055 -#define ERASE_SETUP 0x00800080 -#define ERASE_CONFIRM 0x00300030 -#define PGM_SETUP 0x00A000A0 -#define UNLOCK_BYPASS 0x00200020 -#define FLASH_ADDR1 (0x00000555 << 2) -#define FLASH_ADDR2 (0x000002AA << 2) -#define ERASE_DONE 0x00800080 -#define RDY_MASK 0x00800080 -#define STATUS_PGM_ERR 0x00200020 -#define STATUS_ERASE_ERR 0x00000001 -#else -#define READ_ARRAY 0x00FF00FF -#define ERASE_SETUP 0x00200020 -#define ERASE_CONFIRM 0x00D000D0 -#define PGM_SETUP 0x00400040 -#define STATUS_READ 0x00700070 -#define STATUS_CLEAR 0x00500050 -#define STATUS_BUSY 0x00800080 -#define STATUS_ERASE_ERR 0x00200020 -#define STATUS_PGM_ERR 0x00100010 -#endif + +/* -------- OLD ---------------------------------------------------- */ + + + + +/* Static function defs */ +static u32 EraseOne(const char *whichOne); + + + void EraseBlocks(tBlockType which) { @@ -181,7 +259,7 @@ for(i = 0; i < numBlocks; i++, thisBlock += MAIN_BLOCK_SIZE) { SerialOutputByte('.'); led_toggle(); - if((EraseOne(thisBlock) & STATUS_ERASE_ERR) != 0) { + if(EraseOne(thisBlock) != 0) { printerrprefix(); SerialOutputString("erase error at address 0x"); SerialOutputHex((u32)thisBlock); @@ -196,14 +274,8 @@ void WriteBlocksFromMem(tBlockType type, const u32 *source, int length) { - volatile u32 *flashBase; - u32 result; - int maxLength, i; -#if defined SHANNON || defined NESA -#define READY 1 -#define ERR 2 - int chip1, chip2; -#endif + u32 *flashBase; + int maxLength; if((u32)source & 0x03) { printerror(EALIGN, NULL); @@ -247,169 +319,37 @@ /* this should not happen */ return; } - + + length = (length + 3) / 4; + maxLength /= 4; + if(length > maxLength) length = maxLength; #ifdef BLOB_DEBUG SerialOutputString(__FUNCTION__ "(): Flashing 0x"); SerialOutputHex((u32)length); - SerialOutputString(" bytes from 0x"); + SerialOutputString(" words from 0x"); SerialOutputHex((u32)source); SerialOutputString(" to 0x"); SerialOutputHex((u32)flashBase); SerialOutputByte('\n'); #endif - -#if defined SHANNON || defined NESA - *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK1); - *(u32 *)FLASH_ADDR2 = data_to_flash(UNLOCK2); - *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK_BYPASS); -#endif - - for(i = 0; i < length; i+= 4, flashBase++, source++) { - if((i % MAIN_BLOCK_SIZE) == 0) { - SerialOutputByte('.'); - led_toggle(); - } - - *flashBase = data_to_flash(PGM_SETUP); - *flashBase = *source; - -#if defined SHANNON || defined NESA - - /* This is a pretty similar situation to the erasing status below - * Bit 7 is ~(data bit 7) until the flash is complete. If bit 5 - * gets set before this happens, there is an error, but this could - * happen near the clock edge, and bit 5 could be the actual data - * before bit 7 changes, so we have to read again. - */ - chip1 = chip2 = 0; - do { - result = data_from_flash(*flashBase); - if (!chip1 && ((result & 0x80) == (*source & 0x80))) chip1 = READY; - if (!chip1 && ((result & 0xFFFF) & STATUS_PGM_ERR)) { - result = data_from_flash(*flashBase); - if ((result & 0x80) == (*source & 0x80)) chip1 = READY; - else chip1 = ERR; - } - if (!chip2 && ((result & (0x80 << 16)) == (*source & (0x80 << 16)))) chip2 = READY; - if (!chip2 && ((result >> 16) & STATUS_PGM_ERR)) { - result = data_from_flash(*flashBase); - if ((result & (0x80 << 16)) == (*source & (0x80 << 16))) chip2 = READY; - else chip2 = ERR; - } - - } while (!chip1 || !chip2); - - if (chip1 == ERR || chip2 == ERR || *flashBase != *source) { -#else - do { - *flashBase = data_to_flash(STATUS_READ); - result = data_from_flash(*flashBase); - } while((~result & STATUS_BUSY) != 0); - - *flashBase = data_to_flash(READ_ARRAY); - - if((result & STATUS_PGM_ERR) != 0 || *flashBase != *source) { -#endif - printerrprefix(); - SerialOutputString("Write error at address 0x"); - SerialOutputHex((u32)flashBase); - SerialOutputByte('\n'); - return; - } - } - -#if defined SHANNON || defined NESA - *(u32 *)FLASH_ADDR1 = data_to_flash(READ_ARRAY); -#endif + flash_write_region(flashBase, source, length); } /* WriteBlocksFromMem */ + static u32 EraseOne(const char *whichOne) { -/* Routine to erase one block of flash */ - - volatile u32 *writeMe = (u32 *)whichOne; - u32 result; - -#if defined SHANNON || defined NESA - int chip1, chip2; -#endif + int rv; -#ifdef BLOB_DEBUG - SerialOutputString(__FUNCTION__ "(): erasing block at address 0x"); - SerialOutputHex((u32)whichOne); - SerialOutputByte('\n'); -#endif - -#if defined SHANNON || defined NESA - *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK1); - *(u32 *)FLASH_ADDR2 = data_to_flash(UNLOCK2); - *(u32 *)FLASH_ADDR1 = data_to_flash(ERASE_SETUP); - *(u32 *)FLASH_ADDR1 = data_to_flash(UNLOCK1); - *(u32 *)FLASH_ADDR2 = data_to_flash(UNLOCK2); - *writeMe = data_to_flash(ERASE_CONFIRM); - - /* I just can't find clean ways of dealing with this flash... - * The error bit is a *set* bit, so if its read, and bit 7 is 0, - * but bit 5 is 1, its an error, however, after these status reads - * are done, erased flash goes to 0xff...sooo...each chip has to - * be caught where the bits are the status bits */ - chip1 = chip2 = 0; - do { - result = data_from_flash(*writeMe); - if (!chip1 && (result & 0xFFFF) & ERASE_DONE) chip1 = READY; - if (!chip1 && (result & 0xFFFF) & STATUS_PGM_ERR) chip1 = ERR; - if (!chip2 && (result >> 16) & ERASE_DONE) chip2 = READY; - if (!chip2 && (result >> 16) & STATUS_PGM_ERR) chip2 = ERR; - - } while(!chip1 || !chip2); - - *(u32 *)FLASH_ADDR1 = data_to_flash(READ_ARRAY); - - if (chip1 == ERR || chip2 == ERR) return 1; - return 0; -#else + rv = flash_erase_region((u32 *)whichOne, MAIN_BLOCK_SIZE / 4); - *writeMe = data_to_flash(ERASE_SETUP); - *writeMe = data_to_flash(ERASE_CONFIRM); - - do { - *writeMe = data_to_flash(STATUS_READ); - result = data_from_flash(*writeMe); - } while((~result & STATUS_BUSY) != 0); - - *writeMe = data_to_flash(READ_ARRAY); - return result; -#endif + if(rv < 0) + return 1; + else + return 0; } /* EraseOne */ - - - -#ifdef ADVANCED_FLASH -static void GetBlockOrder(tBlkInfo *blocksInfo, u8 which, - u8 blockOrder[NUM_FLASH_BLOCKS]) -{ - - tBlockType type = blocksInfo->headers[which].type; - char *name = blocksInfo->headers[which].name; - int i; - - /* If the block isn't in use, fail silently. */ - if(!BLOCK_IN_USE(blocksInfo->headers[which])) - return; - - for(i = 0; i < NUM_FLASH_BLOCKS; i++) { - if(BLOCK_IN_USE(blocksInfo->headers[i]) && - (blocksInfo->headers[i].type == type) && - !MyStrNCmp(blocksInfo->headers[i].name, name, BLOCK_NAME_LEN)) { - - blockOrder[blocksInfo->headers[i].seqNum] = i; - } - } -} /* GetBlockOrder */ -#endif |
From: Erik M. <er...@us...> - 2001-10-15 21:52:12
|
Update of /cvsroot/blob/blob/include/blob In directory usw-pr-cvs1:/tmp/cvs-serv19896/include/blob Modified Files: flash.h Log Message: First cleanup of the flash code Index: flash.h =================================================================== RCS file: /cvsroot/blob/blob/include/blob/flash.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- flash.h 2001/10/07 15:27:35 1.2 +++ flash.h 2001/10/15 21:52:09 1.3 @@ -36,6 +36,30 @@ #include <blob/types.h> +typedef struct { + u32 size; + u32 num; + int lockable; +} flash_descriptor_t; + +/* should be filled out by the architecture dependent files */ +extern flash_descriptor_t flash_descriptors[]; + +/* should be provided by the architecture dependent files */ +int erase_flash(u32 *addr); +int write_flash(u32 *dst, const u32* src); + +/* flash data mangle functions */ +u32 data_from_flash(u32 what); +u32 data_to_flash(u32 what); + +/* exported functions */ +int flash_erase_region(u32 *start, u32 nwords); +int flash_write_region(u32 *dst, const u32 *src, u32 nwords); + + +/* -------- OLD ---------------------------------------------------- */ + #define NUM_FLASH_BLOCKS (31) #define FLASH_BLOCK_BASE ((u32 *) 0x020000) #define FLASH_BLOCK_SIZE ((u32) 0x020000) @@ -106,23 +130,9 @@ #define INITRD_LEN (NUM_INITRD_BLOCKS * MAIN_BLOCK_SIZE) #endif -typedef struct { - u32 signature; - char name[BLOCK_NAME_LEN]; - tBlockType type; - u32 seqNum, totSeq; - u32 bytesInBlock; - u32 defLoadAddr; -} tBlkHdr; - -typedef struct { - tBlkHdr headers[NUM_FLASH_BLOCKS]; - u8 firstBlockIndex[NUM_FLASH_BLOCKS]; -} tBlkInfo; -void ScanFlash(tBlkInfo *blocksInfo); -void LoadBlocksToMem(tBlkInfo *blocksInfo, u8 which, u32 *baseAddr); void EraseBlocks(tBlockType which); void WriteBlocksFromMem(tBlockType type, const u32 *source, int length); + #endif |
From: Erik M. <er...@us...> - 2001-10-15 21:47:50
|
Update of /cvsroot/blob/blob/src/blob In directory usw-pr-cvs1:/tmp/cvs-serv18859/src/blob Modified Files: chkmem.c Log Message: An optimisation barrier is handy in flash functions as well, so move it to include/blob/util.h Index: chkmem.c =================================================================== RCS file: /cvsroot/blob/blob/src/blob/chkmem.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- chkmem.c 2001/10/14 20:24:32 1.4 +++ chkmem.c 2001/10/15 21:47:47 1.5 @@ -58,10 +58,6 @@ /* more readable IMHO */ #define MEM( x ) (*((u32 *)x)) -/* Optimization barrier */ -/* The "volatile" is due to gcc bugs */ -#define barrier() __asm__ __volatile__("": : :"memory") - #define MAKE32FROM8(X) (u32) (X | X << 8 | X << 16 | X << 24) #define CHKMEM_ERR (-1) |
From: Erik M. <er...@us...> - 2001-10-15 21:47:50
|
Update of /cvsroot/blob/blob/include/blob In directory usw-pr-cvs1:/tmp/cvs-serv18859/include/blob Modified Files: util.h Log Message: An optimisation barrier is handy in flash functions as well, so move it to include/blob/util.h Index: util.h =================================================================== RCS file: /cvsroot/blob/blob/include/blob/util.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- util.h 2001/10/07 23:01:08 1.3 +++ util.h 2001/10/15 21:47:47 1.4 @@ -56,4 +56,10 @@ /* convert a string to an u32 value */ int strtou32(const char *str, u32 *value); + +/* Optimization barrier */ +/* The "volatile" is due to gcc bugs */ +#define barrier() __asm__ __volatile__("": : :"memory") + + #endif |
From: Erik M. <er...@us...> - 2001-10-15 21:45:16
|
Update of /cvsroot/blob/blob/src/lib In directory usw-pr-cvs1:/tmp/cvs-serv18289 Modified Files: command.c Log Message: we should include blob/error.h Index: command.c =================================================================== RCS file: /cvsroot/blob/blob/src/lib/command.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- command.c 2001/10/07 23:32:05 1.5 +++ command.c 2001/10/15 21:45:13 1.6 @@ -37,6 +37,7 @@ #include <blob/command.h> #include <blob/errno.h> +#include <blob/error.h> #include <blob/init.h> #include <blob/serial.h> #include <blob/time.h> |
From: Erik M. <er...@us...> - 2001-10-15 21:27:10
|
Update of /cvsroot/blob/blob/src/diag In directory usw-pr-cvs1:/tmp/cvs-serv13231/src/diag Modified Files: initcalls.c Log Message: - add led_lock(), led_unlock(), and led_init() functions - use led_init() in init calls - remove led_off() from exit calls (so pleb will remain working) Index: initcalls.c =================================================================== RCS file: /cvsroot/blob/blob/src/diag/initcalls.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- initcalls.c 2001/10/07 22:09:54 1.1 +++ initcalls.c 2001/10/15 21:27:05 1.2 @@ -48,7 +48,7 @@ /* init calls */ __initlist(serial_default_init, INIT_LEVEL_INITIAL_HARDWARE); __initlist(enable_icache, INIT_LEVEL_INITIAL_HARDWARE); -__initlist(led_on, INIT_LEVEL_INITIAL_HARDWARE); +__initlist(led_init, INIT_LEVEL_INITIAL_HARDWARE); __initlist(TimerInit, INIT_LEVEL_OTHER_HARDWARE); @@ -56,4 +56,3 @@ /* exit calls */ __exitlist(disable_icache, INIT_LEVEL_INITIAL_HARDWARE); -__exitlist(led_off, INIT_LEVEL_INITIAL_HARDWARE); |
From: Erik M. <er...@us...> - 2001-10-15 21:27:08
|
Update of /cvsroot/blob/blob/src/blob In directory usw-pr-cvs1:/tmp/cvs-serv13231/src/blob Modified Files: initcalls.c Log Message: - add led_lock(), led_unlock(), and led_init() functions - use led_init() in init calls - remove led_off() from exit calls (so pleb will remain working) Index: initcalls.c =================================================================== RCS file: /cvsroot/blob/blob/src/blob/initcalls.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- initcalls.c 2001/10/07 20:16:57 1.1 +++ initcalls.c 2001/10/15 21:27:05 1.2 @@ -48,7 +48,7 @@ /* init calls */ __initlist(serial_default_init, INIT_LEVEL_INITIAL_HARDWARE); __initlist(enable_icache, INIT_LEVEL_INITIAL_HARDWARE); -__initlist(led_on, INIT_LEVEL_INITIAL_HARDWARE); +__initlist(led_init, INIT_LEVEL_INITIAL_HARDWARE); __initlist(TimerInit, INIT_LEVEL_OTHER_HARDWARE); @@ -56,4 +56,3 @@ /* exit calls */ __exitlist(disable_icache, INIT_LEVEL_INITIAL_HARDWARE); -__exitlist(led_off, INIT_LEVEL_INITIAL_HARDWARE); |