📄 sim_dev.c
字号:
/******************************************************************************/
/* */
/* Copyright (C), 1995-2006, msystems Ltd. All rights reserved. */
/* */
/* Redistribution and use in source and binary forms, with or without */
/* modification, are permitted provided that the following conditions are */
/* met: */
/* 1. Redistributions of source code must retain the above copyright notice, */
/* this list of conditions and the following disclaimer. */
/* 2. Redistributions in binary form must reproduce the above copyright */
/* notice, this list of conditions and the following disclaimer in the */
/* documentation and/or other materials provided with the distribution. */
/* 3. Neither the name of msystems nor the names of its contributors may be */
/* used to endorse or promote products derived from this software without */
/* specific prior written permission. */
/* */
/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED */
/* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */
/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */
/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR */
/* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF */
/* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
/* */
/******************************************************************************/
/*
* $Log:
*/
#include "flchkdef.h"
#include "sim_dev.h"
#include "flsystem.h"
#include "ata_cmds.h"
#include "hib.h"
/*Extern definition of _fseeki64 used for large storage simulation (>2GB)*/
extern int _fseeki64(FILE *, __int64, int);
/*Defines*/
/*=======*/
#define DOCH_SIM_CHIPID1 0x4833
#define DOCH_SIM_CHIPID2 (0xFFFF - DOCH_SIM_CHIPID1)
#define DOCH_SIM_DEFAULT_SECTORS_PER_TRACK 15
#define DOCH_SIM_DEFAULT_NUM_OF_HEADS 1
#define DOCH_SIMSERIAL_NUM "01234567891234567890"
#define DOCH_SIM_FW_VER "Ver 1 "
#define DOCH_SIM_MODEL_NUM "model 123456789023456789013456789012"
/*Global variables*/
/*================*/
/*20Bytes*/
static FLByte DOCH_SIM_EXTINFO_SERIAL_NUM[] = {
'C', 'a', 'p', 'a', 'c', 'i', 't', 'y', ':'
};
/*40Bytes*/
static FLByte DOCH_SIM_EXTINFO_MODEL_NUM[] = {
'M', '-', 'S', 'y', 's', 't', 'e', 'm', 's', ' ',
'S','i','m', 'u', 'l', 'a', 't', 'o',
'r',' ','V','e','r',':'
};
/*16Bytes*/
static FLByte DOCH_SIM_EXTINFO_UNIQUE_ID[] = {
'N', 'o', ' ', 'U', 'n', 'i', 'q', 'u', 'e', 'I', 'D'
};
/*16Bytes*/
static FLByte DOCH_SIM_EXTINFO_PROGNAME[] = {
'S','i','m','P','r','o','g'
};
/*8Bytes*/
static FLByte DOCH_SIM_EXTINFO_PROGVER[] = {
'S','D','K',':'
};
FLBoolean bResetStatus = FALSE;
#ifndef DOCH_RAM_SIMULATION
#ifdef DOCH_FILE_SIMULATION
FLByte * pSimFileName; /* one file for master and slave devices */
FLDword dwSimLength[ATA_MAX_NUM_OF_DEVICES]; /* lengths for each master and slave devices */
#endif /* DOCH_FILE_SIMULATION*/
#endif /* DOCH_RAM_SIMULATION */
DOCH_SimSocket simSocket;
DOCH_PartitionFormatInfo partSetupInfo;
DOCH_DeviceInfo diskOnChipDeviceInfo[ATA_MAX_NUM_OF_DEVICES];
DOCH_ExtendedDeviceInfo extDeviceInfo[ATA_MAX_NUM_OF_DEVICES];
FLByte configPartitions[15][0x200];
FLByte sandBox[DOCH_SECTOR_SIZE * DOCH_MAX_SECTORS];
FLByte ataDebug[DOCH_SECTOR_SIZE];
FLByte activeMode = DOCH_PM_WORK_MODE;
FLByte workMode = DOCH_WM_NORMAL;
FLByte inactiveMode = DOCH_IM_IDLE;
FLWord inactiveModeTO = 0;
FLBoolean intDisabled = FALSE;
/*File seeking arithmetics*/
FLDword gSimDeviceSizeOnFile = 0;
FLDword gDev0SimDeviceSizeOnFile = 0;
FLDword gDev1SimDeviceSizeOnFile = 0;
/*Routines to retrieve pointers to global variables*/
/*=================================================*/
DOCH_SimDevice* getSimDev(FLSNative ataDev) {return &simSocket.device[ataDev];}
DOCH_SimSocket* getSimSocket() {return &simSocket;}
FLByte* getPartSetupInfo(void) {return (FLByte*)(&partSetupInfo);}
FLByte* getDiskOnChipDeviceInfo(FLByte bDev) {return (FLByte*)(&(diskOnChipDeviceInfo[bDev]));}
FLByte* getExtendedDeviceInfo(void) {return (FLByte*)(&extDeviceInfo);}
FLByte* getConfigPartition(FLByte partNum) {return (FLByte*)(&configPartitions[partNum][0]);}
FLByte* getSandBox(void) {return (FLByte*)(sandBox);}
FLByte* getAtaDebug(void) {return (FLByte*)(ataDebug);}
FLSNative parseControlReg(DOCH_SimSocket* simSocket, int val);
void setActiveMode(FLByte WM)
{
if(WM == DOCH_PM_INACTIVE_MODE)
{
if(activeMode != WM)
{
if(getInactiveMode() == DOCH_IM_DPD)
DBG_PRINT_FLOW_PRM(FLZONE_MTD, (FLTXT("DPD Mode Entered!!!\r\n")));
else if(getInactiveMode() == DOCH_IM_IDLE)
DBG_PRINT_FLOW_PRM(FLZONE_MTD, (FLTXT("IDLE Mode Entered!!!\r\n")));
}
else
DBG_PRINT_FLOW_PRM(FLZONE_MTD, (FLTXT("Already in Inactive mode!!!\r\n")));
}
else if(WM == DOCH_PM_WORK_MODE)
{
if(activeMode != WM)
{
if(getWorkMode() == DOCH_WM_NORMAL)
DBG_PRINT_FLOW_PRM(FLZONE_MTD, (FLTXT("Normal Mode Entered!!!\r\n")));
if(getWorkMode() == DOCH_WM_LOW_FREQ)
DBG_PRINT_FLOW_PRM(FLZONE_MTD, (FLTXT("Low Freq Mode Entered!!!\r\n")));
if(getWorkMode() == DOCH_WM_NORMAL_AND_AUTO_STBY)
DBG_PRINT_FLOW_PRM(FLZONE_MTD, (FLTXT("Normal + Auto STBY Mode Entered!!!\r\n")));
if(getWorkMode() == DOCH_WM_LOW_FREQ_AND_AUTO_STBY)
DBG_PRINT_FLOW_PRM(FLZONE_MTD, (FLTXT("Low Freq + Auto STBY Mode Entered!!!\r\n")));
}
else
DBG_PRINT_FLOW_PRM(FLZONE_MTD, (FLTXT("Already in Work mode!!!\r\n")));
}
activeMode = WM;
}
FLByte getActiveMode() {return activeMode;}
void setWorkMode(FLByte WM) {workMode = WM;}
FLByte getWorkMode() {return workMode;}
void setInactiveMode(FLByte WM) {inactiveMode = WM;}
FLByte getInactiveMode() {return inactiveMode;}
void setTimeOutForIdle(FLWord TO){inactiveModeTO = TO;}
FLWord getTimeOutForIdle() {return inactiveModeTO;}
/*Routines that perform various operations AFTER receiving data*/
/*=============================================================*/
static FLSNative authenticatePartition(DOCH_SimSocket* simSocket);
static FLSNative setOtpBit(DOCH_SimSocket* simSocket);
static FLSNative setPartitionProperties(DOCH_SimSocket* simSocket);
static FLSNative setPartitionUserAttr(DOCH_SimSocket* simSocket);
static FLSNative setDiskUserAttr(DOCH_SimSocket* simSocket);
static FLSNative stickyLockAction(DOCH_SimSocket* simSocket);
static FLSNative simDPDMode(DOCH_SimSocket* simSocket, FLBoolean enter);
static FLSNative unAuthenticatePartitions(DOCH_SimDevice* simDev);
static FLSNative addPartition(DOCH_SimSocket* simSocket);
static FLSNative secureErase(DOCH_SimSocket* simSocket);
static FLSNative setMicrocode(DOCH_SimSocket* simSocket);
/*Routine Implementations*/
/*=======================*/
#ifndef DOCH_RAM_SIMULATION
/*********************************************************/
/* Function name : SimRegDeviceFromFile*/
/* Description : register device from given file */
/* Return type : DOCH_Error */
/* Argument : FLByte * bSimFileName - file name */
/*********************************************************/
DOCH_Error SimRegDeviceFromFile(FLSByte * bSimFileName, FLDword dwMasterSizeInSectors, FLDword dwSlaveSizeInSectors )
{
DOCH_Error status = DOCH_AdapterNotFound;
DOCH_SimSocket* pSimSock = getSimSocket();
DOCH_SimDevice* pSim = &(pSimSock->device[0]);
#ifndef DOCH_MEMMAP_FILE
size_t szReadLen; /* TODO - how to simulate big devices without long long??*/
#endif /*DOCH_MEMMAP_FILE*/
FLByte bDev;
FLByte tempBuf[sizeof(SIMULTOR_IDENTIFY_STRING)];
FILE* curFile;
FLBoolean fileExists = FALSE;
FLByte tempDevSelect;
FLWord masterUnitSizeInSectors = (FLWord)(dwMasterSizeInSectors / 512);
FLWord slaveUnitSizeInSectors = (FLWord)(dwSlaveSizeInSectors / 512);
FLDword erasableUnitsTemp;
/*Set default unit size to 256KB if not specified*/
if(masterUnitSizeInSectors == 0)
masterUnitSizeInSectors = 512;
if(slaveUnitSizeInSectors == 0)
slaveUnitSizeInSectors = 512;
if( ((dwMasterSizeInSectors==0) && (dwSlaveSizeInSectors!=0)) || /* master device size not specified, bur slave size specified */
(bSimFileName == NULL) )/* file name not set */
return DOCH_BadParameter;
/*Some arithmetics needed for seeking into simulation file*/
gSimDeviceSizeOnFile = (
sizeof(pSimSock->device[0].dwDevSizeInSectors) +
sizeof(pSimSock->device[0].dwTotalDevSizeInSectors) +
sizeof(pSimSock->device[0].wIPLMode) +
sizeof(pSimSock->device[0].dwEtffsSize) +
sizeof(pSimSock->device[0].bEtffsCode) +
sizeof(pSimSock->device[0].driveParameters) +
sizeof(DOCH_DeviceInfo) +
sizeof(pSimSock->device[0].partitions) +
sizeof(pSimSock->device[0].diskAttributes));
/* Check if file already exists and has the same size */
curFile = fopen( (char*) bSimFileName, "r+b");
if(curFile != NULL)
{
fclose(curFile);
fileExists = TRUE;
}
/* new device should be used */
/*if( dwMasterSizeInSectors != 0 )*/
if(!fileExists)
{
createNewSimFile:
pSimSock->pSimFile = fopen( (char*) bSimFileName, "wbc");
if( pSimSock->pSimFile==NULL )
return DOCH_AdapterNotFound;
/* init all structures */
erasableUnitsTemp = (dwMasterSizeInSectors / masterUnitSizeInSectors);
erasableUnitsTemp = (FLDword)(erasableUnitsTemp * DOCH_SIM_CAPACITY_PERCENTAGE);
pSim->dwDevSizeInSectors = (FLDword)(erasableUnitsTemp * masterUnitSizeInSectors);
pSim->dwDevSizeInSectors += masterUnitSizeInSectors; //IPL
pSim->dwTotalDevSizeInSectors=dwMasterSizeInSectors;
initSimRegisters();
initDriveParameters( (FLByte)((dwSlaveSizeInSectors!=0) ? ATA_MAX_NUM_OF_DEVICES:1));
diskOnChipDeviceInfo[0].dwReservedConfigPartitionSize = 4;
if( dwSlaveSizeInSectors!=0 )
{
pSimSock->bSlavePresent = TRUE;
erasableUnitsTemp = (dwSlaveSizeInSectors / slaveUnitSizeInSectors);
erasableUnitsTemp = (FLDword)(erasableUnitsTemp * DOCH_SIM_CAPACITY_PERCENTAGE);
(pSim+1)->dwDevSizeInSectors = (FLDword)(erasableUnitsTemp * slaveUnitSizeInSectors);
(pSim+1)->dwDevSizeInSectors += slaveUnitSizeInSectors; //IPL
(pSim+1)->dwTotalDevSizeInSectors=dwSlaveSizeInSectors;
diskOnChipDeviceInfo[1].dwReservedConfigPartitionSize = 4;
}
else
{
pSimSock->bSlavePresent = FALSE;
}
initVarious(TRUE);
/* save to file */
#ifdef DOCH_MEMMAP_FILE
{
FLWord rc = 0;
FLWord writeLen = 0;
FLWord i = 0;
FLDword j = 0;
FLDword offset = 0;
FLByte numOfDevices = ((dwSlaveSizeInSectors != 0) + 1);
FLByte dummy = 0;
for(i=0; i<numOfDevices; i++)
{
/*Set offset to Dev0 */
offset = (sizeof(SIMULTOR_IDENTIFY_STRING) +
sizeof(simSocket.bSlavePresent)+
sizeof(simSocket.config_regs));
/* Skip dev0 */
if(i > 0)
offset += gDev0SimDeviceSizeOnFile;
/* Set offset to storage */
offset += (sizeof(simSocket.device[i].dwDevSizeInSectors) +
sizeof(simSocket.device[i].dwTotalDevSizeInSectors) +
sizeof(simSocket.device[i].wIPLMode) +
sizeof(simSocket.device[i].dwXIPMaxSize) +
sizeof(simSocket.device[i].dwEtffsSize) +
sizeof(simSocket.device[i].bEtffsCode) +
sizeof(simSocket.device[i].driveParameters) +
sizeof(DOCH_DeviceInfo) +
sizeof(simSocket.device[i].partitions) +
sizeof(simSocket.device[i].diskAttributes));
/* Seek to the requested offset */
rc = fseek( simSocket.pSimFile, offset, SEEK_SET);
if(rc != 0)
return DOCH_GeneralFailure;
for(j=0; j<(simSocket.device[i].dwDevSizeInSectors<<DOCH_SECTOR_SIZE_BITS); j++)
{
/* Fill storage with "0" */
writeLen = fwrite( (void*)&(dummy), 1,
1, pSimSock->pSimFile );
if( writeLen != 1 )
return DOCH_GeneralFailure;
}
if(i==0)
gDev0SimDeviceSizeOnFile = (gSimDeviceSizeOnFile + (pSim[0].dwDevSizeInSectors << DOCH_SECTOR_SIZE_BITS));
else
gDev1SimDeviceSizeOnFile = (gSimDeviceSizeOnFile + (pSim[1].dwDevSizeInSectors << DOCH_SECTOR_SIZE_BITS));
status = DOCH_OK;
}
}
#else /*DOCH_MEMMAP_FILE*/
/* allocate storage buffer */
pSim[0].bStorage = (FLByte*)DOCH_MALLOC(pSim[0].dwDevSizeInSectors<<DOCH_SECTOR_SIZE_BITS);
if( pSim[0].bStorage == NULL )
{
status = DOCH_NotEnoughMemory;
}
else /* allocation OK */
{
tffsset( pSim[0].bStorage, 0, pSim[0].dwDevSizeInSectors<<DOCH_SECTOR_SIZE_BITS );
if( pSimSock->bSlavePresent == TRUE )
{
pSim[1].bStorage = (FLByte*)DOCH_MALLOC(pSim[1].dwDevSizeInSectors<<DOCH_SECTOR_SIZE_BITS);
if( pSim[1].bStorage == NULL )
{
status = DOCH_NotEnoughMemory;
}
else
{
tffsset( pSim[1].bStorage, 0, pSim[1].dwDevSizeInSectors<<DOCH_SECTOR_SIZE_BITS );
status = DOCH_OK;
}
}
else
{
status = DOCH_OK;
}
}
#endif /*DOCH_MEMMAP_FILE*/
#ifdef DOCH_MEMMAP_FILE
{
FLWord rc = 0;
FLByte i = 0;
/* Seek to the beginning of the simulation file */
rc = fseek( simSocket.pSimFile, 0, SEEK_SET);
if(rc != 0)
return DOCH_GeneralFailure;
tffscpy(tempBuf,SIMULTOR_IDENTIFY_STRING,sizeof(SIMULTOR_IDENTIFY_STRING));
simFileIO(pSimSock, SIM_ITEM_ID_STRING, 0, FALSE, (void*)tempBuf);
simFileIO(pSimSock, SIM_ITEM_SLAVE_PRESENT, 0, FALSE, (void*)&(pSimSock->bSlavePresent));
simFileIO(pSimSock, SIM_ITEM_CONFIG_REGS, 0, FALSE, (void*)&(pSimSock->config_regs));
for(i=0;i<(pSimSock->bSlavePresent + 1); i++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -