navienginebsp/naviengine_assp/pci/pci-ne.cpp
changeset 0 5de814552237
equal deleted inserted replaced
-1:000000000000 0:5de814552237
       
     1 /*
       
     2 * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 #include "pci-ne.h"
       
    21 #include "../naviengine_pci.h"
       
    22 #include <naviengine_priv.h>
       
    23 #include <naviengine.h>
       
    24 
       
    25 
       
    26 _LIT(KTConfigSpace, "TConfigSpace");
       
    27 TConfigSpace::TConfigSpace(TPciFunction& aFunction, DPciBridge& aBridge)
       
    28 	:TAddrSpace(KCfgSpaceSize, KTConfigSpace), iFunction(aFunction), iBridge(aBridge)
       
    29 	{
       
    30 	}
       
    31 
       
    32 /**
       
    33 Read 1 byte from config space. Config space is 256 bytes long
       
    34 out of range access will fault the kernel.
       
    35 */
       
    36 EXPORT_C TUint8 TConfigSpace::Read8(TUint32 aOffset)
       
    37 	{
       
    38 	CheckAccess(E1Byte, aOffset);
       
    39 
       
    40 	return iBridge.ReadConfig8(
       
    41 			iFunction.Bus(),
       
    42 			iFunction.Device(),
       
    43 			iFunction.Function(),
       
    44 			aOffset
       
    45 			);
       
    46 	}
       
    47 
       
    48 EXPORT_C TUint16 TConfigSpace::Read16(TUint32 aOffset)
       
    49 	{
       
    50 	CheckAccess(E2Byte, aOffset);
       
    51 
       
    52 	return iBridge.ReadConfig16(
       
    53 			iFunction.Bus(),
       
    54 			iFunction.Device(),
       
    55 			iFunction.Function(),
       
    56 			aOffset
       
    57 			);
       
    58 	}
       
    59 
       
    60 EXPORT_C TUint32 TConfigSpace::Read32(TUint32 aOffset)
       
    61 	{
       
    62 	CheckAccess(E4Byte, aOffset);
       
    63 
       
    64 	return iBridge.ReadConfig32(
       
    65 			iFunction.Bus(),
       
    66 			iFunction.Device(),
       
    67 			iFunction.Function(),
       
    68 			aOffset
       
    69 			);
       
    70 	}
       
    71 
       
    72 EXPORT_C void TConfigSpace::Write8(TUint32 aOffset, TUint8 aValue)
       
    73 	{
       
    74 	CheckAccess(E1Byte, aOffset);
       
    75 
       
    76 	iBridge.WriteConfig8(
       
    77 			iFunction.Bus(),
       
    78 			iFunction.Device(),
       
    79 			iFunction.Function(),
       
    80 			aOffset,
       
    81 			aValue
       
    82 			);
       
    83 	}
       
    84 
       
    85 EXPORT_C void TConfigSpace::Write16(TUint32 aOffset, TUint16 aValue)
       
    86 	{
       
    87 	CheckAccess(E2Byte, aOffset);
       
    88 
       
    89 	iBridge.WriteConfig16(
       
    90 			iFunction.Bus(),
       
    91 			iFunction.Device(),
       
    92 			iFunction.Function(),
       
    93 			aOffset,
       
    94 			aValue
       
    95 			);
       
    96 	}
       
    97 
       
    98 EXPORT_C void TConfigSpace::Write32(TUint32 aOffset, TUint32 aValue)
       
    99 	{
       
   100 	CheckAccess(E4Byte, aOffset);
       
   101 
       
   102 	iBridge.WriteConfig32(
       
   103 			iFunction.Bus(),
       
   104 			iFunction.Device(),
       
   105 			iFunction.Function(),
       
   106 			aOffset,
       
   107 			aValue
       
   108 			);
       
   109 	}
       
   110 
       
   111 EXPORT_C void TConfigSpace::Modify8(TUint32 aOffset, TUint8 aClearMask, TUint8 aSetMask)
       
   112 	{
       
   113 	CheckAccess(E1Byte, aOffset);
       
   114 
       
   115 	iBridge.ModifyConfig8(
       
   116 			iFunction.Bus(),
       
   117 			iFunction.Device(),
       
   118 			iFunction.Function(),
       
   119 			aOffset,
       
   120 			aClearMask,
       
   121 			aSetMask
       
   122 			);
       
   123 	}
       
   124 
       
   125 EXPORT_C void TConfigSpace::Modify16(TUint32 aOffset, TUint16 aClearMask, TUint16 aSetMask)
       
   126 	{
       
   127 	CheckAccess(E2Byte, aOffset);
       
   128 
       
   129 	iBridge.ModifyConfig16(
       
   130 			iFunction.Bus(),
       
   131 			iFunction.Device(),
       
   132 			iFunction.Function(),
       
   133 			aOffset,
       
   134 			aClearMask,
       
   135 			aSetMask
       
   136 			);
       
   137 	}
       
   138 
       
   139 EXPORT_C void TConfigSpace::Modify32(TUint32 aOffset, TUint32 aClearMask, TUint32 aSetMask)
       
   140 	{
       
   141 	CheckAccess(E4Byte, aOffset);
       
   142 
       
   143 	iBridge.ModifyConfig32(
       
   144 			iFunction.Bus(),
       
   145 			iFunction.Device(),
       
   146 			iFunction.Function(),
       
   147 			aOffset,
       
   148 			aClearMask,
       
   149 			aSetMask
       
   150 			);
       
   151 	}
       
   152 
       
   153 DNaviEnginePciBridge::DNaviEnginePciBridge(TUint aBaseAddress, TUint32 aVirtualWindow)
       
   154 	:DPciBridge(), iBaseAddr(aBaseAddress),
       
   155 	iVirtualWindow(aVirtualWindow),
       
   156 	iAllocator(KPciAddressSpaceSize),
       
   157 	iMapMan(KNeBridgeNumberOfBars, iAllocator, iBaseAddr),
       
   158 	iChunkMan(iMapMan),
       
   159 	iVid(AsspRegister::Read16(iBaseAddr+KHoPciVid)),
       
   160 	iDid(AsspRegister::Read16(iBaseAddr+KHoPciDid))
       
   161 	{
       
   162 	}
       
   163 
       
   164 TInt DNaviEnginePciBridge::Initialise()
       
   165 	{
       
   166 	__KTRACE_OPT(KPCI, Kern::Printf("Initialising Naviengine bridge: Base address: %x", iBaseAddr)) ;
       
   167 	InitialiseRegisters();
       
   168 	return SetupInterrupts();
       
   169 	}
       
   170 
       
   171 DNaviEnginePciBridge::~DNaviEnginePciBridge()
       
   172 	{
       
   173 	}
       
   174 
       
   175 /**
       
   176 Create a DPlatChunkHw which will be accessble to PCI devices under this bridge.
       
   177 
       
   178 @param aSize Amount of memory visible from PCI in bytes.
       
   179 This will be rounded up to the next power of 2 in kilobytes
       
   180 .eg 1K, 2K, 4K etc. @note The actual amount of memory allocated
       
   181 will always be a multiple of the page size (4K), but any excess
       
   182 will not be visible to the PCI bus.
       
   183 @param aPciAddress On success, will be a PCI address by which the chunk may be accessed
       
   184 @return
       
   185 	- KErrNone - On Success
       
   186 	- KErrInUse - aChunk was not NULL
       
   187 	- KErrNotFound - All of Bridge's BARS have been used up. Free one with RemoveChunk
       
   188 	- KErrArgument - aSize was less than 1.
       
   189 */
       
   190 TInt DNaviEnginePciBridge::CreateChunk(DPlatChunkHw*& aChunk, TInt aSize, TUint aAttributes, TUint32& aPciAddress)
       
   191 	{
       
   192 	if(aChunk!=NULL)
       
   193 		return KErrInUse;
       
   194 	if(aSize<1)
       
   195 		return KErrArgument;
       
   196 
       
   197 	return iChunkMan.AddChunk(aChunk, aSize, aAttributes, aPciAddress);
       
   198 	}
       
   199 
       
   200 /**
       
   201 Create a DChunk which will be accessble to PCI devices under this bridge.
       
   202 
       
   203 @param aSize Amount of memory to be allocated to chunk.
       
   204 This will be rounded up to at least the next power of 2 in kilobytes
       
   205 .eg 1K, 2K, 4K, 8k etc.
       
   206 @param aPciAddress On success, will be a PCI address by which the chunk may be accessed
       
   207 @return
       
   208 	- KErrNone - On Success
       
   209 	- KErrInUse - aChunk was not NULL
       
   210 	- KErrNotFound - All of Bridge's BARS have been used up. Free one with RemoveChunk
       
   211 	- KErrArgument - aSize was less than 1.
       
   212 */
       
   213 TInt DNaviEnginePciBridge::CreateChunk(DChunk*& aChunk, TChunkCreateInfo &aAttributes, TUint aOffset, TUint aSize, TUint32& aPciAddress)
       
   214 	{
       
   215 	if(aChunk!=NULL)
       
   216 		return KErrInUse;
       
   217 	if(aSize<1)
       
   218 		return KErrArgument;
       
   219 
       
   220 	return iChunkMan.AddChunk(aChunk, aAttributes, aOffset, aSize, aPciAddress);
       
   221 	}
       
   222 
       
   223 
       
   224 TInt DNaviEnginePciBridge::RemoveChunk(DPlatChunkHw* aChunk)
       
   225 	{
       
   226 	return iChunkMan.RemoveChunk(aChunk);
       
   227 	}
       
   228 
       
   229 TInt DNaviEnginePciBridge::CreateMapping(TUint32 aPhysicalAddress, TInt aSize, TUint32& aPciAddress)
       
   230 	{
       
   231 	if(aSize<1)
       
   232 		return KErrArgument;
       
   233 
       
   234 	return iMapMan.CreateMapping(aPhysicalAddress, aSize, aPciAddress);
       
   235 	}
       
   236 
       
   237 TInt DNaviEnginePciBridge::RemoveMapping(TUint32 aPhysicalAddress)
       
   238 	{
       
   239 	return iMapMan.RemoveMapping(aPhysicalAddress);
       
   240 	}
       
   241 
       
   242 TInt DNaviEnginePciBridge::GetPciAddress(TUint32 aPhysicalAddress, TUint32& aPciAddress)
       
   243 	{
       
   244 	return iMapMan.GetPciAddress(aPhysicalAddress, aPciAddress);
       
   245 	}
       
   246 
       
   247 TInt DNaviEnginePciBridge::GetPhysicalAddress(TUint32 aPciAddress, TUint32& aPhysicalAddress)
       
   248 	{
       
   249 	return iMapMan.GetPhysicalAddress(aPciAddress, aPhysicalAddress);
       
   250 	}
       
   251 
       
   252 /**
       
   253 Attempt to access function at this location. If it exists then scan its
       
   254 bars to create required PCI memory space.
       
   255 Create and return a complete TPciFunction
       
   256 */
       
   257 TPciFunction* DNaviEnginePciBridge::Function(TInt aBus, TInt aDevice, TInt aFunction)
       
   258 	{
       
   259 	const TUint32 val = ReadConfig32(aBus, aDevice, aFunction, 0x0);
       
   260 
       
   261 	//the function does not exist.
       
   262 	if(val == 0xFFFFFFFF)
       
   263 		return NULL;
       
   264 
       
   265 	const TInt16 vid=val&0xFFFF;
       
   266 	TInt16 did=(val>>16)&0xFFFF;
       
   267 
       
   268 	//don't give access to the bridge its self
       
   269 	if(vid==iVid && did==iDid)
       
   270 		return NULL;
       
   271 
       
   272 	TPciFunction* func= new TPciFunction(aBus, aDevice, aFunction, vid, did, *this);
       
   273 	if(NULL==func)
       
   274 		return func;
       
   275 
       
   276 	TAddrSpace& configSpace=*func->GetConfigSpace();
       
   277 
       
   278 	TInt r=KErrNone;
       
   279 	//scan each of the bars
       
   280 	for(TInt i=0; i<KPciNumberOfBars; ++i)
       
   281 		{
       
   282 		const TInt barOffset=KPciBar0+(4*i);
       
   283 		const TUint32 size= ProbeBar(configSpace, barOffset);
       
   284 
       
   285 		if(NULL==size)
       
   286 			continue;
       
   287 
       
   288 		//allocate pci address range
       
   289 		TUint32 pciAddress=0;
       
   290 		r=iAllocator.Allocate(pciAddress, size);
       
   291 		if(r!=KErrNone)
       
   292 			break;
       
   293 
       
   294 		//tell the function what its address is.
       
   295 		r = func->AddMemorySpace(size, pciAddress+iVirtualWindow, i);
       
   296 		if(r!=KErrNone)
       
   297 			break;
       
   298 
       
   299 		//modify bar.
       
   300 		configSpace.Write32(barOffset, pciAddress);
       
   301 		}
       
   302 
       
   303 	if(r==KErrNone)
       
   304 		{
       
   305 		configSpace.Modify16(KHoPciCmd, NULL, KHtPcicmd_Memen);
       
   306 		return func;
       
   307 		}
       
   308 	else
       
   309 		{
       
   310 		delete func;
       
   311 		return NULL;
       
   312 		}
       
   313 
       
   314 	}
       
   315 
       
   316 void DNaviEnginePciBridge::ConfigurationComplete()
       
   317 	{
       
   318 	//state that config is complete and allow subsequent master aborts
       
   319 	//to trigger the error interrupt
       
   320 	AsspRegister::Modify32(iBaseAddr+KHoPciCtrlH, NULL, KHtPciCtrlH_CnfigDone| KHtPciCtrlH_Mase);
       
   321 	Interrupt::Enable(EIntPciInt);
       
   322 	}
       
   323 
       
   324 
       
   325 void DNaviEnginePciBridge::ErrorPrint()
       
   326 	{
       
   327 	Kern::Printf("Pci Errors:");
       
   328 
       
   329 	Kern::Printf(" Status Register");
       
   330 	volatile TUint16 status=AsspRegister::Read16(iBaseAddr+KHoPciStatus);
       
   331 	if(status & KHtPciStatus_ParityError)
       
   332 		Kern::Printf("  Parity Error");
       
   333 	if(status & KHtPciStatus_SystemError)
       
   334 		Kern::Printf("  System Error");
       
   335 	if(status & KHtPciStatus_MasterAbrtRcvd)
       
   336 		Kern::Printf("  MasterAbrtRcvd");
       
   337 	if(status & KHtPciStatus_TargetAbrtRcvd)
       
   338 		Kern::Printf("  TargetAbrtRcvd");
       
   339 	if(status & KHtPciStatus_DPErrorAsserted)
       
   340 		Kern::Printf("  PERR# asserted");
       
   341 
       
   342 	Kern::Printf(" Err1 Register:");
       
   343 	volatile TUint32 error=AsspRegister::Read32(iBaseAddr+KHoError1);
       
   344 	if(error & KHtError1_SystemError)
       
   345 		Kern::Printf("  System Error");
       
   346 	if(error & KHtError1_AMEr)
       
   347 		Kern::Printf("  AHB master error");
       
   348 
       
   349 	Kern::Printf(" PciCtrlHi Register");
       
   350 
       
   351 	volatile TUint32 pciCtrlH=AsspRegister::Read32(iBaseAddr+KHoPciCtrlH);
       
   352 	if(pciCtrlH & KHtPciCtrlH_Aper)
       
   353 		Kern::Printf("  Address Parity error");
       
   354 	if(pciCtrlH & KHtPciCtrlH_Dtep)
       
   355 		Kern::Printf("  Discard time out");
       
   356 	if(pciCtrlH & KHtPciCtrlH_Dper)
       
   357 		Kern::Printf("  Data parity error");
       
   358 	if(pciCtrlH & KHtPciCtrlH_Rlex)
       
   359 		Kern::Printf("  Retry limit exceeded");
       
   360 	if(pciCtrlH & KHtPciCtrlH_Mabo)
       
   361 		Kern::Printf("  Master abort");
       
   362 	if(pciCtrlH & KHtPciCtrlH_Tabo)
       
   363 		Kern::Printf("  Target abort");
       
   364 
       
   365 	}
       
   366 /**
       
   367 @param aOffset A DWord index (32 bit)
       
   368 @return A value sutiable for writing to the bridge's CNFIG_ADDR register
       
   369 */
       
   370 TCnfgAddr DNaviEnginePciBridge::MakeConfigAddress(TInt aBus, TInt aDevice, TInt aFunction, TUint aDwordOffset)
       
   371 	{
       
   372 	using namespace ConfigAddress;
       
   373 	const TUint32 bus=(aBus<<KHsBus);
       
   374 	const TUint32 device=(aDevice<<KHsDevice);
       
   375 	const TUint32 function=(aFunction<<KHsFunction);
       
   376 	const TUint32 offset=(aDwordOffset<<KHsOffset);
       
   377 
       
   378 	__NK_ASSERT_DEBUG( (bus & (~KHmBus)) == NULL);
       
   379 	__NK_ASSERT_DEBUG( (device & (~KHmDevice)) == NULL);
       
   380 	__NK_ASSERT_DEBUG( (function & (~KHmFunction)) == NULL);
       
   381 	__NK_ASSERT_DEBUG( (offset & (~KHmOffset)) == NULL);
       
   382 
       
   383 	return (KHtCnfigEnable|
       
   384 			(bus & KHmBus)|
       
   385 			(device & KHmDevice)|
       
   386 			(function & KHmFunction)|
       
   387 			(offset & KHmOffset)
       
   388 		   );
       
   389 	}
       
   390 
       
   391 /**
       
   392 Probes the specified bar to see whether it is implemented, if so
       
   393 then return the amount of memory space required.
       
   394 
       
   395 @note Driver does not currently support devices which request IO-space
       
   396 or 64-bit bars.
       
   397 */
       
   398 TUint DNaviEnginePciBridge::ProbeBar(TAddrSpace& aCs, TUint32 aBarOffset)
       
   399 	{
       
   400 	__KTRACE_OPT(KPCI, Kern::Printf("DNaviEnginePciBridge::ProbeBar Probing BAR at Offset %d", aBarOffset));
       
   401 
       
   402 	//ignore any writable bits in positions [0:2]
       
   403 	//they shouldn't be writable but are for the NaviEngine host
       
   404 	//bridge
       
   405 	const TUint32 KHmIgnore= Bar::KHtMemSpaceType|Bar::KHmType|Bar::KHtPreFetchable;
       
   406 
       
   407 	aCs.Write32(aBarOffset, 0x00000000);
       
   408 	TUint32 initial= aCs.Read32(aBarOffset);
       
   409 	aCs.Write32(aBarOffset, KMaxTUint32);
       
   410 	TUint32 bar = aCs.Read32(aBarOffset);
       
   411 
       
   412 	//reset after probing
       
   413 	aCs.Write32(aBarOffset, 0x00000000);
       
   414 
       
   415 	if( (bar&(~KHmIgnore)) == (initial&(~KHmIgnore)) )
       
   416 		{
       
   417 		__KTRACE_OPT(KPCI, Kern::Printf(" Function doesn't implement BAR"));
       
   418 		return NULL;
       
   419 		}
       
   420 	if(bar & Bar::KHtMemSpaceType)
       
   421 		{
       
   422 		__KTRACE_OPT(KPCI, Kern::Printf(" IOSpace is not supported") );
       
   423 		return NULL;
       
   424 		}
       
   425 
       
   426 	if(bar & Bar::KHmType )
       
   427 		{
       
   428 		__KTRACE_OPT(KPCI, Kern::Printf(" Only support 32 bit address space") );
       
   429 		return NULL;
       
   430 		}
       
   431 
       
   432 	TUint size= (bar<<1)^(bar);
       
   433 	__KTRACE_OPT(KPCI, Kern::Printf(" Address space: %08x bytes", size));
       
   434 	return size;
       
   435 	}
       
   436 
       
   437 
       
   438 
       
   439 TUint8 DNaviEnginePciBridge::ReadConfig8(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset) const
       
   440 	{
       
   441 	const TUint dwordOffset = aOffset>>2; //divide by 4
       
   442 	const TUint byteOffset = aOffset%4;
       
   443 
       
   444 	const TCnfgAddr location = MakeConfigAddress(aBus, aDevice, aFunction, dwordOffset);
       
   445 
       
   446 	Wait();
       
   447 	AsspRegister::Write32(KHoCnfig_addr+iBaseAddr, location);
       
   448 	volatile TUint8 value = AsspRegister::Read8(iBaseAddr+KHoCnfig_data+byteOffset);
       
   449 	Signal();
       
   450 	return value;
       
   451 	}
       
   452 
       
   453 TUint16 DNaviEnginePciBridge::ReadConfig16(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset) const
       
   454 	{
       
   455 	const TUint dwordOffset = aOffset>>2; //divide by 4
       
   456 	const TUint byteOffset = aOffset%4;
       
   457 
       
   458 	const TCnfgAddr location = MakeConfigAddress(aBus, aDevice, aFunction, dwordOffset);
       
   459 
       
   460 	Wait();
       
   461 	AsspRegister::Write32(KHoCnfig_addr+iBaseAddr, location);
       
   462 	volatile TUint16 value = AsspRegister::Read16(iBaseAddr+KHoCnfig_data+byteOffset);
       
   463 	Signal();
       
   464 	return value;
       
   465 	}
       
   466 
       
   467 /**
       
   468 @param aOffset A byte index
       
   469 */
       
   470 TUint32 DNaviEnginePciBridge::ReadConfig32(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset) const
       
   471 	{
       
   472 	TUint dwordOffset = aOffset>>2; //divide by 4
       
   473 
       
   474 	const TCnfgAddr location = MakeConfigAddress(aBus, aDevice, aFunction, dwordOffset);
       
   475 
       
   476 	Wait();
       
   477 	AsspRegister::Write32(KHoCnfig_addr+iBaseAddr, location);
       
   478 	volatile TInt32 value = AsspRegister::Read32(KHoCnfig_data+iBaseAddr);
       
   479 	Signal();
       
   480 	return value;
       
   481 	}
       
   482 
       
   483 void DNaviEnginePciBridge::WriteConfig8(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset, TUint8 aValue)
       
   484 	{
       
   485 	TUint dwordOffset = aOffset>>2; //divide by 4
       
   486 	const TUint byteOffset = aOffset%4;
       
   487 
       
   488 	const TCnfgAddr location = MakeConfigAddress(aBus, aDevice, aFunction, dwordOffset);
       
   489 
       
   490 	Wait();
       
   491 	AsspRegister::Write32(KHoCnfig_addr+iBaseAddr, location);
       
   492 	AsspRegister::Write8(KHoCnfig_data+iBaseAddr+byteOffset, aValue);
       
   493 	Signal();
       
   494 	}
       
   495 
       
   496 void DNaviEnginePciBridge::WriteConfig16(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset, TUint16 aValue)
       
   497 	{
       
   498 	TUint dwordOffset = aOffset>>2; //divide by 4
       
   499 	const TUint byteOffset = aOffset%4;
       
   500 
       
   501 	const TCnfgAddr location = MakeConfigAddress(aBus, aDevice, aFunction, dwordOffset);
       
   502 
       
   503 	Wait();
       
   504 	AsspRegister::Write32(KHoCnfig_addr+iBaseAddr, location);
       
   505 	AsspRegister::Write16(KHoCnfig_data+iBaseAddr+byteOffset, aValue);
       
   506 	Signal();
       
   507 	}
       
   508 
       
   509 /**
       
   510 @param aOffset A byte index
       
   511 */
       
   512 void DNaviEnginePciBridge::WriteConfig32(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset, TUint32 aValue)
       
   513 	{
       
   514 	//__KTRACE_OPT(KPCI, Kern::Printf("PCI: WriteConfig32: %x:%x:%x os=%x, val=%x ", aBus,aDevice, aFunction, aOffset, aValue));
       
   515 	TUint dwordOffset = aOffset>>2; //divide by 4
       
   516 	const TCnfgAddr location = MakeConfigAddress(aBus, aDevice, aFunction, dwordOffset);
       
   517 
       
   518 	Wait();
       
   519 	AsspRegister::Write32(KHoCnfig_addr+iBaseAddr, location);
       
   520 	AsspRegister::Write32(KHoCnfig_data+iBaseAddr, aValue);
       
   521 	Signal();
       
   522 	}
       
   523 
       
   524 void DNaviEnginePciBridge::ModifyConfig8(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset, TUint8 aClearMask, TUint8 aSetMask)
       
   525 	{
       
   526 	//__KTRACE_OPT(KPCI, Kern::Printf("PCI: ModifyConfig32: %x:%x:%x os=%x, clear=%x, set=%x ",aBus,aDevice, aFunction, aOffset, aClearMask, aSetMask));
       
   527 	TUint dwordOffset = aOffset>>2; //divide by 4 (and trunctate)
       
   528 	const TUint byteOffset = aOffset%4;
       
   529 
       
   530 	const TCnfgAddr location = MakeConfigAddress(aBus, aDevice, aFunction, dwordOffset);
       
   531 
       
   532 	Wait();
       
   533 	AsspRegister::Write32(KHoCnfig_addr+iBaseAddr, location);
       
   534 	AsspRegister::Modify8(KHoCnfig_data+iBaseAddr+byteOffset, aClearMask, aSetMask);
       
   535 	Signal();
       
   536 	}
       
   537 
       
   538 void DNaviEnginePciBridge::ModifyConfig16(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset, TUint16 aClearMask, TUint16 aSetMask)
       
   539 	{
       
   540 	//__KTRACE_OPT(KPCI, Kern::Printf("PCI: ModifyConfig32: %x:%x:%x os=%x, clear=%x, set=%x ",aBus,aDevice, aFunction, aOffset, aClearMask, aSetMask));
       
   541 	TUint dwordOffset = aOffset>>2; //divide by 4 (and trunctate)
       
   542 	const TUint byteOffset = aOffset%4;
       
   543 
       
   544 	const TCnfgAddr location = MakeConfigAddress(aBus, aDevice, aFunction, dwordOffset);
       
   545 
       
   546 	Wait();
       
   547 	AsspRegister::Write32(KHoCnfig_addr+iBaseAddr, location);
       
   548 	AsspRegister::Modify16(KHoCnfig_data+iBaseAddr+byteOffset, aClearMask, aSetMask);
       
   549 	Signal();
       
   550 	}
       
   551 
       
   552 void DNaviEnginePciBridge::ModifyConfig32(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset, TUint32 aClearMask, TUint32 aSetMask)
       
   553 	{
       
   554 	//__KTRACE_OPT(KPCI, Kern::Printf("PCI: ModifyConfig32: %x:%x:%x os=%x, clear=%x, set=%x ",aBus,aDevice, aFunction, aOffset, aClearMask, aSetMask));
       
   555 	TUint dwordOffset = aOffset>>2; //divide by 4 (and trunctate)
       
   556 
       
   557 	const TCnfgAddr location = MakeConfigAddress(aBus, aDevice, aFunction, dwordOffset);
       
   558 
       
   559 	Wait();
       
   560 	AsspRegister::Write32(KHoCnfig_addr+iBaseAddr, location);
       
   561 	AsspRegister::Modify32(KHoCnfig_data+iBaseAddr, aClearMask, aSetMask);
       
   562 	Signal();
       
   563 	}
       
   564 
       
   565 void DNaviEnginePciBridge::InitialiseRegisters()
       
   566 	{
       
   567 	ClearRegisters();
       
   568 
       
   569 	//make the bridge a PCI master and respond as a target
       
   570 	AsspRegister::Modify16(iBaseAddr+KHoPciCmd, 0x0, KHtPcicmd_Bmasen|KHtPcicmd_Memen|KHtPcicmd_Peren|KHtPcicmd_Seren);
       
   571 
       
   572 	//set up inbound access to PCI through window 1.
       
   573 	const TUint32 window1Register =
       
   574 		0| //window points to address 0 of PCI
       
   575 		(0x13<<Initiator::KHsA2PCAMask)| //modify incomming AHB address above 8k
       
   576 		(0x3<<Initiator::KHsType)| //incomming accesses will perform memory read/memory write
       
   577 		0x1; //enable incomming address conversion
       
   578 	AsspRegister::Write32(iBaseAddr+Initiator::KHoReg1, window1Register);
       
   579 
       
   580 	AsspRegister::Write32(iBaseAddr+KHoBarEnable, 0); //disable all BARs, don't yet want access from PCI to AHB
       
   581 
       
   582 	AsspRegister::Modify32(iBaseAddr+KHoPciCtrlH ,NULL,
       
   583 			KHtPciCtrlH_Aerse|
       
   584 			KHtPciCtrlH_Dtimse|
       
   585 			KHtPciCtrlH_Perse|
       
   586 			KHtPciCtrlH_Rtyse|
       
   587 			KHtPciCtrlH_Tase
       
   588 			);
       
   589 	//report errors from PCI bus to AHB64PCI_ERR pin
       
   590 	//report errror on AHB to AHB64PCI_ERR pin
       
   591 	AsspRegister::Modify32(iBaseAddr+KHoError1, NULL,
       
   592 			KHtError1_PEEn|
       
   593 			KHtError1_AMEn
       
   594 			);
       
   595 
       
   596 	}
       
   597 
       
   598 void DNaviEnginePciBridge::ClearRegisters()
       
   599 	{
       
   600 	ClearErrors();
       
   601 
       
   602 	AsspRegister::Modify16(iBaseAddr+KHoPciCmd,
       
   603 			KHtPcicmd_Bmasen|
       
   604 			KHtPcicmd_Memen|
       
   605 			KHtPcicmd_Peren|
       
   606 			KHtPcicmd_Seren,
       
   607 			NULL);
       
   608 
       
   609 	AsspRegister::Modify32(iBaseAddr+KHoPciCtrlH ,
       
   610 			KHtPciCtrlH_CnfigDone|
       
   611 			KHtPciCtrlH_Aerse|
       
   612 			KHtPciCtrlH_Dtimse|
       
   613 			KHtPciCtrlH_Perse|
       
   614 			KHtPciCtrlH_Rtyse|
       
   615 			KHtPciCtrlH_Mase|
       
   616 			KHtPciCtrlH_Tase,
       
   617 			NULL
       
   618 			);
       
   619 
       
   620 	AsspRegister::Modify32(iBaseAddr+KHoError1,
       
   621 			KHtError1_PEEn|
       
   622 			KHtError1_AMEn,
       
   623 			NULL
       
   624 			);
       
   625 
       
   626 	AsspRegister::Write32(KHoCnfig_addr+iBaseAddr, 0x0);
       
   627 
       
   628 	AsspRegister::Write32(iBaseAddr+Initiator::KHoReg1, 0x0);
       
   629 	AsspRegister::Write32(iBaseAddr+Initiator::KHoReg2, 0x0);
       
   630 	}
       
   631 
       
   632 //Clear latched bits by wriring 1 to them
       
   633 void DNaviEnginePciBridge::ClearErrors()
       
   634 	{
       
   635 	AsspRegister::Modify16(iBaseAddr+KHoPciStatus, NULL,
       
   636 		KHtPciStatus_ParityError|
       
   637 		KHtPciStatus_SystemError|
       
   638 		KHtPciStatus_MasterAbrtRcvd|
       
   639 		KHtPciStatus_TargetAbrtRcvd|
       
   640 		KHtPciStatus_DPErrorAsserted
       
   641 		);
       
   642 
       
   643 	AsspRegister::Modify32(iBaseAddr+KHoError1, NULL,
       
   644 			KHtError1_SystemError|
       
   645 			KHtError1_AMEr
       
   646 			);
       
   647 
       
   648 	AsspRegister::Modify32(iBaseAddr+KHoPciCtrlH, NULL,
       
   649 			KHtPciCtrlH_Aper|
       
   650 			KHtPciCtrlH_Dtep|
       
   651 			KHtPciCtrlH_Dper|
       
   652 			KHtPciCtrlH_Rlex|
       
   653 			KHtPciCtrlH_Mabo|
       
   654 			KHtPciCtrlH_Tabo
       
   655 			);
       
   656 
       
   657 	}
       
   658 
       
   659 
       
   660 TInt DNaviEnginePciBridge::SetupInterrupts()
       
   661 	{
       
   662 	__KTRACE_OPT(KPCI, Kern::Printf("DNaviEnginePciBridge: SetupInterrupts()"));
       
   663 	TInt r = KErrNone;
       
   664 
       
   665 	__KTRACE_OPT(KPCI, Kern::Printf("  Binding EIntPciPErrB"));
       
   666 	r = Interrupt::Bind(EIntPciPErrB, ParityErrorISR, this);
       
   667 	__KTRACE_OPT(KPCI, Kern::Printf("  r=%d", r));
       
   668 
       
   669 	__KTRACE_OPT(KPCI, Kern::Printf("  Binding EIntPciSErrB"));
       
   670 	r = Interrupt::Bind(EIntPciSErrB, SystemErrorISR, this);
       
   671 	__KTRACE_OPT(KPCI, Kern::Printf("  r=%d", r));
       
   672 
       
   673 	__KTRACE_OPT(KPCI, Kern::Printf("  Binding EIntPciInt"));
       
   674 	r = Interrupt::Bind(EIntPciInt, PciISR, this);
       
   675 	__KTRACE_OPT(KPCI, Kern::Printf("  r=%d", r));
       
   676 
       
   677 	__KTRACE_OPT(KPCI, Kern::Printf("  Enabling EIntPciPErrB"));
       
   678 	r = Interrupt::Enable(EIntPciPErrB);
       
   679 	__KTRACE_OPT(KPCI, Kern::Printf("  r=%d", r));
       
   680 
       
   681 	__KTRACE_OPT(KPCI, Kern::Printf("  Enabling EIntPciSErrB"));
       
   682 	r = Interrupt::Enable(EIntPciSErrB);
       
   683 	__KTRACE_OPT(KPCI, Kern::Printf("  r=%d", r));
       
   684 
       
   685 	__KTRACE_OPT(KPCI, Kern::Printf("  Enabling EIntPciInt"));
       
   686 	Interrupt::Clear(EIntPciInt);
       
   687 	//r = Interrupt::Enable(EIntPciInt);
       
   688 	__KTRACE_OPT(KPCI, Kern::Printf("  r=%d", r));
       
   689 	return r;
       
   690 	}
       
   691 
       
   692 void DNaviEnginePciBridge::ParityErrorISR(void* aP)
       
   693 	{
       
   694 	Interrupt::Clear(EIntPciPErrB);
       
   695 	Kern::Fault("PCI Parity error",0);
       
   696 	}
       
   697 
       
   698 void DNaviEnginePciBridge::SystemErrorISR(void* aP)
       
   699 	{
       
   700 	Interrupt::Clear(EIntPciSErrB);
       
   701 	Kern::Fault("PCI System error",0);
       
   702 	}
       
   703 
       
   704 /**
       
   705 This interrupt is raised when a bus error has occured, if the
       
   706 appropriate bit has been set (KHtPciCtrlH_Mase).
       
   707 It will also be raised if a peripheral uses one of the
       
   708 native PCI interrupt lines - but this not yet supported.
       
   709 */
       
   710 void DNaviEnginePciBridge::PciISR(void* aP)
       
   711 	{
       
   712 	Interrupt::Clear(EIntPciInt);
       
   713 	DNaviEnginePciBridge* bridge = static_cast<DNaviEnginePciBridge*>(aP);
       
   714 	__KTRACE_OPT(KPCI,
       
   715 			Kern::Printf("Pci interrupt line: Bridge Base address 0x%08x",bridge->iBaseAddr);
       
   716 			bridge->ErrorPrint();
       
   717 			);
       
   718 
       
   719 	volatile TUint16 status=AsspRegister::Read16((bridge->iBaseAddr)+KHoPciStatus);
       
   720 	if(status & KHtPciStatus_SystemError)
       
   721 		{
       
   722 		Kern::Fault("PCI System Error: Fatal",0);
       
   723 		}
       
   724 	bridge->ClearErrors();
       
   725 	}
       
   726 
       
   727 //
       
   728 // TNaviEngineChunkCleanup //
       
   729 //
       
   730 
       
   731 TNaviEngineChunkCleanup::TNaviEngineChunkCleanup(TChunkManager& aChunkMan, TUint32 aPhysicalAddress)
       
   732 	:TChunkCleanup(), iChunkMan(aChunkMan), iPhysicalAddress(aPhysicalAddress)
       
   733 	{
       
   734 	}
       
   735 
       
   736 TNaviEngineChunkCleanup::~TNaviEngineChunkCleanup()
       
   737 	{
       
   738 	}
       
   739 
       
   740 void TNaviEngineChunkCleanup::Destroy()
       
   741 	{
       
   742 	iChunkMan.RemoveChunk(iPhysicalAddress);
       
   743 	}
       
   744 
       
   745 
       
   746 DECLARE_STANDARD_EXTENSION()
       
   747 	{
       
   748 	__KTRACE_OPT(KEXTENSION, Kern::Printf("Pci Extension starting..."));
       
   749 
       
   750 	DPciBridge* internBridge = new DNaviEnginePciBridge(KHwPciBridgeUsb, KHwUsbHWindow);
       
   751 
       
   752 	if(internBridge == NULL)
       
   753 		return KErrNoMemory;
       
   754 
       
   755 	TInt r = internBridge->Initialise();
       
   756 	if(r !=KErrNone)
       
   757 		return r;
       
   758 
       
   759 	r = internBridge->Register();
       
   760 	if(r !=KErrNone)
       
   761 		{
       
   762 		delete internBridge;
       
   763 		return r;
       
   764 		}
       
   765 
       
   766 	r = Pci::Enumerate();
       
   767 	return r;
       
   768 	}
       
   769 
       
   770 
       
   771 
       
   772 
       
   773