📄 atapi.c
字号:
/*
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 + -