cfw_platform.c

来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 657 行 · 第 1/2 页

C
657
字号
 *         function is called.
 *
 * @xref
 *         Overview.Windows CE Kernel OEM Interface
 *         InterruptDisable
 */
void OEMInterruptDisable(DWORD idInt)
{

    INTERRUPTS_OFF();

    // Bounds check.
    if (idInt <= SYSINTR_MAX && SysIntr2Logic[idInt])
    {
        // Disable interrupt.
        pHALir_DisableIrq(SysIntr2Logic[idInt]);
    }

    INTERRUPTS_ON();

    return;
}

/*
 * @func   BOOL | OEMInterruptDone | Signal completion of interrupt processing
 *
 * @rdesc  none
 *
 * @parms
 *         idInt   Interrupt ID to be enabled.
 *                 See Interrupt ID's.Interrupt ID's>  for a list of
 *                 possble values.
 *
 * @comm   OEMInterruptDone is called by the Kernel when a device driver
 *         calls InterruptDone(). The system is not preemtible when this
 *         function is called.
 *
 * @xref
 *         Overview.Kernel Interrupt Support
 *         InterruptDone
 */
void OEMInterruptDone(DWORD idInt)
{

    INTERRUPTS_OFF();

    // NOTE: we expect the interrupt to be turned off at the device.  The
    // state isn't latched in any board-level registers.

    // Enable interrupt.
    OEMInterruptEnable(idInt, NULL, 0);

    INTERRUPTS_ON();

}

/*
 * OEMGetExtensionDRAM
 *
 * For systems with memory sockets which may add more ram, here's where
 * Windows CE finds out about it.
 */
BOOL OEMGetExtensionDRAM(LPDWORD lpMemStart, LPDWORD lpMemLen)
{
    // no extension DRAM
    return FALSE;
}

/*
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;

// *** Not supported at the moment.
return(FALSE);

    /*
     * 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;

void OEMInitInterrupts(HARP_BOOT_ARGS *pBootArgs)
{

    memset(Logic2SysIntr, SYSINTR_NOP, LOGINTR_MAX);
    memset(SysIntr2Logic, 0, SYSINTR_MAX);

    // Set up static interrupt mappings.
    Logic2SysIntr[LOGINTR_KEYBOARD] = SYSINTR_KEYBOARD;	// Keyboard
    SysIntr2Logic[SYSINTR_KEYBOARD] = LOGINTR_KEYBOARD;

    Logic2SysIntr[LOGINTR_MOUSE]    = SYSINTR_MOUSE;	// Mouse
    SysIntr2Logic[SYSINTR_MOUSE]    = LOGINTR_MOUSE;

    Logic2SysIntr[LOGINTR_SERIAL1]  = SYSINTR_SERIAL1;	// Serial1
    SysIntr2Logic[SYSINTR_SERIAL1]  = LOGINTR_SERIAL1;

    Logic2SysIntr[LOGINTR_SERIAL2]  = SYSINTR_SERIAL2;	// Serial2
    SysIntr2Logic[SYSINTR_SERIAL2]  = LOGINTR_SERIAL2;

    // Debug ethernet.
    if (pBootArgs && pBootArgs->ucEdbgIRQ && pBootArgs->ucEdbgIRQ <=LOGINTR_MAX)
    {
        Logic2SysIntr[pBootArgs->ucEdbgIRQ]  = SYSINTR_ETHER;
        SysIntr2Logic[SYSINTR_ETHER]         = pBootArgs->ucEdbgIRQ;
        EdbgOutputDebugString("INFO: Mapped Ethernet IRQ 0x%x to SYSINTR 0x%x\r\n", pBootArgs->ucEdbgIRQ, SYSINTR_ETHER);
    }
    else
        EdbgOutputDebugString("ERROR: Ethernet IRQ not mapped (IRQ=0x%x)\r\n", pBootArgs->ucEdbgIRQ);
    
    // Initialize interrupts for plugged-in PCI devices.
    OEMInitPCISlotInterrupts();
  
}


void OEMInitPCISlotInterrupts(void)
{
    UCHAR Slot    = 0;
    UCHAR BusNum  = 0;	// Bus 0.
    DWORD MaxSlot = 20;	// 20 slots max on bus 0.

    //
    // Look for the video card in slots 1-3.  If found, update the logical
    // to/from SYSINTR interrupt management tables.
    //
    // NOTE: this is a throw-away routine - don't get fancy...
    //
  
    // Pre-configure the IRQ to/from SYSINTR mappings for the three PCI
    // slots.  This will allow any new plug-in card to use interrupts w/o
    // requiring OAL mods.  Hopefully, the driver will call the mapping IOCTL
    // to get the correct SYSINTR for the IRQ it's assigned by the PCI
    // enumerator.  For drivers that hard-code a SYSINTR in their registry
    // section, they'll need to figure out which slot they live in and 
    // choose the appropriate slot SYSINTR value or change the OAL to use
    // a non-slot-specific SYSINTR value (like SYSINTR_VIDEO below).
    //
    Logic2SysIntr[IRQ_PCIINT3]        = SYSINTR_GEN_SLOT1;
    SysIntr2Logic[SYSINTR_GEN_SLOT1]  = IRQ_PCIINT3;

    Logic2SysIntr[IRQ_PCIINT2]        = SYSINTR_GEN_SLOT2;
    SysIntr2Logic[SYSINTR_GEN_SLOT2]  = IRQ_PCIINT2;

    Logic2SysIntr[IRQ_PCIINT1]        = SYSINTR_GEN_SLOT3;
    SysIntr2Logic[SYSINTR_GEN_SLOT3]  = IRQ_PCIINT1;

 
    // Scan all possible buses and slots looking for the display controller.
    //
    for (Slot = 0; Slot <= MaxSlot; Slot++)
    {
        BOOL bIsMultiFunc = FALSE;
        UCHAR Func = 0;

        // For all functions...
        //
        for (Func = 0; Func < 8; Func++)
        {
            WORD vendor = 0;
            DWORD classcode = 0;

            // If it is not a multi-function device, do not treat it as one.
            //
            if ((Func != 0) && !bIsMultiFunc)
                break;

            // Read the device configuration space - get vendor ID.
            //
            vendor = OEM_ReadConfigWord(BusNum, Slot, Func, PCI_VENDOR_ID);

            // Is there a function present?
            //
            if (vendor != PCI_NOTFITTED)
            {
                UCHAR HdrType = 0;
                UCHAR IntLine = 0;

                // Check PCI config header - is it multifunctional?
                HdrType = OEM_ReadConfigByte(BusNum, Slot, Func,
                                             PCI_HEADER_TYPE);

                if (Func == 0)
                    bIsMultiFunc = ((HdrType & 0x80) != 0);

                // Get the function's class and sub-class codes (to ID it as
                // a display controller).
                //
                classcode = OEM_ReadConfigDword(BusNum, Slot, Func,
                                                PCI_REV_ID);

                classcode &= 0xFFFF0000;
                classcode = (classcode >> 16);

                // Is this our display controller?
                // 
                if (classcode == 0x0300)
                {
                    DEBUGMSG(1, (TEXT("INFO: Found video card (%d:%d:%d)\r\n"), BusNum, Slot, Func)); 

                    // Get the interrupt line value assigned by the PCI 
                    // enumeration code and update the IRQ/SYSINTR tables. 
                    //
                    IntLine = OEM_ReadConfigByte(BusNum, Slot, Func,
                                                 PCI_INTERRUPT_LINE);

                    // Update the management tables.
                    //
                    Logic2SysIntr[IntLine]        = SYSINTR_VIDEO;
                    SysIntr2Logic[SYSINTR_VIDEO]  = IntLine;
                }
            }
        }
    }

    return;
 
}


ULONG OEMMapIntLogic2SysIntr(ULONG nLogical)
{
    if (nLogical > LOGINTR_MAX)
        return(SYSINTR_NOP);
    else
        return(Logic2SysIntr[nLogical]);
}


ULONG OEMMapIntSysIntr2Logic(ULONG nSysIntr)
{
    if (nSysIntr > SYSINTR_MAX)
        return(0);
    else
        return(SysIntr2Logic[nSysIntr]);
}

/* EOF cfw_platform.c */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?