⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 atapi.c

📁 支持三星原产的S3C2413开发板
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -