📄 lowlvl.c
字号:
* RETURNS:
* ERR_NONE
* ERR_WRITE
****************************************************************************/
WORD SRAMWrite(DWORD CardAddress, DWORD Length, BYTE_PTR Buffer)
{
FULL_WORD_PTR volatile pointer;
PositionPtr(pointer, CardAddress);
/* Just push the data out. "_f" is for a far copy */
fmemoryCopy(pointer, Buffer, Length);
return(ERR_NONE);
}
#endif
/****************************************************************************
* SRAMROMRead
*
* FUNCTION:
* Read bytes from SRAM.
*
* FORMAT:
* int SRAMROMRead(CardAddress, Length, BufferAddress)
*
* INPUTS:
* dword CardAddress - address on card to begin read
* int Length - number of bytes to read
* dword BufferAddress - address in system RAM to read into
*
* GLOBALS:
* None
*
* CALLS:
* _SlideMemoryWindow(dword CardAddress)
*
* RETURNS:
* ERR_NONE
* ERR_WRITE
****************************************************************************/
WORD SRAMROMRead(DWORD CardAddress, DWORD Length, BYTE_PTR Buffer)
{
FULL_WORD_PTR volatile pointer;
PositionPtr(pointer, CardAddress);
/* Just suck the data out. "_f" is for a far copy */
fmemoryCopy(Buffer, pointer, Length);
return(ERR_NONE);
}
/*
The CFI query command must be issued to address 55h on the
CFI component.
*/
#define Address55h 0x55
/*
CFI command set codes and other values.
*/
#define CmdSetSCS 0x0001
#define CmdSeti8Mb 0x0003
#define EraseSuspend 0x02
#define SuspendToWrite 0x01
/* 09/07/97 KES change 0x20 -> 0x10 */
#define EraseQueueFlag 0x10
#if CFI_OPTIONAL
#define ChipEraseFlag 0x01
#define ProgramSuspendFlag 0x04
#define LockUnlockFlag 0x08
#define QueuedEraseFlag 0x10
#define BlockLockStatusFlag 0x01
#define BlockValidStatusFlag 0x02
#endif
#define EraseSuspendFlag 0x02
/*
Believe it or not, it is easier to get everything in with BYTES in the
structures, then pull out the ones you want then trying to swap things
depending on what endianness the system is. These defines put out the
size they are told to, from the BYTE array passed in.
This method removes any worries about byte order on the system the program
is running on.
Also, this method allows for uniform C code for both x8 and x8x16 arrays
that otherwise would have to have two virtually identical (and very large)
code segments that did all the calculations for each. Instead, this
macro calculates both at runtime and at compiletime certain parameters
and pulls in the appropriate bytes.
Provides for more readable code, and reduces code size.
It is completely ANSI C compatible.
*/
#define BYTEOUT(bob) ((!CFIStruct) ? \
(BYTE)((sizeof(CFIx8paired->bob) == 2) ? \
CFIx8paired->bob[0] : \
CFIx8paired->bob[0]) : \
(BYTE)((sizeof(CFIx8x16paired->bob) == 2) ? \
CFIx8x16paired->bob[0] : \
CFIx8x16paired->bob[0]))
#define WORDOUT(bob) ((!CFIStruct) ? \
(WORD)((sizeof(CFIx8paired->bob) == 4) ? \
(((WORD)CFIx8paired->bob[2] << 8) | CFIx8paired->bob[0]) : \
(((WORD)CFIx8paired->bob[1] << 8) | CFIx8paired->bob[0])) : \
(WORD)((sizeof(CFIx8x16paired->bob) == 4) ? \
(((WORD)CFIx8x16paired->bob[2] << 8) | CFIx8x16paired->bob[0]) : \
(((WORD)CFIx8x16paired->bob[4] << 8) | CFIx8x16paired->bob[0])))
#define DWORDOUT(bob) ((!CFIStruct) ? \
(DWORD)((sizeof(CFIx8paired->bob) == 8) ? \
(((DWORD)CFIx8paired->bob[6] << 24) | ((DWORD)CFIx8paired->bob[4] << 16) | \
((DWORD)CFIx8paired->bob[2] << 8) | CFIx8paired->bob[0]) : \
(((DWORD)CFIx8paired->bob[3] << 24) | ((DWORD)CFIx8paired->bob[2] << 16) | \
((DWORD)CFIx8paired->bob[1] << 8) | CFIx8paired->bob[0])) : \
(DWORD)((sizeof(CFIx8x16paired->bob) == 8) ? \
(((DWORD)CFIx8x16paired->bob[6] << 24) | ((DWORD)CFIx8x16paired->bob[4] << 16) | \
((DWORD)CFIx8x16paired->bob[2] << 8) | CFIx8x16paired->bob[0]) : \
(((DWORD)CFIx8x16paired->bob[12] << 24) | ((DWORD)CFIx8x16paired->bob[8] << 16) | \
((DWORD)CFIx8x16paired->bob[4] << 8) | CFIx8x16paired->bob[0])))
/****************************************************************************
* QueryCFI Ver69
*
* FUNCTION:
* Determine if flash is CFI-compliant; parse data if so
*
* FORMAT:
* int QueryCFI(void)
*
* INPUTS:
* es:[0] -> flash mapped at address 0
* si -> FTLTable
*
* GLOBALS:
* FlashRead
* FlashWrite
* FlashErase
* FlashStatus
* FlashSuspend
* FlashResume
*
* CALLS:
* _SlideMemoryWindow(dword CardAddress)
*
* RETURNS:
* ERR_NONE (0000h)
* ERR_JEDEC (0013h)
* ERR_PARAM (0003h)
****************************************************************************/
WORD QueryCFI(MEDIA_INFO *temp_Info)
{
/*
This is the CFI query structure which the device will present
in response to the CFI query command. The second portion is
the vendor-specific region, as defined by Intel for both SCS
chips (like MLC) and standard 8Mb-compatible CFI chips. Also,
this particular version appears when the media is implemented
as paired x8-only chips or a single x16 chips. In each 16-bit
piece of data, the meaningful data will be duplicated in the
upper and lower 8 bits.
*/
typedef struct
{
BYTE Reserved[0x20]; /* offset 00h */
WORD SignatureQ; /* offset 20h */
WORD SignatureR; /* offset 22h */
WORD SignatureY; /* offset 24h */
BYTE CmdSet[4]; /* offset 26h */
BYTE CmdSetAddr[4]; /* offset 2Ah */
BYTE AltCmdSet[4]; /* offset 2Eh */
BYTE AltCmdSetAddr[4]; /* offset 32h */
BYTE MinVcc[2]; /* offset 36h */
BYTE MaxVcc[2]; /* offset 38h */
BYTE MinVpp[2]; /* offset 3Ah */
BYTE MaxVpp[2]; /* offset 3Ch */
BYTE typBytePgmTime[2]; /* offset 3Eh */
BYTE typBufferPgmTime[2]; /* offset 40h */
BYTE typBlockEraseTime[2]; /* offset 42h */
BYTE typChipEraseTime[2]; /* offset 44h */
BYTE maxBytePgmTime[2]; /* offset 46h */
BYTE maxBufferPgmTime[2]; /* offset 48h */
BYTE maxBlockEraseTime[2]; /* offset 4Ah */
BYTE maxChipEraseTime[2]; /* offset 4Ch */
BYTE DeviceSize[2]; /* offset 4Eh */
BYTE Interface[4]; /* offset 50h */
BYTE WriteSize[4]; /* offset 54h */
BYTE BlkRegions[2]; /* offset 58h */
#if !CFI_ERASE_REGIONS
BYTE BlksRegion[8]; /* offset 5Ah */
#else
BYTE BlksRegion[MAX_ERASE_REGIONS][8];
#endif
} CFIx8PAIRED_STRUCT;
typedef struct
{
BYTE Signature[6]; /* offset 00h */
BYTE Version[4]; /* offset 06h */
BYTE Features[2]; /* offset 0Ah */
BYTE Reserved[6]; /* offset 0Ch */
BYTE Suspend[2]; /* offset 12h */
BYTE Status[4]; /* offset 14h */
BYTE OptVcc[2]; /* offset 18h */
BYTE OptVpp[2]; /* offset 1Ah */
} VSx8PAIRED_STRUCT;
/*
This particular CFI/SCS structure pair represents x8/x16 chips
in a paired x8 implementation. In each 32-bit piece of data,
the meaningful information will be duplicated in each of the
four 8-bit pieces.
*/
typedef struct
{
BYTE Reserved[0x40]; /* offset 00h */
WORD SignatureQ[2]; /* offset 40h */
WORD SignatureR[2]; /* offset 44h */
WORD SignatureY[2]; /* offset 48h */
BYTE CmdSet[8]; /* offset 4Ch */
BYTE CmdSetAddr[8]; /* offset 54h */
BYTE AltCmdSet[8]; /* offset 5C*/
BYTE AltCmdSetAddr[8]; /* offset 64h */
BYTE MinVcc[4]; /* offset 6Ch */
BYTE MaxVcc[4]; /* offset 70h */
BYTE MinVpp[4]; /* offset 74h */
BYTE MaxVpp[4]; /* offset 78h */
BYTE typBytePgmTime[4]; /* offset 7Ch */
BYTE typBufferPgmTime[4]; /* offset 80h */
BYTE typBlockEraseTime[4]; /* offset 84h */
BYTE typChipEraseTime[4]; /* offset 88h */
BYTE maxBytePgmTime[4]; /* offset 8Ch */
BYTE maxBufferPgmTime[4]; /* offset 90h */
BYTE maxBlockEraseTime[4]; /* offset 94h */
BYTE maxChipEraseTime[4]; /* offset 98h */
BYTE DeviceSize[4]; /* offset 9Ch */
BYTE Interface[8]; /* offset A0h */
BYTE WriteSize[8]; /* offset A8h */
BYTE BlkRegions[4]; /* offset B0h */
#if !CFI_ERASE_REGIONS
BYTE BlksRegion[16]; /* offset 5Ah */
#else
BYTE BlksRegion[MAX_ERASE_REGIONS][16];
#endif
} CFIx8x16PAIRED_STRUCT;
typedef struct
{
BYTE Signature[12]; /* offset 00h */
BYTE Version[8]; /* offset 0Ch */
BYTE Features[4]; /* offset 14h */
BYTE Reserved[12]; /* offset 18h */
BYTE Suspend[4]; /* offset 24h */
BYTE Status[8]; /* offset 28h */
BYTE OptVcc[4]; /* offset 30h */
BYTE OptVpp[4]; /* offset 34h */
} VSx8x16PAIRED_STRUCT;
CFIx8PAIRED_STRUCT volatile FAR_PTR CFIx8paired;
VSx8PAIRED_STRUCT volatile FAR_PTR VSx8paired;
CFIx8x16PAIRED_STRUCT volatile FAR_PTR CFIx8x16paired;
VSx8x16PAIRED_STRUCT volatile FAR_PTR VSx8x16paired;
FULL_WORD_PTR volatile pointer0ed, pointer;
WORD CmdSet = 0;
WORD CommandSetAddr = 0;
BYTE CFIStruct = 0;
#if CFI_ERASE_REGIONS
BYTE CFIRegion;
#endif
HWImplement = 0;
PositionPtr(pointer0ed, temp_Info->media_size);
pointer = pointer0ed;
IncreasePtr(pointer, (Address55h * 2));
*pointer = FlashCommandQueryCFI*0x101; /* Issue QueryCFI command */
CFIx8paired = (CFIx8PAIRED_STRUCT FAR_PTR)pointer0ed; /* Set up struct pointer */
/* Set the CmdSet var */
/* In this case, the setup of the chips returns doubles of the info,
so they must be paired 8bit parts */
if ((CFIx8paired->SignatureQ == (WORD)LETTERS_QQ) &&
(CFIx8paired->SignatureR == (WORD)LETTERS_RR) &&
(CFIx8paired->SignatureY == (WORD)LETTERS_YY))
{
CmdSet = (CFIx8paired->CmdSet[3] << 8) + CFIx8paired->CmdSet[0];
HWImplement |= Implementx8+ImplementPaired;
CFIStruct = 0;
}
else
{
/* Position pointer to 154h */
IncreasePtr(pointer, (Address55h * 2));
/* In this case, the setup of the chips returns quads of the info,
so they must be paired 8/16bit parts */
*pointer = FlashCommandQueryCFI*0x101;
CFIx8x16paired = (CFIx8x16PAIRED_STRUCT FAR_PTR)pointer0ed;
if ((CFIx8x16paired->SignatureQ[0] == (WORD)LETTERS_QQ) &&
(CFIx8x16paired->SignatureR[0] == (WORD)LETTERS_RR) &&
(CFIx8x16paired->SignatureY[0] == (WORD)LETTERS_YY))
{
CmdSet = (CFIx8x16paired->CmdSet[5] << 8) + CFIx8x16paired->CmdSet[0];
HWImplement |= Implementx8x16+ImplementPaired;
CFIStruct= 1;
}
else
{
/* Set pointer to AAh, which is where we write first */
DecreasePtr(pointer, (Address55h * 2));
/* In this case a since 16bit part is doing all the work */
if ((CFIx8paired->SignatureQ == (WORD)LETTER_Q) &&
(CFIx8paired->SignatureR == (WORD)LETTER_R) &&
(CFIx8paired->SignatureY == (WORD)LETTER_Y))
{
CmdSet = (CFIx8paired->CmdSet[3] << 8) + CFIx8paired->CmdSet[0];
HWImplement |= Implementx16;
CFIStruct = 0;
}
else
{
*pointer0ed = FlashCommandClear*0x101;
*pointer0ed = FlashCommandClear*0x101;
return (ERR_JEDEC);
}
}
}
/* Here we scroll through the table trying to match the JEDEC_ID to
something in it. */
Offset=0;
while(CFITable[Offset].CommandSetID != 0xFFFF)
{
if (CFITable[Offset].CommandSetID == CmdSet)
break;
Offset++;
}
if (CFITable[Offset].CommandSetID == 0xFFFF)
{
while((*pointer0ed = FlashCommandStatus*0x101), (*pointer0ed != 0x8080))
*pointer0ed = FlashCommandClear*0x101;
return (ERR_JEDEC);
}
/* Set up pointers for functions based on table values */
#if SEGMENTED
*(WORD_PTR)&FlashRead = (WORD)(CFITable[Offset].DeviceRead);
*(WORD_PTR)&FlashWrite = (WORD)(CFITable[Offset].DeviceWrite);
*(WORD_PTR)&FlashErase = (WORD)(CFITable[Offset].DeviceErase);
#if ERASE_BACKGROUND
*(WORD_PTR)&FlashStatus = (WORD)CFITable[Offset].DeviceStatus;
*(WORD_PTR)&FlashSuspend = (WORD)CFITable[Offset].DeviceSuspend;
*(WORD_PTR)&FlashResume = (WORD)CFITable[Offset].DeviceResume;
#endif
#if CFI_OPTIONAL
*(WORD_PTR)&FlashLock = (WORD)CFITable[Offset].DeviceLock;
*(WORD_PTR)&FlashUnlock = (WORD)CFITable[Offset].DeviceUnlock;
*(WORD_PTR)&FlashChipErase = (WORD)CFITable[Offset].DeviceChipErase;
*(WORD_PTR)&FlashConfigureStatus = (WORD)CFITable[Offset].DeviceConfigureStatus;
#endif
#else
*(DWORD_PTR)&FlashRead = (DWORD)(CFITable[Offset].DeviceRead);
*(DWORD_PTR)&FlashWrite = (DWORD)(CFITable[Offset].DeviceWrite);
*(DWORD_PTR)&FlashErase = (DWORD)(CFITable[Offset].DeviceErase);
#if ERASE_BACKGROUND
*(DWORD_PTR)&FlashStatus = (DWORD)(CFITable[Offset].DeviceStatus);
*(DWORD_PTR)&FlashSuspend = (DWORD)(CFITable[Offset].DeviceSuspend);
*(DWORD_PTR)&FlashResume = (DWORD)(CFITable[Offset].DeviceResume);
#endif
#if CFI_OPTIONAL
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -