📄 biosial.c
字号:
/*******************************************************************************
*
* Copyright 2003,MARVELL SEMICONDUCTOR ISRAEL, LTD.
* THIS CODE CONTAINS CONFIDENTIAL INFORMATION OF MARVELL.
* NO RIGHTS ARE GRANTED HEREIN UNDER ANY PATENT, MASK WORK RIGHT OR COPYRIGHT
* OF MARVELL OR ANY THIRD PARTY. MARVELL RESERVES THE RIGHT AT ITS SOLE
* DISCRETION TO REQUEST THAT THIS CODE BE IMMEDIATELY RETURNED TO MARVELL.
* THIS CODE IS PROVIDED "AS IS". MARVELL MAKES NO WARRANTIES, EXPRESSED,
* IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, COMPLETENESS OR PERFORMANCE.
*
* MARVELL COMPRISES MARVELL TECHNOLOGY GROUP LTD. (MTGL) AND ITS SUBSIDIARIES,
* MARVELL INTERNATIONAL LTD. (MIL), MARVELL TECHNOLOGY, INC. (MTI), MARVELL
* SEMICONDUCTOR, INC. (MSI), MARVELL ASIA PTE LTD. (MAPL), MARVELL JAPAN K.K.
* (MJKK), MARVELL SEMICONDUCTOR ISRAEL. (MSIL), MARVELL TAIWAN, LTD. AND
* SYSKONNECT GMBH.
*
********************************************************************************
* main.c - C File for implementation of BIOS Intermediate Application Layer.
*
* DESCRIPTION:
* None.
*
* DEPENDENCIES:
* mvOs.h
* mvSata.h.
* mvStorageDev.h
* mvRegs.h
*
* FILE REVISION NUMBER:
* $Revision: 1.7 $
*******************************************************************************/
#include "mvOs.h"
#include "mvBiosIal.h"
#include "mvSata.h"
#include "mvStorageDev.h"
#include "mvIALCommonUtils.h"
/* Defines */
/* CHS geometry definition */
#define HEADS 255
#define SECTORS 63
#define CYLINDER 1022
#define USE_REGISTER_ACCESS_PROTECTED_MODE
/* Global variables */
/* Global descriptors table */
unsigned int GDT[] = { 0xf, 0, 0, 0,
0xffff, 0, 0x9200, 0x8f};
/* mvSata Adapter location on PCI bus */
unsigned long mvSataBarOffset;
unsigned char mvSataResult;
unsigned char mvSataDeviceNum;
unsigned char mvSataBusNum;
unsigned short mvSataDeviceId;
unsigned char mvSataRevisionId;
/* Local stack */
#define stackSize 0x600
unsigned short stack[stackSize/2] = {0,};
unsigned short oldStack, oldStackSegment, oldDataSegment;
unsigned short savedInt13CodeSegment, savedInt13InstructionPointer;
unsigned int alreadySavedInt13Vector = 0;
unsigned int alreadyInitializedChannelsFlag = 0;
unsigned int alreadyHookedInt13 = 0;
unsigned short bcvEsDataSegment;
unsigned short bcvDiPointer;
/* drivesNumbers is for checking if the adapter owns the drive with the int13 */
unsigned char drivesNumbers[MV_SATA_BIOS_MAX_DRIVES] =
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
}; //修改--将MV_SATA_CHANNELS_NUM替换为MV_SATA_BIOS_MAX_DRIVES
/*
* sataChannelNumner is used as a SATA channel in case a match is found using
* drivesNumers
*/
MV_U8 sataChannelNumber[MV_SATA_BIOS_MAX_DRIVES] =
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
}; //修改--将MV_SATA_CHANNELS_NUM替换为MV_SATA_BIOS_MAX_DRIVES
/*
* portMultiplierPort is used a device port number on the port multiplier in
* case a match is found using drivesNumbers.
*/
MV_U8 portMultiplierPort[MV_SATA_BIOS_MAX_DRIVES] =
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
}; //修改--将MV_SATA_CHANNELS_NUM替换为MV_SATA_BIOS_MAX_DRIVES
unsigned short pnpCheckSegment, pnpCheckOffset, pnpCheckResult;
MV_U8 requestedAllignment = 2; /* Default buffer allignment is 2 bytes */
/* Data structure describing mvSata adapter and channels */
HW_ADAPTER_DESCRIPTION sataAdapter ={0,};
MV_BOOLEAN useIoBar = MV_FALSE;
/* Local functions */
static MV_BOOLEAN findAndInitChannels(void);
MV_BOOLEAN StartChannel( PHW_ADAPTER_DESCRIPTION HwDeviceExtension,
MV_U8 channelIndex, MV_BOOLEAN PMEnabled, MV_U8 PMPort);
static MV_U16 readSystemClockTimer(void);
static MV_BOOLEAN
StartPM(PHW_ADAPTER_DESCRIPTION HwDeviceExtension, MV_U8 channelIndex,
MV_BOOLEAN *driveList);
static void outCharacter(unsigned char character);
static unsigned char getCurrentInstalledDrives(void);
static unsigned int getCurrentInt13CodeSegment(void);
static unsigned int getCurrentInt13InstructionPointer(void);
static void setCurrentInstalledDrives(unsigned char drive);
static void setCurrentInt13InstructionPointer(unsigned short value);
static void setCurrentInt13CodeSegment(unsigned short value);
static unsigned short getStackSegment(void);
static unsigned short getCodeSegment(void);
static void int13EntryPoint (void);
static int hookChannel(MV_U8 channel);
static unsigned short mvSataReadConfigWord(unsigned short offset);
static void oldInt13VectorCode(void);
static void initializeDriver(void);
static void activateA20Gate(void);
static void Ata2HostString(MV_U16 *source, MV_U16 *target, MV_U16 wordsCount);
static unsigned long readRegisterProtectedMode (register unsigned long offset);
static void writeRegisterProtectedMode (unsigned long offset, unsigned long value);
static void writeRegisterIoBar (unsigned short base_, unsigned long offset_,
unsigned long value_);
static unsigned long readRegisterIoBar (unsigned short base_,
unsigned long offset_);
/* BCV Entry points */
void bcvEntryPoint_ch0(void);
void bcvEntryPoint_ch1(void);
void bcvEntryPoint_ch2(void);
void bcvEntryPoint_ch3(void);
void bcvEntryPoint_ch4(void);
void bcvEntryPoint_ch5(void);
void bcvEntryPoint_ch6(void);
void bcvEntryPoint_ch7(void);
typedef union
{
unsigned short val;
struct
{
unsigned char lval;
unsigned char hval;
} parts;
} reg16;
#define MV_EDMA_REQUEST_COMMANDS_NUM 11
typedef struct mvDmaRequestQueueEntry
{
/* Fields set by CORE driver */
volatile MV_U32 prdLowAddr;
volatile MV_U32 prdHighAddr;
volatile MV_U16 controlFlags;
volatile MV_U16 command[MV_EDMA_REQUEST_COMMANDS_NUM];
} MV_DMA_REQUEST_QUEUE_ENTRY;
/*******************************************************************************
* main - Option ROM entry point
*
*
* DESCRIPTION:
* Option ROM initializatoin function.
* BIOS far calls this function for initializtion.
*
* INPUT:
* ES:DI - PNP header (only if PNP BIOS)
*
* RETURN:
* AX = 0x130 (indication IPL capable device)
*
* COMMENTS:
* This function must be first function in main.c - it's compiled address
* must be 0x30a (using Open Watcom compiler).
*
*******************************************************************************/
void main(void)
{
_asm {
mov cs:mvSataBusNum, ah
mov cs:mvSataDeviceNum, al
pop di
pop si
pop dx
pop cx
pop bx
pop bp
pusha
push fs
push gs
push es
push ds
push cs
pop ds
mov oldStack, sp
mov oldStackSegment,ss
; Change the stack segment and pointer
push cs
pop ss
lea sp, stack
add sp, stackSize - 0x10
mov pnpCheckSegment, es
mov pnpCheckOffset, di
mov pnpCheckResult, 0
call initializeDriver
cmp pnpCheckResult, 1 ; Check ifthis is a PNP BIOS
je initOut ;If so, BCV entries will initialize the adapter
mov al, 0
call hookChannel
mov al, 1
call hookChannel
mov al, 2
call hookChannel
mov al, 3
call hookChannel
mov al, 4
call hookChannel
mov al, 5
call hookChannel
mov al, 6
call hookChannel
mov al, 7
call hookChannel
initOut :
mov sp, oldStack
mov ss, oldStackSegment
pop ds
pop es
pop gs
pop fs
popa
mov ax, 0x0130 ; Indicates that IPL Device supports int 13 found
retf
}
}
/*******************************************************************************
* bcvEntryPoint_chX - 8 Functions for BCV entry point
*
*
* DESCRIPTION:
* 8 functions needed for BCV entry point (PNP BIOS). Each function for a
* specific SATA channel.
*
* INPUT:
* ES:DI - PNP header (only if PNP BIOS)
*
* RETURN:
* AX = 0x130 (indication IPL capable device)
*
*******************************************************************************/
#define bcvEntryPointGenerate(x) void bcvEntryPoint_ch##x## (void) \
{ \
_asm { push ds } \
_asm { push cs } \
_asm { pop ds } \
_asm { mov oldStackSegment, ss } \
_asm { push cs } \
_asm { pop ss } \
_asm { mov oldStack, sp } \
_asm { lea sp, stack } \
_asm { add sp, stackSize-0x10 } \
_asm { and sp, 0xfff0 } \
_asm { pusha } \
_asm { push fs } \
_asm { push gs } \
_asm { push es } \
_asm { mov bcvEsDataSegment, es } \
_asm { mov bcvDiPointer, di } \
hookChannel(##x##); \
_asm { pop es } \
_asm { pop gs } \
_asm { pop fs } \
_asm { popa } \
_asm { mov sp, oldStack } \
_asm { mov ss, oldStackSegment } \
_asm { pop ds } \
_asm { mov ax, 0x0130 } \
_asm { retf } \
}
bcvEntryPointGenerate (0);
bcvEntryPointGenerate(1);
bcvEntryPointGenerate(2);
bcvEntryPointGenerate(3);
bcvEntryPointGenerate(4);
bcvEntryPointGenerate(5);
bcvEntryPointGenerate(6);
bcvEntryPointGenerate(7);
static MV_BOOLEAN
StartPM(PHW_ADAPTER_DESCRIPTION HwDeviceExtension,
MV_U8 channelIndex, MV_BOOLEAN *driveList)
{
MV_SATA_ADAPTER *pSataAdapter = &(HwDeviceExtension->mvSataAdapter);
MV_U8 PMPort;
MV_SATA_PM_DEVICE_INFO PMInfo;
MV_U8 temp;
for(temp = 0 ; temp < MV_SATA_PM_MAX_PORTS ; temp ++)
{
driveList[temp] = MV_FALSE;
}
if(mvGetPMDeviceInfo(pSataAdapter, channelIndex, &PMInfo) == MV_FALSE)
{
MV_ERROR("MV IAL[%d %d]: Failed to get PortMultiplier Info\n",
pSataAdapter->adapterId, channelIndex);
return MV_FALSE;
}
for(PMPort = 0; PMPort < PMInfo.numberOfPorts; PMPort++)
{
MV_U32 SStatus;
/*
* Skip PMPort #0 - this should be already enabled due to legacy mode
* transition of PM
*/
if(PMPort > 0)
{
if(mvPMDevEnableStaggeredSpinUp(pSataAdapter, channelIndex, PMPort) ==
MV_FALSE)
{
MV_ERROR("MV IAL[%d %d %d]: EnableStaggeredSpinUp Failed\n",
pSataAdapter->adapterId, channelIndex, PMPort);
if(mvStorageDevATASoftResetDevice(pSataAdapter, channelIndex,
MV_SATA_PM_CONTROL_PORT, NULL) == MV_FALSE)
{
MV_ERROR("MV IAL [%d %d]: failed to Soft Reset PM control port\n"
, pSataAdapter->adapterId, channelIndex);
}
continue;
}
}
if(mvPMDevReadReg(pSataAdapter, channelIndex, PMPort,
MV_SATA_PSCR_SSTATUS_REG_NUM, &SStatus, NULL) ==
MV_FALSE)
{
MV_ERROR("MV IAL[%d %d %d]: mvPMDevReadReg Failed\n",
pSataAdapter->adapterId, channelIndex, PMPort);
if(mvStorageDevATASoftResetDevice(pSataAdapter, channelIndex,
MV_SATA_PM_CONTROL_PORT, NULL) == MV_FALSE)
{
MV_ERROR("MV IAL [%d %d]: failed to Soft Reset PM control port\n"
, pSataAdapter->adapterId, channelIndex);
}
continue;
}
MV_PRINTD ("MV IAL[%d %d %x]: S-Status: 0x%x\n", pSataAdapter->adapterId,
channelIndex, PMPort, SStatus);
if((SStatus & 0xf) != 3)
{
MV_PRINTD("MV IAL[%d %d %d]: No device found\n",
pSataAdapter->adapterId, channelIndex, PMPort);
continue;
}
/* Disk is connected to PMPort device port on port multiplier */
driveList[PMPort] = MV_TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -