1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kernel/eka/memmodel/epoc/direct/arm/xutils.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,82 @@
1.4 +// Copyright (c) 1994-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32\memmodel\epoc\direct\arm\xutils.cpp
1.18 +//
1.19 +//
1.20 +
1.21 +//#define __DBG_MON_FAULT__
1.22 +//#define __RAM_LOADED_CODE__
1.23 +//#define __EARLY_DEBUG__
1.24 +
1.25 +#include "arm_mem.h"
1.26 +
1.27 +/**
1.28 + @pre Call in a thread context.
1.29 + @pre Interrupts must be enabled.
1.30 + @pre Kernel must be unlocked.
1.31 + */
1.32 +EXPORT_C TPhysAddr Epoc::LinearToPhysical(TLinAddr aLinAddr)
1.33 + {
1.34 + CHECK_PRECONDITIONS(MASK_KERNEL_UNLOCKED|MASK_INTERRUPTS_ENABLED|MASK_NOT_ISR|MASK_NOT_IDFC,"Epoc::LinearToPhysical");
1.35 + __KTRACE_OPT(KMMU,Kern::Printf("Epoc::LinearToPhysical(%08x)", aLinAddr));
1.36 +#ifdef __CPU_HAS_MMU
1.37 + // Deal with faking no MMU on hardware with an MMU
1.38 + if (!Arm::MmuActive())
1.39 + return aLinAddr;
1.40 + TUint32 phys=0xffffffffu;
1.41 + TUint32 pdphys = Arm::MmuTTBR0();
1.42 + TUint32 pdlin = TheSuperPage().iPageDir;
1.43 + TUint32 offset = pdlin - pdphys; // offset from phys to lin for page directory/tables
1.44 + const TUint32* pageDir = (const TUint32*)pdlin;
1.45 + TUint32 pde = pageDir[aLinAddr>>20];
1.46 + __KTRACE_OPT(KMMU,Kern::Printf("PDE %08x", pde));
1.47 + if ((pde&3)==2)
1.48 + {
1.49 + // section
1.50 + phys = (pde&0xfff00000u) | (aLinAddr&0x000fffffu);
1.51 + }
1.52 + else if ((pde&3)==1)
1.53 + {
1.54 + // page table
1.55 + TUint32 ptphys = pde & 0xfffffc00u;
1.56 + const TUint32* pageTable = (const TUint32*)(ptphys + offset);
1.57 + TUint32 pte = pageTable[(aLinAddr>>12)&0xff];
1.58 + __KTRACE_OPT(KMMU,Kern::Printf("PTE %08x", pte));
1.59 + if ((pte&3)==1)
1.60 + {
1.61 + // 64K page
1.62 + phys = (pte&0xffff0000u) | (aLinAddr&0x0000ffffu);
1.63 + }
1.64 + else if (pte&3)
1.65 + {
1.66 + // 4K page
1.67 + phys = (pte&0xfffff000u) | (aLinAddr&0x00000fffu);
1.68 + }
1.69 + else
1.70 + {
1.71 + FAULT();
1.72 + }
1.73 + }
1.74 + else
1.75 + {
1.76 + FAULT();
1.77 + }
1.78 + __KTRACE_OPT(KMMU,Kern::Printf("Physical address = %08x",phys));
1.79 + return phys;
1.80 +#else
1.81 + // real non-MMU hardware
1.82 + return aLinAddr;
1.83 +#endif
1.84 + }
1.85 +