|
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 */
|