patch-2.4.19 linux-2.4.19/arch/mips/galileo-boards/ev64120/compressed/flashdrv.c
Next file: linux-2.4.19/arch/mips/galileo-boards/ev64120/compressed/galileo_port.h
Previous file: linux-2.4.19/arch/mips/galileo-boards/ev64120/compressed/fixit
Back to the patch index
Back to the overall index
- Lines: 1561
- Date:
Fri Aug 2 17:39:43 2002
- Orig file:
linux-2.4.18/arch/mips/galileo-boards/ev64120/compressed/flashdrv.c
- Orig date:
Wed Dec 31 16:00:00 1969
diff -urN linux-2.4.18/arch/mips/galileo-boards/ev64120/compressed/flashdrv.c linux-2.4.19/arch/mips/galileo-boards/ev64120/compressed/flashdrv.c
@@ -0,0 +1,1560 @@
+/* flashdrv.c - FLASH memory functions and definitions*/
+
+/* Copyright Galileo Technology. */
+
+/*
+DESCRIPTION
+This flash driver gives the user a convenient interface to FLASH memory located
+on the user`s board, it supports various layout configurations such as:
+1. One pure 8 bit device (Such as AMD`s AM29LV040B).
+2. 1,2,4 or 8 devices 16 bit wide configured to operate in 8 bit mode.
+3. 1,2 or 4 devices each 16 bit wide.
+Before using the driver you must call the initialization function at least once
+or when ever you are changing the FLASH base address.
+The list bellow contains the supported FLASH memory devices, new devices can be
+added easily in the future.
+*/
+
+/*includes*/
+#ifdef __linux__
+#include <asm/galileo-boards/evb64120A/flashdrv.h>
+#else
+#include "flashdrv.h"
+#endif
+/* locals */
+
+#ifdef __MIPSEB__ // skranz, add
+#define BE // skranz, add
+#endif // skranz, add
+
+/******************************************************************************
+* Those two tables contain the supported flash devices information needed by
+* the driver:
+* The first table "flashParametrs" starts with 10 shared fields
+* (currently 6 are reserved):
+* index 0 => Pointer to an entry in the second table list
+* index 1 => baseAddress - Flash memory device base address.
+* index 2 => width - 1, 2, 4 or 8 Bytes.
+* index 3 => mode - PURE8, X8 or X16 flash configuration (for X16 devices only)
+* The second table (flashTypes) contains:
+* Entry`s structure:
+* Manufacture ID,Device ID,number of sectors,list of sector`s sizes
+* (in Kbytes starting with sector number 0).
+* The end of the list is pointed with a zero.
+******************************************************************************/
+unsigned int flashParametrs[10]; /* 0 Entry pointer */
+ /* 0 Base address */
+ /* 0 Width */
+ /* 0 Mode */
+ /* 0,0,0,0,0,0, spare entries. */
+unsigned int flashTypes[] = {
+
+ /* 0 */ AMD_FLASH, AM29F400BB, 11, 16, 8, 8, 32, 64, 64, 64, 64,
+ 64, 64, 64,
+ /* 1 */ AMD_FLASH, AM29F400BT, 11, 64, 64, 64, 64, 64, 64, 64, 32,
+ 8, 8, 16,
+ /* 2 */ ST_FLASH, M29W040, 8, 64, 64, 64, 64, 64, 64, 64, 64,
+ /* 3 */ AMD_FLASH, AM29LV040B, 8, 64, 64, 64, 64, 64, 64, 64, 64,
+ /* 4 */ AMD_FLASH, AM29LV800BT, 19, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64,
+ 64, 64, 64, 64, 64, 32, 8, 8, 16,
+ /* 5 */ INTEL_FLASH, I28F320J3A, 32, 128, 128, 128, 128, 128, 128,
+ 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128,
+ /* 6 */ INTEL_FLASH, I28F640J3A, 64, 128, 128, 128, 128, 128, 128,
+ 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128,
+ /* 7 */ INTEL_FLASH, I28F128J3A, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ /* 8 */ AMD_FLASH, AM29LV400BB, 11, 16, 8, 8, 32, 64, 64, 64, 64,
+ 64, 64, 64,
+ /* 9 */ AMD_FLASH, AM29LV400BT, 11, 64, 64, 64, 64, 64, 64, 64, 32,
+ 8, 8, 16,
+ /* 10 */ INTEL_FLASH, I28F320B3_T, 71, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 8, 8, 8, 8, 8, 8, 8, 8,
+ /* 11 */ INTEL_FLASH, I28F320B3_B, 71, 8, 8, 8, 8, 8, 8, 8, 8, 64,
+ 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ /* 12 */ INTEL_FLASH, I28F160B3_B, 39, 8, 8, 8, 8, 8, 8, 8, 8, 64,
+ 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64,
+ /* 13 */ INTEL_FLASH, I28F160B3_T, 39, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 8, 8, 8, 8, 8, 8, 8, 8,
+
+ 0 /* End of list indicator */
+};
+
+/********************************************************************
+* flashInit - Initializes the FLASH memory driver`s parameters, this function
+* must be called at least once before using the FLASH memory.
+* If you are changing the FLASH base address call this function
+* again.
+*
+* INPUTS: unsigned int flashBaseAddress - The flash base Address.
+* unsigned int flashWidth - Flash bus width in Bytes: 1,2,4 or 8.
+* flashMode - PURE8, X8 or X16.
+* RETURNS: Flash Size, zero when operation (flashInit) failed.
+*********************************************************************/
+unsigned int flashInit(unsigned int flashBaseAddress,
+ unsigned int flashWidth, FLASHmode flashMode)
+{
+ unsigned short mfrId = 0;
+ unsigned short devId = 0xffff;
+ unsigned int FirstAddr, SecondAddr, ThirdAddr;
+ unsigned int pArray = 0;
+ unsigned int counter;
+ unsigned int flashSize = 0;
+
+ /* update the list with relevant parametrs */
+ flashParametrs[0] = 0; /* Default initialization */
+ flashParametrs[1] = flashBaseAddress;
+ flashParametrs[2] = flashWidth;
+ flashParametrs[3] = flashMode;
+ /* Get the FLASH`s ID */
+ switch (FLASH_WIDTH) {
+ case 1:
+ /* AMD or ST ?? * */
+ if (flashMode == PURE8) { /* Boot Flash */
+ FirstAddr = 0x5555;
+ SecondAddr = 0x2aaa;
+ ThirdAddr = 0x5555;
+ } else { /* X16 device configured to 8bit Mode */
+
+ FirstAddr = 0xaaaa;
+ SecondAddr = 0x5555;
+ ThirdAddr = 0xaaaa;
+ }
+ flashReset();
+ WRITE_CHAR(FLASH_BASE_ADDRESS + FirstAddr, 0xAA);
+ WRITE_CHAR(FLASH_BASE_ADDRESS + SecondAddr, 0x55);
+ WRITE_CHAR(FLASH_BASE_ADDRESS + ThirdAddr, 0x90);
+ READ_CHAR(FLASH_BASE_ADDRESS + 0x0, &mfrId);
+ if (mfrId == AMD_FLASH || mfrId == ST_FLASH) {
+ flashReset();
+ WRITE_CHAR(FLASH_BASE_ADDRESS + FirstAddr, 0xAA);
+ WRITE_CHAR(FLASH_BASE_ADDRESS + SecondAddr, 0x55);
+ WRITE_CHAR(FLASH_BASE_ADDRESS + ThirdAddr, 0x90);
+ READ_CHAR(FLASH_BASE_ADDRESS + 0x1, &devId);
+ break;
+ }
+ /* Micron or Intel ?? * */
+ WRITE_CHAR(FLASH_BASE_ADDRESS, 0xff); /* Read Array */
+ /* Flash reset for Intel/Micron */
+ WRITE_CHAR(FLASH_BASE_ADDRESS, 0x90); /* IDENTIFY Device */
+ READ_CHAR(FLASH_BASE_ADDRESS + 0x0, &mfrId); /*Address for ManufactureID */
+ if (mfrId == INTEL_FLASH || mfrId == MICRON_FLASH) {
+ WRITE_CHAR(FLASH_BASE_ADDRESS, 0xff); /* Read Array */
+ /*Flash reset for Intel/Micron */
+ WRITE_CHAR(FLASH_BASE_ADDRESS, 0x90); /* IDENTIFY Device */
+ READ_CHAR(FLASH_BASE_ADDRESS + 0x1, &devId); /*Address for DeviceID */
+ }
+ break;
+ case 2:
+ case 4:
+ case 8:
+ /* AMD or ST ??? */
+ flashReset();
+ WRITE_SHORT(FLASH_BASE_ADDRESS + 0x5555 * FLASH_WIDTH,
+ 0xaa);
+ WRITE_SHORT(FLASH_BASE_ADDRESS + 0x2aaa * FLASH_WIDTH,
+ 0x55);
+ WRITE_SHORT(FLASH_BASE_ADDRESS + 0x5555 * FLASH_WIDTH,
+ 0x90);
+ READ_SHORT(FLASH_BASE_ADDRESS, &mfrId);
+ flashReset();
+ /* Read the device ID */
+ if (mfrId == AMD_FLASH || mfrId == ST_FLASH) {
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ 0x5555 * FLASH_WIDTH, 0xaa);
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ 0x2aaa * FLASH_WIDTH, 0x55);
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ 0x5555 * FLASH_WIDTH, 0x90);
+ READ_SHORT(FLASH_BASE_ADDRESS + 0x1 * FLASH_WIDTH,
+ &devId);
+ break;
+ }
+ /* Micron or Intel ?? * */
+ WRITE_WORD(FLASH_BASE_ADDRESS, 0x00ff00ff);
+ WRITE_WORD(FLASH_BASE_ADDRESS, 0x00900090);
+ if ((FLASH_WIDTH == 4) || (FLASH_WIDTH == 8)) { /* 32 or 64 bit */
+ READ_SHORT(FLASH_BASE_ADDRESS, &mfrId);
+ } else { /* FLASH_WIDTH = 2 */
+
+ READ_SHORT(FLASH_BASE_ADDRESS, &mfrId);
+ }
+ if ((mfrId == INTEL_FLASH) || (mfrId == MICRON_FLASH)) {
+ /* Flash reset for Intel/Micron */
+ flashReset();
+ WRITE_WORD(FLASH_BASE_ADDRESS, 0x00ff00ff);
+ WRITE_WORD(FLASH_BASE_ADDRESS, 0x00900090);
+ READ_SHORT(FLASH_BASE_ADDRESS + 0x1 * FLASH_WIDTH,
+ &devId);
+ }
+ break;
+
+ }
+ /* Try to locate the device in the supported flashes list (FLASH_TYPE).
+ according to the keys:
+ 1) mfrId - manufactor ID.
+ 2) devId - device ID.
+ */
+
+ while (true) {
+ if (flashTypes[pArray] == 0) {
+ flashReset();
+ return 0; /* Device not in the list */
+ }
+ if ((flashTypes[pArray] == mfrId) &&
+ (flashTypes[pArray + 1] == devId)) {
+ POINTER_TO_FLASH = pArray;
+ for (counter = 0;
+ counter < flashTypes[NUMBER_OF_SECTORS];
+ counter++) {
+ flashSize =
+ flashSize +
+ flashTypes[FIRST_SECTOR_SIZE +
+ counter];
+ }
+ if (FLASH_MODE != PURE8) {
+ flashReset();
+ return (flashSize * _1K *
+ (FLASH_WIDTH / (FLASH_MODE / 8)));
+ } else {
+ flashReset();
+ return (flashSize * _1K * FLASH_WIDTH);
+ }
+ }
+ pArray += (3 + flashTypes[pArray + 2]); /* Move to next entry */
+ }
+}
+
+/********************************************************************
+* flashReset - Resets the Flash memory (FLASH`s internal protocol reset).
+*
+* INTPUTS: N/A
+* OUTPUT: N/A
+*********************************************************************/
+void flashReset()
+{
+ unsigned char ucData;
+ unsigned short usData;
+ unsigned int uiData;
+
+ if ((flashTypes[POINTER_TO_FLASH] == AMD_FLASH) ||
+ (flashTypes[POINTER_TO_FLASH]) == ST_FLASH) {
+ if (FLASH_MODE == X16) {
+ ucData = 0xf0;
+ usData = 0xf0;
+ uiData = 0x00f000f0;
+ } else { /* case of PURE8 or X8 */
+
+ ucData = 0xf0;
+ usData = 0xf0f0;
+ uiData = 0xf0f0f0f0;
+ }
+ } else {
+ if (FLASH_MODE == X16) {
+ ucData = 0xff;
+ usData = 0xff;
+ uiData = 0x00ff00ff;
+ } else { /* case of PURE8 or X8 */
+
+ ucData = 0xff;
+ usData = 0xffff;
+ uiData = 0xffffffff;
+ }
+ }
+ switch (FLASH_WIDTH) {
+ case 1:
+ WRITE_CHAR(FLASH_BASE_ADDRESS, ucData);
+ break;
+ case 2:
+ WRITE_SHORT(FLASH_BASE_ADDRESS, usData);
+ break;
+ case 4:
+ WRITE_WORD(FLASH_BASE_ADDRESS, uiData);
+ break;
+ case 8:
+ WRITE_WORD(FLASH_BASE_ADDRESS, uiData);
+ WRITE_WORD(FLASH_BASE_ADDRESS + 0x4, uiData);
+ break;
+ }
+}
+
+/********************************************************************
+* flashErase - The function erases the WHOLE flash memory.
+*
+*
+* RETURNS: true on success,false on failure
+*********************************************************************/
+bool flashErase()
+{
+ unsigned int totalFlashSize;
+ unsigned int address;
+ unsigned int readData;
+ unsigned int nextSector;
+
+ flashReset();
+ totalFlashSize = flashGetSize();
+ /* scan all flash memory space. */
+ address = 0;
+ while (address < totalFlashSize) {
+ readData = flashReadWord(address);
+ if (readData != 0xffffffff) { /* offset with dirty data. */
+ flashEraseSector(flashInWhichSector(address));
+ nextSector = flashInWhichSector(address) + 1;
+ if (nextSector < flashTypes[NUMBER_OF_SECTORS])
+ /* jump to next sector. */
+ address = flashGetSectorOffset(nextSector);
+ else
+ /* end of erasing. */
+ address = totalFlashSize;
+ } else
+ address += 4;
+ }
+ return true;
+}
+
+/********************************************************************
+* flashEraseSector - The function erases a specific sector in the flash memory.
+*
+* INPUTS: Sector number.
+* RETURNS: true on success,false on failure.
+*********************************************************************/
+bool flashEraseSector(unsigned int sectorNumber)
+{
+ volatile unsigned int spin;
+ unsigned int regValue;
+ unsigned int sectorBaseAddress = 0;
+ unsigned int i;
+ unsigned int data20, dataD0, data70;
+ unsigned int dataPoll;
+ unsigned int FirstAddr, SecondAddr, ThirdAddr, FourthAddr,
+ FifthAddr;
+ unsigned int FirstData, SecondData, ThirdData;
+ unsigned int FourthData, FifthData, SixthData;
+
+ /* calculate the sector base Address according to the following parametrs:
+ 1: FLASH_WIDTH
+ 2: the size of each sector which it detailed in the table */
+
+ /* checking the if the sectorNumber is legal. */
+ if (sectorNumber > flashTypes[NUMBER_OF_SECTORS] - 1)
+ return false;
+ /* now the calculation begining of the sector Address */
+ for (i = 0; i < sectorNumber; i++) {
+ sectorBaseAddress =
+ sectorBaseAddress + flashTypes[FIRST_SECTOR_SIZE + i];
+ }
+ /* In case of X8 wide the address should be */
+ if (FLASH_MODE == PURE8)
+ sectorBaseAddress = _1K * sectorBaseAddress;
+ if (FLASH_MODE == X8)
+ sectorBaseAddress = _1K * sectorBaseAddress;
+ /* In case of X16 wide the address should be */
+ if (FLASH_MODE == X16)
+ sectorBaseAddress = _1K * sectorBaseAddress / 2;
+ flashReset();
+ if ((flashTypes[POINTER_TO_FLASH] == AMD_FLASH) || \
+ (flashTypes[POINTER_TO_FLASH] == ST_FLASH)) {
+ switch (FLASH_WIDTH) {
+ case 1:
+ if (FLASH_MODE == PURE8) { /* Boot Flash PURE8 */
+ FirstAddr = 0x5555;
+ SecondAddr = 0x2aaa;
+ ThirdAddr = 0x5555;
+ FourthAddr = 0x5555;
+ FifthAddr = 0x2aaa;
+ } else {
+ FirstAddr = 0xaaaa;
+ SecondAddr = 0x5555;
+ ThirdAddr = 0xaaaa;
+ FourthAddr = 0xaaaa;
+ FifthAddr = 0x5555;
+ }
+ WRITE_CHAR(FLASH_BASE_ADDRESS + FirstAddr, 0xAA);
+ WRITE_CHAR(FLASH_BASE_ADDRESS + SecondAddr, 0x55);
+ WRITE_CHAR(FLASH_BASE_ADDRESS + ThirdAddr, 0x80);
+ WRITE_CHAR(FLASH_BASE_ADDRESS + FourthAddr, 0xAA);
+ WRITE_CHAR(FLASH_BASE_ADDRESS + FifthAddr, 0x55);
+ WRITE_CHAR(
+ (FLASH_BASE_ADDRESS +
+ (sectorBaseAddress & 0xffffff00)),
+ 0x30);
+ /* Poll on the flash */
+ do {
+ READ_CHAR(FLASH_BASE_ADDRESS +
+ sectorBaseAddress, ®Value);
+ } while ((regValue & 0x80) != 0x80);
+
+ break;
+ case 2:
+ if (FLASH_MODE == X16) {
+ FirstData = 0xaa; /* Data for the First Cycle */
+ SecondData = 0x55; /* Data for the Second Cycle */
+ ThirdData = 0x80; /* Data for the Third Cycle */
+ FourthData = 0xaa; /* Data for the Fourth Cycle */
+ FifthData = 0x55; /* Data for the Fifth Cycle */
+ SixthData = 0x30; /* Data for the Sixth Cycle */
+ FirstAddr = 0x5555; /* Address for the First Cycle */
+ SecondAddr = 0x2aaa; /* Address for the Second Cycle */
+ ThirdAddr = 0x5555; /* Address for the Third Cycle */
+ FourthAddr = 0x5555; /* Address for the Fourth Cycle */
+ FifthAddr = 0x2aaa; /* Address for the Fifth Cycle */
+ } else { /* (FLASH_MODE = 8) */
+
+ FirstData = 0xaaaa; /* Data for the First Cycle */
+ SecondData = 0x5555; /* Data for the Second Cycle */
+ ThirdData = 0x8080; /* Data for the Third Cycle */
+ FourthData = 0xaaaa; /* Data for the Fourth Cycle */
+ FifthData = 0x5555; /* Data for the Fifth Cycle */
+ SixthData = 0x3030; /* Data for the Sixth Cycle */
+ FirstAddr = 0xaaaa; /* Address for the First Cycle */
+ SecondAddr = 0x5555; /* Address for the Second Cycle */
+ ThirdAddr = 0xaaaa; /* Address for the Third Cycle */
+ FourthAddr = 0xaaaa; /* Address for the Fourth Cycle */
+ FifthAddr = 0x5555; /* Address for the Fifth Cycle */
+ }
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ FirstAddr * FLASH_WIDTH, FirstData);
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ SecondAddr * FLASH_WIDTH, SecondData);
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ ThirdAddr * FLASH_WIDTH, ThirdData);
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ FourthAddr * FLASH_WIDTH, FourthData);
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ FifthAddr * FLASH_WIDTH, FifthData);
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ (sectorBaseAddress & 0xffffff00) *
+ FLASH_WIDTH, SixthData);
+ /* Poll on the flash */
+ if (FLASH_MODE == X16) { /* 1 device of 16 bit */
+ dataPoll = 0x0080;
+ } else { /* (FLASH_MODE = 8) ==> 2 devices , 8 bit each => 16bit */
+
+ dataPoll = 0x8080;
+ }
+ do {
+ READ_SHORT(FLASH_BASE_ADDRESS +
+ sectorBaseAddress * FLASH_WIDTH,
+ ®Value);
+ for (spin = 0; spin < 100; spin++) {
+ } // skranz, added spin loop.
+ } while ((regValue & dataPoll) != dataPoll);
+ break;
+ case 4:
+ if (FLASH_MODE == X16) {
+ FirstData = 0x00aa00aa; /* Data for the First Cycle */
+ SecondData = 0x00550055; /* Data for the Second Cycle */
+ ThirdData = 0x00800080; /* Data for the Third Cycle */
+ FourthData = 0x00aa00aa; /* Data for the Fourth Cycle */
+ FifthData = 0x00550055; /* Data for the Fifth Cycle */
+ SixthData = 0x00300030; /* Data for the Sixth Cycle */
+ FirstAddr = 0x5555; /* Address for the First Cycle */
+ SecondAddr = 0x2aaa; /* Address for the Second Cycle */
+ ThirdAddr = 0x5555; /* Address for the Third Cycle */
+ FourthAddr = 0x5555; /* Address for the Fourth Cycle */
+ FifthAddr = 0x2aaa; /* Address for the Fifth Cycle */
+ } else { /* if (FLASH_MODE == 8) */
+
+ FirstData = 0xaaaaaaaa; /* Data for the First Cycle */
+ SecondData = 0x55555555; /* Data for the Second Cycle */
+ ThirdData = 0x80808080; /* Data for the Third Cycle */
+ FourthData = 0xAAAAAAAA; /* Data for the Fourth Cycle */
+ FifthData = 0x55555555; /* Data for the Fifth Cycle */
+ SixthData = 0x30303030; /* Data for the Sixth Cycle */
+ FirstAddr = 0xaaaa; /* Address for the First Cycle */
+ SecondAddr = 0x5555; /* Address for the Second Cycle */
+ ThirdAddr = 0xaaaa; /* Address for the Third Cycle */
+ FourthAddr = 0xaaaa; /* Address for the Fourth Cycle */
+ FifthAddr = 0x5555; /* Address for the Fifth Cycle */
+ }
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ FirstAddr * FLASH_WIDTH, FirstData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ SecondAddr * FLASH_WIDTH, SecondData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ ThirdAddr * FLASH_WIDTH, ThirdData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ FourthAddr * FLASH_WIDTH, FourthData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ FifthAddr * FLASH_WIDTH, FifthData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ (sectorBaseAddress & 0xffffff00) *
+ FLASH_WIDTH, SixthData);
+ /* Poll on the flash */
+ if (FLASH_MODE == X16) { /* 4 devices , 16 bit each => 64bit */
+ dataPoll = 0x00800080;
+ } else { /* (FLASH_MODE = 8) ==> 8 devices , 8 bit each => 64bit */
+
+ dataPoll = 0x80808080;
+ }
+ do {
+ READ_WORD(FLASH_BASE_ADDRESS +
+ sectorBaseAddress * FLASH_WIDTH,
+ ®Value);
+ } while ((regValue & dataPoll) != dataPoll);
+ break;
+ case 8: /* In case of 64bit width the transformation is 1->8 */
+ if (FLASH_MODE == X16) {
+ FirstData = 0x00aa00aa; /* Data for the First Cycle */
+ SecondData = 0x00550055; /* Data for the Second Cycle */
+ ThirdData = 0x00800080; /* Data for the Third Cycle */
+ FourthData = 0x00aa00aa; /* Data for the Fourth Cycle */
+ FifthData = 0x00550055; /* Data for the Fifth Cycle */
+ SixthData = 0x00300030; /* Data for the Sixth Cycle */
+ FirstAddr = 0x5555; /* Address for the First Cycle */
+ SecondAddr = 0x2aaa; /* Address for the Second Cycle */
+ ThirdAddr = 0x5555; /* Address for the Third Cycle */
+ FourthAddr = 0x5555; /* Address for the Fourth Cycle */
+ FifthAddr = 0x2aaa; /* Address for the Fifth Cycle */
+ } else { /* (FLASH_MODE = 8 */
+
+ FirstData = 0xaaaaaaaa; /* Data for the First Cycle */
+ SecondData = 0x55555555; /* Data for the Second Cycle */
+ ThirdData = 0x80808080; /* Data for the Third Cycle */
+ FourthData = 0xAAAAAAAA; /* Data for the Fourth Cycle */
+ FifthData = 0x55555555; /* Data for the Fifth Cycle */
+ SixthData = 0x30303030; /* Data for the Sixth Cycle */
+ FirstAddr = 0xaaaa; /* Address for the First Cycle */
+ SecondAddr = 0x5555; /* Address for the Second Cycle */
+ ThirdAddr = 0xaaaa; /* Address for the Third Cycle */
+ FourthAddr = 0xaaaa; /* Address for the Fourth Cycle */
+ FifthAddr = 0x5555; /* Address for the Fifth Cycle */
+ }
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ FirstAddr * FLASH_WIDTH, FirstData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ SecondAddr * FLASH_WIDTH, SecondData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ ThirdAddr * FLASH_WIDTH, ThirdData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ FourthAddr * FLASH_WIDTH, FourthData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ FifthAddr * FLASH_WIDTH, FifthData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ (sectorBaseAddress & 0xffffff00) *
+ FLASH_WIDTH, SixthData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ FirstAddr * FLASH_WIDTH + 4, FirstData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ SecondAddr * FLASH_WIDTH + 4,
+ SecondData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ ThirdAddr * FLASH_WIDTH + 4, ThirdData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ FourthAddr * FLASH_WIDTH + 4,
+ FourthData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ FifthAddr * FLASH_WIDTH + 4, FifthData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ (sectorBaseAddress & 0xffffff00)
+ * FLASH_WIDTH + 4, SixthData);
+ /* Poll on the flash */
+ if (FLASH_MODE == X16) { /* 4 devices , 16 bit each => 64bit */
+ dataPoll = 0x00800080;
+ } else { /* (FLASH_MODE = 8) ==> 8 devices , 8 bit each => 64bit */
+
+ dataPoll = 0x80808080;
+ }
+ do {
+ READ_WORD(FLASH_BASE_ADDRESS +
+ sectorBaseAddress * FLASH_WIDTH,
+ ®Value);
+ } while ((regValue & dataPoll) != dataPoll);
+ do {
+ READ_WORD(FLASH_BASE_ADDRESS +
+ sectorBaseAddress * FLASH_WIDTH +
+ 4, ®Value);
+ } while ((regValue & dataPoll) != dataPoll);
+ break;
+ default:
+ return false;
+ }
+ } /* End of 'flash erase sector' for AMD/ST */
+ else { /* Intel/Micron */
+
+ switch (FLASH_WIDTH) {
+ case 1:
+ WRITE_CHAR(FLASH_BASE_ADDRESS, 0x20);
+ WRITE_CHAR(
+ (FLASH_BASE_ADDRESS +
+ (sectorBaseAddress & 0xffffff00)),
+ 0xd0);
+ /* Poll on the flash */
+ while (true) {
+ WRITE_CHAR(FLASH_BASE_ADDRESS, 0x70);
+ READ_CHAR(FLASH_BASE_ADDRESS, ®Value);
+ if ((regValue & 0x80) == 0x80)
+ break;
+ }
+ break;
+ case 2:
+ if (FLASH_MODE == X16) { /* 1 device 16 bit. */
+ data20 = 0x0020;;
+ dataD0 = 0x00d0;;
+ } else { /* (FLASH_MODE = 8) ==> 2 devices , 8 bit each => 16bit */
+
+ data20 = 0x2020;
+ dataD0 = 0xd0d0;
+ }
+ WRITE_SHORT(FLASH_BASE_ADDRESS, data20);
+ WRITE_SHORT(
+ (FLASH_BASE_ADDRESS +
+ ((sectorBaseAddress * 2) &
+ 0xffffff00)), dataD0);
+ /* Poll on the flash */
+ if (FLASH_MODE == X16) {
+ dataPoll = 0x0080;
+ data70 = 0x0070;
+ } else { /* (FLASH_MODE = 8) */
+
+ dataPoll = 0x8080;
+ data70 = 0x7070;
+ }
+ while (true) {
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ sectorBaseAddress * 2, data70);
+ READ_SHORT(FLASH_BASE_ADDRESS +
+ sectorBaseAddress * 2,
+ ®Value);
+ if ((regValue & 0x0080) == 0x0080)
+ break;
+ }
+ break;
+ case 4:
+ if (FLASH_MODE == X16) { /* 2 devices , 16 bit each => 32bit */
+ data20 = 0x00200020;
+ dataD0 = 0x00d000d0;
+ } else { /* (FLASH_MODE = 8) ==> 4 devices , 8 bit each => 32bit */
+
+ data20 = 0x20202020;
+ dataD0 = 0xd0d0d0d0;
+ }
+ WRITE_WORD(FLASH_BASE_ADDRESS, data20);
+ WRITE_WORD(
+ (FLASH_BASE_ADDRESS +
+ ((sectorBaseAddress * 4) &
+ 0xffffff00)), dataD0);
+ /* Poll on the flash */
+ if (FLASH_MODE == X16) {
+ dataPoll = 0x0080;
+ data70 = 0x0070;
+ } else { /* (FLASH_MODE = 8) */
+
+ dataPoll = 0x8080;
+ data70 = 0x7070;
+ }
+ while (true) {
+ WRITE_SHORT(FLASH_BASE_ADDRESS, data70);
+ READ_SHORT(FLASH_BASE_ADDRESS, ®Value);
+ if ((regValue & dataPoll) == dataPoll)
+ break;
+ }
+ while (true) {
+ WRITE_SHORT(FLASH_BASE_ADDRESS + 2,
+ data70);
+ READ_SHORT(FLASH_BASE_ADDRESS + 2,
+ ®Value);
+ if ((regValue & dataPoll) == dataPoll)
+ break;
+ }
+ break;
+ case 8:
+ if (FLASH_MODE == X16) { /* 4 devices , 16 bit each => 64bit */
+ data20 = 0x00200020;
+ dataD0 = 0x00d000d0;
+ } else { /* (FLASH_MODE = 8) ==> 8 devices , 8 bit each => 64bit */
+
+ data20 = 0x20202020;
+ dataD0 = 0xd0d0d0d0;
+ }
+ WRITE_WORD(FLASH_BASE_ADDRESS, data20);
+ WRITE_WORD(
+ (FLASH_BASE_ADDRESS +
+ ((sectorBaseAddress * 8) &
+ 0xffffff00)), dataD0);
+ WRITE_WORD(FLASH_BASE_ADDRESS + 4, data20);
+ WRITE_WORD(
+ (FLASH_BASE_ADDRESS +
+ ((sectorBaseAddress * 8) & 0xffffff00 +
+ 4)), dataD0);
+ /* Poll on the flash */
+ if (FLASH_MODE == X16) {
+ dataPoll = 0x0080;
+ data70 = 0x0070;
+ } else { /* (FLASH_MODE = 8) */
+
+ dataPoll = 0x8080;
+ data70 = 0x7070;
+ }
+ while (true) {
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ sectorBaseAddress * 8, data70);
+ READ_SHORT(FLASH_BASE_ADDRESS +
+ sectorBaseAddress * 8,
+ ®Value);
+ if ((regValue & dataPoll) == dataPoll)
+ break;
+ }
+ while (true) {
+ WRITE_SHORT(FLASH_BASE_ADDRESS + 2,
+ data70);
+ READ_SHORT(FLASH_BASE_ADDRESS + 2,
+ ®Value);
+ if ((regValue & dataPoll) == dataPoll)
+ break;
+ }
+ while (true) {
+ WRITE_SHORT(FLASH_BASE_ADDRESS + 4,
+ data70);
+ READ_SHORT(FLASH_BASE_ADDRESS + 4,
+ ®Value);
+ if ((regValue & dataPoll) == dataPoll)
+ break;
+ }
+ while (true) {
+ WRITE_SHORT(FLASH_BASE_ADDRESS + 6,
+ data70);
+ READ_SHORT(FLASH_BASE_ADDRESS + 6,
+ ®Value);
+ if ((regValue & dataPoll) == dataPoll)
+ break;
+ }
+ break;
+ default:
+ return false;
+ }
+ }
+ flashReset();
+ return true;
+}
+
+/********************************************************************
+* flashWriteWord - Write 32Bit to the FLASH memory at the given offset from the
+* FLASH base address.
+* address 0 = 0x00000000 !!
+* Attention!!! data "0" cannot be programed back to
+* "1" (only by first performing an earase operation).
+* The function takes care of Big/Little endian conversion
+*
+* INPUTS: offset - The offset from the flash`s base address.
+* data - The data that should be written.
+* RETURNS: true on success,false on failure
+*********************************************************************/
+bool flashWriteWord(unsigned int offset, unsigned int data)
+{
+ unsigned char c, rc;
+ unsigned short s, rs;
+ register unsigned int rw;
+ register unsigned int regValue;
+ register unsigned int FirstAddr, SecondAddr, ThirdAddr;
+ register unsigned int FirstData, SecondData, ThirdData;
+ register unsigned int data10, data20, data70, data80;
+
+ if ((flashTypes[POINTER_TO_FLASH] == AMD_FLASH) || \
+ (flashTypes[POINTER_TO_FLASH] == ST_FLASH)) {
+ switch (FLASH_WIDTH) {
+ case 1: /* Split the 32 bit write into four 8bit Writings */
+ if (FLASH_MODE == PURE8) { /* Boot Flash */
+ FirstAddr = 0x5555;
+ SecondAddr = 0x2aaa;
+ ThirdAddr = 0x5555;
+ } else {
+ FirstAddr = 0xaaaa;
+ SecondAddr = 0x5555;
+ ThirdAddr = 0xaaaa;
+ }
+ WRITE_CHAR(FLASH_BASE_ADDRESS + FirstAddr, 0xaa);
+ WRITE_CHAR(FLASH_BASE_ADDRESS + SecondAddr, 0x55);
+ WRITE_CHAR(FLASH_BASE_ADDRESS + ThirdAddr, 0xa0);
+#ifdef BE
+ c = (data >> 24);
+#else
+ c = data;
+#endif
+ WRITE_CHAR(FLASH_BASE_ADDRESS + offset, c);
+ /* Writing first Byte */
+ while (true) {
+ READ_CHAR(FLASH_BASE_ADDRESS + offset,
+ &rc);
+ if ((rc & 0x80) == (c & 0x80)) /* DQ7 =? DATA */
+ break; /* DQ7 = DATA */
+ if ((rc & 0x20) == 0x20) { /* DQ5 =? '1' */
+ READ_CHAR(FLASH_BASE_ADDRESS +
+ offset, &rc);
+ if ((rc & 0x80) == (c & 0x80))
+ break; /* DQ7 = DATA */
+ else
+ return false; /* DQ7 != DATA */
+ }
+ }
+ WRITE_CHAR(FLASH_BASE_ADDRESS + FirstAddr, 0xaa);
+ WRITE_CHAR(FLASH_BASE_ADDRESS + SecondAddr, 0x55);
+ WRITE_CHAR(FLASH_BASE_ADDRESS + ThirdAddr, 0xa0);
+#ifdef BE
+ c = (data >> 16);
+#else
+ c = (data >> 8);
+#endif
+ WRITE_CHAR(FLASH_BASE_ADDRESS + offset + 1, c);
+ /* Writing second Byte */
+ while (true) {
+ READ_CHAR(FLASH_BASE_ADDRESS + offset + 1,
+ &rc);
+ if ((rc & 0x80) == (c & 0x80)) /* DQ7 =? DATA */
+ break; /* DQ7 = DATA */
+ if ((rc & 0x20) == 0x20) { /* DQ5 =? '1' */
+ READ_CHAR(FLASH_BASE_ADDRESS +
+ offset + 1, &rc);
+ if ((rc & 0x80) == (c & 0x80))
+ break; /* DQ7 = DATA */
+ else
+ return false; /* DQ7 != DATA */
+ }
+ }
+ WRITE_CHAR(FLASH_BASE_ADDRESS + FirstAddr, 0xaa);
+ WRITE_CHAR(FLASH_BASE_ADDRESS + SecondAddr, 0x55);
+ WRITE_CHAR(FLASH_BASE_ADDRESS + ThirdAddr, 0xa0);
+#ifdef BE
+ c = (data >> 8);
+#else
+ c = (data >> 16);
+#endif
+ WRITE_CHAR(FLASH_BASE_ADDRESS + offset + 2, c);
+ /* Writing third Byte */
+ while (true) {
+ READ_CHAR(FLASH_BASE_ADDRESS + offset + 2,
+ &rc);
+ if ((rc & 0x80) == (c & 0x80)) /* DQ7 =? DATA */
+ break; /* DQ7 = DATA */
+ if ((rc & 0x20) == 0x20) { /* DQ5 =? '1' */
+ READ_CHAR(FLASH_BASE_ADDRESS +
+ offset + 2, &rc);
+ if ((rc & 0x80) == (c & 0x80))
+ break; /* DQ7 = DATA */
+ else
+ return false; /* DQ7 != DATA */
+ }
+ }
+ WRITE_CHAR(FLASH_BASE_ADDRESS + FirstAddr, 0xaa);
+ WRITE_CHAR(FLASH_BASE_ADDRESS + SecondAddr, 0x55);
+ WRITE_CHAR(FLASH_BASE_ADDRESS + ThirdAddr, 0xa0);
+#ifdef BE
+ c = data;
+#else
+ c = (data >> 24);
+#endif
+ WRITE_CHAR(FLASH_BASE_ADDRESS + offset + 3, c);
+ /* Writing fourth Byte */
+ while (true) {
+ READ_CHAR(FLASH_BASE_ADDRESS + offset + 3,
+ &rc);
+ if ((rc & 0x80) == (c & 0x80)) /* DQ7 =? DATA */
+ break; /* DQ7 = DATA */
+ if ((rc & 0x20) == 0x20) { /* DQ5 =? '1' */
+ READ_CHAR(FLASH_BASE_ADDRESS +
+ offset + 3, &rc);
+ if ((rc & 0x80) == (c & 0x80))
+ break; /* DQ7 = DATA */
+ else
+ return false; /* DQ7 != DATA */
+ }
+ }
+ break;
+ case 2: /* Split the 32 bit write into two 8/16 bit Writings
+ (16bit width). */
+ if (FLASH_MODE == X16) {
+ FirstData = 0xaa; /* Data for the First Cycle */
+ SecondData = 0x55; /* Data for the Second Cycle */
+ ThirdData = 0xa0; /* Data for the Third Cycle */
+ FirstAddr = 0x5555; /* Address for the First Cycle */
+ SecondAddr = 0x2aaa; /* Address for the Second Cycle */
+ ThirdAddr = 0x5555; /* Address for the Third Cycle */
+ } else { /* if (FLASH_MODE == 8) */
+
+ FirstData = 0xaaaa; /* Data for the First Cycle */
+ SecondData = 0x5555; /* Data for the Second Cycle */
+ ThirdData = 0xa0a0; /* Data for the Third Cycle */
+ FirstAddr = 0xaaaa; /* Address for the First Cycle */
+ SecondAddr = 0x5555; /* Address for the Second Cycle */
+ ThirdAddr = 0xaaaa; /* Address for the Third Cycle */
+ }
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ FirstAddr * FLASH_WIDTH, FirstData);
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ SecondAddr * FLASH_WIDTH, SecondData);
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ ThirdAddr * FLASH_WIDTH, ThirdData);
+#ifdef BE
+ s = (data >> 16);
+#else
+ s = data;
+#endif
+ WRITE_SHORT(FLASH_BASE_ADDRESS + offset, s);
+ /* Writing Two Bytes */
+ if (FLASH_MODE == X16) {
+ data80 = 0x80;;
+ data20 = 0x20;;
+ } else { /* if (FLASH_MODE == 8) */
+
+ data80 = 0x8080;
+ data20 = 0x2020;
+ }
+ while (true) {
+ READ_SHORT(FLASH_BASE_ADDRESS + offset,
+ &rs);
+ if ((rs & data80) == (s & data80)) /* DQ7 =? DATA */
+ break; /* DQ7 = DATA */
+ if ((rs & data20) == data20) { /* DQ5 =? DATA */
+ READ_SHORT(FLASH_BASE_ADDRESS +
+ offset, &rs);
+ if ((rs & data80) == (s & data80))
+ break; /* DQ7 = DATA */
+ else {
+ flashReset();
+ return false; /* DQ7 != DATA */
+ }
+ }
+ }
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ FirstAddr * FLASH_WIDTH, FirstData);
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ SecondAddr * FLASH_WIDTH, SecondData);
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ ThirdAddr * FLASH_WIDTH, ThirdData);
+#ifdef BE
+ s = data;
+#else
+ s = (data >> 16);
+#endif
+ WRITE_SHORT(FLASH_BASE_ADDRESS + offset + 2, s);
+ /* Writing Two Bytes */
+ while (true) {
+ READ_SHORT(FLASH_BASE_ADDRESS + offset + 2,
+ &rs);
+ if ((rs & data80) == (s & data80)) /* DQ7 =? DATA */
+ break; /* DQ7 = DATA */
+ if ((rs & data20) == data20) { /* DQ5 =? '1' */
+ READ_SHORT(FLASH_BASE_ADDRESS +
+ offset + 2, &rs);
+ if ((rs & data80) == (s & data80))
+ break; /* DQ7 = DATA */
+ else {
+ flashReset();
+ return false; /* DQ7 != DATA */
+ }
+ }
+ }
+ return true;
+ case 4:
+ case 8:
+ if (FLASH_MODE == X16) {
+ FirstData = 0x00aa00aa;
+ SecondData = 0x00550055;
+ ThirdData = 0x00a000a0;
+ FirstAddr = 0x5555;
+ SecondAddr = 0x2aaa;
+ ThirdAddr = 0x5555;
+ } else { /* (FLASH_MODE == 8) */
+
+ FirstData = 0xaaaaaaaa; /* Data for the First Cycle */
+ SecondData = 0x55555555; /* Data for the Second Cycle */
+ ThirdData = 0xa0a0a0a0; /* Data for the Third Cycle */
+ FirstAddr = 0xaaaaaaaa; /* Address for the First Cycle */
+ SecondAddr = 0x55555555; /* Address for the Second Cycle */
+ ThirdAddr = 0xaaaaaaaa; /* Address for the Third Cycle */
+ }
+ WRITE_WORD(FLASH_BASE_ADDRESS + FirstAddr *
+ FLASH_WIDTH + offset % FLASH_WIDTH,
+ FirstData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ SecondAddr * FLASH_WIDTH +
+ offset % FLASH_WIDTH, SecondData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ ThirdAddr * FLASH_WIDTH +
+ offset % FLASH_WIDTH, ThirdData);
+ /* writting the word. */
+ WRITE_WORD(FLASH_BASE_ADDRESS + offset, data);
+ /* preparing the polling patterns. */
+ if (FLASH_MODE == X16) {
+ data80 = 0x00800080;
+ data20 = 0x00200020;
+ } else { /* (FLASH_MODE == 8) */
+
+ data80 = 0x80808080;
+ data20 = 0x20202020;
+ }
+ while (true) { /* polling loop. */
+ rw = READWORD(FLASH_BASE_ADDRESS + offset);
+ /* DQ7 =? DATA */
+ if ((rw & data80) == (data & data80))
+ break; /* DQ7 = DATA */
+ if ((rw & data20) == data20) { /* DQ5 =? '1' */
+ rw =
+ READWORD(FLASH_BASE_ADDRESS +
+ offset);
+ if ((rw & data80) ==
+ (data & data80)) break; /* DQ7 = DATA */
+ else
+ return false; /* DQ7 != DATA */
+ }
+ }
+ return true;
+ default:
+ return false; /* case of invalid flash Width. */
+ }
+ } else { /* Intel/Micron */
+
+ switch (FLASH_WIDTH) {
+ case 1:
+ /* Writing First Byte */
+ WRITE_CHAR(FLASH_BASE_ADDRESS, 0x10);
+#ifdef BE
+ c = (data >> 24);
+#else
+ c = data;
+#endif
+ WRITE_CHAR(FLASH_BASE_ADDRESS + offset, c);
+ while (true) {
+ /* Reading STATUS Register */
+ WRITE_CHAR(FLASH_BASE_ADDRESS, 0x70);
+ regValue = READCHAR(FLASH_BASE_ADDRESS);
+ if ((regValue & 0x80) == 0x80)
+ break; /* Case of Write-Operation had Ended */
+ }
+ /* Reading STATUS Register for Writing Verification */
+ WRITE_CHAR(FLASH_BASE_ADDRESS, 0x70);
+ regValue = READCHAR(FLASH_BASE_ADDRESS);
+ if ((regValue & 0x10) == 0x10)
+ return false; /* Write failure */
+
+ /* Writing Second Byte */
+ WRITE_CHAR(FLASH_BASE_ADDRESS + 1, 0x10);
+#ifdef BE
+ c = (data >> 16);
+#else
+ c = (data >> 8);
+#endif
+ WRITE_CHAR(FLASH_BASE_ADDRESS + offset + 1, c);
+ while (true) {
+ /* Reading STATUS Register */
+ WRITE_CHAR(FLASH_BASE_ADDRESS + 1, 0x70);
+ regValue =
+ READCHAR(FLASH_BASE_ADDRESS + 1);
+ if ((regValue & 0x80) == 0x80)
+ break; /* Write operation ended */
+ }
+ /* Reading STATUS Register for Writing verification */
+ WRITE_CHAR(FLASH_BASE_ADDRESS + 1, 0x70);
+ regValue = READCHAR(FLASH_BASE_ADDRESS + 1);
+ if ((regValue & 0x10) == 0x10)
+ return false; /* Write failure */
+
+ /* Writing Third Byte */
+ WRITE_CHAR(FLASH_BASE_ADDRESS + 2, 0x10);
+#ifdef BE
+ c = (data >> 8);
+#else
+ c = (data >> 16);
+#endif
+ WRITE_CHAR(FLASH_BASE_ADDRESS + offset + 2, c);
+ while (true) {
+ /* Reading STATUS Register */
+ WRITE_CHAR(FLASH_BASE_ADDRESS + 2, 0x70);
+ regValue =
+ READCHAR(FLASH_BASE_ADDRESS + 2);
+ if ((regValue & 0x80) == 0x80)
+ break; /* Write operation ended */
+ }
+ /* Reading STATUS Register for Writing Verification */
+ WRITE_CHAR(FLASH_BASE_ADDRESS + 2, 0x70);
+ regValue = READCHAR(FLASH_BASE_ADDRESS + 2);
+ if ((regValue & 0x10) == 0x10)
+ return false; /* Write failure */
+
+ /* Writing Fourth Byte */
+ WRITE_CHAR(FLASH_BASE_ADDRESS + 3, 0x10);
+#ifdef BE
+ c = data;
+#else
+ c = (data >> 24);
+#endif
+ WRITE_CHAR(FLASH_BASE_ADDRESS + offset + 3, c);
+ while (true) {
+ /* Reading STATUS Register */
+ WRITE_CHAR(FLASH_BASE_ADDRESS + 3, 0x70);
+ regValue =
+ READCHAR(FLASH_BASE_ADDRESS + 3);
+ if ((regValue & 0x80) == 0x80)
+ break; /* Write operation ended */
+ }
+ /* Reading STATUS Register for Writing Verification */
+ WRITE_CHAR(FLASH_BASE_ADDRESS + 3, 0x70);
+ regValue = READCHAR(FLASH_BASE_ADDRESS + 3);
+ if ((regValue & 0x10) == 0x10)
+ return false; /* Write failure */
+ flashReset();
+ return true;
+ case 2:
+ if (FLASH_MODE == X16) { /* Case of one X16 bit device */
+ FirstData = 0x0010; /* Data for the First Cycle */
+ } else { /* if (FLASH_MODE == 8) ==> Case of two X8 bit devices */
+
+ FirstData = 0x1010; /* Data for the First Cycle */
+ }
+ /* Writing First two Bytes */
+ WRITE_SHORT(FLASH_BASE_ADDRESS, FirstData);
+#ifdef BE
+ s = (data >> 16);
+#else
+ s = data;
+#endif
+ WRITE_SHORT(FLASH_BASE_ADDRESS + offset, s);
+ if (FLASH_MODE == X16) {
+ data70 = 0x0070;
+ data80 = 0x0080;
+ data10 = 0x0010;
+ } else { /* case of (FLASH_MODE == X8) */
+
+ data70 = 0x7070;
+ data80 = 0x8080;
+ data10 = 0x1010;
+ }
+ /* polling on writing action => when done break. */
+ while (true) {
+ WRITE_SHORT(FLASH_BASE_ADDRESS, data70);
+ regValue = READSHORT(FLASH_BASE_ADDRESS);
+ if ((regValue & data80) == data80)
+ break;
+ }
+ /* Reading STATUS Register for Writing Verification */
+ WRITE_CHAR(FLASH_BASE_ADDRESS, data70);
+ regValue = READCHAR(FLASH_BASE_ADDRESS);
+ if ((regValue & data10) == data10)
+ return false; /* Write failure */
+ /* Writing Last two Bytes */
+ WRITE_SHORT(FLASH_BASE_ADDRESS + 2, FirstData);
+#ifdef BE
+ s = data;
+#else
+ s = (data >> 16);
+#endif
+ WRITE_SHORT(FLASH_BASE_ADDRESS + offset + 2, s);
+ /* polling on writing action => when done break. */
+ while (true) {
+ WRITE_SHORT(FLASH_BASE_ADDRESS + 2,
+ data70);
+ regValue =
+ READSHORT(FLASH_BASE_ADDRESS + 2);
+ if ((regValue & data80) == data80)
+ break;
+ }
+ /* Reading STATUS Register for Writing Verification */
+ WRITE_CHAR(FLASH_BASE_ADDRESS, data70);
+ regValue = READCHAR(FLASH_BASE_ADDRESS);
+ if ((regValue & data10) == data10)
+ return false; /* Write failure */
+ flashReset();
+ return true;
+ case 4:
+ case 8:
+ if (FLASH_MODE == X16) { /* Case of one X16 bit device */
+ FirstData = 0x00100010; /* Data for the First Cycle */
+ } else { /* (FLASH_MODE == 8) ==> Case of two X8 bit devices */
+
+ FirstData = 0x10101010; /* Data for the First Cycle */
+ }
+ /* Writing First two Bytes */
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ offset % FLASH_WIDTH, FirstData);
+#ifdef BE
+ s = (data >> 16);
+#else
+ s = data;
+#endif
+ /* writing the 32-bit data to flash. */
+ WRITE_WORD(FLASH_BASE_ADDRESS + offset, data);
+ if (FLASH_MODE == X16) {
+ data70 = 0x0070;
+ data80 = 0x0080;
+ data10 = 0x0010;
+ } else { /* (FLASH_MODE == 8) */
+
+ data70 = 0x7070;
+ data80 = 0x8080;
+ data10 = 0x1010;
+ }
+ while (true) {
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ offset % FLASH_WIDTH, data70);
+ regValue = READSHORT(FLASH_BASE_ADDRESS);
+ if ((regValue & data80) == data80)
+ break;
+ }
+ /* Reading STATUS Register for Writing Verification */
+ WRITE_CHAR(FLASH_BASE_ADDRESS, data70);
+ regValue = READCHAR(FLASH_BASE_ADDRESS);
+ if ((regValue & data10) == data10)
+ return false; /* Write failure */
+
+ /* Writing Last two Bytes */
+#ifdef BE
+ s = data;
+#else
+ s = (data >> 16);
+#endif
+ while (true) {
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ offset % FLASH_WIDTH + 2,
+ data70);
+ regValue =
+ READSHORT(FLASH_BASE_ADDRESS +
+ offset % FLASH_WIDTH + 2);
+ if ((regValue & data80) == data80)
+ break;
+ }
+ /* Reading STATUS Register for Writing Verification */
+ WRITE_CHAR(FLASH_BASE_ADDRESS, data70);
+ regValue = READCHAR(FLASH_BASE_ADDRESS);
+ if ((regValue & data10) == data10)
+ return false; /* Write failure */
+
+ flashReset();
+ return true;
+ default:
+ flashReset();
+ return false;
+ }
+ }
+ flashReset();
+ return true;
+}
+
+/********************************************************************
+* flashReadWord - Read 32Bit from the FLASH memory at a given offset
+* from the FLASH base address.
+* address 0 = 0x00000000 !!
+* The function takes care of Big/Little endian conversion
+* INPUTS: offset,the offset from the flash`s base address
+* RETURNS: data
+*********************************************************************/
+unsigned int flashReadWord(unsigned int offset)
+{
+ unsigned int regValue;
+ flashReset();
+ READ_WORD(FLASH_BASE_ADDRESS + offset, ®Value);
+ return regValue;
+}
+
+/********************************************************************
+* flashInWhichSector - Returns the sector`s number at which offset is at.
+*
+* INPUTS: Offset
+* RETURNS: Sector number,or 0xffffffff in case the address is out of range or
+* flash wasn't initialize.
+*********************************************************************/
+unsigned int flashInWhichSector(unsigned int offset)
+{
+ unsigned int sectorNumber, numberOfDevices;
+ unsigned int accMemory = 0;
+
+ if ((FLASH_MODE == PURE8) || (FLASH_MODE == X8)) {
+ numberOfDevices = FLASH_WIDTH;
+ } else { /* X16 mode */
+
+ numberOfDevices = FLASH_WIDTH / 2;
+ }
+ for (sectorNumber = 0;
+ sectorNumber < flashTypes[NUMBER_OF_SECTORS]; sectorNumber++) {
+ accMemory =
+ accMemory + flashTypes[FIRST_SECTOR_SIZE +
+ sectorNumber];
+ if (offset < accMemory * numberOfDevices * 1024)
+ return sectorNumber;
+ }
+ return 0xffffffff;
+}
+
+/********************************************************************
+* flashGetSectorSize - When given a Valid sector Number returns its Size.
+*
+* INPUTS: unsigned int sectorNumber.
+* RETURNS: Sector size. (if Sector number isn't valid or flash wasn't
+* initialize return 0.)
+*********************************************************************/
+unsigned int flashGetSectorSize(unsigned int sectorNumber)
+{
+ if (sectorNumber >= flashTypes[NUMBER_OF_SECTORS])
+ return 0;
+ else {
+ if (FLASH_MODE != PURE8)
+ return (flashTypes
+ [FIRST_SECTOR_SIZE +
+ sectorNumber] * _1K * (FLASH_WIDTH * 8 /
+ FLASH_MODE));
+ else /* in case of PUR8 */
+ return (flashTypes
+ [FIRST_SECTOR_SIZE +
+ sectorNumber] * _1K * FLASH_WIDTH);
+ }
+}
+
+/********************************************************************
+* getFlashSize - Return Total flash size.
+*
+* INPUTS: N/A.
+* RETURNS: Flash size. (If flash wasn't initialize return 0)
+*********************************************************************/
+unsigned int flashGetSize()
+{
+ unsigned int sectorNum;
+ unsigned int totalSize = 0;
+
+ if (POINTER_TO_FLASH == 0)
+ return 0; /* case of flash not initialize */
+ for (sectorNum = 0; sectorNum < flashTypes[NUMBER_OF_SECTORS];
+ sectorNum++) {
+ totalSize += flashGetSectorSize(sectorNum);
+ }
+ return (totalSize);
+
+}
+
+/********************************************************************
+* flashGetSectorOffset - Returns sector base address.
+*
+* INPUTS: unsigned int sectorNum.
+* RETURNS: Sector Base Address.
+*********************************************************************/
+unsigned int flashGetSectorOffset(unsigned int sectorNum)
+{
+ unsigned int i;
+ unsigned int sectorBaseAddress = 0;
+ unsigned int numOfDevices;
+
+ if (sectorNum > (flashParametrs[NUMBER_OF_SECTORS] - 1))
+ return 0xffffffff;
+ for (i = 0; i < sectorNum; i++) {
+ sectorBaseAddress =
+ sectorBaseAddress + flashTypes[FIRST_SECTOR_SIZE + i];
+ }
+ if (FLASH_MODE == X16)
+ numOfDevices = FLASH_WIDTH * 8 / FLASH_MODE;
+ else
+ numOfDevices = FLASH_WIDTH;
+ return (_1K * sectorBaseAddress * numOfDevices);
+
+}
+
+/********************************************************************
+* flashWriteBlock - Write block of chars to flash.
+*
+* INPUTS: unsigned int offset - flash destination address.
+* unsigned int numOfByte - block size.
+* unsigned char * blockAddress - block source address.
+* RETURNS: Number of Bytes written.
+*********************************************************************/
+unsigned int flashWriteBlock(unsigned int offset, unsigned int numOfByte,
+ unsigned char *blockAddress)
+{
+ register unsigned int flashWrite;
+ register unsigned int align;
+ register unsigned int num;
+ register unsigned int i;
+
+ if ((offset + numOfByte) > flashGetSize())
+ numOfByte = flashGetSize() - offset; /* getting to flash boundary. */
+ num = numOfByte;
+ align = offset % 4; /* alignment toward flash. */
+ /* writes chars until the offset toward flash will be align. */
+ for (i = align; (i < 4) && (numOfByte > 0) && (align != 0); i++) {
+ flashWriteChar(offset, blockAddress[0]);
+ numOfByte--;
+ offset++;
+ blockAddress++;
+ }
+ while (numOfByte > 3) {
+#ifdef LE
+ flashWrite = blockAddress[0] | (blockAddress[1] << 8) |
+ (blockAddress[2] << 16) | (blockAddress[3] << 24);
+#else
+ flashWrite = blockAddress[3] | (blockAddress[2] << 8) |
+ (blockAddress[1] << 16) | (blockAddress[0] << 24);
+#endif
+ if (flashWrite != 0xffffffff) /* for optimization. */
+ flashWriteWord(offset, flashWrite);
+ numOfByte -= 4;
+ blockAddress += 4;
+ offset += 4;
+ }
+ while (numOfByte > 0) {
+ flashWriteChar(offset, blockAddress[0]);
+ numOfByte--;
+ blockAddress++;
+ offset++;
+ }
+ return num;
+}
+
+/********************************************************************
+* flashReadBlock - Read block of chars from flash.
+*
+* INPUTS: unsigned int offset - flash source address.
+* unsigned int numOfByte - block size.
+* unsigned char * blockAddress - block destination address.
+* RETURNS: Number of Bytes written.
+*********************************************************************/
+unsigned int flashReadBlock(unsigned int offset, unsigned int numOfByte,
+ unsigned char *blockAddress)
+{
+ unsigned int i;
+ for (i = 0; i < numOfByte; i++) {
+ blockAddress[i] = flashReadChar(offset + i);
+ }
+ return numOfByte;
+}
+
+/********************************************************************
+* flashReadChar - read one charecter form given flash offset.
+*
+* INPUTS: unsigned int offset - required offset to be read from.
+* RETURNS: read charecter.
+*********************************************************************/
+unsigned char flashReadChar(unsigned int offset)
+{
+ unsigned char regValue;
+
+ flashReset();
+ READ_CHAR(FLASH_BASE_ADDRESS + offset, ®Value);
+ return regValue;
+}
+
+/********************************************************************
+* flashReadShort - read 16bit form given flash offset.
+*
+* INPUTS: unsigned int offset - required offset to be read from.
+* RETURNS: 16bit data.
+*********************************************************************/
+unsigned short flashReadShort(unsigned int offset)
+{
+ unsigned short regValue;
+
+ flashReset();
+ READ_SHORT(FLASH_BASE_ADDRESS + offset, ®Value);
+ return regValue;
+}
+
+/********************************************************************
+* flashWriteShort - write 16bit data to a given flash offset.
+* It reads the whole word 32bit wide, modify the short
+* and write back the word.
+*
+* INPUTS: unsigned int offset - required offset to be write to.
+* unsigned short sdata - data to be written.
+* RETURNS: true if writting successesed false otherwise.
+*********************************************************************/
+bool flashWriteShort(unsigned int offset, unsigned short sdata)
+{
+ unsigned int align;
+ unsigned int flashWrite;
+ unsigned int flashRead;
+
+ align = offset % 4;
+ if ((align == 1) || (align == 3))
+ return false; /* offset misaligned. */
+ flashRead = flashReadWord(offset - align);
+ if (align == 0)
+#ifdef BE
+ flashWrite = (flashRead & 0x0000ffff) | (sdata << 16);
+#else
+ flashWrite = (flashRead & 0xffff0000) | sdata;
+#endif
+ else /* (align == 2) */
+#ifdef BE
+ flashWrite = (flashRead & 0xffff0000) | sdata;
+#else
+ flashWrite = (flashRead & 0x0000ffff) | (sdata << 16);
+#endif
+ flashWriteWord(offset - align, flashWrite);
+ return true;
+
+}
+
+/********************************************************************
+* flashWriteChar - write one charecter (8 bit) to a given flash offset.
+* It reads the whole word 32bit wide, modify the charecter
+* and write back the word.
+*
+* INPUTS: unsigned int offset - required offset to be write to.
+* unsigned short sdata - data to be written.
+* RETURNS: true if writting successed.
+*********************************************************************/
+bool flashWriteChar(unsigned int offset, unsigned char cdata)
+{
+ unsigned int align;
+ unsigned int flashWrite;
+ unsigned int flashRead;
+
+ align = offset % 4;
+ flashRead = flashReadWord(offset - align);
+#ifdef BE
+ flashWrite = (flashRead & ~(0xff000000 >> (8 * align))) |
+ (cdata << (8 * (3 - align)));
+#else
+ flashWrite = (flashRead & ~(0xff000000 << (8 * align))) |
+ (cdata << (8 * align));
+#endif
+ flashWriteWord(offset - align, flashWrite);
+ return true;
+}
+
+/********************************************************************
+* flashGetNumOfSectors - write one charecter (8 bit) to a given flash offset.
+* It reads the whole word 32bit wide, modify the
+* charecter and write back the word.
+*
+* INPUTS: N/A.
+* RETURNS: Number of sectors.
+*********************************************************************/
+unsigned int flashGetNumOfSectors(void)
+{
+ return (flashTypes[NUMBER_OF_SECTORS]);
+}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)