From: Russ D. <ru...@us...> - 2001-07-23 05:44:29
|
Update of /cvsroot/blob/blob/src In directory usw-pr-cvs1:/tmp/cvs-serv15048/src Modified Files: Tag: blob_1_0_9_hack flash.c main.c Log Message: Initial AMD flash support (tuxscreen) Index: flash.c =================================================================== RCS file: /cvsroot/blob/blob/src/flash.c,v retrieving revision 1.1.1.1.2.5 retrieving revision 1.1.1.1.2.6 diff -u -r1.1.1.1.2.5 -r1.1.1.1.2.6 --- flash.c 2001/07/22 22:54:26 1.1.1.1.2.5 +++ flash.c 2001/07/23 05:44:26 1.1.1.1.2.6 @@ -115,6 +115,22 @@ u32 data_from_flash(u32 what); u32 data_to_flash(u32 what); +#if defined SHANNON +#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 @@ -124,9 +140,8 @@ #define STATUS_BUSY 0x00800080 #define STATUS_ERASE_ERR 0x00200020 #define STATUS_PGM_ERR 0x00100010 - - +#endif void EraseBlocks(tBlockType which) { @@ -174,6 +189,11 @@ volatile u32 *flashBase; u32 result; int maxLength, i; +#if defined SHANNON +#define READY 1 +#define ERR 2 + int chip1, chip2; +#endif if((u32)source & 0x03) { SerialOutputString("*** Source is not on a word boundary: 0x"); @@ -219,6 +239,12 @@ SerialOutputHex((u32)flashBase); SerialOutputByte('\n'); #endif + +#if defined SHANNON + *(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) { @@ -229,7 +255,36 @@ *flashBase = data_to_flash(PGM_SETUP); *flashBase = *source; +#if defined SHANNON + + /* 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); @@ -237,17 +292,21 @@ *flashBase = data_to_flash(READ_ARRAY); if((result & STATUS_PGM_ERR) != 0 || *flashBase != *source) { +#endif SerialOutputString("\n*** Write error at address 0x"); SerialOutputHex((u32)flashBase); SerialOutputByte('\n'); return; } } + +#if defined SHANNON + *(u32 *)FLASH_ADDR1 = data_to_flash(READ_ARRAY); +#endif } /* WriteBlocksFromMem */ - static u32 EraseOne(const char *whichOne) { /* Routine to erase one block of flash */ @@ -255,12 +314,46 @@ volatile u32 *writeMe = (u32 *)whichOne; u32 result; +#if defined SHANNON + int chip1, chip2; +#endif + #ifdef BLOB_DEBUG SerialOutputString(__FUNCTION__ "(): erasing block at address 0x"); SerialOutputHex((u32)whichOne); SerialOutputByte('\n'); #endif +#if defined SHANNON + *(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 + *writeMe = data_to_flash(ERASE_SETUP); *writeMe = data_to_flash(ERASE_CONFIRM); @@ -271,8 +364,8 @@ *writeMe = data_to_flash(READ_ARRAY); return result; +#endif } /* EraseOne */ - Index: main.c =================================================================== RCS file: /cvsroot/blob/blob/src/main.c,v retrieving revision 1.1.1.1.2.9 retrieving revision 1.1.1.1.2.10 diff -u -r1.1.1.1.2.9 -r1.1.1.1.2.10 --- main.c 2001/07/22 22:54:26 1.1.1.1.2.9 +++ main.c 2001/07/23 05:44:26 1.1.1.1.2.10 @@ -261,8 +261,7 @@ #elif defined PLEB theKernel(0, 20); #elif defined SHANNON -#warning "This is NOT the correct SHANNON architecture number!" - theKernel(0, 18); + theKernel(0, 97); #else /* Be generic and just tell the kernel that we are an SA1100 architecture */ |