📄 pciext.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 + -