📄 hal4ata.c
字号:
/*
//////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1999 - 2003 PHILIPS Semiconductors - APIC
//
// Module Name:
//
// HAL4ATA.c
//
// Abstract:
//
// This is HAL for IDE controllers.
//
// Author:
//
// Hilbert Zhang ZhenYu
//
// Environment:
//
// kernel mode only
//
// Notes:
//
// Revision History:
// Create Date: Nov. 19 1999
//
//////////////////////////////////////////////////////////////////////////////
// Implementation Notes:
*/
#include <reg51.h> /* special function register declarations */
#undef GLOBAL_EXT
#include "SysCnfg.h"
#include "BasicTyp.h"
#include "common.h"
#include "Hal4Sys.h"
#include "ATA.h"
#include "RBC.h"
#include "RBCCmd.h"
#include "Hal4ATA.h"
#include "TPBulk.h"
/*
//*************************************************************************
// Public Data
//*************************************************************************
*/
STRUC_EXT TPBLK_STRUC DATA_SEG TPBulk_Block;
#define TPBulk_CBW TPBulk_Block.TPBulk_CommandBlock
#define RBC_CDB TPBulk_CBW.cdbRBC
#define RBC_LUN TPBulk_CBW.bCBW_LUN
#define TPBulk_CSW TPBulk_Block.TPBulk_CommandStatus
#define Hal4ATA_Atapi RBC_CDB
STRUC_EXT HW_ATA_DEVICES_EXTENSION Hal4ATA_DevExt;
#define ATADevExt_IDData Hal4ATA_DevExt.IdentifyData
BIT_EXT ATABF_IsAttached;
BIT_EXT ATABF_IsSupportMultiSector;
BIT_EXT ATABF_IDEXfer_dir;
BIT_EXT ATABF_IsSkipSetParameters;
INT8_EXT Hal4ATA_SectCntInBlk;
/*
//*************************************************************************
// Private Data
//*************************************************************************
*/
// Static
INT8 BDATA_SEG Hal4ATA_StatusByte;
sbit Hal4ATA_StatusByte_ERR = Hal4ATA_StatusByte^0;
sbit Hal4ATA_StatusByte_IDX = Hal4ATA_StatusByte^1;
sbit Hal4ATA_StatusByte_CORR = Hal4ATA_StatusByte^2;
sbit Hal4ATA_StatusByte_DRQ = Hal4ATA_StatusByte^3;
sbit Hal4ATA_StatusByte_DSC = Hal4ATA_StatusByte^4;
sbit Hal4ATA_StatusByte_DF = Hal4ATA_StatusByte^5;
sbit Hal4ATA_StatusByte_DRDY = Hal4ATA_StatusByte^6;
sbit Hal4ATA_StatusByte_BSY = Hal4ATA_StatusByte^7;
INT8 BDATA_SEG Hal4ATA_DevReg = 0xA0;
sbit Hal4ATA_DevReg_DEV = Hal4ATA_DevReg^4;
sbit Hal4ATA_DevReg_b5 = Hal4ATA_DevReg^5;
sbit Hal4ATA_DevReg_LBA = Hal4ATA_DevReg^6;
sbit Hal4ATA_DevReg_b7 = Hal4ATA_DevReg^7;
// Temp
FLEXI_INT32 Hal4ATA_Track;
INT8 Hal4ATA_drvSelect;
/*
code LUT_DATA lut_Data=
{
0x00, 0x80, 0x06, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x29, 0x00,
0x00, 0x80, 0x06, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x29, 0x00,
0x00, 0x80, 0x06, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x29, 0x00,
0x00, 0x80, 0x06, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x29, 0x00,
0x00, 0x80, 0x06, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x29, 0x00,
0x00, 0x80, 0x06, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x29, 0x00,
0x00, 0x80, 0x06, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x29, 0x00,
0x00, 0x80, 0x06, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x29, 0x00,
0x00, 0x80, 0x06, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x29, 0x00,
0x00, 0x80, 0x06, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x29, 0x00,
0x00, 0x80, 0x06, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x29, 0x00,
0x00, 0x80, 0x06, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x29, 0x00,
0x00, 0x80, 0x06, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x29, 0x00,
0x00, 0x80, 0x06, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x29, 0x00,
0x00, 0x80, 0x06, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x29, 0x00,
0x00, 0x80, 0x06, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x29, 0x00,
0x00, 0x80, 0x06, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x29, 0x00,
0x00, 0x80, 0x06, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x29, 0x00,
0x00, 0x80, 0x06, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x29, 0x00,
0x00, 0x80, 0x06, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x29, 0x00,
0x00, 0x80, 0x06, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x29, 0x00,
0x00, 0x80, 0x06, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x29, 0x00,
0x00, 0x80, 0x06, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x29, 0x00,
0x00, 0x80, 0x06, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x29, 0x00,
0x00, 0x80, 0x06, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x29, 0x00,
0x00, 0x80, 0x06, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x29, 0x00,
}
*/
/*
//*************************************************************************
// Subroutines -- Level 1
//*************************************************************************
*/
void
Hal4ATA_GetStatus(void)
{
Hal4ATA_StatusByte = Hal4Sys_ATAPortInB(ATAREG4IN_ALTERNATE_STATUS);
}
BOOLEAN
Hal4ATA_WaitOnBusyNDrdy(void)
{
INT16 i;
BOOLEAN retStatus = FALSE;
#ifndef DEBUG
for (i = 250; i!=0; i--)
#else
while(TRUE)
#endif
{
Hal4ATA_GetStatus();
while ( Hal4ATA_StatusByte_DRDY !=1)
{
Hal4Sys_Wait4US();
Hal4ATA_GetStatus();
}
// if IDE_STATUS_BUSY && !IDE_STATUS_DRDY
//Hal4ATA_StatusByte_ERR = Hal4ATA_StatusByte^0
/*
if (Hal4ATA_StatusByte_ERR != 0 || Hal4ATA_StatusByte_DF != 0)
{
break;
}
else if(Hal4ATA_StatusByte_BSY !=0 || Hal4ATA_StatusByte_DRDY !=1)
Hal4Sys_Wait4US();
else
{
retStatus = TRUE;
break;
}
}
return retStatus;
*/
retStatus = TRUE;
break;
}
return retStatus;
}
BOOLEAN
Hal4ATA_WaitOnBusyNDrq(void)
{
INT16 i;
BOOLEAN retStatus = FALSE;
#ifndef DEBUG
for (i = 25000; i!=0; i--)
#else
while(TRUE)
#endif
{
Hal4ATA_GetStatus();
while (Hal4ATA_StatusByte_DRQ !=1)
{
Hal4ATA_GetStatus();
}
/*
if (Hal4ATA_StatusByte_ERR != 0 || Hal4ATA_StatusByte_DF != 0)
{
break;
}
else if(Hal4ATA_StatusByte_BSY !=0 || Hal4ATA_StatusByte_DRQ !=1)
Hal4Sys_Wait4US();
else
{
retStatus = TRUE;
break;
}
}
*/
break;
}
return TRUE;
}
BOOLEAN
Hal4ATA_WaitOnBusy(void)
{
INT16 i;
// BOOLEAN retStatus = FALSE;
#ifndef DEBUG
for (i = 25000; i!=0; i--)
#else
while(TRUE)
#endif
{
Hal4ATA_GetStatus();
while (Hal4ATA_StatusByte_BSY !=0)
{
// Hal4Sys_Wait4US();
Hal4ATA_GetStatus();
}
/*
if (Hal4ATA_StatusByte_ERR != 0 || Hal4ATA_StatusByte_DF != 0)
{
break;
}
else if(Hal4ATA_StatusByte_BSY)
{
Hal4Sys_Wait4US();
}
else
{
retStatus = TRUE;
break;
}
}
return retStatus;
*/
break;
}
return TRUE;
}
/*
BOOLEAN
Hal4ATA_WaitForDrq(void)
{
// INT16 w;
BOOLEAN retStatus = FALSE;
//#ifndef DEBUG
// for (w = 25000; w!=0; w--)
//#else
while(TRUE)
//#endif
{
Hal4ATA_GetStatus();
// if (Hal4ATA_StatusByte_ERR != 0 || Hal4ATA_StatusByte_DF != 0)
// {
// break;
// }
// else if (Hal4ATA_StatusByte_DRQ != 1) //IDE_STATUS_DRQ
// if (Hal4ATA_StatusByte_DRQ != 1) //IDE_STATUS_DRQ
// Hal4Sys_Wait4US();
// else
// {
// retStatus = TRUE;
break;
// }
}
return retStatus;
}
*/
/*
//*************************************************************************
// Subroutines -- Level 2
//*************************************************************************
*/
BOOLEAN
Hal4ATA_SelDevice(void)
{
BOOLEAN retStatus = FALSE;
if(Hal4ATA_WaitOnBusy())
{
// ATAREG4OUT_DEVICE_HEAD = ATAREG_GRP0+6 = 0x56
// ATAREG_GRP0 =0x50
// BUFF_DIR_RD, !D12CS, !BUFF_EN, !IDE_CS1, !IDE_CS0, A2, A1, A0
//0x56 0 1 0 1 0 1 1 0
Hal4Sys_ATAPortOutB(ATAREG4OUT_DEVICE_HEAD,Hal4ATA_DevReg);
retStatus = Hal4ATA_WaitOnBusyNDrdy();
}
return retStatus;
}
/*
//*************************************************************************
// Subroutines -- Level 3
//*************************************************************************
*/
BOOLEAN
Hal4ATA_IdeSoftReset(void)
{
INT8 c;
BOOLEAN retStatus = FALSE;
Hal4ATA_DevReg_DEV = FALSE;
if(Hal4ATA_SelDevice())
{
/*
// SoftReset the device.
*/
Hal4Sys_ATAPortOutB(ATAREG4OUT_CONTROL,IDE_DC_RESET_CONTROLLER|IDE_DC_DISABLE_INTERRUPTS );
Hal4Sys_WaitInUS(32); //>25US
Hal4Sys_ATAPortOutB(ATAREG4OUT_CONTROL,IDE_DC_REENABLE_CONTROLLER|IDE_DC_DISABLE_INTERRUPTS );
for(c = 20; c != 0; c--)
Hal4Sys_WaitInUS(50000); // 50MS
#ifndef DEBUG
for(c = 31; c!=0; c--) // 31 Seconds time out
#else
while(TRUE)
#endif
{
if(Hal4ATA_WaitOnBusyNDrdy())
{
retStatus = TRUE;
break;
}
}
}
}
/*
//*************************************************************************
// Subroutines -- level 4
//*************************************************************************
*/
BOOLEAN
Hal4ATA_IssueIDEIdentify(void)
{
INT16 i;
BOOLEAN retStatus = FALSE;
// Select device.
if(Hal4ATA_SelDevice())
{
// Send IDE IDENTIFY command.
// IDE_COMMAND_IDENTIFY=0xEC ;
Hal4Sys_ATAPortOutB(ATAREG4OUT_COMMAND, IDE_COMMAND_IDENTIFY);
if(Hal4ATA_WaitOnBusyNDrq())
{
/*
// Suck out 256 words. After waiting for one model that asserts busy
// after receiving the Packet Identify command.
*/
if(Hal4ATA_InitDevExt())
retStatus = TRUE;
}
/*
// Work around for some IDE and one model Atapi that will present more than
// 256 words for the Identify data.
*/
for (i=10000; i != 0; i--)
{
Hal4ATA_GetStatus();
if (Hal4ATA_StatusByte_DRQ)
{
/*
// Suck out any remaining bytes and throw away.
*/
Hal4Sys_ATADataPortInW();
}
else
break;
}
}
return retStatus;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -