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

📄 ide.c

📁 CIRRUS 公司EP93XX系列CPU的WINCE下的BSP
💻 C
📖 第 1 页 / 共 3 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Module Name: ide.c

Abstract: Boot loader IDE/ATA access functions.

Functions:

    ide_reset           - Reset IDE drive.
    id_drive            - Locate/identify drive.
    lba_to_pchs         - Convert LBA address to Physical CHS.
    read_sector         - Read the contents of a disk sector.
    init_ide            - Initialize IDE drive.
    load_image_ide      - Load OS image from drive.
    OEMHDDPlatformInit  - Blcommon interface functions.
    OEMHDDPreDownload   -  "
    OEMHDDReadData      -  "
    OEMHDDLaunch        -  "

Notes:
    
     Assumptions:
     - only primary master drive is supported
     - FAT16
     - file op routines only work on a single file at a time 
     - kernel image is in the root directory with the bootloader image

--*/

#include <windows.h>
#include <memorymap.h>
#include <blcommon.h>
#include <halether.h>
#include <debugtimer.h>
#include <atapi2.h>
#include "eboot.h"
#include "hwdefs.h"
#include "ide.h"
#include "fat.h"

extern void EdbgDumpHexBuf(PUCHAR pBuf, DWORD Count);

int m_BootDeviceType =0;
static BOOL m_f16Bit=TRUE;
static BOOL m_fLBAMode=TRUE;
static IDENTIFY_DATA m_Id;
static int m_bSectorsPerBlock=1;
static int     m_dwDevice =0;

#define ZONE_INFO                     1
#define SERPRINT                    EdbgOutputDebugString

// This data supplements the BPB information - used to save time.
extern t_FAT_PARMS g_FATParms;


// Global variables.
//
//UCHAR g_bsect[SECTOR_SIZE];
ULONG g_sectorsread=0;
UCHAR g_bstartcounting=0;
//STATUSBAR g_statbar;


// Function prototypes.
//
//int create_statusbar(PSTATUSBAR pbar, ULONG sval, ULONG eval);
//int update_statusbar(PSTATUSBAR pbar, ULONG cval);
//BOOL InitNIC(void);

// Externs.
//
extern FILEINFO g_fileinfo;
extern BOOLEAN ReadSectors(UCHAR Drive, ULONG LBA, USHORT nSectors, PUCHAR pBuffer);


ULONG ATAReadRegister(ULONG ulRegister)
{
    switch(m_BootDeviceType)
    {
        case BOOT_FROM_PCMCIA:
            return *(volatile UCHAR *)(PCMCIACARD_IO + (ulRegister>>2));
        break;
        case BOOT_FROM_IDE_ATADISK:
        case BOOT_FROM_IDE_CDROM:
        {
            ULONG uiValue;
            register ULONG ulControl;
            *IDE_CTRL = ulControl = IDE_CTRL_DIOR | IDE_CTRL_DIOW | ulRegister;
            *IDE_CTRL = ulControl &= ~IDE_CTRL_DIOR;
            *IDE_CTRL = ulControl |= IDE_CTRL_DIOR;
        
            uiValue = *IDE_DATAIN;
        
            if(ulRegister == CSDA_DATA_REG)
            {
                return(uiValue & 0xFFFF);
            }
            else
            {
                return(uiValue & 0xFF);
            }
        }
        break;
        
        
    }
    return 0;
}

void ATAWriteRegister(ULONG ulRegister, UINT uiData)
{
    switch(m_BootDeviceType)
    {
        case BOOT_FROM_PCMCIA:
            *(volatile UCHAR *)(PCMCIACARD_IO + (ulRegister>>2)) = (BYTE)uiData;
        break;
        case BOOT_FROM_IDE_CDROM:
        case BOOT_FROM_IDE_ATADISK:
        {
            register ULONG   ulControl;
            *IDE_CTRL       = ulControl = IDE_CTRL_DIOR | IDE_CTRL_DIOW | ulRegister;
            *IDE_DATAOUT    = uiData;
            *IDE_CTRL = ulControl &= ~IDE_CTRL_DIOW;
            *IDE_CTRL = ulControl |= IDE_CTRL_DIOW;
        }
        break;
    }
}
BYTE GetBaseStatus()
{
    if(m_BootDeviceType == BOOT_FROM_PCMCIA)
        return *(volatile UCHAR *)(PCMCIACARD_IO + IDE_STAT_REG);
    else
        return (BYTE) (ATAReadRegister(CSDA_STAT_REG) & 0xFF);
}
BYTE GetAltStatus()
{
    if(m_BootDeviceType == BOOT_FROM_PCMCIA)
        return *(volatile UCHAR *)(PCMCIACARD_IO + IDE_ALT_CTRL_REG);
    else
        return (BYTE) (ATAReadRegister(CSDA_ALT_STAT_REG) & 0xFF);
}
void WriteAltDriveController(BYTE bData)
{
    if(m_BootDeviceType == BOOT_FROM_PCMCIA)
        *(volatile UCHAR *)(PCMCIACARD_IO + IDE_ALT_CTRL_REG) = (BYTE)bData;
    else
        ATAWriteRegister(CSDA_ALT_CTRL_REG, (ULONG) bData);
}
void SetDriveHead(BYTE bDriveHead)
{
    ATAWriteRegister(CSDA_DRVHD_REG, (ULONG) bDriveHead);
}
BYTE GetReason()
{
    return (BYTE) (ATAReadRegister(CSDA_REASON_REG) & 0xFF);
}
BYTE GetError()
{
    return (BYTE) (ATAReadRegister(CSDA_ERROR_REG) & 0xFF);
}
void SelectDevice()
{
    ATAWriteRegister(CSDA_DRVHD_REG, (m_dwDevice == 0 ) ? ATA_HEAD_DRIVE_1 : ATA_HEAD_DRIVE_2);
}
void WriteCommand(BYTE bCommand)
{
    ATAWriteRegister(CSDA_CMD_REG, (ULONG) bCommand);
}
void WriteFeature(BYTE bFeature)
{
    ATAWriteRegister(CSDA_FEATURE_REG, (ULONG) bFeature);
}
void WriteSectorCount(BYTE bValue)
{
    ATAWriteRegister(CSDA_SECTCNT_REG, (ULONG) bValue);
}
void WriteDriveHeadReg(BYTE bValue)
{
    ATAWriteRegister(CSDA_DRVHD_REG, (ULONG) bValue);
}
void WriteSectorNumber(BYTE bValue)
{
    ATAWriteRegister(CSDA_SECTNUM_REG, (ULONG) bValue);
}
///void WriteDriveController(BYTE bData)
///{
///    ATAWriteRegister(CSDA_ALT_CTRL_REG, (ULONG) bData);
///}
void WriteLowCount(BYTE bValue)
{
    ATAWriteRegister(CSDA_CYLL_REG, (ULONG) bValue);
}
void WriteHighCount(BYTE bValue)
{
    ATAWriteRegister(CSDA_CYLH_REG, (ULONG) bValue);
}

void ReadWordBuffer( PWORD pBuffer, DWORD dwCount)
{
    PWORD pEnd;
    pEnd = pBuffer + dwCount;

    if(m_BootDeviceType == BOOT_FROM_PCMCIA)
    {
        while(pBuffer < pEnd)
        {
            *pBuffer++ = *(volatile USHORT *)(PCMCIACARD_IO + IDE_DATA_REG);
        }
    }
    else
    {
        while(pBuffer < pEnd)
        {
            *pBuffer++ = (WORD)(ATAReadRegister(CSDA_DATA_REG) & 0xFFFF);
        }
    }
}
void ReadByteBuffer( PBYTE pBuffer, DWORD dwCount)
{
    DWORD   dwIndex;
    for(dwIndex = 0 ; dwIndex < dwCount ; dwIndex++)
    {
        pBuffer[dwIndex] = (BYTE)(ATAReadRegister(CSDA_DATA_REG) & 0xFF);
    }
}
WORD ReadWord()
{
    if(m_BootDeviceType == BOOT_FROM_PCMCIA)
        return *(volatile USHORT *)(PCMCIACARD_IO + IDE_DATA_REG);
    else
        return ((WORD)(ATAReadRegister(CSDA_DATA_REG) & 0xFFFF));
}
WORD ReadByte()
{
    return ((BYTE)(ATAReadRegister(CSDA_DATA_REG) & 0xFF));
}
BOOL WaitForDisc_P(BYTE bStatusType, DWORD dwTimeOut,DWORD dwPeriod)
{
    BYTE bStatusRead;
    bStatusRead = 0;

    if (dwPeriod == 0)
        dwPeriod = dwTimeOut;

    while( TRUE)  
    {
        bStatusRead = GetAltStatus();
        switch (bStatusType)  {
            case WAIT_TYPE_BUSY:
                if (bStatusRead & ATA_STATUS_BUSY)  
                {
//                    DEBUGMSG(ZONE_IO, (TEXT("ATAPI:WaitForDisc - WAIT_TYPE_BUSY\r\n")));
                    goto ExitDone;
                }
                break;

            case WAIT_TYPE_NOT_BUSY:
                if (!(bStatusRead & ATA_STATUS_BUSY))  
                {
//                    DEBUGMSG(ZONE_IO, (TEXT("ATAPI:WaitForDisc - WAIT_TYPE_NOT_BUSY\r\n")));
                    goto ExitDone;
                }
                break;

            case WAIT_TYPE_READY:
                if (bStatusRead & ATA_STATUS_READY) 
                {
//                    DEBUGMSG(ZONE_IO, (TEXT("ATAPI:WaitForDisc - WAIT_TYPE_READY\r\n")));
                    // DelayInuSec(100);
                    goto ExitDone;
                }
                break;

            case WAIT_TYPE_DRQ: 
                if (bStatusRead & ATA_STATUS_DATA_REQ) 
                {
//                    DEBUGMSG(ZONE_IO, (TEXT("ATAPI:WaitForDisc - WAIT_TYPE_DRQ\r\n")));
                    goto ExitDone;
                }
                break;

            case WAIT_TYPE_NOT_DRQ:
                if (!(bStatusRead & ATA_STATUS_DATA_REQ)) 
                {
//                    DEBUGMSG(ZONE_IO, (TEXT("ATAPI:WaitForDisc - WAIT_TYPE_NOT_DRQ\r\n")));
                    goto ExitDone;
                }
                break;
                
            case WAIT_TYPE_ERROR: 
                if (bStatusRead & ATA_STATUS_ERROR) 
                {
//                    DEBUGMSG(ZONE_IO, (TEXT("ATAPI:WaitForDisc - WAIT_TYPE_ERROR\r\n")));
                    goto ExitDone;
                }
                break;                
        }       
        if ((int)dwTimeOut > 0) 
        {
            DelayInuSec(dwPeriod);
            dwTimeOut -= dwPeriod;
        } 
        else 
        {
            // DEBUGMSG(ZONE_ERROR, (TEXT("ATAPI:WaitForDisc - TimeOut !!! WaitType = %ld Status=%02X\r\n"), bStatusType, bStatusRead));
            return ERROR_GEN_FAILURE;
        }    
    }

ExitDone:
    return ERROR_SUCCESS;
}
BOOL WaitForDisc(BYTE bStatusType, DWORD dwTimeOut)
{
    DWORD dwPeriod =0;
    return WaitForDisc_P(bStatusType, dwTimeOut, dwPeriod);
}
void ide_enable()
{

    SERPRINT("Enable IDE controller\r\n");

    *IDE_CFG    = 0; 

    //
    // Initialize the IDE interface to PIO mode 4.
    //
    *IDE_CFG    = IDE_CFG_IDEEN | IDE_CFG_PIOEN | IDE_CFG_PIO4 | (1 <<IDE_CFG_WST_SHIFT);

    *IDE_CTRL   = IDE_CTRL_DIOR | IDE_CTRL_DIOW | CSDA_DATA_REG;


    //
    // Make sure that MDMA and UDMA are disabled.
    //
    *IDE_MDMAOP = 0;
    *IDE_UDMAOP = 0;    

//    SelectDevice();
//    WriteDriveController( ATA_CTRL_ENABLE_INTR);

⌨️ 快捷键说明

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