arm_mmu.cpp revision 1.2.8.2 1 /* -*-C++-*- $NetBSD: arm_mmu.cpp,v 1.2.8.2 2001/05/08 18:51:25 uch Exp $ */
2
3 /*-
4 * Copyright (c) 2001 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by UCHIYAMA Yasushi.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the NetBSD
21 * Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39 #include <arm/arm_mmu.h>
40 #include <console.h>
41
42 MemoryManager_ArmMMU::MemoryManager_ArmMMU(Console *&cons,
43 size_t pagesize)
44 : MemoryManager(cons, pagesize)
45 {
46 DPRINTF((TEXT("Use ARM software MMU.\n")));
47 }
48
49 MemoryManager_ArmMMU::~MemoryManager_ArmMMU(void)
50 {
51 SetKMode(_kmode);
52 }
53
54 BOOL
55 MemoryManager_ArmMMU::init(void)
56 {
57 u_int32_t reg;
58
59 _kmode = SetKMode(1);
60 // Check system mode
61 if ((GetCPSR() & 0x1f) != 0x1f) {
62 DPRINTF((TEXT("not System mode\n")));
63 return FALSE;
64 }
65 // Domain access control.(full access)
66 SetCop15Reg3(~0);
67
68 // Get Translation table base.
69 reg = GetCop15Reg2();
70 _table_base = reg & ARM_MMU_TABLEBASE_MASK;
71 DPRINTF((TEXT("page directory address=0x%08x->0x%08x(0x%08x)\n"),
72 _table_base, readPhysical4(_table_base), reg));
73
74 return TRUE;
75 }
76
77 paddr_t
78 MemoryManager_ArmMMU::searchPage(vaddr_t vaddr)
79 {
80 paddr_t daddr, paddr = ~0;
81 u_int32_t desc1, desc2;
82
83 // set marker.
84 memset(LPVOID(vaddr), 0xa5, _page_size);
85
86 // PID virtual address mapping.
87 DPRINTF((TEXT("Virtual Address 0x%08x"), vaddr));
88 vaddr |= GetCop15Reg13();
89 DPRINTF((TEXT("(+PID)-> 0x%08x\n"), vaddr));
90
91 daddr = _table_base | ARM_MMU_TABLEINDEX(vaddr);
92 desc1 = readPhysical4(daddr);
93 DPRINTF((TEXT("1st level descriptor 0x%08x(addr 0x%08x)\n"),
94 desc1, daddr));
95
96 switch(ARM_MMU_LEVEL1DESC_TRANSLATE_TYPE(desc1)) {
97 default:
98 DPRINTF((TEXT("1st level descriptor fault.\n")));
99 break;
100 case ARM_MMU_LEVEL1DESC_TRANSLATE_SECTION:
101 paddr = ARM_MMU_SECTION_BASE(desc1) |
102 ARM_MMU_VADDR_SECTION_INDEX(vaddr);
103 DPRINTF((TEXT("section Physical Address 0x%08x\n"), paddr));
104 break;
105 case ARM_MMU_LEVEL1DESC_TRANSLATE_PAGE:
106 DPRINTF((TEXT("-> Level2 page descriptor.\n")));
107 daddr = ARM_MMU_PTE_BASE(desc1) |
108 ARM_MMU_VADDR_PTE_INDEX(vaddr);
109 desc2 = readPhysical4(daddr);
110 DPRINTF((TEXT("2nd level descriptor 0x%08x(addr 0x%08x)\n"),
111 desc2, daddr));
112 switch(desc2 & 0x3) {
113 default:
114 DPRINTF((TEXT("2nd level descriptor fault.\n")));
115 break;
116 case 2: // 4Kpage
117 paddr =(desc2 & 0xfffff000) |(vaddr & 0x00000fff);
118 break;
119 case 1: // 64Kpage
120 paddr =(desc2 & 0xffff0000) |(vaddr & 0x0000ffff);
121 break;
122 }
123 break;
124 }
125
126 return paddr;
127 }
128