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 + -
显示快捷键?