⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pciext.c

📁 Wince4.2 BSP for SH4 engineering development board
💻 C
字号:

//
//      Copyright (c) Renesas Technology Corp. 2001-2003  All Rights Reserved.
//
//      OEM Adaptation Layer
//
//----------------------------------------------------------------------------
//
//  FILE      : PCIEXT.C
//  CREATED   : 2001.10.26 (for PFM-DS6D)
//  MODIFIED  : 2003.08.06
//  AUTHOR    : Renesas Technology Corp.
//  HARDWARE  : RENESAS HS7751RSTC01H (ITS-DS5, S1-E with CIS I/O board)
//  TARGET OS : Microsoft(R) Windows(R) CE .NET 4.2
//  NOTES     : 
//  FUNCTION  : PCI interrupt controls and interrupt resource managements
//  HISTORY   :
//              2001.10.26
//              - Created for PFM-DS6D by modifying ASPEN's code in CEPB4.0.
//              - Message outputs by "EDBGOutputDebugString" are deleted.
//              2002. 6. 1
//              - Modified for HS7751RSTC01H.
//              2002. 8.28
//              - Critical section is inserted to guard interrupt table.
//				2002.9.26
//				- Released for HS7751RSTC01H.

//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//


#include <windows.h>
#include <nkintr.h>
#include <ceddk.h>
#include <halether.h>
#include "shx.h"
//#include "platform.h"
#include "oalintr.h"
#include "pciext.h"
#include "s1e.h"


static DWORD IrqTablePrimaryBus[4][4] = {
    {IRQ_INTA, IRQ_INTB, IRQ_INTC, IRQ_INTD},// Bus 0, Device 0, 3.3V slot0(CN11)
    {IRQ_INTB, IRQ_INTC, IRQ_INTD, IRQ_INTA},// Bus 0, Device 1, 3.3V slot1(CN12)
    {IRQ_INTC, IRQ_INTD, IRQ_INTA, IRQ_INTB},// Bus 0, Device 2, 3.3V slot2(CN13)
    {SYSINTR_NOP, SYSINTR_NOP, SYSINTR_NOP, SYSINTR_NOP} // Bus 0, Device 3, Intel 21150 PCI-PCI bridge
};

static DWORD IrqTableSecondaryBus[4][4] = {
    {IRQ_INTA, IRQ_INTB, IRQ_INTC, IRQ_INTD},// Bus 1, Device 0, 5V slot0(CN15)
    {IRQ_INTB, IRQ_INTC, IRQ_INTD, IRQ_INTA},// Bus 1, Device 1, 5V slot1(CN16)
    {SYSINTR_NOP, SYSINTR_NOP, SYSINTR_NOP, SYSINTR_NOP},// Bus 1, Device 2, No Device
    {SYSINTR_NOP, SYSINTR_NOP, SYSINTR_NOP, SYSINTR_NOP} // Bus 1, Device 3, No Device
};


ULONG Logic2SysIntr[MAX_PCI_IRQ + 1];
ULONG SysIntr2Logic[SYSINTR_MAXIMUM];

CRITICAL_SECTION csSysIntrTable;

void OEMInitInterrupts()
{
    memset(Logic2SysIntr, 0xFF, sizeof(Logic2SysIntr));
    memset(SysIntr2Logic, 0xFF, sizeof(SysIntr2Logic));
}

DWORD OEMTranslateIrq(
    DWORD Irq 
    )
{
	if (Irq < SYSINTR_PCI_START)
		return Irq; // IF it is Built-in Interrupt. It is one-to-one map
	else
    if (Irq > MAX_PCI_IRQ ) {
		ASSERT(FALSE);
        return -1;
    } else {
		ASSERT( Logic2SysIntr[Irq]!=0xFF);
        return Logic2SysIntr[Irq];
    }
}


DWORD OEMTranslateSysIntr(
    DWORD SysIntr 
    )
{
    if (SysIntr >= SYSINTR_MAXIMUM) {
		ASSERT(FALSE);
        return -1;
    } else {
		ASSERT( Logic2SysIntr[SysIntr]!=0xFF);
        return SysIntr2Logic[SysIntr];
    }
}


DWORD OEMRequestSysIntr(
    DWORD Irq 
    )
{
    DWORD SysIntr;
    DWORD dwRet;

    RETAILMSG(1, (TEXT("\r\nOEMRequestSysIntr: Irq:%d\r\n"),Irq));

    if (Irq < SYSINTR_PCI_START){
        RETAILMSG(1, (TEXT("\r\nOEMRequestSysIntr: Built-in Interrupt\r\n")));
        return Irq; // IF it is Built-in Interrupt. It is one-to-one map
    }
    else if (Irq > MAX_PCI_IRQ) {
        ASSERT(FALSE);
        RETAILMSG(1, (TEXT("\r\nOEMRequestSysIntr: exceeded MAX_PCI_IRQ!!!\r\n")));
        return 0xFFFFFFFF; // unsigned
    }

    if ((Irq != IRQ_INTA) && (Irq != IRQ_INTB) && (Irq != IRQ_INTC) && (Irq != IRQ_INTD)) {
        ASSERT(FALSE);
        RETAILMSG(1, (TEXT("\r\nOEMRequestSysIntr: unknown IRQ!!!\r\n")));
        return 0xFFFFFFFF; // unsigned
    }

    __try {
        EnterCriticalSection(&csSysIntrTable);
        // Look for next free SYSINTR
        for (SysIntr = SYSINTR_PCI_START; SysIntr < SYSINTR_MAXIMUM; SysIntr++) {
            if (SysIntr2Logic[SysIntr] == -1) break;
        }

        // No free SYSINTRs left
        if (SysIntr >= SYSINTR_MAXIMUM) {
            ASSERT(FALSE);
		    RETAILMSG(1, (TEXT("\r\nOEMRequestSysIntr: No free SYSINTRs left!!!\r\n")));
            dwRet = 0xFFFFFFFF;
            __leave;
        }
    
        // Make SYSINTR -> Irq association
        SysIntr2Logic[SysIntr] = Irq;

        // Make Irq -> SYSINTR association, only if not multiply-mapped
        if (Logic2SysIntr[Irq] == -1) { 
            Logic2SysIntr[Irq] = SysIntr;
        }
        dwRet = SysIntr;
    }
    __finally {
        LeaveCriticalSection(&csSysIntrTable);
    }

    return dwRet;
}


BOOL
OEMGetInterrupt(
    PDEVICE_LOCATION pDevLoc,
    PDWORD pIrq
    )
{
    int Bus = pDevLoc->BusNumber;
    int Device = (pDevLoc->LogicalLoc >> 8) & 0xFF;

    *pIrq = 0xFF;
    
    // Currently supporting only PCIbus
    if (pDevLoc->IfcType != PCIBus){
		RETAILMSG(1, (TEXT("\r\nOEMGetInterrupt: Type isn't PCIBus!\r\n")));
		return FALSE;
    }

    // Make sure interrupt Pin is in range
    if ((pDevLoc->Pin < 1) || (pDevLoc->Pin > 4)) return FALSE;

    if (Bus == 0) {
        // Bus 0 has devices 0 through 2 mapped
        if ((Device < 0) || (Device > 2)) {
            return FALSE;
        }

        *pIrq = IrqTablePrimaryBus[Device][pDevLoc->Pin - 1];
		RETAILMSG(1, (TEXT("\r\nOEMGetInterrupt: Irq:%d\r\n"),*pIrq));
        return TRUE;
    } else if(Bus == 1){
        // Bus 1 has devices 0 through 1 mapped
        if ((Device < 0) || (Device > 1)) {
            return FALSE;
        }

        *pIrq = IrqTableSecondaryBus[Device][pDevLoc->Pin - 1];
		RETAILMSG(1, (TEXT("\r\nOEMGetInterrupt: Irq:%d\r\n"),*pIrq));
        return TRUE;
    } else {
		RETAILMSG(1, (TEXT("\r\nOEMGetInterrupt: Bus Number is not in range!\r\n")));
		return FALSE;
    }

}


BOOL OEMPciIntrEnable(DWORD dwIrq)
{
	switch (dwIrq) {
	case IRQ_INTA:
		WRITE_REGISTER_USHORT(PF_INTMR, READ_REGISTER_USHORT(PF_INTMR) & ~PF_INTMR_MASK_PCI_INTA);
		break;
	case IRQ_INTB:
		WRITE_REGISTER_USHORT(PF_INTMR, READ_REGISTER_USHORT(PF_INTMR) & ~PF_INTMR_MASK_PCI_INTB);
		break;
	case IRQ_INTC:
		WRITE_REGISTER_USHORT(PF_INTMR, READ_REGISTER_USHORT(PF_INTMR) & ~PF_INTMR_MASK_PCI_INTC);
		break;
	case IRQ_INTD:
		WRITE_REGISTER_USHORT(PF_INTMR, READ_REGISTER_USHORT(PF_INTMR) & ~PF_INTMR_MASK_PCI_INTD);
		break;
	default:
		return FALSE;
	}
	return TRUE;
}

BOOL OEMPciIntrDisable(DWORD dwIrq)
{
	switch (dwIrq) {
	case IRQ_INTA:
		WRITE_REGISTER_USHORT(PF_INTMR, READ_REGISTER_USHORT(PF_INTMR) | PF_INTMR_MASK_PCI_INTA);
		break;
	case IRQ_INTB:
		WRITE_REGISTER_USHORT(PF_INTMR, READ_REGISTER_USHORT(PF_INTMR) | PF_INTMR_MASK_PCI_INTB);
		break;
	case IRQ_INTC:
		WRITE_REGISTER_USHORT(PF_INTMR, READ_REGISTER_USHORT(PF_INTMR) | PF_INTMR_MASK_PCI_INTC);
		break;
	case IRQ_INTD:
		WRITE_REGISTER_USHORT(PF_INTMR, READ_REGISTER_USHORT(PF_INTMR) | PF_INTMR_MASK_PCI_INTD);
		break;
	default:
		return FALSE;
	}
	return TRUE;
}
BOOL OEMPciIntrDone(DWORD dwIrq)
{
	return OEMPciIntrEnable(dwIrq);
}

/*
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\PCI]
    "Dll"="PCIbus.dll"
    "Order"=dword:20
    "Flags"=dword:1
    "NoConfig"=dword:0
    "MemBase"=dword:10000000
    "MemLen"=dword:04000000
    "IoBase"=dword:0
    "IoLen"=dword:00040000
*/

⌨️ 快捷键说明

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