📄 lowlvl.c
字号:
/* Repositions a pointer to a different place in memory to access card. */
/* It will slide the window to the area if the need arises, and then set */
/* the pointer to the position either in the memory window, or if there is */
/* no windowing, simply sets the pointer position */
#define PositionPtr(Ptr,Addr) \
LowSlideWindow(Addr); \
PointerAssignment(Ptr, Addr);
#define IncreasePtr(Ptr,Bytes) PointerAddition(Ptr, Bytes)
#define DecreasePtr(Ptr,Bytes) PointerSubtraction(Ptr, Bytes)
#if SWAP
/****************************************************************************
* LSWAP
*
* FUNCTION: This function swaps the bytes in a DWORD. For example, if a DWORD
* containing FFEE8877 is inputted to this function, then LSWAP will output
* 7788EEFF.
*
* INPUTS:
* x - Any DWORD
*
* GLOBALS:
* None
*
* OUTPUTS:
* See RETURNS section below
*
* CALLS:
* None
*
* FORMAT:
* DWORD LSWAP(DWORD);
*
* RETURNS:
* x - A swapped DWORD
***************************************************************************/
DWORD LSWAP(DWORD x)
{
x = ((((x) & 0x000000ff) << 24) + \
(((x) & 0x0000ff00) << 8) + \
(((x) & 0x00ff0000) >> 8) + \
(((x) & 0xff000000) >> 24));
return x;
}
/****************************************************************************
* BSWAP
*
* FUNCTION: This function swaps the bytes in a WORD. For example, if a WORD
* containing FF88 is inputted to this function, then BSWAP will output 88FF.
*
* INPUTS:
* x - A WORD
*
* GLOBALS:
* None
*
* OUTPUTS:
* See RETURNS section below
*
* CALLS:
* None
*
* FORMAT:
* WORD BSWAP(WORD);
*
* RETURNS:
* x - A swapped WORD
***************************************************************************/
WORD BSWAP(WORD x)
{
x = (((WORD)((WORD)(x) << 8)) |
((WORD)((WORD)(x) >> 8)));
return x;
}
#endif
/****************************************************************************
* _FlashDevCompatCheck
*
* FUNCTION:
* Upon card insertion, determine various card parameters (flash type,
* card size, block size, number of blocks) and return them.
*
* INPUTS:
* FTLTable ptr
*
* GLOBALS:
* FlashRead Address of flash read routine
* FlashWrite Address of flash write routine
* FlashErase Address of flash erase routine
* FlashSuspend Address of flash suspend routine Ver68
* FlashResume Address of flash resume routine Ver68
*
* FORMAT:
* int _FlashDevCompatCheck(FTLTable *)
*
* CALLS:
* _SlideMemoryWindow(dword CardAddress)
*
* RETURNS:
* If card identified successfully:
* ERR_NONE
* FTLTable ptr ->
* dword MediaSize Size of card, in bytes
* dword MediaBlockSize Size of flash block, in bytes
* int MediaBlocks Number of blocks
* byte MediaType WP, suspend capability, type
* If card not identified:
* ERR_JEDEC
****************************************************************************/
WORD FlashDevCompatCheck(MEDIA_INFO *temp_Info)
{
FULL_WORD_PTR volatile WinAddress;/* Where in memory to access memory window */
WORD Save16bits; /* Where we will save info during detection */
WORD JedecStore; /* Place to keep Jedec_Id for searching */
BYTE Method=0;
#if CFI_ERASE_REGIONS
BYTE CFIRegions;
#endif
#if SEGMENTED
FTLTablePtr = (WORD)temp_Info; /* Set the pointer that PCIC.ASM uses for info */
#endif
temp_Info->media_type = 0; /* Set this to 0 right away */
temp_Info->media_size = 0; /* We will be setting this higher and */
/* higher as we go along.. */
#if !CFI_ERASE_REGIONS
temp_Info->number_blocks = 0;
#else
temp_Info->number_regions = 0;
for (CFIRegions = 0; CFIRegions < MAX_ERASE_REGIONS; CFIRegions++)
{
temp_Info->number_blocks[CFIRegions] = 0;
temp_Info->block_size[CFIRegions] = 0;
}
#endif
PositionPtr(WinAddress, temp_Info->media_size); /* Set pointer to base memory address */
Save16bits = *WinAddress; /* Save what is currently here */
/* If CFI is there, then everything is fine, otherwise keep going with */
/* Algorithm. */
if (QueryCFI(temp_Info) == ERR_NONE)
{
temp_Info->manuf_id = 0x89;
temp_Info->device_id = 0x00;
return(ERR_NONE);
}
/* Issue Read command to clear things up */
*WinAddress = FlashCommandRead*0x101;
/* Issue word-sized old Intel ReadID command */
*WinAddress = FlashCommandReadID*0x101;
/* If SRAM, the contents will now be the ReadID value */
if (*WinAddress == (WORD)FlashCommandReadID*0x101)
{
#if SRAM_MEDIA
/* It is SRAM, so now determine card size. */
*WinAddress = Save16bits; /* Restore the SRAM location */
temp_Info->media_size = RAMSize(Save16bits); /* Call ramsize routine&set size */
temp_Info->media_type = 0x01; /* Set SRAM flag */
/* Set up functions correctly for SRAM */
FlashRead = SRAMROMRead;
FlashWrite = SRAMWrite;
FlashErase = SRAMErase;
#if ERASE_BACKGROUND
FlashSuspend = WriteProtectSusRes;
FlashResume = WriteProtectSusRes;
#endif
/* We're all done, so exit with no error! */
return(ERR_NONE);
#else
return (ERR_JEDEC);
#endif
}
/* If value did not change, then try AMD compat check */
if (*WinAddress == Save16bits)
{
/* Send Prefix1 to address AAAAh */
SlideMemoryWindow(0xAAAA);
WinAddress = (FULL_WORD_PTR)(MC_ADDR + (MC_WIND_MSK & 0xAAAA));
*WinAddress = FlashCommandPrefix1*0x101;
/* Send Prefix2 to address 5554h */
SlideMemoryWindow(0x5554);
WinAddress = (FULL_WORD_PTR)(MC_ADDR + (MC_WIND_MSK & 0x5554));
*WinAddress = FlashCommandPrefix2*0x101;
/* Send ReadID to address AAAAh */
SlideMemoryWindow(0xAAAA);
WinAddress = (FULL_WORD_PTR)(MC_ADDR + (MC_WIND_MSK & 0xAAAA));
*WinAddress = FlashCommandReadID*0x101;
SlideMemoryWindow(0);
WinAddress = (FULL_WORD_PTR)MC_ADDR;
/* If not responding, must be ROM (write-protected) */
if (*WinAddress == Save16bits)
{
temp_Info->media_type |= 0x04;
/* Set up function pointers for ROM (can't do much) */
FlashRead = SRAMROMRead;
FlashWrite = WriteProtectWrite;
FlashErase = WriteProtectErase;
#if ERASE_BACKGROUND
FlashSuspend = WriteProtectSusRes;
FlashResume = WriteProtectSusRes;
#endif
/* We're all done, so exit with no error! */
return(ERR_NONE);
}
Method = 1; /* If 1, means to use this, if 0 (default), use ReadID */
}
/* Get the JEDEC ID and store it */
temp_Info->manuf_id = *WinAddress;
temp_Info->device_id = *(WinAddress+1);
JedecStore = (temp_Info->manuf_id << 8) | temp_Info->device_id;
/* Here we scroll through the table trying to match the JEDEC_ID to
something in it. */
Offset=0;
while(FlashTechnologyTable[Offset].Device_JEDEC != 0xFFFF)
{
if (FlashTechnologyTable[Offset].Device_JEDEC == JedecStore)
break;
Offset++;
}
if (FlashTechnologyTable[Offset].Device_JEDEC == 0xFFFF)
return (ERR_JEDEC);
/* If we have gotten this far we have identified the device in the */
/* TechnologyTable, and can load the Media_Info passed in with info */
/* Load block size */
#if !CFI_ERASE_REGIONS
temp_Info->block_size = FlashTechnologyTable[Offset].DeviceBlockSize;
#else
temp_Info->number_regions = 1;
temp_Info->block_size[0] = FlashTechnologyTable[Offset].DeviceBlockSize;
#endif
/* Set suspend capability */
temp_Info->media_type |= 0x02; /* Turn off suspend */
if (FlashTechnologyTable[Offset].DeviceCapabilities & 0x3)
temp_Info->media_type &= 0xFD;
/* Set up pointers for functions based on table values */
#if SEGMENTED
*(WORD_PTR)&FlashRead = (WORD)(FlashTechnologyTable[Offset].DeviceRead);
*(WORD_PTR)&FlashWrite = (WORD)(FlashTechnologyTable[Offset].DeviceWrite);
*(WORD_PTR)&FlashErase = (WORD)(FlashTechnologyTable[Offset].DeviceErase);
#if ERASE_BACKGROUND
*(WORD_PTR)&FlashStatus = (WORD)FlashTechnologyTable[Offset].DeviceStatus;
*(WORD_PTR)&FlashSuspend = (WORD)FlashTechnologyTable[Offset].DeviceSuspend;
*(WORD_PTR)&FlashResume = (WORD)FlashTechnologyTable[Offset].DeviceResume;
#endif
#else
*(DWORD_PTR)&FlashRead = (DWORD)(FlashTechnologyTable[Offset].DeviceRead);
*(DWORD_PTR)&FlashWrite = (DWORD)(FlashTechnologyTable[Offset].DeviceWrite);
*(DWORD_PTR)&FlashErase = (DWORD)(FlashTechnologyTable[Offset].DeviceErase);
#if ERASE_BACKGROUND
*(DWORD_PTR)&FlashStatus = (DWORD)FlashTechnologyTable[Offset].DeviceStatus;
*(DWORD_PTR)&FlashSuspend = (DWORD)FlashTechnologyTable[Offset].DeviceSuspend;
*(DWORD_PTR)&FlashResume = (DWORD)FlashTechnologyTable[Offset].DeviceResume;
#endif
#endif
while(1)
{
/* One device has come and gone, so add it's sizes on. */
temp_Info->media_size += FlashTechnologyTable[Offset].DeviceSize;
#if !CFI_ERASE_REGIONS
temp_Info->number_blocks += FlashTechnologyTable[Offset].DeviceBlocks;
#else
temp_Info->number_blocks[0] += FlashTechnologyTable[Offset].DeviceBlocks;
#endif
/* Set window to next device */
PositionPtr(WinAddress, temp_Info->media_size);
/* If device is in ReadID mode, then this is the first one again */
if (((*WinAddress & 0xFF00) + (*(WinAddress+1) & 0x00FF)) == JedecStore)
{
*WinAddress = FlashCommandRead*0x101;
return (ERR_NONE);
}
if (Method) /* If need to use AMD method */
{
/* Send Prefix1 to address AAAAh */
SlideMemoryWindow(temp_Info->media_size + 0xAAAA);
WinAddress = (FULL_WORD_PTR)(MC_ADDR + (MC_WIND_MSK & 0xAAAA));
*WinAddress = FlashCommandPrefix1*0x101;
/* Send Prefix2 to address 5554h */
SlideMemoryWindow(temp_Info->media_size + 0x5554);
WinAddress = (FULL_WORD_PTR)(MC_ADDR + (MC_WIND_MSK & 0x5554));
*WinAddress = FlashCommandPrefix2*0x101;
/* Send ReadID to address AAAAh */
SlideMemoryWindow(temp_Info->media_size + 0xAAAA);
WinAddress = (FULL_WORD_PTR)MC_ADDR + (MC_WIND_MSK & 0xAAAA);
*WinAddress = FlashCommandReadID*0x101;
}
else /* Else use Intelligent Identifier method */
{
*WinAddress = FlashCommandReadID*0x101;
}
/* If there is no Jedec here, then the card does not map around to 0 */
/* When accessed over card size, therefore we are at the end. */
if (((*WinAddress & 0xFF00) + (*(WinAddress+1) & 0x00FF)) != JedecStore)
{
return (ERR_NONE);
}
/* Otherwise, set device back to read mode and continue */
*WinAddress = FlashCommandRead*0x101;
return(ERR_NONE);
}
}
#if SRAM_MEDIA
/****************************************************************************
* RAMSize
*
* FUNCTION:
* Determine the size of a RAM card. Load it into temp_Info->MediaSize
*
* INPUTS:
* Original Word at address 0;
*
* FORMAT:
* RAMSize(WORD)
*
* CALLS:
* _SlideMemoryWindow(dword CardAddress)
*
* RETURNS:
* dword Size Size of card, in bytes
****************************************************************************/
DWORD RAMSize(WORD OriginalWord)
{
FULL_WORD_PTR volatile pointer;
WORD SaveWord, SaveTest;
/* Start up at 64k */
DWORD Size=0;
while (1)
{
/* Move upward by 10000h increments, checking each time */
Size += 0x10000;
PositionPtr(pointer, Size);
/* Get a word from this position, and XOR it */
SaveWord = (*pointer ^= 0xFFFF);
/* Write, then check to see if it changed. If not, we are done. */
*pointer = SaveWord;
if (*pointer == SaveWord) return (Size);
SaveWord ^= 0xFFFF; /* Return SaveWord to original state */
/* If this word == word at address 0, possibility exists we wrapped */
if (SaveWord == OriginalWord)
{
PositionPtr(pointer, 0);
SaveTest = *pointer;
PositionPtr(pointer, Size);
*pointer = OriginalWord;
OriginalWord ^= 0xFFFF;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -