tlb.cc revision 8098
16112SN/A/* 26112SN/A * Copyright (c) 2007-2008 The Hewlett-Packard Development Company 36112SN/A * All rights reserved. 49988Snilay@cs.wisc.edu * 58835SAli.Saidi@ARM.com * The license below extends only to copyright in the software and shall 69988Snilay@cs.wisc.edu * not be construed as granting a license to any other intellectual 77935SN/A * property including but not limited to intellectual property relating 87935SN/A * to a hardware implementation of the functionality of the software 97935SN/A * licensed hereunder. You may use the software subject to the license 106112SN/A * terms below provided that you ensure that this notice is replicated 116112SN/A * unmodified and in its entirety in all distributions of the software, 126112SN/A * modified or unmodified, in source code or in binary form. 1310315Snilay@cs.wisc.edu * 148835SAli.Saidi@ARM.com * Redistribution and use in source and binary forms, with or without 159885Sstever@gmail.com * modification, are permitted provided that the following conditions are 169885Sstever@gmail.com * met: redistributions of source code must retain the above copyright 179988Snilay@cs.wisc.edu * notice, this list of conditions and the following disclaimer; 188835SAli.Saidi@ARM.com * redistributions in binary form must reproduce the above copyright 198835SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer in the 2010315Snilay@cs.wisc.edu * documentation and/or other materials provided with the distribution; 218835SAli.Saidi@ARM.com * neither the name of the copyright holders nor the names of its 2210063Snilay@cs.wisc.edu * contributors may be used to endorse or promote products derived from 236112SN/A * this software without specific prior written permission. 249481Snilay@cs.wisc.edu * 258721SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 268721SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 278835SAli.Saidi@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 288835SAli.Saidi@ARM.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 297935SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 307935SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 317935SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 327935SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 337935SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 347935SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 357935SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 369885Sstever@gmail.com * 379885Sstever@gmail.com * Authors: Gabe Black 389885Sstever@gmail.com */ 399885Sstever@gmail.com 409885Sstever@gmail.com#include <cstring> 4110315Snilay@cs.wisc.edu 429988Snilay@cs.wisc.edu#include "config/full_system.hh" 4310315Snilay@cs.wisc.edu 449885Sstever@gmail.com#include "arch/x86/faults.hh" 456112SN/A#include "arch/x86/insts/microldstop.hh" 466112SN/A#include "arch/x86/pagetable.hh" 476112SN/A#include "arch/x86/regs/misc.hh" 489481Snilay@cs.wisc.edu#include "arch/x86/tlb.hh" 4910063Snilay@cs.wisc.edu#include "arch/x86/x86_traits.hh" 506112SN/A#include "base/bitfield.hh" 519885Sstever@gmail.com#include "base/trace.hh" 526112SN/A#include "config/full_system.hh" 536112SN/A#include "cpu/thread_context.hh" 548835SAli.Saidi@ARM.com#include "cpu/base.hh" 556112SN/A#include "mem/packet_access.hh" 566112SN/A#include "mem/request.hh" 579988Snilay@cs.wisc.edu 586112SN/A#if FULL_SYSTEM 596112SN/A#include "arch/x86/pagetable_walker.hh" 608835SAli.Saidi@ARM.com#else 619481Snilay@cs.wisc.edu#include "mem/page_table.hh" 626112SN/A#include "sim/process.hh" 636112SN/A#endif 646112SN/A 656112SN/Anamespace X86ISA { 666112SN/A 676112SN/ATLB::TLB(const Params *p) : BaseTLB(p), configAddress(0), size(p->size) 688835SAli.Saidi@ARM.com{ 696112SN/A tlb = new TlbEntry[size]; 709885Sstever@gmail.com std::memset(tlb, 0, sizeof(TlbEntry) * size); 7110315Snilay@cs.wisc.edu 729481Snilay@cs.wisc.edu for (int x = 0; x < size; x++) 736112SN/A freeList.push_back(&tlb[x]); 746112SN/A 756112SN/A#if FULL_SYSTEM 766112SN/A walker = p->walker; 776112SN/A walker->setTLB(this); 786112SN/A#endif 796112SN/A} 806112SN/A 819885Sstever@gmail.comTlbEntry * 828983Snate@binkert.orgTLB::insert(Addr vpn, TlbEntry &entry) 836112SN/A{ 849885Sstever@gmail.com //TODO Deal with conflicting entries 859988Snilay@cs.wisc.edu 866123SN/A TlbEntry *newEntry = NULL; 879348SAli.Saidi@ARM.com if (!freeList.empty()) { 888241SN/A newEntry = freeList.front(); 896112SN/A freeList.pop_front(); 906112SN/A } else { 916112SN/A newEntry = entryList.back(); 928835SAli.Saidi@ARM.com entryList.pop_back(); 939348SAli.Saidi@ARM.com } 9410036SAli.Saidi@ARM.com *newEntry = entry; 956112SN/A newEntry->vaddr = vpn; 968835SAli.Saidi@ARM.com entryList.push_front(newEntry); 979885Sstever@gmail.com return newEntry; 989348SAli.Saidi@ARM.com} 996112SN/A 1006112SN/ATLB::EntryList::iterator 1016112SN/ATLB::lookupIt(Addr va, bool update_lru) 1028983Snate@binkert.org{ 1036112SN/A //TODO make this smarter at some point 1049885Sstever@gmail.com EntryList::iterator entry; 1059885Sstever@gmail.com for (entry = entryList.begin(); entry != entryList.end(); entry++) { 1069885Sstever@gmail.com if ((*entry)->vaddr <= va && (*entry)->vaddr + (*entry)->size > va) { 1079885Sstever@gmail.com DPRINTF(TLB, "Matched vaddr %#x to entry starting at %#x " 1089885Sstever@gmail.com "with size %#x.\n", va, (*entry)->vaddr, (*entry)->size); 1099988Snilay@cs.wisc.edu if (update_lru) { 1109885Sstever@gmail.com entryList.push_front(*entry); 11110036SAli.Saidi@ARM.com entryList.erase(entry); 1129885Sstever@gmail.com entry = entryList.begin(); 1139885Sstever@gmail.com } 1146112SN/A break; 1156112SN/A } 1169988Snilay@cs.wisc.edu } 1176112SN/A return entry; 1186112SN/A} 1196112SN/A 1206112SN/ATlbEntry * 1219885Sstever@gmail.comTLB::lookup(Addr va, bool update_lru) 1228983Snate@binkert.org{ 1236112SN/A EntryList::iterator entry = lookupIt(va, update_lru); 1249885Sstever@gmail.com if (entry == entryList.end()) 1259988Snilay@cs.wisc.edu return NULL; 1266123SN/A else 1279348SAli.Saidi@ARM.com return *entry; 1288241SN/A} 1296112SN/A 1306112SN/Avoid 1316112SN/ATLB::invalidateAll() 1328835SAli.Saidi@ARM.com{ 1339348SAli.Saidi@ARM.com DPRINTF(TLB, "Invalidating all entries.\n"); 13410036SAli.Saidi@ARM.com while (!entryList.empty()) { 1356112SN/A TlbEntry *entry = entryList.front(); 1368835SAli.Saidi@ARM.com entryList.pop_front(); 1379885Sstever@gmail.com freeList.push_back(entry); 1389348SAli.Saidi@ARM.com } 1396112SN/A} 1406112SN/A 1416112SN/Avoid 1428983Snate@binkert.orgTLB::setConfigAddress(uint32_t addr) 1436112SN/A{ 1449885Sstever@gmail.com configAddress = addr; 1459885Sstever@gmail.com} 1469885Sstever@gmail.com 1479885Sstever@gmail.comvoid 1489885Sstever@gmail.comTLB::invalidateNonGlobal() 1499988Snilay@cs.wisc.edu{ 1509885Sstever@gmail.com DPRINTF(TLB, "Invalidating all non global entries.\n"); 15110036SAli.Saidi@ARM.com EntryList::iterator entryIt; 1529885Sstever@gmail.com for (entryIt = entryList.begin(); entryIt != entryList.end();) { 1539885Sstever@gmail.com if (!(*entryIt)->global) { 1548835SAli.Saidi@ARM.com freeList.push_back(*entryIt); 1558835SAli.Saidi@ARM.com entryList.erase(entryIt++); 1569988Snilay@cs.wisc.edu } else { 1578835SAli.Saidi@ARM.com entryIt++; 1589481Snilay@cs.wisc.edu } 1599481Snilay@cs.wisc.edu } 1609988Snilay@cs.wisc.edu} 1619481Snilay@cs.wisc.edu 1626112SN/Avoid 1636112SN/ATLB::demapPage(Addr va, uint64_t asn) 1649988Snilay@cs.wisc.edu{ 1656112SN/A EntryList::iterator entry = lookupIt(va, false); 1666112SN/A if (entry != entryList.end()) { 1676112SN/A freeList.push_back(*entry); 1686112SN/A entryList.erase(entry); 1699988Snilay@cs.wisc.edu } 1706112SN/A} 1716112SN/A 1726112SN/AFault 1736112SN/ATLB::translateInt(RequestPtr req, ThreadContext *tc) 1746112SN/A{ 1756112SN/A DPRINTF(TLB, "Addresses references internal memory.\n"); 1766112SN/A Addr vaddr = req->getVaddr(); 1776112SN/A Addr prefix = (vaddr >> 3) & IntAddrPrefixMask; 1786112SN/A if (prefix == IntAddrPrefixCPUID) { 1799988Snilay@cs.wisc.edu panic("CPUID memory space not yet implemented!\n"); 18010315Snilay@cs.wisc.edu } else if (prefix == IntAddrPrefixMSR) { 1816112SN/A vaddr = vaddr >> 3; 1826112SN/A req->setFlags(Request::MMAPED_IPR); 1836112SN/A Addr regNum = 0; 1846112SN/A switch (vaddr & ~IntAddrPrefixMask) { 1856112SN/A case 0x10: 1866112SN/A regNum = MISCREG_TSC; 1876112SN/A break; 1886112SN/A case 0x1B: 1896112SN/A regNum = MISCREG_APIC_BASE; 1906112SN/A break; 1916112SN/A case 0xFE: 1926112SN/A regNum = MISCREG_MTRRCAP; 1939481Snilay@cs.wisc.edu break; 19410063Snilay@cs.wisc.edu case 0x174: 1956112SN/A regNum = MISCREG_SYSENTER_CS; 1969885Sstever@gmail.com break; 1976112SN/A case 0x175: 1986112SN/A regNum = MISCREG_SYSENTER_ESP; 1998835SAli.Saidi@ARM.com break; 2006112SN/A case 0x176: 2016112SN/A regNum = MISCREG_SYSENTER_EIP; 2029988Snilay@cs.wisc.edu break; 2036112SN/A case 0x179: 2046112SN/A regNum = MISCREG_MCG_CAP; 2058835SAli.Saidi@ARM.com break; 2069481Snilay@cs.wisc.edu case 0x17A: 2076112SN/A regNum = MISCREG_MCG_STATUS; 2086112SN/A break; 2096112SN/A case 0x17B: 2106112SN/A regNum = MISCREG_MCG_CTL; 2116112SN/A break; 2126112SN/A case 0x1D9: 2138835SAli.Saidi@ARM.com regNum = MISCREG_DEBUG_CTL_MSR; 2146112SN/A break; 2159885Sstever@gmail.com case 0x1DB: 21610315Snilay@cs.wisc.edu regNum = MISCREG_LAST_BRANCH_FROM_IP; 2179481Snilay@cs.wisc.edu break; 2186112SN/A case 0x1DC: 2196112SN/A regNum = MISCREG_LAST_BRANCH_TO_IP; 2206112SN/A break; 2216112SN/A case 0x1DD: 2226112SN/A regNum = MISCREG_LAST_EXCEPTION_FROM_IP; 2236112SN/A break; 2246112SN/A case 0x1DE: 2256112SN/A regNum = MISCREG_LAST_EXCEPTION_TO_IP; 2269885Sstever@gmail.com break; 2278983Snate@binkert.org case 0x200: 2286112SN/A regNum = MISCREG_MTRR_PHYS_BASE_0; 2299885Sstever@gmail.com break; 2309988Snilay@cs.wisc.edu case 0x201: 2316123SN/A regNum = MISCREG_MTRR_PHYS_MASK_0; 2329348SAli.Saidi@ARM.com break; 2338241SN/A case 0x202: 2346112SN/A regNum = MISCREG_MTRR_PHYS_BASE_1; 2356112SN/A break; 2366112SN/A case 0x203: 2378835SAli.Saidi@ARM.com regNum = MISCREG_MTRR_PHYS_MASK_1; 2389348SAli.Saidi@ARM.com break; 23910036SAli.Saidi@ARM.com case 0x204: 2406112SN/A regNum = MISCREG_MTRR_PHYS_BASE_2; 2418835SAli.Saidi@ARM.com break; 2429885Sstever@gmail.com case 0x205: 2439348SAli.Saidi@ARM.com regNum = MISCREG_MTRR_PHYS_MASK_2; 2446112SN/A break; 2456112SN/A case 0x206: 2466112SN/A regNum = MISCREG_MTRR_PHYS_BASE_3; 2478983Snate@binkert.org break; 2486112SN/A case 0x207: 2499885Sstever@gmail.com regNum = MISCREG_MTRR_PHYS_MASK_3; 2509885Sstever@gmail.com break; 2519885Sstever@gmail.com case 0x208: 2529885Sstever@gmail.com regNum = MISCREG_MTRR_PHYS_BASE_4; 2539885Sstever@gmail.com break; 2549988Snilay@cs.wisc.edu case 0x209: 2559885Sstever@gmail.com regNum = MISCREG_MTRR_PHYS_MASK_4; 25610036SAli.Saidi@ARM.com break; 2579885Sstever@gmail.com case 0x20A: 2589885Sstever@gmail.com regNum = MISCREG_MTRR_PHYS_BASE_5; 2596112SN/A break; 2606112SN/A case 0x20B: 2619988Snilay@cs.wisc.edu regNum = MISCREG_MTRR_PHYS_MASK_5; 2626112SN/A break; 2636112SN/A case 0x20C: 2646112SN/A regNum = MISCREG_MTRR_PHYS_BASE_6; 2656112SN/A break; 2669885Sstever@gmail.com case 0x20D: 2678983Snate@binkert.org regNum = MISCREG_MTRR_PHYS_MASK_6; 2686112SN/A break; 2699885Sstever@gmail.com case 0x20E: 2709988Snilay@cs.wisc.edu regNum = MISCREG_MTRR_PHYS_BASE_7; 2716123SN/A break; 2729348SAli.Saidi@ARM.com case 0x20F: 2738241SN/A regNum = MISCREG_MTRR_PHYS_MASK_7; 2746112SN/A break; 2756112SN/A case 0x250: 2766112SN/A regNum = MISCREG_MTRR_FIX_64K_00000; 2778835SAli.Saidi@ARM.com break; 2789348SAli.Saidi@ARM.com case 0x258: 27910036SAli.Saidi@ARM.com regNum = MISCREG_MTRR_FIX_16K_80000; 2806112SN/A break; 2818835SAli.Saidi@ARM.com case 0x259: 2829885Sstever@gmail.com regNum = MISCREG_MTRR_FIX_16K_A0000; 2839348SAli.Saidi@ARM.com break; 2846112SN/A case 0x268: 2856112SN/A regNum = MISCREG_MTRR_FIX_4K_C0000; 2866112SN/A break; 2878983Snate@binkert.org case 0x269: 2886112SN/A regNum = MISCREG_MTRR_FIX_4K_C8000; 2899885Sstever@gmail.com break; 2909885Sstever@gmail.com case 0x26A: 2919885Sstever@gmail.com regNum = MISCREG_MTRR_FIX_4K_D0000; 2929885Sstever@gmail.com break; 2939885Sstever@gmail.com case 0x26B: 2949988Snilay@cs.wisc.edu regNum = MISCREG_MTRR_FIX_4K_D8000; 2959885Sstever@gmail.com break; 29610036SAli.Saidi@ARM.com case 0x26C: 2979885Sstever@gmail.com regNum = MISCREG_MTRR_FIX_4K_E0000; 2989885Sstever@gmail.com break; 2998835SAli.Saidi@ARM.com case 0x26D: 3008835SAli.Saidi@ARM.com regNum = MISCREG_MTRR_FIX_4K_E8000; 3019988Snilay@cs.wisc.edu break; 3028835SAli.Saidi@ARM.com case 0x26E: 3039481Snilay@cs.wisc.edu regNum = MISCREG_MTRR_FIX_4K_F0000; 3049481Snilay@cs.wisc.edu break; 3059988Snilay@cs.wisc.edu case 0x26F: 3069481Snilay@cs.wisc.edu regNum = MISCREG_MTRR_FIX_4K_F8000; 3076112SN/A break; 3086112SN/A case 0x277: 3099988Snilay@cs.wisc.edu regNum = MISCREG_PAT; 3106112SN/A break; 3116112SN/A case 0x2FF: 3126112SN/A regNum = MISCREG_DEF_TYPE; 3136112SN/A break; 3149988Snilay@cs.wisc.edu case 0x400: 3156112SN/A regNum = MISCREG_MC0_CTL; 3166112SN/A break; 3176112SN/A case 0x404: 3189481Snilay@cs.wisc.edu regNum = MISCREG_MC1_CTL; 31910063Snilay@cs.wisc.edu break; 3206112SN/A case 0x408: 3219885Sstever@gmail.com regNum = MISCREG_MC2_CTL; 3226112SN/A break; 3236112SN/A case 0x40C: 3248835SAli.Saidi@ARM.com regNum = MISCREG_MC3_CTL; 3256112SN/A break; 3266112SN/A case 0x410: 3279988Snilay@cs.wisc.edu regNum = MISCREG_MC4_CTL; 3286112SN/A break; 3296112SN/A case 0x414: 3308835SAli.Saidi@ARM.com regNum = MISCREG_MC5_CTL; 3319481Snilay@cs.wisc.edu break; 3326112SN/A case 0x418: 3336112SN/A regNum = MISCREG_MC6_CTL; 3346112SN/A break; 3356112SN/A case 0x41C: 3366112SN/A regNum = MISCREG_MC7_CTL; 3376112SN/A break; 3388835SAli.Saidi@ARM.com case 0x401: 3396112SN/A regNum = MISCREG_MC0_STATUS; 3409885Sstever@gmail.com break; 34110315Snilay@cs.wisc.edu case 0x405: 3429481Snilay@cs.wisc.edu regNum = MISCREG_MC1_STATUS; 3436112SN/A break; 3446112SN/A case 0x409: 3456112SN/A regNum = MISCREG_MC2_STATUS; 3466112SN/A break; 3476112SN/A case 0x40D: 3486112SN/A regNum = MISCREG_MC3_STATUS; 3496112SN/A break; 3506112SN/A case 0x411: 3519885Sstever@gmail.com regNum = MISCREG_MC4_STATUS; 3528983Snate@binkert.org break; 3536112SN/A case 0x415: 3549885Sstever@gmail.com regNum = MISCREG_MC5_STATUS; 3559988Snilay@cs.wisc.edu break; 3566123SN/A case 0x419: 3579348SAli.Saidi@ARM.com regNum = MISCREG_MC6_STATUS; 3588241SN/A break; 3596112SN/A case 0x41D: 3606112SN/A regNum = MISCREG_MC7_STATUS; 3616112SN/A break; 3628835SAli.Saidi@ARM.com case 0x402: 3639348SAli.Saidi@ARM.com regNum = MISCREG_MC0_ADDR; 36410036SAli.Saidi@ARM.com break; 3656112SN/A case 0x406: 3668835SAli.Saidi@ARM.com regNum = MISCREG_MC1_ADDR; 3679885Sstever@gmail.com break; 3689348SAli.Saidi@ARM.com case 0x40A: 3696112SN/A regNum = MISCREG_MC2_ADDR; 3706112SN/A break; 3716112SN/A case 0x40E: 3728983Snate@binkert.org regNum = MISCREG_MC3_ADDR; 3736112SN/A break; 3749885Sstever@gmail.com case 0x412: 3759885Sstever@gmail.com regNum = MISCREG_MC4_ADDR; 3769885Sstever@gmail.com break; 3779885Sstever@gmail.com case 0x416: 3789885Sstever@gmail.com regNum = MISCREG_MC5_ADDR; 3799988Snilay@cs.wisc.edu break; 3809885Sstever@gmail.com case 0x41A: 38110036SAli.Saidi@ARM.com regNum = MISCREG_MC6_ADDR; 3829885Sstever@gmail.com break; 3839885Sstever@gmail.com case 0x41E: 3846112SN/A regNum = MISCREG_MC7_ADDR; 3856112SN/A break; 3869988Snilay@cs.wisc.edu case 0x403: 3876112SN/A regNum = MISCREG_MC0_MISC; 3886112SN/A break; 3896112SN/A case 0x407: 3906112SN/A regNum = MISCREG_MC1_MISC; 3919885Sstever@gmail.com break; 3928983Snate@binkert.org case 0x40B: 3936112SN/A regNum = MISCREG_MC2_MISC; 3949885Sstever@gmail.com break; 3959988Snilay@cs.wisc.edu case 0x40F: 3966123SN/A regNum = MISCREG_MC3_MISC; 3979348SAli.Saidi@ARM.com break; 3988241SN/A case 0x413: 3996112SN/A regNum = MISCREG_MC4_MISC; 4006112SN/A break; 4016112SN/A case 0x417: 4028835SAli.Saidi@ARM.com regNum = MISCREG_MC5_MISC; 4039348SAli.Saidi@ARM.com break; 40410036SAli.Saidi@ARM.com case 0x41B: 4056112SN/A regNum = MISCREG_MC6_MISC; 4068835SAli.Saidi@ARM.com break; 4079885Sstever@gmail.com case 0x41F: 4089348SAli.Saidi@ARM.com regNum = MISCREG_MC7_MISC; 4096112SN/A break; 4106112SN/A case 0xC0000080: 4116112SN/A regNum = MISCREG_EFER; 4128983Snate@binkert.org break; 4136112SN/A case 0xC0000081: 4149885Sstever@gmail.com regNum = MISCREG_STAR; 4159885Sstever@gmail.com break; 4169885Sstever@gmail.com case 0xC0000082: 4179885Sstever@gmail.com regNum = MISCREG_LSTAR; 4189885Sstever@gmail.com break; 4199988Snilay@cs.wisc.edu case 0xC0000083: 4209885Sstever@gmail.com regNum = MISCREG_CSTAR; 42110036SAli.Saidi@ARM.com break; 4229885Sstever@gmail.com case 0xC0000084: 4239885Sstever@gmail.com regNum = MISCREG_SF_MASK; 4248835SAli.Saidi@ARM.com break; 4258835SAli.Saidi@ARM.com case 0xC0000100: 4269988Snilay@cs.wisc.edu regNum = MISCREG_FS_BASE; 4278835SAli.Saidi@ARM.com break; 4289481Snilay@cs.wisc.edu case 0xC0000101: 4299481Snilay@cs.wisc.edu regNum = MISCREG_GS_BASE; 4309988Snilay@cs.wisc.edu break; 4319481Snilay@cs.wisc.edu case 0xC0000102: 4326112SN/A regNum = MISCREG_KERNEL_GS_BASE; 4336112SN/A break; 4349988Snilay@cs.wisc.edu case 0xC0000103: 4356112SN/A regNum = MISCREG_TSC_AUX; 4366112SN/A break; 4376112SN/A case 0xC0010000: 4386112SN/A regNum = MISCREG_PERF_EVT_SEL0; 4399988Snilay@cs.wisc.edu break; 4406112SN/A case 0xC0010001: 4416112SN/A regNum = MISCREG_PERF_EVT_SEL1; 4426112SN/A break; 4439481Snilay@cs.wisc.edu case 0xC0010002: 44410063Snilay@cs.wisc.edu regNum = MISCREG_PERF_EVT_SEL2; 4456112SN/A break; 4469885Sstever@gmail.com case 0xC0010003: 4476112SN/A regNum = MISCREG_PERF_EVT_SEL3; 4486112SN/A break; 4498835SAli.Saidi@ARM.com case 0xC0010004: 4506112SN/A regNum = MISCREG_PERF_EVT_CTR0; 4516112SN/A break; 4529988Snilay@cs.wisc.edu case 0xC0010005: 4536112SN/A regNum = MISCREG_PERF_EVT_CTR1; 4546112SN/A break; 4558835SAli.Saidi@ARM.com case 0xC0010006: 4569481Snilay@cs.wisc.edu regNum = MISCREG_PERF_EVT_CTR2; 4576112SN/A break; 4586112SN/A case 0xC0010007: 4596112SN/A regNum = MISCREG_PERF_EVT_CTR3; 4606112SN/A break; 4616112SN/A case 0xC0010010: 4626112SN/A regNum = MISCREG_SYSCFG; 4638835SAli.Saidi@ARM.com break; 4646112SN/A case 0xC0010016: 4659885Sstever@gmail.com regNum = MISCREG_IORR_BASE0; 46610315Snilay@cs.wisc.edu break; 4679481Snilay@cs.wisc.edu case 0xC0010017: 4686112SN/A regNum = MISCREG_IORR_BASE1; 4696112SN/A break; 4706112SN/A case 0xC0010018: 4716112SN/A regNum = MISCREG_IORR_MASK0; 4726112SN/A break; 4736112SN/A case 0xC0010019: 4746112SN/A regNum = MISCREG_IORR_MASK1; 4756112SN/A break; 4769885Sstever@gmail.com case 0xC001001A: 4778983Snate@binkert.org regNum = MISCREG_TOP_MEM; 4786112SN/A break; 4799885Sstever@gmail.com case 0xC001001D: 4809988Snilay@cs.wisc.edu regNum = MISCREG_TOP_MEM2; 4816123SN/A break; 4829348SAli.Saidi@ARM.com case 0xC0010114: 4838241SN/A regNum = MISCREG_VM_CR; 4846112SN/A break; 4856112SN/A case 0xC0010115: 4866112SN/A regNum = MISCREG_IGNNE; 4878835SAli.Saidi@ARM.com break; 4889348SAli.Saidi@ARM.com case 0xC0010116: 48910036SAli.Saidi@ARM.com regNum = MISCREG_SMM_CTL; 4906112SN/A break; 4918835SAli.Saidi@ARM.com case 0xC0010117: 4929885Sstever@gmail.com regNum = MISCREG_VM_HSAVE_PA; 4939348SAli.Saidi@ARM.com break; 4946112SN/A default: 4956112SN/A return new GeneralProtection(0); 4966112SN/A } 4978983Snate@binkert.org //The index is multiplied by the size of a MiscReg so that 4986112SN/A //any memory dependence calculations will not see these as 4999885Sstever@gmail.com //overlapping. 5009885Sstever@gmail.com req->setPaddr(regNum * sizeof(MiscReg)); 5019885Sstever@gmail.com return NoFault; 5029885Sstever@gmail.com } else if (prefix == IntAddrPrefixIO) { 5039885Sstever@gmail.com // TODO If CPL > IOPL or in virtual mode, check the I/O permission 5049988Snilay@cs.wisc.edu // bitmap in the TSS. 5059885Sstever@gmail.com 50610036SAli.Saidi@ARM.com Addr IOPort = vaddr & ~IntAddrPrefixMask; 5079885Sstever@gmail.com // Make sure the address fits in the expected 16 bit IO address 5089885Sstever@gmail.com // space. 5096112SN/A assert(!(IOPort & ~0xFFFF)); 5106112SN/A if (IOPort == 0xCF8 && req->getSize() == 4) { 5119988Snilay@cs.wisc.edu req->setFlags(Request::MMAPED_IPR); 5126112SN/A req->setPaddr(MISCREG_PCI_CONFIG_ADDRESS * sizeof(MiscReg)); 5136112SN/A } else if ((IOPort & ~mask(2)) == 0xCFC) { 5146112SN/A req->setFlags(Request::UNCACHEABLE); 5156112SN/A Addr configAddress = 5169885Sstever@gmail.com tc->readMiscRegNoEffect(MISCREG_PCI_CONFIG_ADDRESS); 5178983Snate@binkert.org if (bits(configAddress, 31, 31)) { 5186112SN/A req->setPaddr(PhysAddrPrefixPciConfig | 5199885Sstever@gmail.com mbits(configAddress, 30, 2) | 5209988Snilay@cs.wisc.edu (IOPort & mask(2))); 5216123SN/A } else { 5229348SAli.Saidi@ARM.com req->setPaddr(PhysAddrPrefixIO | IOPort); 5238241SN/A } 5246112SN/A } else { 5256112SN/A req->setFlags(Request::UNCACHEABLE); 5266112SN/A req->setPaddr(PhysAddrPrefixIO | IOPort); 5278835SAli.Saidi@ARM.com } 5289348SAli.Saidi@ARM.com return NoFault; 52910036SAli.Saidi@ARM.com } else { 5306112SN/A panic("Access to unrecognized internal address space %#x.\n", 5318835SAli.Saidi@ARM.com prefix); 5329885Sstever@gmail.com } 5339348SAli.Saidi@ARM.com} 5346112SN/A 5356112SN/AFault 5366112SN/ATLB::translate(RequestPtr req, ThreadContext *tc, Translation *translation, 5378983Snate@binkert.org Mode mode, bool &delayedResponse, bool timing) 5386112SN/A{ 5399885Sstever@gmail.com uint32_t flags = req->getFlags(); 5409885Sstever@gmail.com int seg = flags & SegmentFlagMask; 5419885Sstever@gmail.com bool storeCheck = flags & (StoreCheck << FlagShift); 5429885Sstever@gmail.com 5439885Sstever@gmail.com // If this is true, we're dealing with a request to a non-memory address 5449988Snilay@cs.wisc.edu // space. 5459885Sstever@gmail.com if (seg == SEGMENT_REG_MS) { 54610036SAli.Saidi@ARM.com return translateInt(req, tc); 5479885Sstever@gmail.com } 5489885Sstever@gmail.com 5498835SAli.Saidi@ARM.com delayedResponse = false; 5508835SAli.Saidi@ARM.com Addr vaddr = req->getVaddr(); 5519988Snilay@cs.wisc.edu DPRINTF(TLB, "Translating vaddr %#x.\n", vaddr); 5528835SAli.Saidi@ARM.com 5539481Snilay@cs.wisc.edu HandyM5Reg m5Reg = tc->readMiscRegNoEffect(MISCREG_M5_REG); 5549481Snilay@cs.wisc.edu 5559988Snilay@cs.wisc.edu // If protected mode has been enabled... 5569481Snilay@cs.wisc.edu if (m5Reg.prot) { 5576112SN/A DPRINTF(TLB, "In protected mode.\n"); 5586112SN/A // If we're not in 64-bit mode, do protection/limit checks 5599988Snilay@cs.wisc.edu if (m5Reg.mode != LongMode) { 5606112SN/A DPRINTF(TLB, "Not in long mode. Checking segment protection.\n"); 5616112SN/A // Check for a NULL segment selector. 5626112SN/A if (!(seg == SEGMENT_REG_TSG || seg == SYS_SEGMENT_REG_IDTR || 5636112SN/A seg == SEGMENT_REG_HS || seg == SEGMENT_REG_LS) 5649988Snilay@cs.wisc.edu && !tc->readMiscRegNoEffect(MISCREG_SEG_SEL(seg))) 5656112SN/A return new GeneralProtection(0); 5669885Sstever@gmail.com bool expandDown = false; 5679885Sstever@gmail.com SegAttr attr = tc->readMiscRegNoEffect(MISCREG_SEG_ATTR(seg)); 5689885Sstever@gmail.com if (seg >= SEGMENT_REG_ES && seg <= SEGMENT_REG_HS) { 56910315Snilay@cs.wisc.edu if (!attr.writable && (mode == Write || storeCheck)) 5709988Snilay@cs.wisc.edu return new GeneralProtection(0); 57110315Snilay@cs.wisc.edu if (!attr.readable && mode == Read) 5729885Sstever@gmail.com return new GeneralProtection(0); 5739885Sstever@gmail.com expandDown = attr.expandDown; 57410315Snilay@cs.wisc.edu 57510315Snilay@cs.wisc.edu } 57610315Snilay@cs.wisc.edu Addr base = tc->readMiscRegNoEffect(MISCREG_SEG_BASE(seg)); 57710315Snilay@cs.wisc.edu Addr limit = tc->readMiscRegNoEffect(MISCREG_SEG_LIMIT(seg)); 57810315Snilay@cs.wisc.edu // This assumes we're not in 64 bit mode. If we were, the default 57910315Snilay@cs.wisc.edu // address size is 64 bits, overridable to 32. 58010315Snilay@cs.wisc.edu int size = 32; 58110315Snilay@cs.wisc.edu bool sizeOverride = (flags & (AddrSizeFlagBit << FlagShift)); 5826112SN/A SegAttr csAttr = tc->readMiscRegNoEffect(MISCREG_CS_ATTR); 5836112SN/A if ((csAttr.defaultSize && sizeOverride) || 5849885Sstever@gmail.com (!csAttr.defaultSize && !sizeOverride)) 5858983Snate@binkert.org size = 16; 5866112SN/A Addr offset = bits(vaddr - base, size-1, 0); 5879885Sstever@gmail.com Addr endOffset = offset + req->getSize() - 1; 5889988Snilay@cs.wisc.edu if (expandDown) { 5896123SN/A DPRINTF(TLB, "Checking an expand down segment.\n"); 5909348SAli.Saidi@ARM.com warn_once("Expand down segments are untested.\n"); 5918241SN/A if (offset <= limit || endOffset <= limit) 5926112SN/A return new GeneralProtection(0); 5939348SAli.Saidi@ARM.com } else { 5946112SN/A if (offset > limit || endOffset > limit) 5958835SAli.Saidi@ARM.com return new GeneralProtection(0); 5969348SAli.Saidi@ARM.com } 59710036SAli.Saidi@ARM.com } 5986112SN/A // If paging is enabled, do the translation. 5998835SAli.Saidi@ARM.com if (m5Reg.paging) { 6009885Sstever@gmail.com DPRINTF(TLB, "Paging enabled.\n"); 6019348SAli.Saidi@ARM.com // The vaddr already has the segment base applied. 6026112SN/A TlbEntry *entry = lookup(vaddr); 6036112SN/A if (!entry) { 6048983Snate@binkert.org#if FULL_SYSTEM 6059885Sstever@gmail.com Fault fault = walker->start(tc, translation, req, mode); 6069885Sstever@gmail.com if (timing || fault != NoFault) { 6079885Sstever@gmail.com // This gets ignored in atomic mode. 6089885Sstever@gmail.com delayedResponse = true; 6099885Sstever@gmail.com return fault; 6109885Sstever@gmail.com } 6119885Sstever@gmail.com entry = lookup(vaddr); 6129988Snilay@cs.wisc.edu assert(entry); 6139885Sstever@gmail.com#else 61410036SAli.Saidi@ARM.com DPRINTF(TLB, "Handling a TLB miss for " 6159885Sstever@gmail.com "address %#x at pc %#x.\n", 6166112SN/A vaddr, tc->instAddr()); 6176112SN/A 6189055Ssaidi@eecs.umich.edu Process *p = tc->getProcessPtr(); 6199885Sstever@gmail.com TlbEntry newEntry; 6209988Snilay@cs.wisc.edu bool success = p->pTable->lookup(vaddr, newEntry); 6216112SN/A if (!success && mode != Execute) { 6229620Snilay@cs.wisc.edu p->checkAndAllocNextPage(vaddr); 6237524SN/A success = p->pTable->lookup(vaddr, newEntry); 6249096Sandreas.hansson@arm.com } 6259150SAli.Saidi@ARM.com if (!success) { 6269885Sstever@gmail.com return new PageFault(vaddr, true, mode, true, false); 6276112SN/A } else { 6286112SN/A Addr alignedVaddr = p->pTable->pageAlign(vaddr); 6298983Snate@binkert.org DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr, 6309276Snilay@cs.wisc.edu newEntry.pageStart()); 6319885Sstever@gmail.com entry = insert(alignedVaddr, newEntry); 6329885Sstever@gmail.com } 6339988Snilay@cs.wisc.edu DPRINTF(TLB, "Miss was serviced.\n"); 6348983Snate@binkert.org#endif 6356112SN/A } 6366112SN/A // Do paging protection checks. 6376112SN/A bool inUser = (m5Reg.cpl == 3 && 6386112SN/A !(flags & (CPL0FlagBit << FlagShift))); 6398983Snate@binkert.org CR0 cr0 = tc->readMiscRegNoEffect(MISCREG_CR0); 6406112SN/A bool badWrite = (!entry->writable && (inUser || cr0.wp)); 6416112SN/A if ((inUser && !entry->user) || (mode == Write && badWrite)) { 6429055Ssaidi@eecs.umich.edu // The page must have been present to get into the TLB in 6439885Sstever@gmail.com // the first place. We'll assume the reserved bits are 6449988Snilay@cs.wisc.edu // fine even though we're not checking them. 6456112SN/A return new PageFault(vaddr, true, mode, inUser, false); 6469620Snilay@cs.wisc.edu } 6477524SN/A if (storeCheck && badWrite) { 6489096Sandreas.hansson@arm.com // This would fault if this were a write, so return a page 6498983Snate@binkert.org // fault that reflects that happening. 6508983Snate@binkert.org return new PageFault(vaddr, true, Write, inUser, false); 6516112SN/A } 6529885Sstever@gmail.com 6539885Sstever@gmail.com 6549988Snilay@cs.wisc.edu DPRINTF(TLB, "Entry found with paddr %#x, " 6559885Sstever@gmail.com "doing protection checks.\n", entry->paddr); 6569885Sstever@gmail.com Addr paddr = entry->paddr | (vaddr & (entry->size-1)); 657 DPRINTF(TLB, "Translated %#x -> %#x.\n", vaddr, paddr); 658 req->setPaddr(paddr); 659 if (entry->uncacheable) 660 req->setFlags(Request::UNCACHEABLE); 661 } else { 662 //Use the address which already has segmentation applied. 663 DPRINTF(TLB, "Paging disabled.\n"); 664 DPRINTF(TLB, "Translated %#x -> %#x.\n", vaddr, vaddr); 665 req->setPaddr(vaddr); 666 } 667 } else { 668 // Real mode 669 DPRINTF(TLB, "In real mode.\n"); 670 DPRINTF(TLB, "Translated %#x -> %#x.\n", vaddr, vaddr); 671 req->setPaddr(vaddr); 672 } 673 // Check for an access to the local APIC 674#if FULL_SYSTEM 675 LocalApicBase localApicBase = tc->readMiscRegNoEffect(MISCREG_APIC_BASE); 676 Addr baseAddr = localApicBase.base * PageBytes; 677 Addr paddr = req->getPaddr(); 678 if (baseAddr <= paddr && baseAddr + PageBytes > paddr) { 679 // The Intel developer's manuals say the below restrictions apply, 680 // but the linux kernel, because of a compiler optimization, breaks 681 // them. 682 /* 683 // Check alignment 684 if (paddr & ((32/8) - 1)) 685 return new GeneralProtection(0); 686 // Check access size 687 if (req->getSize() != (32/8)) 688 return new GeneralProtection(0); 689 */ 690 // Force the access to be uncacheable. 691 req->setFlags(Request::UNCACHEABLE); 692 req->setPaddr(x86LocalAPICAddress(tc->contextId(), paddr - baseAddr)); 693 } 694#endif 695 return NoFault; 696}; 697 698Fault 699TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode) 700{ 701 bool delayedResponse; 702 return TLB::translate(req, tc, NULL, mode, delayedResponse, false); 703} 704 705void 706TLB::translateTiming(RequestPtr req, ThreadContext *tc, 707 Translation *translation, Mode mode) 708{ 709 bool delayedResponse; 710 assert(translation); 711 Fault fault = 712 TLB::translate(req, tc, translation, mode, delayedResponse, true); 713 if (!delayedResponse) 714 translation->finish(fault, req, tc, mode); 715} 716 717#if FULL_SYSTEM 718 719Tick 720TLB::doMmuRegRead(ThreadContext *tc, Packet *pkt) 721{ 722 return tc->getCpuPtr()->ticks(1); 723} 724 725Tick 726TLB::doMmuRegWrite(ThreadContext *tc, Packet *pkt) 727{ 728 return tc->getCpuPtr()->ticks(1); 729} 730 731Walker * 732TLB::getWalker() 733{ 734 return walker; 735} 736 737#endif 738 739void 740TLB::serialize(std::ostream &os) 741{ 742} 743 744void 745TLB::unserialize(Checkpoint *cp, const std::string §ion) 746{ 747} 748 749} // namespace X86ISA 750 751X86ISA::TLB * 752X86TLBParams::create() 753{ 754 return new X86ISA::TLB(this); 755} 756