cfw.c
来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 1,178 行 · 第 1/3 页
C
1,178 行
void OEMInterruptDisable(
DWORD idInt // @parm Interrupt ID to be disabled. See <t Interrupt ID's>
// for the list of possible values.
)
{
DEBUGMSG(1,(TEXT("+OEMInterruptDisable(idInt=%d)\r\n"), idInt));
INTERRUPTS_OFF();
switch (idInt) {
case SYSINTR_BREAK:
break;
case SYSINTR_KEYBOARD:
WRITE_REGISTER_USHORT( CC_INTC_NIMR, READ_REGISTER_USHORT(CC_INTC_NIMR) | CC_INTC_NIMR_PS2KBM_MASK );
break;
case SYSINTR_SERIAL:
WRITE_REGISTER_USHORT( CC_UART_REGBASE + CC_UART_UMCR_OFFSET,
READ_REGISTER_USHORT(CC_UART_REGBASE + CC_UART_UMCR_OFFSET)&0xFFF7 );
WRITE_REGISTER_USHORT( CC_INTC_NIMR,READ_REGISTER_USHORT(CC_INTC_NIMR)|CC_INTC_NIMR_UART0M_MASK );
break;
case SYSINTR_AUDIO:
break;
case SYSINTR_PCMCIA_STATE:
PCMCIA_int_users --;
if (!PCMCIA_int_users)
{
WRITE_REGISTER_USHORT(CC_INTC_REGBASE+CC_INTC_NIMR_OFFSET,
(READ_REGISTER_USHORT(CC_INTC_REGBASE+CC_INTC_NIMR_OFFSET) |
CC_INTC_NIMR_PCC0M_MASK));
WRITE_REGISTER_USHORT(CC_INTC_REGBASE+CC_INTC_NIMR_OFFSET,
(READ_REGISTER_USHORT(CC_INTC_REGBASE+CC_INTC_NIMR_OFFSET) |
CC_INTC_NIMR_PCC1M_MASK));
}
break;
case SYSINTR_PCMCIA_LEVEL:
PCMCIA_int_users --;
if (!PCMCIA_int_users)
{
WRITE_REGISTER_USHORT(CC_INTC_REGBASE+CC_INTC_NIMR_OFFSET,
(READ_REGISTER_USHORT(CC_INTC_REGBASE+CC_INTC_NIMR_OFFSET) |
CC_INTC_NIMR_PCC0M_MASK));
WRITE_REGISTER_USHORT(CC_INTC_REGBASE+CC_INTC_NIMR_OFFSET,
(READ_REGISTER_USHORT(CC_INTC_REGBASE+CC_INTC_NIMR_OFFSET) |
CC_INTC_NIMR_PCC1M_MASK));
}
break;
case SYSINTR_RTC_ALARM:
break;
case SYSINTR_TIMING:
break;
case SYSINTR_IR:
/* disable the HD64465 IRDA interrupt */
/* all other setup of the 16550 is done in the IST */
WRITE_REGISTER_USHORT( CC_INTC_NIMR,
READ_REGISTER_USHORT(CC_INTC_NIMR)|CC_INTC_NIMR_IRDAM_MASK );
break;
case SYSINTR_USB:
WRITE_REGISTER_USHORT( CC_INTC_NIMR,
READ_REGISTER_USHORT(CC_INTC_NIMR)|CC_INTC_NIMR_USBM_MASK );
break;
case SYSINTR_MOUSE:
WRITE_REGISTER_USHORT( CC_INTC_NIMR, READ_REGISTER_USHORT(CC_INTC_NIMR) | CC_INTC_NIMR_PS2MSM_MASK );
break;
case SYSINTR_PARALLEL:
DEBUGMSG(1, (TEXT("IDIS: PARALLEL: Previous IMASK = 0x%x\r\n"), READ_REGISTER_USHORT(CC_INTC_NIMR)));
WRITE_REGISTER_USHORT( CC_INTC_NIMR,
READ_REGISTER_USHORT(CC_INTC_NIMR)|CC_INTC_NIMR_PPM_MASK );
DEBUGMSG(1, (TEXT("IDIS: PARALLEL: New IMASK = 0x%x\r\n"), READ_REGISTER_USHORT(CC_INTC_NIMR)));
break;
case SYSINTR_ETHER:
#if (SH_PLATFORM==PLATFORM_ASPEN)
DEBUGMSG(1, (TEXT("IDIS: Previous IMASK = 0x%x\r\n"), READ_REGISTER_ULONG(FPGA_IMASK)));
WRITE_REGISTER_ULONG(FPGA_IMASK, (READ_REGISTER_ULONG(FPGA_IMASK) & ~FPGA_IMASK_ILAN) );
DEBUGMSG(1, (TEXT("IDIS: New IMASK = 0x%x\r\n"), READ_REGISTER_ULONG(FPGA_IMASK)));
#elif (SH_PLATFORM==PLATFORM_BIGSUR)
DEBUGMSG(1, (TEXT("IE 3: Previous IMASK = 0x%x\r\n"), READ_REGISTER_UCHAR(INT_IMASK3)));
WRITE_REGISTER_UCHAR(INT_IMASK3, (READ_REGISTER_UCHAR(INT_IMASK3 ) | FPGA_IMASK_ENETINT) );
DEBUGMSG(1, (TEXT("IE 3: New IMASK = 0x%x\r\n"), READ_REGISTER_UCHAR(INT_IMASK3 )));
#endif (SH_PLATFORM==PLATFORM_ASPEN)
break;
case SYSINTR_IDE:
#if (SH_PLATFORM==PLATFORM_ASPEN)
DEBUGMSG(1, (TEXT("IDIS: Previous IMASK = 0x%x\r\n"), READ_REGISTER_ULONG(FPGA_IMASK)));
WRITE_REGISTER_ULONG(FPGA_IMASK, (READ_REGISTER_ULONG(FPGA_IMASK) & ~FPGA_IMASK_IIDE) );
DEBUGMSG(1, (TEXT("IDIS: New IMASK = 0x%x\r\n"), READ_REGISTER_ULONG(FPGA_IMASK)));
#elif (SH_PLATFORM==PLATFORM_BIGSUR)
DEBUGMSG(1, (TEXT("IE 3: Previous IMASK = 0x%x\r\n"), READ_REGISTER_UCHAR(INT_IMASK1)));
WRITE_REGISTER_UCHAR(INT_IMASK1, (READ_REGISTER_UCHAR(INT_IMASK1 ) | FPGA_IMASK_IDE_INT) );
DEBUGMSG(1, (TEXT("IE 3: New IMASK = 0x%x\r\n"), READ_REGISTER_UCHAR(INT_IMASK1 )));
#endif (SH_PLATFORM==PLATFORM_ASPEN)
break;
}
INTERRUPTS_ON();
}
/*
@func BOOL | OEMInterruptDone | Signal completion of interrupt processing
@rdesc none
@comm OEMInterruptDone is called by the Kernel when a device driver
calls <f InterruptDone>. The system is not preemtible when this
function is called.
@xref <l Overview.Kernel Interrupt Support> <f InterruptDone>
*/
void OEMInterruptDone(
DWORD idInt // @parm Interrupt ID. See <t Interrupt ID's>
// for the list of possible values.
)
{
USHORT IntsToClear = 0;
PDRIVER_GLOBALS pDriverGlobals = (PDRIVER_GLOBALS)DRIVER_GLOBALS_PHYSICAL_MEMORY_START;
#ifdef DEBUG_CFW
DEBUGMSG(1,(TEXT("+OEMInterruptDone(idInt=%d)\r\n"), idInt));
#endif DEBUG_CFW
INTERRUPTS_OFF();
switch (idInt) {
case SYSINTR_BREAK:
break;
case SYSINTR_KEYBOARD:
WRITE_REGISTER_USHORT( CC_INTC_NIMR, READ_REGISTER_USHORT(CC_INTC_NIMR)&CC_INTC_NIMR_PS2KBM_UNMASK );
break;
case SYSINTR_SERIAL:
/* enable the HD64465 UART interrupt */
/* all other setup of the 16550 is done in the IST */
WRITE_REGISTER_USHORT( CC_INTC_NIMR,READ_REGISTER_USHORT(CC_INTC_NIMR)&CC_INTC_NIMR_UART0M_UNMASK );
WRITE_REGISTER_USHORT( CC_UART_REGBASE + CC_UART_UMCR_OFFSET,
READ_REGISTER_USHORT(CC_UART_REGBASE + CC_UART_UMCR_OFFSET)|0x0008 );
break;
case SYSINTR_AUDIO:
break;
case SYSINTR_PCMCIA_STATE:
IntsToClear = pDriverGlobals->pcm.slot0Enable;
IntsToClear &= ~CC_PCMCIA_CSCR_TPS2206_SEL; // Select TPS2206
WRITE_REGISTER_USHORT((CC_PCMCIA_REGBASE + CC_PCMCIA_PCC0CSCR_OFFSET),
(READ_REGISTER_USHORT((CC_PCMCIA_REGBASE + CC_PCMCIA_PCC0CSCR_OFFSET)) &
~IntsToClear));
IntsToClear = pDriverGlobals->pcm.slot1Enable;
WRITE_REGISTER_USHORT((CC_PCMCIA_REGBASE + CC_PCMCIA_PCC1CSCR_OFFSET),
((READ_REGISTER_USHORT((CC_PCMCIA_REGBASE + CC_PCMCIA_PCC1CSCR_OFFSET)) &
~IntsToClear)));
/* if there are users, then we must re-enable the ints */
if (PCMCIA_int_users)
{
WRITE_REGISTER_USHORT((CC_INTC_REGBASE+CC_INTC_NIMR_OFFSET),
READ_REGISTER_USHORT(CC_INTC_REGBASE+CC_INTC_NIMR_OFFSET) &
~CC_INTC_NIMR_PCC0M_MASK);
WRITE_REGISTER_USHORT((CC_INTC_REGBASE+CC_INTC_NIMR_OFFSET),
READ_REGISTER_USHORT(CC_INTC_REGBASE+CC_INTC_NIMR_OFFSET) &
~CC_INTC_NIMR_PCC1M_MASK);
}
break;
case SYSINTR_PCMCIA_LEVEL:
IntsToClear = pDriverGlobals->pcm.slot0Enable;
IntsToClear &= (CC_PCMCIA_CSCR_IREQ_INT_REQ);
WRITE_REGISTER_USHORT((CC_PCMCIA_REGBASE + CC_PCMCIA_PCC0CSCR_OFFSET),
(READ_REGISTER_USHORT((CC_PCMCIA_REGBASE + CC_PCMCIA_PCC0CSCR_OFFSET)) &
~IntsToClear));
IntsToClear = pDriverGlobals->pcm.slot1Enable;
IntsToClear &= (CC_PCMCIA_CSCR_IREQ_INT_REQ);
WRITE_REGISTER_USHORT((CC_PCMCIA_REGBASE + CC_PCMCIA_PCC1CSCR_OFFSET),
(READ_REGISTER_USHORT((CC_PCMCIA_REGBASE + CC_PCMCIA_PCC1CSCR_OFFSET)) &
~IntsToClear));
/* if there are users, then we must re-enable the ints */
if (PCMCIA_int_users)
{
WRITE_REGISTER_USHORT(CC_INTC_REGBASE+CC_INTC_NIMR_OFFSET,
(READ_REGISTER_USHORT(CC_INTC_REGBASE+CC_INTC_NIMR_OFFSET) &
~CC_INTC_NIMR_PCC0M_MASK));
WRITE_REGISTER_USHORT(CC_INTC_REGBASE+CC_INTC_NIMR_OFFSET,
(READ_REGISTER_USHORT(CC_INTC_REGBASE+CC_INTC_NIMR_OFFSET) &
~CC_INTC_NIMR_PCC1M_MASK));
}
break;
// #endif ASPEN
case SYSINTR_RTC_ALARM:
break;
case SYSINTR_TIMING:
break;
case SYSINTR_IR:
/* enable the HD64465 IRDA interrupt */
/* all other setup of the 16550 is done in the IST */
WRITE_REGISTER_USHORT( CC_INTC_NIMR,
READ_REGISTER_USHORT(CC_INTC_NIMR)&CC_INTC_NIMR_IRDAM_UNMASK );
break;
case SYSINTR_USB:
WRITE_REGISTER_USHORT( CC_INTC_NIMR,
READ_REGISTER_USHORT(CC_INTC_NIMR)&CC_INTC_NIMR_USBM_UNMASK );
break;
case SYSINTR_MOUSE:
WRITE_REGISTER_USHORT( CC_INTC_NIMR, READ_REGISTER_USHORT(CC_INTC_NIMR)&CC_INTC_NIMR_PS2MSM_UNMASK );
break;
case SYSINTR_PARALLEL:
DEBUGMSG(1, (TEXT("IDON: PARALLEL: Previous IMASK = 0x%x\r\n"), READ_REGISTER_USHORT(CC_INTC_NIMR)));
WRITE_REGISTER_USHORT( CC_INTC_NIMR,
READ_REGISTER_USHORT(CC_INTC_NIMR)&CC_INTC_NIMR_PPM_UNMASK );
DEBUGMSG(1, (TEXT("IDON: PARALLEL: New IMASK = 0x%x\r\n"), READ_REGISTER_USHORT(CC_INTC_NIMR)));
case SYSINTR_ETHER:
#if (SH_PLATFORM==PLATFORM_ASPEN)
WRITE_REGISTER_ULONG(FPGA_IMASK, (READ_REGISTER_ULONG(FPGA_IMASK) | FPGA_IMASK_ILAN) );
#elif (SH_PLATFORM==PLATFORM_BIGSUR)
WRITE_REGISTER_UCHAR(INT_IMASK3, (READ_REGISTER_UCHAR(INT_IMASK3 ) & ~FPGA_IMASK_ENETINT) );
#endif (SH_PLATFORM==PLATFORM_ASPEN)
break;
case SYSINTR_IDE:
#if (SH_PLATFORM==PLATFORM_ASPEN)
WRITE_REGISTER_ULONG(FPGA_IMASK, (READ_REGISTER_ULONG(FPGA_IMASK) | FPGA_IMASK_IIDE) );
#elif (SH_PLATFORM==PLATFORM_BIGSUR)
WRITE_REGISTER_UCHAR(INT_IMASK1, (READ_REGISTER_UCHAR(INT_IMASK1 ) & ~FPGA_IMASK_IDE_INT) );
#endif (SH_PLATFORM==PLATFORM_ASPEN)
break;
}
INTERRUPTS_ON();
}
//------------------------------------------------------------------------------
//
// OEMQueryPerformanceCounter
//
// The OEMQueryPerformanceCounter function retrieves the current value of
// the high-resolution performance counter, if one exists.
//
// BOOL QueryPerformanceCounter(
//
// LARGE_INTEGER *lpliPerformanceCount // address of current counter value
// );
//
// Parameters
//
// lpliPerformanceCount
//
// Points to a variable that the function sets, in counts, to the current
// performance-counter value. If the installed hardware does not support
// a high-resolution performance counter, this parameter can be to zero.
//
// Return Value
//
// If the installed hardware supports a high-resolution performance
// counter, the return value is TRUE.
// If the installed hardware does not support a high-resolution
// performance counter, the return value is FALSE.
//
// If this function is implemented by the OEM, the pointer pQueryPerformanceCounter
// should be initialized as follows:
//
// BOOL (*pQueryPerformanceCounter)(LARGE_INTEGER *lpliPerformanceCount)=OEMQueryPerformanceCounter;
//
//------------------------------------------------------------------------------
BOOL
OEMQueryPerformanceCounter(
LARGE_INTEGER *lpliPerformanceCount
)
{
extern DWORD PerfCountSinceTick();
ULARGE_INTEGER liBase;
DWORD dwCurCount;
// Make sure CurTicks is the same before and after read of counter to account for
// possible rollover
do {
liBase = CurTicks;
dwCurCount = PerfCountSinceTick();
} while (liBase.LowPart != CurTicks.LowPart) ;
lpliPerformanceCount->QuadPart = liBase.QuadPart + dwCurCount;
return TRUE;
}
//------------------------------------------------------------------------------
//
// OEMQueryPerformanceFrequency
//
// The OEMQueryPerformanceFrequency function retrieves the frequency of
// the high-resolution performance counter, if one exists.
//
// BOOL OEMQueryPerformanceFrequency(
//
// LARGE_INTEGER *lpliPerformanceFreq // address of current frequency
// );
//
// Parameters
//
// lpliPerformanceFreq
//
// Points to a variable that the function sets, in counts per second, to
// the current performance-counter frequency. If the installed hardware
// does not support a high-resolution performance counter, this parameter
// can be to zero.
//
// Return Value
//
// If the installed hardware supports a high-resolution performance
// counter, the return value is TRUE.
// If the installed hardware does not support a high-resolution
// performance counter, the return value is FALSE.
//
// If this function is implemented by the OEM, the pointer pQueryPerformanceFrequency
// should be initialized as follows:
//
// BOOL (*pQueryPerformanceFrequency)(LARGE_INTEGER *lpPerformanceFrequency)=OEMQueryPerformanceFrequency;
//
//------------------------------------------------------------------------------
BOOL
OEMQueryPerformanceFrequency(
LARGE_INTEGER *lpliPerformanceFreq
)
{
extern DWORD PerfCountFreq();
lpliPerformanceFreq->HighPart = 0;
lpliPerformanceFreq->LowPart = PerfCountFreq();
return TRUE;
}
// set pointers to OEM functions
BOOL (*pQueryPerformanceCounter)(LARGE_INTEGER *lpliPerformanceCount)=OEMQueryPerformanceCounter;
BOOL (*pQueryPerformanceFrequency)(LARGE_INTEGER *lpliPerformanceFreq)=OEMQueryPerformanceFrequency;
//
// CPU-specific functions for OEMIdle
//
extern void CPUEnterIdle(DWORD dwIdleParam);
extern DWORD CPUGetSysTimerCountMax(DWORD dwIdleMSecRequested);
extern void CPUSetSysTimerCount(DWORD dwIdleMSec);
extern BOOL CPUClearSysTimerIRQ(void);
#if (CE_MAJOR_VER == 0x0003)
//
// cedar
//
extern DWORD
CPUGetSysTimerCountElapsed(
DWORD dwTimerCountdownMSec,
volatile DWORD *pCurMSec,
volatile DWORD *pDiffMSec,
DWORD *pPartialCurMSec,
DWORD *pPartialDiffMSec,
volatile ULARGE_INTEGER *pCurTicks
);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?