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

📄 atapi.c

📁 三星公司 2440 开发板 wince 5.0 BSP
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
Low-level Driver file for CF HDD

Modified by jungpil.choi 2006.2.10
For 2440A CF HDD board(Reference Team made)   


--*/



#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 S3C2440_ATAPI_REG *g_vATAPIRegs;
volatile S3C2440A_IOPORT_REG *m_vpIOPRegs;
volatile S3C2440A_MEMCTRL_REG *m_vpMEMRegs;


#define CF_CPLD_Tacs	(0x3)	// 4clk
#define CF_CPLD_Tcos	(0x3)	// 4clk
#define CF_CPLD_Tacc	(0x7)	// 14clk
#define CF_CPLD_Tcoh	(0x3)	// 4clk
#define CF_CPLD_Tah		(0x3)	// 4clk
#define CF_CPLD_Tacp	(0x0)	// 0clk
#define CF_CPLD_PMC		(0x0)	// normal(1data)

#define CF_CPLD_ATT_BASE_ADDRESS     (0xAA020000)	//(0x00020000) nGCS5
#define CF_CPLD_MEM_BASE_ADDRESS     (0xAA060000)	//(0x00060000)
#define CF_CPLD_IO_BASE_ADDRESS      (0xAA010000)	//(0x00050000)

#define ALTSTAT

UINT8 *g_vDmaBuffer;

UINT32 g_uCfgReg;
ATA_DEV_INFO g_oDevice[2];
ATA_MODE g_eMode;

//#define CFHDDTEST

#ifdef CFHDDTEST
#define Sleep(a)  {int i; for(i=0; i < a*10;i++) RETAILMSG(RTL_MSG, (TEXT(".")));	}
#endif

#define DRQ_TIMEOUT 0
#define DRQ_ERROR -1
#define DRQ_OK 1

#define MAX_DELAY_BUSY_TO_DRQ 1000000



int AtapiRegisterInit(void) /*__fn__*/
{

	int RetValue=TRUE;
//	RETAILMSG(RTL_MSG, (TEXT("+++ ATAPI_CF : Before Entering OpenMedia()\r\n")));	


     // control register shuld be modified to 2440
#ifndef CFHDDTEST
	m_vpIOPRegs = (S3C2440A_IOPORT_REG*)VirtualAlloc(0, sizeof(S3C2440A_IOPORT_REG), MEM_RESERVE, PAGE_NOACCESS);
	if (m_vpIOPRegs == NULL) 
	{
		DEBUGMSG (1,(TEXT("+++ ATAPI_CF : m_vpIOPRegs is not allocated\n\r")));
		RetValue = FALSE;
	}
	if (!VirtualCopy((PVOID)m_vpIOPRegs, (PVOID)(S3C2440A_BASE_REG_PA_IOPORT >> 8), sizeof(S3C2440A_IOPORT_REG), PAGE_PHYSICAL|PAGE_READWRITE|PAGE_NOCACHE)) {
		DEBUGMSG (1,(TEXT("+++ ATAPI_CF : m_vpIOPRegs is not mapped\n\r")));
		RetValue = FALSE;
	}
	DEBUGMSG (1,(TEXT("+++ ATAPI_CF : m_vpIOPRegs is mapped to %x\n\r"), m_vpIOPRegs));
	
	m_vpMEMRegs = (S3C2440A_MEMCTRL_REG*)VirtualAlloc(0,sizeof(S3C2440A_MEMCTRL_REG), MEM_RESERVE,PAGE_NOACCESS);
	if(m_vpMEMRegs == NULL) 
	{
		DEBUGMSG (1,(TEXT("+++ ATAPI_CF : m_vpMEMRegs is not allocated\n\r")));
		RetValue = FALSE;
	}
	if(!VirtualCopy((PVOID)m_vpMEMRegs,(PVOID)(S3C2440A_BASE_REG_PA_MEMCTRL >> 8),sizeof(S3C2440A_MEMCTRL_REG), PAGE_PHYSICAL|PAGE_READWRITE|PAGE_NOCACHE)) {

		DEBUGMSG (1,(TEXT("+++ ATAPI_CF : m_vpMEMRegs is not mapped\n\r")));
		RetValue = FALSE;
	}    
	DEBUGMSG (1,(TEXT("+++ ATAPI_CF : m_vpMEMRegs is mapped to %x\n\r"), m_vpMEMRegs));

	g_vATAPIRegs= (volatile S3C2440_ATAPI_REG *)VirtualAlloc(0, sizeof(S3C2440_ATAPI_REG), MEM_RESERVE, PAGE_NOACCESS);
	if (g_vATAPIRegs == NULL) 
	{
		ERRORMSG(1,(TEXT("+++ ATAPI_CF : For g_vATAPIRegs : VirtualAlloc failed!\r\n")));
		RetValue = FALSE;
	}
	else 
	{
		if (!VirtualCopy((PVOID)g_vATAPIRegs, (PVOID)(S3C2440A_BASE_REG_PA_ATAPI >>8),
			sizeof(S3C2440_ATAPI_REG), PAGE_READWRITE | PAGE_NOCACHE | PAGE_PHYSICAL)) 
		{
			DEBUGMSG(1,(TEXT("+++ ATAPI_CF : For INTRregs: VirtualCopy failed!\r\n")));
			RetValue = FALSE;
		}
	}
#else
    m_vpIOPRegs = (S3C2440A_IOPORT_REG*)OALPAtoVA(S3C2440A_BASE_REG_PA_IOPORT);
    m_vpMEMRegs = (S3C2440A_MEMCTRL_REG*)OALPAtoVA(S3C2440A_BASE_REG_PA_MEMCTRL);
    g_vATAPIRegs= (volatile S3C2440_ATAPI_REG *)OALPAtoVA(S3C2440A_BASE_REG_PA_ATAPI);
#endif


//	RETAILMSG(1,(TEXT("+++ ATAPI_CF : Turn On CF HDD!!!\r\n")));
//	Sleep(3000);

    //resetting should be moved somewhrer
	m_vpIOPRegs->GPGCON = (m_vpIOPRegs->GPGCON & ~(0x3<<22)) | (0x2<<22); 
	m_vpIOPRegs->GPGDAT &= ~(1<<11);
	Sleep(1000);
    m_vpIOPRegs->GPGDAT |= (1<<11);
	Sleep(1000);
	m_vpIOPRegs->GPGDAT &= ~(1<<11);
	Sleep(1000);


//	RETAILMSG(1,(TEXT("+++ ATAPI_CF : Resetting CF HDD!!!\r\n")));
	// nGCS5=nWAIT,16-bit
	m_vpMEMRegs->BWSCON = (m_vpMEMRegs->BWSCON & ~(0xf<<20)) |(0<<23)|(1<<22)|(1<<20);

	// BANK5 access timing
	m_vpMEMRegs->BANKCON5 = 0xffff;


	return RetValue;
}

int AtapiDeviceInit(void)
{

    g_pcPC->mode = FALSE;
    g_pcPC->register_file_address = 0x0;
    g_pcPC->drive = g_pdPD;
    g_pcPC->drive->features = FALSE;
    g_pcPC->drive->total_lba = 0L;
	if ( !AtapiRegisterInit() )
		return FALSE;

	if (!(OpenMedia(PIO_CPU)))
		return FALSE;
	return TRUE;
}

int GetDataFromDevice(UINT16 *data) 
{
	UINT16 tempRead;

	if (!(WaitForDeviceAccessReady()))
		return FALSE;
	tempRead = g_vATAPIRegs->ATA_PIO_DAT;
	*data = tempRead;
	return TRUE;
}

void GetByteDataFromDevice(UINT8 *data) 
{
	UINT16 tempRead;

	WaitForDeviceAccessReady();
	tempRead = g_vATAPIRegs->ATA_PIO_DAT;
	*data = (UINT8)(tempRead&0xFF);
	*(data+1)=(UINT8)((tempRead>>8)&0xFF);
}



int ReadDeviceReg(volatile UINT8 *nRegister, UINT8 *data) 
{
	UINT16 tempRead;
	if (!(WaitForNoBusyStatus()))
		return FALSE;
	tempRead = *nRegister;
	*data = (UINT8)(tempRead&0xFF);
	return TRUE;
	}

int WaitForNoBusyStatus(void)
{
	UINT8 tempRead;
	UINT8  retVal=TRUE;
	UINT32 count=1;

	do {
		if ( count == 100000000)			
		{
			retVal=FALSE;
			RETAILMSG(RTL_MSG, (TEXT("+++ ATAPI_CF : WaitForDeviceAccessReady error..\r\n")));	
			break;
		}
		count++;
        tempRead = g_vATAPIRegs->ATA_PIO_DAD;
	} while(tempRead & 0x80);
	return retVal;
}


int WaitForDeviceAccessReady(void)
{
	UINT8 tempRead;
	UINT8  retVal=TRUE;
	UINT32 count=1;

	do {
    	if ( count == 10000000)
    	{
    		retVal=FALSE;
    		RETAILMSG(RTL_MSG, (TEXT("+++ ATAPI_CF : WaitForDeviceAccessReady error..\r\n")));	
    		break;
    	}
    	count++;
        tempRead = g_vATAPIRegs->ATA_PIO_DAD;

    	if(!(tempRead & 0x08));// RETAILMSG(RTL_MSG, (TEXT("+++ ATAPI_CF : Wait Device Ready Value %x\r\n"),tempRead));	
    	else break;
	}while(1);
	return retVal;
}


int WriteOnTaskFileReg(volatile UINT8 *nRegister,UINT32 nValue) 
{
	if (!(WaitForNoBusyStatus()))
		return FALSE;
	*nRegister  = nValue; // write register 
	return TRUE;
}


int IdentifyDevice(void) 
{
	UINT16 readBuffer[256]={0,};
	UINT8 tempBuffer;
	UINT8 *tempString;
//	UINT32 tBuf[4];
	short i;
	
//	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]);
//		RETAILMSG(RTL_MSG, (TEXT ("[%03d]DATA : 0x%04X\n"),i, readBuffer[i]));
		UINT16 tempRead;
		tempRead = g_vATAPIRegs->ATA_PIO_DAT;
		readBuffer[i] = tempRead;
	}

	for(i=0; i<ATA_SECTORSIZE/2; i++) {
//		RETAILMSG(RTL_MSG, (TEXT ("[%03d]DATA : 0x%04X\n"),i, 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++) RETAILMSG(RTL_MSG,(TEXT("%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)));

	g_oDevice[0].MaxSectors = (UINT32)((readBuffer[7] << 16) | readBuffer[8]);

	g_pcPC->drive->total_lba = g_oDevice[0].MaxSectors;
//	RETAILMSG(RTL_MSG,(TEXT("\nMax Sectors : %d\n"),g_oDevice[0].MaxSectors));
	if(g_pcPC->drive->total_lba < 0) return FALSE;

	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;
//		RETAILMSG(RTL_MSG,(TEXT("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;
    //jungpil
	g_oDevice[0].MaxPioMode = PIO0;	

//	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));


//	RETAILMSG(RTL_MSG,(TEXT("Max UDMA Mode : %d\n"),g_oDevice[0].MaxUdmaMode));
//	RETAILMSG(RTL_MSG,(TEXT("Current UDMA Mode : %d\n"),g_oDevice[0].CurrentUdmaMode));
	//
	//verify identify data~~~~~~~~~~~~~~~~~~~~~~~END
	//

	g_uCfgReg &= (~0x40); // set Little endian

	return TRUE;
}


// jungpil not implemented. maybe clockout0(TP7) shuld be used 
void SetAtaOnOff(UINT8 OnOff)
{
//	UINT32 temp;
	//Inp32(ATA_CONTROL, temp);
/*	temp = g_vATAPIRegs->ATA_CONTROL;

	if(OnOff==1)
		//Outp32(ATA_CONTROL, temp | 0x1);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -