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} |