|
1 // Copyright (c) 1994-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of the License "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // e32\memmodel\epoc\direct\arm\xutils.cpp |
|
15 // |
|
16 // |
|
17 |
|
18 //#define __DBG_MON_FAULT__ |
|
19 //#define __RAM_LOADED_CODE__ |
|
20 //#define __EARLY_DEBUG__ |
|
21 |
|
22 #include "arm_mem.h" |
|
23 |
|
24 /** |
|
25 @pre Call in a thread context. |
|
26 @pre Interrupts must be enabled. |
|
27 @pre Kernel must be unlocked. |
|
28 */ |
|
29 EXPORT_C TPhysAddr Epoc::LinearToPhysical(TLinAddr aLinAddr) |
|
30 { |
|
31 CHECK_PRECONDITIONS(MASK_KERNEL_UNLOCKED|MASK_INTERRUPTS_ENABLED|MASK_NOT_ISR|MASK_NOT_IDFC,"Epoc::LinearToPhysical"); |
|
32 __KTRACE_OPT(KMMU,Kern::Printf("Epoc::LinearToPhysical(%08x)", aLinAddr)); |
|
33 #ifdef __CPU_HAS_MMU |
|
34 // Deal with faking no MMU on hardware with an MMU |
|
35 if (!Arm::MmuActive()) |
|
36 return aLinAddr; |
|
37 TUint32 phys=0xffffffffu; |
|
38 TUint32 pdphys = Arm::MmuTTBR0(); |
|
39 TUint32 pdlin = TheSuperPage().iPageDir; |
|
40 TUint32 offset = pdlin - pdphys; // offset from phys to lin for page directory/tables |
|
41 const TUint32* pageDir = (const TUint32*)pdlin; |
|
42 TUint32 pde = pageDir[aLinAddr>>20]; |
|
43 __KTRACE_OPT(KMMU,Kern::Printf("PDE %08x", pde)); |
|
44 if ((pde&3)==2) |
|
45 { |
|
46 // section |
|
47 phys = (pde&0xfff00000u) | (aLinAddr&0x000fffffu); |
|
48 } |
|
49 else if ((pde&3)==1) |
|
50 { |
|
51 // page table |
|
52 TUint32 ptphys = pde & 0xfffffc00u; |
|
53 const TUint32* pageTable = (const TUint32*)(ptphys + offset); |
|
54 TUint32 pte = pageTable[(aLinAddr>>12)&0xff]; |
|
55 __KTRACE_OPT(KMMU,Kern::Printf("PTE %08x", pte)); |
|
56 if ((pte&3)==1) |
|
57 { |
|
58 // 64K page |
|
59 phys = (pte&0xffff0000u) | (aLinAddr&0x0000ffffu); |
|
60 } |
|
61 else if (pte&3) |
|
62 { |
|
63 // 4K page |
|
64 phys = (pte&0xfffff000u) | (aLinAddr&0x00000fffu); |
|
65 } |
|
66 else |
|
67 { |
|
68 FAULT(); |
|
69 } |
|
70 } |
|
71 else |
|
72 { |
|
73 FAULT(); |
|
74 } |
|
75 __KTRACE_OPT(KMMU,Kern::Printf("Physical address = %08x",phys)); |
|
76 return phys; |
|
77 #else |
|
78 // real non-MMU hardware |
|
79 return aLinAddr; |
|
80 #endif |
|
81 } |
|
82 |