| author | William Roberts <williamr@symbian.org> |
| Fri, 01 Oct 2010 12:45:26 +0100 | |
| changeset 3 | b41049883d87 |
| parent 0 | 5de814552237 |
| permissions | -rw-r--r-- |
/* * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). * All rights reserved. * This component and the accompanying materials are made available * under the terms of "Eclipse Public License v1.0" * which accompanies this distribution, and is available * at the URL "http://www.eclipse.org/legal/epl-v10.html". * * Initial Contributors: * Nokia Corporation - initial contribution. * * Contributors: * * Description: * */ #include "pci-ne.h" #include "../naviengine_pci.h" #include <naviengine_priv.h> #include <naviengine.h> _LIT(KTConfigSpace, "TConfigSpace"); TConfigSpace::TConfigSpace(TPciFunction& aFunction, DPciBridge& aBridge) :TAddrSpace(KCfgSpaceSize, KTConfigSpace), iFunction(aFunction), iBridge(aBridge) { } /** Read 1 byte from config space. Config space is 256 bytes long out of range access will fault the kernel. */ EXPORT_C TUint8 TConfigSpace::Read8(TUint32 aOffset) { CheckAccess(E1Byte, aOffset); return iBridge.ReadConfig8( iFunction.Bus(), iFunction.Device(), iFunction.Function(), aOffset ); } EXPORT_C TUint16 TConfigSpace::Read16(TUint32 aOffset) { CheckAccess(E2Byte, aOffset); return iBridge.ReadConfig16( iFunction.Bus(), iFunction.Device(), iFunction.Function(), aOffset ); } EXPORT_C TUint32 TConfigSpace::Read32(TUint32 aOffset) { CheckAccess(E4Byte, aOffset); return iBridge.ReadConfig32( iFunction.Bus(), iFunction.Device(), iFunction.Function(), aOffset ); } EXPORT_C void TConfigSpace::Write8(TUint32 aOffset, TUint8 aValue) { CheckAccess(E1Byte, aOffset); iBridge.WriteConfig8( iFunction.Bus(), iFunction.Device(), iFunction.Function(), aOffset, aValue ); } EXPORT_C void TConfigSpace::Write16(TUint32 aOffset, TUint16 aValue) { CheckAccess(E2Byte, aOffset); iBridge.WriteConfig16( iFunction.Bus(), iFunction.Device(), iFunction.Function(), aOffset, aValue ); } EXPORT_C void TConfigSpace::Write32(TUint32 aOffset, TUint32 aValue) { CheckAccess(E4Byte, aOffset); iBridge.WriteConfig32( iFunction.Bus(), iFunction.Device(), iFunction.Function(), aOffset, aValue ); } EXPORT_C void TConfigSpace::Modify8(TUint32 aOffset, TUint8 aClearMask, TUint8 aSetMask) { CheckAccess(E1Byte, aOffset); iBridge.ModifyConfig8( iFunction.Bus(), iFunction.Device(), iFunction.Function(), aOffset, aClearMask, aSetMask ); } EXPORT_C void TConfigSpace::Modify16(TUint32 aOffset, TUint16 aClearMask, TUint16 aSetMask) { CheckAccess(E2Byte, aOffset); iBridge.ModifyConfig16( iFunction.Bus(), iFunction.Device(), iFunction.Function(), aOffset, aClearMask, aSetMask ); } EXPORT_C void TConfigSpace::Modify32(TUint32 aOffset, TUint32 aClearMask, TUint32 aSetMask) { CheckAccess(E4Byte, aOffset); iBridge.ModifyConfig32( iFunction.Bus(), iFunction.Device(), iFunction.Function(), aOffset, aClearMask, aSetMask ); } DNaviEnginePciBridge::DNaviEnginePciBridge(TUint aBaseAddress, TUint32 aVirtualWindow) :DPciBridge(), iBaseAddr(aBaseAddress), iVirtualWindow(aVirtualWindow), iAllocator(KPciAddressSpaceSize), iMapMan(KNeBridgeNumberOfBars, iAllocator, iBaseAddr), iChunkMan(iMapMan), iVid(AsspRegister::Read16(iBaseAddr+KHoPciVid)), iDid(AsspRegister::Read16(iBaseAddr+KHoPciDid)) { } TInt DNaviEnginePciBridge::Initialise() { __KTRACE_OPT(KPCI, Kern::Printf("Initialising Naviengine bridge: Base address: %x", iBaseAddr)) ; InitialiseRegisters(); return SetupInterrupts(); } DNaviEnginePciBridge::~DNaviEnginePciBridge() { } /** Create a DPlatChunkHw which will be accessble to PCI devices under this bridge. @param aSize Amount of memory visible from PCI in bytes. This will be rounded up to the next power of 2 in kilobytes .eg 1K, 2K, 4K etc. @note The actual amount of memory allocated will always be a multiple of the page size (4K), but any excess will not be visible to the PCI bus. @param aPciAddress On success, will be a PCI address by which the chunk may be accessed @return - KErrNone - On Success - KErrInUse - aChunk was not NULL - KErrNotFound - All of Bridge's BARS have been used up. Free one with RemoveChunk - KErrArgument - aSize was less than 1. */ TInt DNaviEnginePciBridge::CreateChunk(DPlatChunkHw*& aChunk, TInt aSize, TUint aAttributes, TUint32& aPciAddress) { if(aChunk!=NULL) return KErrInUse; if(aSize<1) return KErrArgument; return iChunkMan.AddChunk(aChunk, aSize, aAttributes, aPciAddress); } /** Create a DChunk which will be accessble to PCI devices under this bridge. @param aSize Amount of memory to be allocated to chunk. This will be rounded up to at least the next power of 2 in kilobytes .eg 1K, 2K, 4K, 8k etc. @param aPciAddress On success, will be a PCI address by which the chunk may be accessed @return - KErrNone - On Success - KErrInUse - aChunk was not NULL - KErrNotFound - All of Bridge's BARS have been used up. Free one with RemoveChunk - KErrArgument - aSize was less than 1. */ TInt DNaviEnginePciBridge::CreateChunk(DChunk*& aChunk, TChunkCreateInfo &aAttributes, TUint aOffset, TUint aSize, TUint32& aPciAddress) { if(aChunk!=NULL) return KErrInUse; if(aSize<1) return KErrArgument; return iChunkMan.AddChunk(aChunk, aAttributes, aOffset, aSize, aPciAddress); } TInt DNaviEnginePciBridge::RemoveChunk(DPlatChunkHw* aChunk) { return iChunkMan.RemoveChunk(aChunk); } TInt DNaviEnginePciBridge::CreateMapping(TUint32 aPhysicalAddress, TInt aSize, TUint32& aPciAddress) { if(aSize<1) return KErrArgument; return iMapMan.CreateMapping(aPhysicalAddress, aSize, aPciAddress); } TInt DNaviEnginePciBridge::RemoveMapping(TUint32 aPhysicalAddress) { return iMapMan.RemoveMapping(aPhysicalAddress); } TInt DNaviEnginePciBridge::GetPciAddress(TUint32 aPhysicalAddress, TUint32& aPciAddress) { return iMapMan.GetPciAddress(aPhysicalAddress, aPciAddress); } TInt DNaviEnginePciBridge::GetPhysicalAddress(TUint32 aPciAddress, TUint32& aPhysicalAddress) { return iMapMan.GetPhysicalAddress(aPciAddress, aPhysicalAddress); } /** Attempt to access function at this location. If it exists then scan its bars to create required PCI memory space. Create and return a complete TPciFunction */ TPciFunction* DNaviEnginePciBridge::Function(TInt aBus, TInt aDevice, TInt aFunction) { const TUint32 val = ReadConfig32(aBus, aDevice, aFunction, 0x0); //the function does not exist. if(val == 0xFFFFFFFF) return NULL; const TInt16 vid=val&0xFFFF; TInt16 did=(val>>16)&0xFFFF; //don't give access to the bridge its self if(vid==iVid && did==iDid) return NULL; TPciFunction* func= new TPciFunction(aBus, aDevice, aFunction, vid, did, *this); if(NULL==func) return func; TAddrSpace& configSpace=*func->GetConfigSpace(); TInt r=KErrNone; //scan each of the bars for(TInt i=0; i<KPciNumberOfBars; ++i) { const TInt barOffset=KPciBar0+(4*i); const TUint32 size= ProbeBar(configSpace, barOffset); if(NULL==size) continue; //allocate pci address range TUint32 pciAddress=0; r=iAllocator.Allocate(pciAddress, size); if(r!=KErrNone) break; //tell the function what its address is. r = func->AddMemorySpace(size, pciAddress+iVirtualWindow, i); if(r!=KErrNone) break; //modify bar. configSpace.Write32(barOffset, pciAddress); } if(r==KErrNone) { configSpace.Modify16(KHoPciCmd, NULL, KHtPcicmd_Memen); return func; } else { delete func; return NULL; } } void DNaviEnginePciBridge::ConfigurationComplete() { //state that config is complete and allow subsequent master aborts //to trigger the error interrupt AsspRegister::Modify32(iBaseAddr+KHoPciCtrlH, NULL, KHtPciCtrlH_CnfigDone| KHtPciCtrlH_Mase); Interrupt::Enable(EIntPciInt); } void DNaviEnginePciBridge::ErrorPrint() { Kern::Printf("Pci Errors:"); Kern::Printf(" Status Register"); volatile TUint16 status=AsspRegister::Read16(iBaseAddr+KHoPciStatus); if(status & KHtPciStatus_ParityError) Kern::Printf(" Parity Error"); if(status & KHtPciStatus_SystemError) Kern::Printf(" System Error"); if(status & KHtPciStatus_MasterAbrtRcvd) Kern::Printf(" MasterAbrtRcvd"); if(status & KHtPciStatus_TargetAbrtRcvd) Kern::Printf(" TargetAbrtRcvd"); if(status & KHtPciStatus_DPErrorAsserted) Kern::Printf(" PERR# asserted"); Kern::Printf(" Err1 Register:"); volatile TUint32 error=AsspRegister::Read32(iBaseAddr+KHoError1); if(error & KHtError1_SystemError) Kern::Printf(" System Error"); if(error & KHtError1_AMEr) Kern::Printf(" AHB master error"); Kern::Printf(" PciCtrlHi Register"); volatile TUint32 pciCtrlH=AsspRegister::Read32(iBaseAddr+KHoPciCtrlH); if(pciCtrlH & KHtPciCtrlH_Aper) Kern::Printf(" Address Parity error"); if(pciCtrlH & KHtPciCtrlH_Dtep) Kern::Printf(" Discard time out"); if(pciCtrlH & KHtPciCtrlH_Dper) Kern::Printf(" Data parity error"); if(pciCtrlH & KHtPciCtrlH_Rlex) Kern::Printf(" Retry limit exceeded"); if(pciCtrlH & KHtPciCtrlH_Mabo) Kern::Printf(" Master abort"); if(pciCtrlH & KHtPciCtrlH_Tabo) Kern::Printf(" Target abort"); } /** @param aOffset A DWord index (32 bit) @return A value sutiable for writing to the bridge's CNFIG_ADDR register */ TCnfgAddr DNaviEnginePciBridge::MakeConfigAddress(TInt aBus, TInt aDevice, TInt aFunction, TUint aDwordOffset) { using namespace ConfigAddress; const TUint32 bus=(aBus<<KHsBus); const TUint32 device=(aDevice<<KHsDevice); const TUint32 function=(aFunction<<KHsFunction); const TUint32 offset=(aDwordOffset<<KHsOffset); __NK_ASSERT_DEBUG( (bus & (~KHmBus)) == NULL); __NK_ASSERT_DEBUG( (device & (~KHmDevice)) == NULL); __NK_ASSERT_DEBUG( (function & (~KHmFunction)) == NULL); __NK_ASSERT_DEBUG( (offset & (~KHmOffset)) == NULL); return (KHtCnfigEnable| (bus & KHmBus)| (device & KHmDevice)| (function & KHmFunction)| (offset & KHmOffset) ); } /** Probes the specified bar to see whether it is implemented, if so then return the amount of memory space required. @note Driver does not currently support devices which request IO-space or 64-bit bars. */ TUint DNaviEnginePciBridge::ProbeBar(TAddrSpace& aCs, TUint32 aBarOffset) { __KTRACE_OPT(KPCI, Kern::Printf("DNaviEnginePciBridge::ProbeBar Probing BAR at Offset %d", aBarOffset)); //ignore any writable bits in positions [0:2] //they shouldn't be writable but are for the NaviEngine host //bridge const TUint32 KHmIgnore= Bar::KHtMemSpaceType|Bar::KHmType|Bar::KHtPreFetchable; aCs.Write32(aBarOffset, 0x00000000); TUint32 initial= aCs.Read32(aBarOffset); aCs.Write32(aBarOffset, KMaxTUint32); TUint32 bar = aCs.Read32(aBarOffset); //reset after probing aCs.Write32(aBarOffset, 0x00000000); if( (bar&(~KHmIgnore)) == (initial&(~KHmIgnore)) ) { __KTRACE_OPT(KPCI, Kern::Printf(" Function doesn't implement BAR")); return NULL; } if(bar & Bar::KHtMemSpaceType) { __KTRACE_OPT(KPCI, Kern::Printf(" IOSpace is not supported") ); return NULL; } if(bar & Bar::KHmType ) { __KTRACE_OPT(KPCI, Kern::Printf(" Only support 32 bit address space") ); return NULL; } TUint size= (bar<<1)^(bar); __KTRACE_OPT(KPCI, Kern::Printf(" Address space: %08x bytes", size)); return size; } TUint8 DNaviEnginePciBridge::ReadConfig8(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset) const { const TUint dwordOffset = aOffset>>2; //divide by 4 const TUint byteOffset = aOffset%4; const TCnfgAddr location = MakeConfigAddress(aBus, aDevice, aFunction, dwordOffset); Wait(); AsspRegister::Write32(KHoCnfig_addr+iBaseAddr, location); volatile TUint8 value = AsspRegister::Read8(iBaseAddr+KHoCnfig_data+byteOffset); Signal(); return value; } TUint16 DNaviEnginePciBridge::ReadConfig16(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset) const { const TUint dwordOffset = aOffset>>2; //divide by 4 const TUint byteOffset = aOffset%4; const TCnfgAddr location = MakeConfigAddress(aBus, aDevice, aFunction, dwordOffset); Wait(); AsspRegister::Write32(KHoCnfig_addr+iBaseAddr, location); volatile TUint16 value = AsspRegister::Read16(iBaseAddr+KHoCnfig_data+byteOffset); Signal(); return value; } /** @param aOffset A byte index */ TUint32 DNaviEnginePciBridge::ReadConfig32(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset) const { TUint dwordOffset = aOffset>>2; //divide by 4 const TCnfgAddr location = MakeConfigAddress(aBus, aDevice, aFunction, dwordOffset); Wait(); AsspRegister::Write32(KHoCnfig_addr+iBaseAddr, location); volatile TInt32 value = AsspRegister::Read32(KHoCnfig_data+iBaseAddr); Signal(); return value; } void DNaviEnginePciBridge::WriteConfig8(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset, TUint8 aValue) { TUint dwordOffset = aOffset>>2; //divide by 4 const TUint byteOffset = aOffset%4; const TCnfgAddr location = MakeConfigAddress(aBus, aDevice, aFunction, dwordOffset); Wait(); AsspRegister::Write32(KHoCnfig_addr+iBaseAddr, location); AsspRegister::Write8(KHoCnfig_data+iBaseAddr+byteOffset, aValue); Signal(); } void DNaviEnginePciBridge::WriteConfig16(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset, TUint16 aValue) { TUint dwordOffset = aOffset>>2; //divide by 4 const TUint byteOffset = aOffset%4; const TCnfgAddr location = MakeConfigAddress(aBus, aDevice, aFunction, dwordOffset); Wait(); AsspRegister::Write32(KHoCnfig_addr+iBaseAddr, location); AsspRegister::Write16(KHoCnfig_data+iBaseAddr+byteOffset, aValue); Signal(); } /** @param aOffset A byte index */ void DNaviEnginePciBridge::WriteConfig32(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset, TUint32 aValue) { //__KTRACE_OPT(KPCI, Kern::Printf("PCI: WriteConfig32: %x:%x:%x os=%x, val=%x ", aBus,aDevice, aFunction, aOffset, aValue)); TUint dwordOffset = aOffset>>2; //divide by 4 const TCnfgAddr location = MakeConfigAddress(aBus, aDevice, aFunction, dwordOffset); Wait(); AsspRegister::Write32(KHoCnfig_addr+iBaseAddr, location); AsspRegister::Write32(KHoCnfig_data+iBaseAddr, aValue); Signal(); } void DNaviEnginePciBridge::ModifyConfig8(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset, TUint8 aClearMask, TUint8 aSetMask) { //__KTRACE_OPT(KPCI, Kern::Printf("PCI: ModifyConfig32: %x:%x:%x os=%x, clear=%x, set=%x ",aBus,aDevice, aFunction, aOffset, aClearMask, aSetMask)); TUint dwordOffset = aOffset>>2; //divide by 4 (and trunctate) const TUint byteOffset = aOffset%4; const TCnfgAddr location = MakeConfigAddress(aBus, aDevice, aFunction, dwordOffset); Wait(); AsspRegister::Write32(KHoCnfig_addr+iBaseAddr, location); AsspRegister::Modify8(KHoCnfig_data+iBaseAddr+byteOffset, aClearMask, aSetMask); Signal(); } void DNaviEnginePciBridge::ModifyConfig16(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset, TUint16 aClearMask, TUint16 aSetMask) { //__KTRACE_OPT(KPCI, Kern::Printf("PCI: ModifyConfig32: %x:%x:%x os=%x, clear=%x, set=%x ",aBus,aDevice, aFunction, aOffset, aClearMask, aSetMask)); TUint dwordOffset = aOffset>>2; //divide by 4 (and trunctate) const TUint byteOffset = aOffset%4; const TCnfgAddr location = MakeConfigAddress(aBus, aDevice, aFunction, dwordOffset); Wait(); AsspRegister::Write32(KHoCnfig_addr+iBaseAddr, location); AsspRegister::Modify16(KHoCnfig_data+iBaseAddr+byteOffset, aClearMask, aSetMask); Signal(); } void DNaviEnginePciBridge::ModifyConfig32(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset, TUint32 aClearMask, TUint32 aSetMask) { //__KTRACE_OPT(KPCI, Kern::Printf("PCI: ModifyConfig32: %x:%x:%x os=%x, clear=%x, set=%x ",aBus,aDevice, aFunction, aOffset, aClearMask, aSetMask)); TUint dwordOffset = aOffset>>2; //divide by 4 (and trunctate) const TCnfgAddr location = MakeConfigAddress(aBus, aDevice, aFunction, dwordOffset); Wait(); AsspRegister::Write32(KHoCnfig_addr+iBaseAddr, location); AsspRegister::Modify32(KHoCnfig_data+iBaseAddr, aClearMask, aSetMask); Signal(); } void DNaviEnginePciBridge::InitialiseRegisters() { ClearRegisters(); //make the bridge a PCI master and respond as a target AsspRegister::Modify16(iBaseAddr+KHoPciCmd, 0x0, KHtPcicmd_Bmasen|KHtPcicmd_Memen|KHtPcicmd_Peren|KHtPcicmd_Seren); //set up inbound access to PCI through window 1. const TUint32 window1Register = 0| //window points to address 0 of PCI (0x13<<Initiator::KHsA2PCAMask)| //modify incomming AHB address above 8k (0x3<<Initiator::KHsType)| //incomming accesses will perform memory read/memory write 0x1; //enable incomming address conversion AsspRegister::Write32(iBaseAddr+Initiator::KHoReg1, window1Register); AsspRegister::Write32(iBaseAddr+KHoBarEnable, 0); //disable all BARs, don't yet want access from PCI to AHB AsspRegister::Modify32(iBaseAddr+KHoPciCtrlH ,NULL, KHtPciCtrlH_Aerse| KHtPciCtrlH_Dtimse| KHtPciCtrlH_Perse| KHtPciCtrlH_Rtyse| KHtPciCtrlH_Tase ); //report errors from PCI bus to AHB64PCI_ERR pin //report errror on AHB to AHB64PCI_ERR pin AsspRegister::Modify32(iBaseAddr+KHoError1, NULL, KHtError1_PEEn| KHtError1_AMEn ); } void DNaviEnginePciBridge::ClearRegisters() { ClearErrors(); AsspRegister::Modify16(iBaseAddr+KHoPciCmd, KHtPcicmd_Bmasen| KHtPcicmd_Memen| KHtPcicmd_Peren| KHtPcicmd_Seren, NULL); AsspRegister::Modify32(iBaseAddr+KHoPciCtrlH , KHtPciCtrlH_CnfigDone| KHtPciCtrlH_Aerse| KHtPciCtrlH_Dtimse| KHtPciCtrlH_Perse| KHtPciCtrlH_Rtyse| KHtPciCtrlH_Mase| KHtPciCtrlH_Tase, NULL ); AsspRegister::Modify32(iBaseAddr+KHoError1, KHtError1_PEEn| KHtError1_AMEn, NULL ); AsspRegister::Write32(KHoCnfig_addr+iBaseAddr, 0x0); AsspRegister::Write32(iBaseAddr+Initiator::KHoReg1, 0x0); AsspRegister::Write32(iBaseAddr+Initiator::KHoReg2, 0x0); } //Clear latched bits by wriring 1 to them void DNaviEnginePciBridge::ClearErrors() { AsspRegister::Modify16(iBaseAddr+KHoPciStatus, NULL, KHtPciStatus_ParityError| KHtPciStatus_SystemError| KHtPciStatus_MasterAbrtRcvd| KHtPciStatus_TargetAbrtRcvd| KHtPciStatus_DPErrorAsserted ); AsspRegister::Modify32(iBaseAddr+KHoError1, NULL, KHtError1_SystemError| KHtError1_AMEr ); AsspRegister::Modify32(iBaseAddr+KHoPciCtrlH, NULL, KHtPciCtrlH_Aper| KHtPciCtrlH_Dtep| KHtPciCtrlH_Dper| KHtPciCtrlH_Rlex| KHtPciCtrlH_Mabo| KHtPciCtrlH_Tabo ); } TInt DNaviEnginePciBridge::SetupInterrupts() { __KTRACE_OPT(KPCI, Kern::Printf("DNaviEnginePciBridge: SetupInterrupts()")); TInt r = KErrNone; __KTRACE_OPT(KPCI, Kern::Printf(" Binding EIntPciPErrB")); r = Interrupt::Bind(EIntPciPErrB, ParityErrorISR, this); __KTRACE_OPT(KPCI, Kern::Printf(" r=%d", r)); __KTRACE_OPT(KPCI, Kern::Printf(" Binding EIntPciSErrB")); r = Interrupt::Bind(EIntPciSErrB, SystemErrorISR, this); __KTRACE_OPT(KPCI, Kern::Printf(" r=%d", r)); __KTRACE_OPT(KPCI, Kern::Printf(" Binding EIntPciInt")); r = Interrupt::Bind(EIntPciInt, PciISR, this); __KTRACE_OPT(KPCI, Kern::Printf(" r=%d", r)); __KTRACE_OPT(KPCI, Kern::Printf(" Enabling EIntPciPErrB")); r = Interrupt::Enable(EIntPciPErrB); __KTRACE_OPT(KPCI, Kern::Printf(" r=%d", r)); __KTRACE_OPT(KPCI, Kern::Printf(" Enabling EIntPciSErrB")); r = Interrupt::Enable(EIntPciSErrB); __KTRACE_OPT(KPCI, Kern::Printf(" r=%d", r)); __KTRACE_OPT(KPCI, Kern::Printf(" Enabling EIntPciInt")); Interrupt::Clear(EIntPciInt); //r = Interrupt::Enable(EIntPciInt); __KTRACE_OPT(KPCI, Kern::Printf(" r=%d", r)); return r; } void DNaviEnginePciBridge::ParityErrorISR(void* aP) { Interrupt::Clear(EIntPciPErrB); Kern::Fault("PCI Parity error",0); } void DNaviEnginePciBridge::SystemErrorISR(void* aP) { Interrupt::Clear(EIntPciSErrB); Kern::Fault("PCI System error",0); } /** This interrupt is raised when a bus error has occured, if the appropriate bit has been set (KHtPciCtrlH_Mase). It will also be raised if a peripheral uses one of the native PCI interrupt lines - but this not yet supported. */ void DNaviEnginePciBridge::PciISR(void* aP) { Interrupt::Clear(EIntPciInt); DNaviEnginePciBridge* bridge = static_cast<DNaviEnginePciBridge*>(aP); __KTRACE_OPT(KPCI, Kern::Printf("Pci interrupt line: Bridge Base address 0x%08x",bridge->iBaseAddr); bridge->ErrorPrint(); ); volatile TUint16 status=AsspRegister::Read16((bridge->iBaseAddr)+KHoPciStatus); if(status & KHtPciStatus_SystemError) { Kern::Fault("PCI System Error: Fatal",0); } bridge->ClearErrors(); } // // TNaviEngineChunkCleanup // // TNaviEngineChunkCleanup::TNaviEngineChunkCleanup(TChunkManager& aChunkMan, TUint32 aPhysicalAddress) :TChunkCleanup(), iChunkMan(aChunkMan), iPhysicalAddress(aPhysicalAddress) { } TNaviEngineChunkCleanup::~TNaviEngineChunkCleanup() { } void TNaviEngineChunkCleanup::Destroy() { iChunkMan.RemoveChunk(iPhysicalAddress); } DECLARE_STANDARD_EXTENSION() { __KTRACE_OPT(KEXTENSION, Kern::Printf("Pci Extension starting...")); DPciBridge* internBridge = new DNaviEnginePciBridge(KHwPciBridgeUsb, KHwUsbHWindow); if(internBridge == NULL) return KErrNoMemory; TInt r = internBridge->Initialise(); if(r !=KErrNone) return r; r = internBridge->Register(); if(r !=KErrNone) { delete internBridge; return r; } r = Pci::Enumerate(); return r; }