pagetable_walker.cc (5897:29cecf4fe602) pagetable_walker.cc (5904:5c61233cbd53)
1/*
2 * Copyright (c) 2007 The Hewlett-Packard Development Company
3 * All rights reserved.
4 *
5 * Redistribution and use of this software in source and binary forms,
6 * with or without modification, are permitted provided that the
7 * following conditions are met:
8 *

--- 87 unchanged lines hidden (view full) ---

96 pte = read->get<uint32_t>();
97 VAddr vaddr = entry.vaddr;
98 bool uncacheable = pte.pcd;
99 Addr nextRead = 0;
100 bool doWrite = false;
101 bool badNX = pte.nx && (!tlb->allowNX() || !enableNX);
102 switch(state) {
103 case LongPML4:
1/*
2 * Copyright (c) 2007 The Hewlett-Packard Development Company
3 * All rights reserved.
4 *
5 * Redistribution and use of this software in source and binary forms,
6 * with or without modification, are permitted provided that the
7 * following conditions are met:
8 *

--- 87 unchanged lines hidden (view full) ---

96 pte = read->get<uint32_t>();
97 VAddr vaddr = entry.vaddr;
98 bool uncacheable = pte.pcd;
99 Addr nextRead = 0;
100 bool doWrite = false;
101 bool badNX = pte.nx && (!tlb->allowNX() || !enableNX);
102 switch(state) {
103 case LongPML4:
104 DPRINTF(PageTableWalker,
105 "Got long mode PML4 entry %#016x.\n", (uint64_t)pte);
104 nextRead = ((uint64_t)pte & (mask(40) << 12)) + vaddr.longl3 * size;
105 doWrite = !pte.a;
106 pte.a = 1;
107 entry.writable = pte.w;
108 entry.user = pte.u;
109 if (badNX || !pte.p) {
110 stop();
111 return pageFault(pte.p);
112 }
113 entry.noExec = pte.nx;
114 nextState = LongPDP;
115 break;
116 case LongPDP:
106 nextRead = ((uint64_t)pte & (mask(40) << 12)) + vaddr.longl3 * size;
107 doWrite = !pte.a;
108 pte.a = 1;
109 entry.writable = pte.w;
110 entry.user = pte.u;
111 if (badNX || !pte.p) {
112 stop();
113 return pageFault(pte.p);
114 }
115 entry.noExec = pte.nx;
116 nextState = LongPDP;
117 break;
118 case LongPDP:
119 DPRINTF(PageTableWalker,
120 "Got long mode PDP entry %#016x.\n", (uint64_t)pte);
117 nextRead = ((uint64_t)pte & (mask(40) << 12)) + vaddr.longl2 * size;
118 doWrite = !pte.a;
119 pte.a = 1;
120 entry.writable = entry.writable && pte.w;
121 entry.user = entry.user && pte.u;
122 if (badNX || !pte.p) {
123 stop();
124 return pageFault(pte.p);
125 }
126 nextState = LongPD;
127 break;
128 case LongPD:
121 nextRead = ((uint64_t)pte & (mask(40) << 12)) + vaddr.longl2 * size;
122 doWrite = !pte.a;
123 pte.a = 1;
124 entry.writable = entry.writable && pte.w;
125 entry.user = entry.user && pte.u;
126 if (badNX || !pte.p) {
127 stop();
128 return pageFault(pte.p);
129 }
130 nextState = LongPD;
131 break;
132 case LongPD:
133 DPRINTF(PageTableWalker,
134 "Got long mode PD entry %#016x.\n", (uint64_t)pte);
129 doWrite = !pte.a;
130 pte.a = 1;
131 entry.writable = entry.writable && pte.w;
132 entry.user = entry.user && pte.u;
133 if (badNX || !pte.p) {
134 stop();
135 return pageFault(pte.p);
136 }

--- 12 unchanged lines hidden (view full) ---

149 entry.global = pte.g;
150 entry.patBit = bits(pte, 12);
151 entry.vaddr = entry.vaddr & ~((2 * (1 << 20)) - 1);
152 tlb->insert(entry.vaddr, entry);
153 stop();
154 return NoFault;
155 }
156 case LongPTE:
135 doWrite = !pte.a;
136 pte.a = 1;
137 entry.writable = entry.writable && pte.w;
138 entry.user = entry.user && pte.u;
139 if (badNX || !pte.p) {
140 stop();
141 return pageFault(pte.p);
142 }

--- 12 unchanged lines hidden (view full) ---

155 entry.global = pte.g;
156 entry.patBit = bits(pte, 12);
157 entry.vaddr = entry.vaddr & ~((2 * (1 << 20)) - 1);
158 tlb->insert(entry.vaddr, entry);
159 stop();
160 return NoFault;
161 }
162 case LongPTE:
163 DPRINTF(PageTableWalker,
164 "Got long mode PTE entry %#016x.\n", (uint64_t)pte);
157 doWrite = !pte.a;
158 pte.a = 1;
159 entry.writable = entry.writable && pte.w;
160 entry.user = entry.user && pte.u;
161 if (badNX || !pte.p) {
162 stop();
163 return pageFault(pte.p);
164 }
165 entry.paddr = (uint64_t)pte & (mask(40) << 12);
166 entry.uncacheable = uncacheable;
167 entry.global = pte.g;
168 entry.patBit = bits(pte, 12);
169 entry.vaddr = entry.vaddr & ~((4 * (1 << 10)) - 1);
170 tlb->insert(entry.vaddr, entry);
171 stop();
172 return NoFault;
173 case PAEPDP:
165 doWrite = !pte.a;
166 pte.a = 1;
167 entry.writable = entry.writable && pte.w;
168 entry.user = entry.user && pte.u;
169 if (badNX || !pte.p) {
170 stop();
171 return pageFault(pte.p);
172 }
173 entry.paddr = (uint64_t)pte & (mask(40) << 12);
174 entry.uncacheable = uncacheable;
175 entry.global = pte.g;
176 entry.patBit = bits(pte, 12);
177 entry.vaddr = entry.vaddr & ~((4 * (1 << 10)) - 1);
178 tlb->insert(entry.vaddr, entry);
179 stop();
180 return NoFault;
181 case PAEPDP:
182 DPRINTF(PageTableWalker,
183 "Got legacy mode PAE PDP entry %#08x.\n", (uint32_t)pte);
174 nextRead = ((uint64_t)pte & (mask(40) << 12)) + vaddr.pael2 * size;
175 if (!pte.p) {
176 stop();
177 return pageFault(pte.p);
178 }
179 nextState = PAEPD;
180 break;
181 case PAEPD:
184 nextRead = ((uint64_t)pte & (mask(40) << 12)) + vaddr.pael2 * size;
185 if (!pte.p) {
186 stop();
187 return pageFault(pte.p);
188 }
189 nextState = PAEPD;
190 break;
191 case PAEPD:
192 DPRINTF(PageTableWalker,
193 "Got legacy mode PAE PD entry %#08x.\n", (uint32_t)pte);
182 doWrite = !pte.a;
183 pte.a = 1;
184 entry.writable = pte.w;
185 entry.user = pte.u;
186 if (badNX || !pte.p) {
187 stop();
188 return pageFault(pte.p);
189 }

--- 11 unchanged lines hidden (view full) ---

201 entry.global = pte.g;
202 entry.patBit = bits(pte, 12);
203 entry.vaddr = entry.vaddr & ~((2 * (1 << 20)) - 1);
204 tlb->insert(entry.vaddr, entry);
205 stop();
206 return NoFault;
207 }
208 case PAEPTE:
194 doWrite = !pte.a;
195 pte.a = 1;
196 entry.writable = pte.w;
197 entry.user = pte.u;
198 if (badNX || !pte.p) {
199 stop();
200 return pageFault(pte.p);
201 }

--- 11 unchanged lines hidden (view full) ---

213 entry.global = pte.g;
214 entry.patBit = bits(pte, 12);
215 entry.vaddr = entry.vaddr & ~((2 * (1 << 20)) - 1);
216 tlb->insert(entry.vaddr, entry);
217 stop();
218 return NoFault;
219 }
220 case PAEPTE:
221 DPRINTF(PageTableWalker,
222 "Got legacy mode PAE PTE entry %#08x.\n", (uint32_t)pte);
209 doWrite = !pte.a;
210 pte.a = 1;
211 entry.writable = entry.writable && pte.w;
212 entry.user = entry.user && pte.u;
213 if (badNX || !pte.p) {
214 stop();
215 return pageFault(pte.p);
216 }
217 entry.paddr = (uint64_t)pte & (mask(40) << 12);
218 entry.uncacheable = uncacheable;
219 entry.global = pte.g;
220 entry.patBit = bits(pte, 7);
221 entry.vaddr = entry.vaddr & ~((4 * (1 << 10)) - 1);
222 tlb->insert(entry.vaddr, entry);
223 stop();
224 return NoFault;
225 case PSEPD:
223 doWrite = !pte.a;
224 pte.a = 1;
225 entry.writable = entry.writable && pte.w;
226 entry.user = entry.user && pte.u;
227 if (badNX || !pte.p) {
228 stop();
229 return pageFault(pte.p);
230 }
231 entry.paddr = (uint64_t)pte & (mask(40) << 12);
232 entry.uncacheable = uncacheable;
233 entry.global = pte.g;
234 entry.patBit = bits(pte, 7);
235 entry.vaddr = entry.vaddr & ~((4 * (1 << 10)) - 1);
236 tlb->insert(entry.vaddr, entry);
237 stop();
238 return NoFault;
239 case PSEPD:
240 DPRINTF(PageTableWalker,
241 "Got legacy mode PSE PD entry %#08x.\n", (uint32_t)pte);
226 doWrite = !pte.a;
227 pte.a = 1;
228 entry.writable = pte.w;
229 entry.user = pte.u;
230 if (!pte.p) {
231 stop();
232 return pageFault(pte.p);
233 }

--- 12 unchanged lines hidden (view full) ---

246 entry.global = pte.g;
247 entry.patBit = bits(pte, 12);
248 entry.vaddr = entry.vaddr & ~((4 * (1 << 20)) - 1);
249 tlb->insert(entry.vaddr, entry);
250 stop();
251 return NoFault;
252 }
253 case PD:
242 doWrite = !pte.a;
243 pte.a = 1;
244 entry.writable = pte.w;
245 entry.user = pte.u;
246 if (!pte.p) {
247 stop();
248 return pageFault(pte.p);
249 }

--- 12 unchanged lines hidden (view full) ---

262 entry.global = pte.g;
263 entry.patBit = bits(pte, 12);
264 entry.vaddr = entry.vaddr & ~((4 * (1 << 20)) - 1);
265 tlb->insert(entry.vaddr, entry);
266 stop();
267 return NoFault;
268 }
269 case PD:
270 DPRINTF(PageTableWalker,
271 "Got legacy mode PD entry %#08x.\n", (uint32_t)pte);
254 doWrite = !pte.a;
255 pte.a = 1;
256 entry.writable = pte.w;
257 entry.user = pte.u;
258 if (!pte.p) {
259 stop();
260 return pageFault(pte.p);
261 }
262 // 4 KB page
263 entry.size = 4 * (1 << 10);
264 nextRead = ((uint64_t)pte & (mask(20) << 12)) + vaddr.norml2 * size;
265 nextState = PTE;
266 break;
267 case PTE:
272 doWrite = !pte.a;
273 pte.a = 1;
274 entry.writable = pte.w;
275 entry.user = pte.u;
276 if (!pte.p) {
277 stop();
278 return pageFault(pte.p);
279 }
280 // 4 KB page
281 entry.size = 4 * (1 << 10);
282 nextRead = ((uint64_t)pte & (mask(20) << 12)) + vaddr.norml2 * size;
283 nextState = PTE;
284 break;
285 case PTE:
286 DPRINTF(PageTableWalker,
287 "Got legacy mode PTE entry %#08x.\n", (uint32_t)pte);
268 doWrite = !pte.a;
269 pte.a = 1;
270 entry.writable = pte.w;
271 entry.user = pte.u;
272 if (!pte.p) {
273 stop();
274 return pageFault(pte.p);
275 }

--- 260 unchanged lines hidden (view full) ---

536 return &port;
537 else
538 panic("No page table walker port named %s!\n", if_name);
539}
540
541Fault
542Walker::pageFault(bool present)
543{
288 doWrite = !pte.a;
289 pte.a = 1;
290 entry.writable = pte.w;
291 entry.user = pte.u;
292 if (!pte.p) {
293 stop();
294 return pageFault(pte.p);
295 }

--- 260 unchanged lines hidden (view full) ---

556 return &port;
557 else
558 panic("No page table walker port named %s!\n", if_name);
559}
560
561Fault
562Walker::pageFault(bool present)
563{
564 DPRINTF(PageTableWalker, "Raising page fault.\n");
544 HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
545 return new PageFault(entry.vaddr, present, write,
546 m5reg.cpl == 3, false, execute && enableNX);
547}
548
549}
550
551X86ISA::Walker *
552X86PagetableWalkerParams::create()
553{
554 return new X86ISA::Walker(this);
555}
565 HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
566 return new PageFault(entry.vaddr, present, write,
567 m5reg.cpl == 3, false, execute && enableNX);
568}
569
570}
571
572X86ISA::Walker *
573X86PagetableWalkerParams::create()
574{
575 return new X86ISA::Walker(this);
576}