📄 cf_util.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
/** @file cf_util.c
* @Compact flash utility routines used by interface module
*
* Copyright (c) Marvell Semiconductor, Inc.
*/
#include "precomp.h"
#ifdef MRV_USE_HELPER_IMAGE
#include "helper.h"
#endif
#ifdef MRV_CHIP_8385H
#include "cf8385h.h" // CF8385H
#elif defined(MRV_CHIP_8385PN)
#include "cf8385.h" // CF8385PN
#elif defined(MRV_CHIP_8381PN)
#include "cf8381.h" // CF8381PN
#elif defined(MRV_CHIP_8381P)
#include "cf8381.h" // CF8381P
#elif defined(MRV_CHIP_8380)
#include "cf8380.h" // CF8380
#else
#include "cf25.h" // CF8305
#endif
#define FWDELAY 500000 // cycles should give us about 10 seconds
#define FWBLOCK_DELAY 500000 // cycles for fw block delay. org=500
//************************************************************************************
//* Function: printReg16
//* Description: Debug utility program to print out msg and 8 bit MrvDrv reg.
//* Returns void
//* Date: 04/22/2003
//************************************************************************************
void printReg8( char *msg, ULONG port)
{
UCHAR ucTemp;
NdisRawReadPortUchar(port, &ucTemp);
DBGPRINT(DBG_REGS,("%s %x\n", msg, (ULONG)ucTemp ));
}
//************************************************************************************
//* Function: printReg16
//* Description: Debug utility program to print out msg and 16 bit MrvDrv reg.
//* Returns void
//* Date: 04/22/2003
//************************************************************************************
void printReg16( char *msg, ULONG port)
{
USHORT usTemp;
NdisRawReadPortUchar( port, &usTemp);
DBGPRINT(DBG_REGS,("%s %x\n", msg, (ULONG)usTemp ));
}
//************************************************************************************
//* Function: DumpMrvDrvRegs
//* Description: Routine to dump all MrvDrvs CF regs
//* Since Marvell pretty much refuses to give any support or information
//* about their bootloader it was necessary to reverse engineer the
//* darn thing.
//* Returns void
//* Date: 04/22/2003
//************************************************************************************
#if DBG
void DumpMrvDrvRegs( PCF_OBJECT pCf, char *msg )
{
// USHORT usTemp;
DBGPRINT(DBG_REGS,("MRVDRV REG DUMP: %s\n", msg ));
DBGPRINT(DBG_REGS,("HOST CONTROL REGISTER DUMP\n"));
printReg16("CFMACREG_HCR_HOST_STATUS ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_HCR_HOST_STATUS);
printReg16("CFMACREG_HCR_CARD_INT_CAUSE ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_HCR_HOST_STATUS);
printReg16("CFMACREG_HCR_HOST_INT_MASK ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_HCR_HOST_INT_MASK);
// printReg16("CFMACREG_HCR_READ_BASE_LOW ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_HCR_READ_BASE_LOW);
// printReg16("CFMACREG_HCR_READ_BASE_HIGH ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_HCR_READ_BASE_HIGH);
// printReg16("CFMACREG_HCR_WRITE_BASE_LOW ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_HCR_WRITE_BASE_LOW);
// printReg16("CFMACREG_HCR_WRITE_BASE_HIGH ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_HCR_WRITE_BASE_HIGH);
// printReg16("CFMACREG_HCR_IO_READ_PORT ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_HCR_IO_READ_PORT);
// printReg16("CFMACREG_HCR_IO_CMD_READ_PORT ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_HCR_IO_CMD_READ_PORT);
printReg16("CFMACREG_HCR_IO_WRITE_LEN ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_HCR_IO_WRITE_LEN);
// printReg16("CFMACREG_HCR_IO_WRITE_PORT ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_HCR_IO_WRITE_PORT);
printReg16("CFMACREG_HCR_IO_CMD_WRITE_LEN ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_HCR_IO_CMD_WRITE_LEN);
// printReg16("CFMACREG_HCR_IO_CMD_WRITE_PORT ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_HCR_IO_CMD_WRITE_PORT);
printReg8("CFMACREG_HCR_SCRATCH_PORT ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_HCR_SCRATCH_PORT);
// printReg16("CFMACREG_HCR_CIS_ADDR_PORT ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_HCR_CIS_ADDR_PORT);
// printReg16("CFMACREG_HCR_CIS_DATA_PORT ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_HCR_CIS_DATA_PORT);
// printReg16("CFMACREG_HCR_IO_GBUS_REG_READ ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_HCR_IO_GBUS_REG_READ);
// printReg16("CFMACREG_HCR_IO_GBUS_REG_WRITE ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_HCR_IO_GBUS_REG_WRITE);
DBGPRINT(DBG_REGS,("CARD CONTROL REGISTER DUMP\n"));
printReg16("CFMACREG_CCR_PRODUCT_ID ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_CCR_PRODUCT_ID);
printReg16("CFMACREG_CCR_CARD_STATUS ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_CCR_CARD_STATUS);
printReg8 ("CFMACREG_CCR_HOST_INT_CAUSE ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_CCR_HOST_INT_CAUSE);
printReg16("CFMACREG_CCR_IO_READ_LEN ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_CCR_IO_READ_LEN);
// printReg16("CFMACREG_CCR_SQ_READ_BASE_LOW ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_CCR_SQ_READ_BASE_LOW);
// printReg16("CFMACREG_CCR_SQ_READ_BASE_HIGH ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_CCR_SQ_READ_BASE_HIGH);
// printReg16("CFMACREG_CCR_SQ_WRITE_BASE_LOW ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_CCR_SQ_WRITE_BASE_LOW);
// printReg16("CFMACREG_CCR_SQ_WRITE_BASE_HIGH ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_CCR_SQ_WRITE_BASE_HIGH);
printReg16("CFMACREG_CCR_IO_CMD_READ_LEN ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_CCR_SQ_WRITE_BASE_HIGH);
// printReg16("CFMACREG_CCR_SQ_CMD_READ_BASE_LOW ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_CCR_SQ_CMD_READ_BASE_LOW);
// printReg16("CFMACREG_CCR_SQ_CMD_READ_BASE_HIGH ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_CCR_SQ_CMD_READ_BASE_HIGH);
// printReg16("CFMACREG_CCR_SQ_CMD_WRITE_BASE_LOW ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_CCR_SQ_CMD_WRITE_BASE_LOW);
// printReg16("CFMACREG_CCR_SQ_CMD_WRITE_BASE_HIGH",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_CCR_SQ_CMD_WRITE_BASE_HIGH);
printReg8 ("CFMACREG_CCR_CARD_CFG ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_CCR_CARD_CFG);
printReg8 ("CFMACREG_CCR_SCRATCH_PORT ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_CCR_SCRATCH_PORT);
printReg16("CFMACREG_CCR_TX_FRAME_SEQ_NUM ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_CCR_TX_FRAME_SEQ_NUM);
printReg8 ("CFMACREG_CCR_TX_FRAME_STATUS ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_CCR_TX_FRAME_STATUS);
printReg8 ("CFMACREG_CCR_CARD_INT_MASK ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_CCR_CARD_INT_MASK);
// printReg8 ("CFMACREG_CCR_CIS_ADR_PORT ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_CCR_CIS_ADR_PORT);
// printReg16("CFMACREG_CCR_CIS_DATA_PORT ",pCf -> ulMrvDrvVirtualIoBase+CFMACREG_CCR_CIS_DATA_PORT);
}
#endif
//************************************************************************************
//* Function: cf_InitInterface
//* Description: Initializes the compact flash interface data and hardware..
//* Returns IX_STATUS_SUCCESS if OK, IX_STATUS_FAILURE if any problems.
//* Date: 04/08/2003
//************************************************************************************
IX_STATUS cf_InitInterface( PCF_OBJECT pCf)
{
IX_STATUS stat;
pCf -> cfHostIntMask = 0x1f; // Initialize the host interrupt mask.
stat = cf_DisableHostInterrupts( pCf, CFMACREG_HCR_HIM_MASK); // Disable all interrupts.
return stat;
}
//************************************************************************************
//* Function: cf_EnableInterrupts
//* Description: Enables interrupts on the compact flash interface.
//* Returns IX_STATUS_SUCCESS if all OK. IX_STATUS_FAILURE if any problems.
//* Date: 04/07/2003
//************************************************************************************
IX_STATUS cf_EnableHostInterrupts( PCF_OBJECT pCf, USHORT mask )
{
mask &= CFMACREG_HCR_HIM_MASK; // Get rid of any unknown bits.
#if DBG
DBGPRINT(DBG_ISR,("Enabling HOST interrupts mask %x\n",mask));
if ( mask & CFMACREG_HCR_HIM_TxDnLdRdy )
DBGPRINT(DBG_ISR,("Enabling CFMACREG_HCR_HIM_TxDnLdRdy \n"));
if ( mask & CFMACREG_HCR_HIM_RxUpLdRdy )
DBGPRINT(DBG_ISR,("Enabling CFMACREG_HCR_HIM_RxUpLdRdy \n"));
if ( mask & CFMACREG_HCR_HIM_CmdDnLdRdy )
DBGPRINT(DBG_ISR,("Enabling CFMACREG_HCR_HIM_CmdDnLdRdy \n"));
if ( mask & CFMACREG_HCR_HIM_CmdRspRdy )
DBGPRINT(DBG_ISR,("Enabling CFMACREG_HCR_HIM_CmdRspRdy \n"));
if ( mask & CFMACREG_HCR_HIM_CardEvent )
DBGPRINT(DBG_ISR,("Enabling CFMACREG_HCR_HIM_CardEvent \n"));
#endif
pCf -> cfHostIntMask = mask; // remember what's enabled.
NdisRawWritePortUshort(
pCf -> ulMrvDrvVirtualIoBase + CFMACREG_HCR_HOST_INT_MASK, mask);
return IX_STATUS_SUCCESS;
}
//************************************************************************************
//* Function: cf_DisableHostInterrupts
//* Description: Disables host interrupts on the compact flash interface by mask
// pass in mask with bits set for the interrupts to be disabled.
//* Returns IX_STATUS_SUCCESS if all OK. IX_STATUS_FAILURE if any problems.
//* NOTE: Please notice that the paramter is the mask of interrupts to disable.
//* Routine will only disable the interrupts specified in the mask
//* Date: 04/07/2003
//************************************************************************************
IX_STATUS cf_DisableHostInterrupts( PCF_OBJECT pCf, USHORT mask )
{
mask &= CFMACREG_HCR_HIM_MASK; // Get rid of any unknown bits.
#if DBG
DBGPRINT(DBG_ISR,("Disabling HOST interrupts mask %x\n",mask));
if ( mask & CFMACREG_HCR_HIM_TxDnLdRdy )
DBGPRINT(DBG_ISR,("Disabling CFMACREG_HCR_HIM_TxDnLdRdy \n"));
if ( mask & CFMACREG_HCR_HIM_RxUpLdRdy )
DBGPRINT(DBG_ISR,("Disabling CFMACREG_HCR_HIM_RxUpLdRdy \n"));
if ( mask & CFMACREG_HCR_HIM_CmdDnLdRdy )
DBGPRINT(DBG_ISR,("Disabling CFMACREG_HCR_HIM_CmdDnLdRdy \n"));
if ( mask & CFMACREG_HCR_HIM_CmdRspRdy )
DBGPRINT(DBG_ISR,("Disabling CFMACREG_HCR_HIM_CmdRspRdy \n"));
if ( mask & CFMACREG_HCR_HIM_CardEvent )
DBGPRINT(DBG_ISR,("Disabling CFMACREG_HCR_HIM_CardEvent \n"));
#endif
//pCf -> cfHostIntMask &= ~mask; // Track what we disabled..
NdisRawWritePortUshort(
pCf->ulMrvDrvVirtualIoBase + CFMACREG_HCR_HOST_INT_MASK, pCf->cfHostIntMask );
return IX_STATUS_SUCCESS;
}
//************************************************************************************
//* Function: cf_FirmwareDownload
//* Description: Downloads firmware image to device over compact flash interface.
//* Returns IX_STATUS_SUCCESS if all OK. IX_STATUS_FAILURE if any problems.
//* NOTE: Please notice that the paramter is the mask of interrupts to disable.
//* Routine will only disable the interrupts specified in the mask
//* Date: 04/07/2003
//************************************************************************************
IX_STATUS
cf_FirmwareDownload(
PCF_OBJECT pCf,
IN PMRVDRV_ADAPTER Adapter
)
{
UINT blockCount = 0;
UINT sizeOfFirmware;
UINT sizeSend = 0;
UINT sizeBlockInUshort;
UINT cmdIOaddr;
USHORT i, sizeBlock, *pusPtr;
// USHORT usTempUshort;
UCHAR ucTempUchar;
ULONG firmwareDelay = 0;
PHostCmd_DS_GEN ptrHead;
// ULONG intCode;
CmdCtrlNode *pourNode;
DBGPRINT(DBG_FWDL,("INIT - Firmware download start\n"));
sizeOfFirmware = sizeof(fmimage);
pourNode = GetFreeCmdCtrlNode(Adapter); // We need only one
ptrHead = (PHostCmd_DS_GEN) pourNode->BufVirtualAddr;
//
// 05/01/03 - New FW download code - GLA
//
cmdIOaddr = pCf->ulMrvDrvVirtualIoBase + CFMACREG_HCR_IO_CMD_WRITE_PORT; // output address
while (sizeSend < sizeOfFirmware)
{
blockCount++;
sizeBlock = 256;
// Move the data from firmware buf to the command header
NdisMoveMemory(ptrHead, &fmimage[sizeSend], sizeBlock);
// Get number of ushorts
sizeBlockInUshort = (sizeBlock + 1) / 2;
pusPtr = (PUSHORT)(ptrHead);
// Write number of bytes to be sent
NdisRawWritePortUshort(
pCf -> ulMrvDrvVirtualIoBase + CFMACREG_HCR_IO_CMD_WRITE_LEN,
sizeBlockInUshort*2);
for(i=0; i<sizeBlockInUshort; i++ )
{
NdisRawWritePortUshort(cmdIOaddr,*pusPtr);
pusPtr++;
#ifdef FLUSH_FIFOS
// PDM: After writing every 16th word, flush the fifos.
// we don't want to do it when i=0, but when i=15
if ( ((i+1)&0x000f) == 0 )
{
DBGPRINT(DBG_FWDL,("Flushing FIFOs\n"));
NdisRawWritePortUshort(
pCf->ulMrvDrvVirtualIoBase + CFMACREG_HCR_HOST_STATUS,
CFMACREG_HCR_HS_FlushDataFifo);
}
#endif // end of FLUSH_FIFOS
}
//#endif // end of _X86
// PDM: When we're done, flush the FIFOs.
DBGPRINT(DBG_FWDL,("Flushing FIFOs\n"));
NdisRawWritePortUshort(
pCf->ulMrvDrvVirtualIoBase + CFMACREG_HCR_HOST_STATUS,
CFMACREG_HCR_HS_FlushDataFifo);
DBGPRINT(DBG_FWDL,("Downloaded Block %d of Firmware\n", blockCount));
#ifdef POCKETPC_FIX
// Set scratch register to 0x55 (firmware block ready)
NdisRawWritePortUshort(
pCf -> ulMrvDrvVirtualIoBase + CFMACREG_CCR_SCRATCH_PORT-1,
0x5555);
#else
// Set scratch register to 0x55 (firmware block ready)
NdisRawWritePortUchar(
pCf -> ulMrvDrvVirtualIoBase + CFMACREG_CCR_SCRATCH_PORT,
0x55);
#endif //POCKETPC_FIX
// This is a workaround for CE - They byte writes do not work.
// so we back up a reg to the scratch register as a word.
// This is ported directly from code sent by Marvell
// - recommend changing this to r/w/modify to preserve the contents of 0x3e
#ifdef UNDER_CE
// Set scratch register to 0x55 (firmware block ready)
NdisRawWritePortUshort(
pCf -> ulMrvDrvVirtualIoBase + 0x3E,
0x5555);
#endif
// Assert the Command Download Over interrupt
NdisRawWritePortUchar(
pCf->ulMrvDrvVirtualIoBase + CFMACREG_HCR_HOST_STATUS,
CFMACREG_HCR_HS_CmdDnLdOvr);
NdisRawWritePortUshort(
pCf->ulMrvDrvVirtualIoBase + CFMACREG_HCR_CARD_INT_CAUSE,
CFMACREG_HCR_CIC_CmdDnLdOvr);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -