📄 atapi.c
字号:
#include "atapi.h"
#include "defines.h"
#include <windows.h>
#include "atadisk.h"
#include "system.h"
extern PDEVICE_CONTROLLER g_pcPC;
extern PDRIVE_DESC g_pdPD;
volatile S3C2413_ATAPI_REG *g_vATAPIRegs;
volatile S3C2413_EBI_REG *g_vEBIRegs;
UINT8 *g_vDmaBuffer;
UINT32 g_uCfgReg;
ATA_DEV_INFO g_oDevice[2];
ATA_MODE g_eMode;
int AtapiRegisterInit(void) /*__fn__*/
{
int RetValue=TRUE;
//RETAILMSG(RTL_MSG, (TEXT("+++ ATAPI_CF : Before Entering OpenMedia()\r\n")));
g_vATAPIRegs= (volatile S3C2413_ATAPI_REG *)VirtualAlloc(0, sizeof(S3C2413_ATAPI_REG), MEM_RESERVE, PAGE_NOACCESS);
if (g_vATAPIRegs == NULL)
{
RETAILMSG(1,(TEXT("For g_vATAPIRegs : VirtualAlloc failed! error code %d\r\n"),GetLastError()));
RetValue = FALSE;
}
else
{
if (!VirtualCopy((PVOID)g_vATAPIRegs, (PVOID)(S3C2413_BASE_REG_PA_ATAPI>> 8),
sizeof(S3C2413_ATAPI_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE))
{
RETAILMSG(1,(TEXT("For INTRregs: VirtualCopy failed!\r\n")));
RetValue = FALSE;
}
}
g_vDmaBuffer = (UINT8 *)VirtualAlloc(0, PIODMA_BUFFER_SIZE, MEM_RESERVE, PAGE_NOACCESS);
if (g_vDmaBuffer == NULL)
{
RETAILMSG(RTL_MSG,(TEXT("For g_vDmaBuffer : VirtualAlloc failed! error code %d\r\n"),GetLastError()));
RetValue = FALSE;
}
else
{
if (!VirtualCopy((PVOID)g_vDmaBuffer, (PVOID)(PIODMA_BUFFER_PA>> 8),
PIODMA_BUFFER_SIZE, PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE))
{
RETAILMSG(RTL_MSG,(TEXT("For g_vDmaBuffer: VirtualCopy failed!\r\n")));
RetValue = FALSE;
}
}
g_vEBIRegs = (volatile S3C2413_EBI_REG *)VirtualAlloc(0, sizeof(S3C2413_EBI_REG), MEM_RESERVE, PAGE_NOACCESS);
if (g_vEBIRegs == NULL)
{
RETAILMSG(1,(TEXT("For g_vATAPIRegs : VirtualAlloc failed error code %d\r\n"),GetLastError()));
return FALSE;
}
else
{
if (!VirtualCopy((PVOID)g_vEBIRegs, (PVOID)(S3C2413_BASE_REG_PA_EBI>> 8),
sizeof(S3C2413_EBI_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE))
{
RETAILMSG(1,(TEXT("For INTRregs: VirtualCopy failed!\r\n")));
return FALSE;
}
}
//RETAILMSG(RTL_MSG,(TEXT("### 1.EBI_BANK_CFG : 0x%x\r\n"),g_vEBIRegs->BANK_CFG));
g_vEBIRegs->BANK_CFG |= (0x3<<4);
//RETAILMSG(RTL_MSG,(TEXT("### 2.EBI_BANK_CFG : 0x%x\r\n"),g_vEBIRegs->BANK_CFG));
return RetValue;
}
int AtapiDeviceInit(void)
{
int i;
//RETAILMSG(RTL_MSG, (TEXT("+++ ATAPI_CF : Check point 1 ()\r\n")));
g_pcPC->mode = FALSE;
// g_pcPC->controller_number = -1;
// g_pcPC->interrupt_number = -1;
// g_pcPC->opencount = FALSE;
//RETAILMSG(RTL_MSG, (TEXT("+++ ATAPI_CF : Check point 2 ()\r\n")));
g_pcPC->register_file_address = 0x0;
/* Get the drive structure infomation */
//RETAILMSG(RTL_MSG, (TEXT("+++ ATAPI_CF : Check point 3 ()\r\n")));
g_pcPC->drive = g_pdPD;
//RETAILMSG(RTL_MSG, (TEXT("+++ ATAPI_CF : Check point 4 ()\r\n")));
g_pcPC->drive->features = FALSE;
//RETAILMSG(RTL_MSG, (TEXT("+++ ATAPI_CF : Check point 5 ()\r\n")));
g_pcPC->drive->total_lba = 0L;
//RETAILMSG(RTL_MSG, (TEXT("+++ ATAPI_CF : Before Entering AtapiregisterInit()\r\n")));
if ( !AtapiRegisterInit() )
return FALSE;
if (!(OpenMedia(PIO_DMA)))
return FALSE;
return TRUE;
}
int GetDataFromDevice(UINT16 *data)
{
UINT32 tempRead;
if (!(WaitForDeviceAccessReady()))
return FALSE;
//Inp32(ATA_PIO_DTR, tempRead);
tempRead = g_vATAPIRegs->ATA_PIO_DTR;
if (!(WaitForDeviceAccessReady()))
return FALSE;
//Inp32(ATA_PIO_RDATA, tempRead);
tempRead = g_vATAPIRegs->ATA_PIO_RDATA;
*data = (UINT16)(tempRead&0xFFFF);
return TRUE;
}
void GetByteDataFromDevice(UINT8 *data)
{
UINT32 tempRead;
WaitForDeviceAccessReady();
//Inp32(ATA_PIO_DTR, tempRead);
tempRead = g_vATAPIRegs->ATA_PIO_DTR;
WaitForDeviceAccessReady();
//Inp32(ATA_PIO_RDATA, tempRead);
tempRead = g_vATAPIRegs->ATA_PIO_RDATA;
*data = (UINT8)(tempRead&0xFF);
*(data+1)=(UINT8)((tempRead>>8)&0xFF);
}
int ReadDeviceReg(volatile UINT32 *nRegister, UINT8 *data)
{
UINT32 tempRead;
if (!(WaitForDeviceAccessReady()))
return FALSE;
//Inp32(nRegister, tempRead);
tempRead = *nRegister;
if (!(WaitForDeviceAccessReady()))
return FALSE;
//Inp32(ATA_PIO_RDATA, tempRead);
tempRead = g_vATAPIRegs->ATA_PIO_RDATA;
*data = (UINT8)(tempRead&0xFF);
return TRUE;
}
int WaitForNoBusyStatus(void)
{
UINT8 tempRead;
UINT32 count=1;
UINT16 retVal=TRUE;
//RETAILMSG(RTL_MSG,(TEXT("+++ 1.Atapi status reg 0x%x\r\n"),g_vATAPIRegs->ATA_PIO_RDATA));
while(1)
{
count++;
if (!(ReadDeviceReg(DEV_ALTANATE, &tempRead)))
return FALSE;
if (!(ReadDeviceReg(DEV_STATUS, &tempRead)))
return FALSE;
//if (count%1000000 == 0 )
//RETAILMSG(RTL_MSG,(TEXT("+++ 2.Atapi status reg 0x%x\r\n"),g_vATAPIRegs->ATA_PIO_RDATA));
if((tempRead&STATUS_DEVICE_BUSY_1) == 0)
break;
if(count == 10000000 )
{
//RETAILMSG(RTL_MSG,(TEXT("+++ WaitForNoBusyStatus\r\n")));
retVal = FALSE;
break;
}
}
return retVal;
}
int WaitForDeviceAccessReady(void)
{
UINT32 tempRead;
UINT8 retVal=TRUE;
UINT32 count=1;
do {
//Inp32(ATA_FIFO_STATUS, tempRead); // modified by Bryan W. Lee (Oct.19th, 2005)
if ( count == 10000000)
{
retVal=FALSE;
//RETAILMSG(RTL_MSG, (TEXT("+++ ATAPI_CF : WaitForDeviceAccessReady error..\r\n")));
break;
}
count++;
tempRead = g_vATAPIRegs->ATA_FIFO_STATUS;
} while((tempRead>>28)!=0);
return retVal;
}
int WriteOnTaskFileReg(volatile UINT32 *nRegister,UINT32 nValue)
{
if (!(WaitForDeviceAccessReady()))
return FALSE;
*nRegister = nValue; // write register
return TRUE;
}
int IdentifyDevice(void)
{
UINT16 readBuffer[256]={0,};
UINT8 tempBuffer;
UINT8 *tempString;
UINT32 tBuf[4];
short i;
g_uCfgReg |= (0x40);
g_vATAPIRegs->ATA_CFG = g_uCfgReg; // set Big endian (must be)
g_vATAPIRegs->ATA_IRQ_MASK = 0xffffffff;
//RETAILMSG(RTL_MSG, (TEXT("+++ ATAPI_CF : IdentifyDevice() check point 1.\r\n")));
if (!(WriteOnTaskFileReg(DEV_DEVICE, 0x40)))
return FALSE;
//RETAILMSG(RTL_MSG, (TEXT("+++ ATAPI_CF : IdentifyDevice() check point 2.\r\n")));
if (!(WriteOnTaskFileReg(DEV_STATUS, IDENTIFYDEVICE)))
return FALSE;
//RETAILMSG(RTL_MSG, (TEXT("+++ ATAPI_CF : IdentifyDevice() check point 3.\r\n")));
if (!(WaitForNoBusyStatus()))
return FALSE;
//RETAILMSG(RTL_MSG, (TEXT("+++ ATAPI_CF : IdentifyDevice() check point 4.\r\n")));
for(i=0; i<ATA_SECTORSIZE/2; i++) {
GetDataFromDevice(&readBuffer[i]);
// DbgAta(("DATA : 0x%04X\n",readBuffer[i]));
}
//RETAILMSG(RTL_MSG, (TEXT("+++ ATAPI_CF : IdentifyDevice() check point 5.\r\n")));
if (!(WaitForNoBusyStatus()))
return FALSE;
//
//verify identify data~~~~~~~~~~~~~~~~~~~~~~~~~~
//
tempString = (UINT8 *)&readBuffer[10];
// for(i=0;i<20;i++) DbgAta(("%c",*(tempString+i)));
// tempString = (UINT8 *)&readBuffer[27];
//RETAILMSG(RTL_MSG,(TEXT("\r\nModel Number :")));
for(i=0;i<10;i++) //RETAILMSG(RTL_MSG,(TEXT("%c"),*((UINT8 *)tempString+i)));
for(i=0;i<10;i++)
//RETAILMSG(RTL_MSG,(TEXT("%c"),*((UINT8 *)tempString+i)));
for(i=0;i<4;i++) //RETAILMSG(RTL_MSG,(TEXT("%c"),*((UINT8 *)tempString+26+i)));
for(i=0;i<20;i++) //RETAILMSG(RTL_MSG,(TEXT("%c"),*((UINT8 *)tempString+34+i)));
tBuf[0] = (UINT8)(readBuffer[61]&0xff);
tBuf[1] = (UINT8)((readBuffer[61]&0xff00)>>8);
tBuf[2] = (UINT8)(readBuffer[60]&0xff);
tBuf[3] = (UINT8)((readBuffer[60]&0xff00)>>8);
g_oDevice[0].MaxSectors = (UINT32)((tBuf[0]<<24)|(tBuf[1]<<16)|(tBuf[2]<<8)|tBuf[3]);
g_pcPC->drive->total_lba = g_oDevice[0].MaxSectors;
//RETAILMSG(RTL_MSG,(TEXT("\nMax Sectors : %d\n"),g_oDevice[0].MaxSectors));
g_pcPC->drive->num_cylinders = readBuffer[54];
//RETAILMSG(RTL_MSG,(TEXT("cylinders : %d\n"),g_pcPC->drive->num_cylinders));
g_pcPC->drive->num_heads = readBuffer[55];
//RETAILMSG(RTL_MSG,(TEXT("head : %d\n"),g_pcPC->drive->num_heads));
g_pcPC->drive->sec_p_track = readBuffer[56];
//RETAILMSG(RTL_MSG,(TEXT("sec_p_track : %d\n"),g_pcPC->drive->sec_p_track));
// Caution: readBuffer[x] - Big Endian, so upper byte means LSB..
g_oDevice[0].MaxMultiple= (readBuffer[47]>>8)&0xFF;
//RETAILMSG(RTL_MSG,(TEXT("\nMax Multiple : %02X\n"),g_oDevice[0].MaxMultiple));
if (readBuffer[59]&0x1) { //multiple sector setting is valid
g_oDevice[0].CurrentMultiple= (readBuffer[59]>>8)&0xFF;
//DbgAta(("Current Multiple : %03X\n",g_oDevice[0].CurrentMultiple));
}
if (((readBuffer[64]>>8)&0x3) == 1) g_oDevice[0].MaxPioMode = PIO3;
else if (((readBuffer[64]>>8)&0x3) == 3) g_oDevice[0].MaxPioMode = PIO4;
else g_oDevice[0].MaxPioMode = PIO2;
RETAILMSG(1,(TEXT("Max PIO Mode : %d\n"),g_oDevice[0].MaxPioMode));
g_oDevice[0].MaxUdmaMode =0;
tempBuffer = readBuffer[88]>>8;
for(i=4;i>=0;i--) {
if(tempBuffer&(0x01<<i)) {
g_oDevice[0].MaxUdmaMode = i;
break;
}
}
//RETAILMSG(RTL_MSG,(TEXT("+++ Last Check 1.%d\n"),g_oDevice[0].MaxPioMode));
g_oDevice[0].CurrentUdmaMode =0;
tempBuffer = readBuffer[88]&0x00ff;
for(i=0;i<5;i++) {
if(tempBuffer&(0x01<<i)) {
g_oDevice[0].CurrentUdmaMode = i;
break; ///
}
}
//RETAILMSG(RTL_MSG,(TEXT("+++ Last Check 2.%d\n"),g_oDevice[0].MaxPioMode));
// DbgAta(("Max UDMA Mode : %d\n",g_oDevice[0].MaxUdmaMode));
// DbgAta(("Current UDMA Mode : %d\n",g_oDevice[0].CurrentUdmaMode));
//
//verify identify data~~~~~~~~~~~~~~~~~~~~~~~END
//
g_uCfgReg &= (~0x40); // set Little endian
g_vATAPIRegs->ATA_CFG = g_uCfgReg;
//Outp32(ATA_CFG, g_uCfgReg);
return TRUE;
}
void SetLittleEndian(void)
{
// set Little endian
g_uCfgReg &= (~0x40);
g_vATAPIRegs->ATA_CFG = g_uCfgReg;
}
void SetAtaOnOff(UINT8 OnOff)
{
UINT32 temp;
//Inp32(ATA_CONTROL, temp);
temp = g_vATAPIRegs->ATA_CONTROL;
if(OnOff==1)
//Outp32(ATA_CONTROL, temp | 0x1);
g_vATAPIRegs->ATA_CONTROL = temp | 0x1;
else if(OnOff == 0)
//Outp32(ATA_CONTROL, temp &0xfffffffe);
g_vATAPIRegs->ATA_CONTROL = temp & 0xfffffffe;
}
void Init(void)
{
SetAtaOnOff(1);
g_uCfgReg = 0;
SetLittleEndian();
//CheckDevice();
}
void Init12(PIOMODE pmode, UINT32 multisize, UDMAMODE umode)
{
SetAtaOnOff(1);
g_uCfgReg = 0;
g_uCfgReg &= (~0x40); // set Little endian
//Outp32(ATA_CFG, m_uCfgReg);
g_vATAPIRegs->ATA_CFG = g_uCfgReg;
SetPioMode(pmode);
SetMultiple(multisize);
//SetUdmaMode(umode);
CheckDevice();
}
int OpenMedia(ATA_MODE mode)
{
Init();
if (!(IdentifyDevice()))
return FALSE;
SetAtaMode(mode);
if (mode == PIO_CPU || mode == PIO_DMA)
{
//RETAILMSG(RTL_MSG, (TEXT("### ATAPI MAXPIOMODE %d\r\n"),g_oDevice[0].MaxPioMode));
if (!(SetPioMode(g_oDevice[0].MaxPioMode)))
return FALSE;
}
else
{
UDMAMODE udmaMode =
(g_oDevice[0].MaxPioMode == 0) ? UDMA0 :
(g_oDevice[0].MaxPioMode == 1) ? UDMA1 :
(g_oDevice[0].MaxPioMode == 2) ? UDMA2 :
(g_oDevice[0].MaxPioMode == 3) ? UDMA3 : UDMA4;
SetPioMode(PIO0);
//SetUdmaMode(udmaMode);
}
return TRUE;
}
int SetAtaDevice(UINT32 uLBA, UINT32 uSectorCount)
{
if (!(WriteOnTaskFileReg(DEV_SECTOR,uSectorCount&0xFF)))
return FALSE;
if (!(WriteOnTaskFileReg(DEV_LOWLBA,uLBA&0xFF)))
return FALSE;
if (!(WriteOnTaskFileReg(DEV_MIDLBA,(uLBA>>8)&0xFF)))
return FALSE;
if (!(WriteOnTaskFileReg(DEV_HIGHLBA,(uLBA>>16)&0xFF)))
return FALSE;
if (!(WriteOnTaskFileReg(DEV_DEVICE,((uLBA>>24)&0xF)|0x40)))
return FALSE;
return TRUE;
}
int AtaDiskRead(DWORD dStartSec, BYTE *pTargetBuf, UINT16 usNumSec)
{
#if 1
UINT32 resCount;
UINT32 remainCount;
UINT32 goingLBA;
UINT32 goingDstAddr;
UINT32 wCount;
UINT8* uAtaHostAddr;
UINT32 i;
remainCount = usNumSec;
goingLBA = dStartSec;
wCount = 0;
SetLittleEndian();
while(remainCount != 0)
{
if(remainCount>256)
{
resCount = 256; //0 means 256
remainCount -= 256;
}
else
{
resCount = remainCount;
remainCount = 0;
}
goingLBA = dStartSec + wCount*256;
uAtaHostAddr = pTargetBuf + wCount*256*ATA_SECTORSIZE;
SetAtaDevice(goingLBA, resCount);
WriteOnTaskFileReg(DEV_COMMAND, READSECTOR);
while(resCount-- ) {
if (!(WaitForNoBusyStatus()))
return FALSE;
for (i=0;i<ATA_SECTORSIZE/2;i++) {
GetByteDataFromDevice(uAtaHostAddr);
uAtaHostAddr+=2;
}
}
if (!(WaitForNoBusyStatus()))
return FALSE;
wCount++;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -