vtophys.cc revision 2107
17160Sgblack@eecs.umich.edu/* 27160Sgblack@eecs.umich.edu * Copyright (c) 2002-2005 The Regents of The University of Michigan 37160Sgblack@eecs.umich.edu * All rights reserved. 47160Sgblack@eecs.umich.edu * 57160Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 67160Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 77160Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 87160Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 97160Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 107160Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 117160Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 127160Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 137160Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 147160Sgblack@eecs.umich.edu * this software without specific prior written permission. 157160Sgblack@eecs.umich.edu * 167160Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 177160Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 187160Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 197160Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 207160Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 217160Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 227160Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 237160Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 247160Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 257160Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 267160Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 277160Sgblack@eecs.umich.edu */ 287160Sgblack@eecs.umich.edu 297160Sgblack@eecs.umich.edu#include <string> 307160Sgblack@eecs.umich.edu 317160Sgblack@eecs.umich.edu#include "arch/alpha/vtophys.hh" 327160Sgblack@eecs.umich.edu#include "base/trace.hh" 337160Sgblack@eecs.umich.edu#include "cpu/exec_context.hh" 347160Sgblack@eecs.umich.edu#include "mem/functional/physical.hh" 357160Sgblack@eecs.umich.edu 367160Sgblack@eecs.umich.eduusing namespace std; 377160Sgblack@eecs.umich.eduusing namespace AlphaISA; 387160Sgblack@eecs.umich.edu 397160Sgblack@eecs.umich.eduAlphaISA::PageTableEntry 407160Sgblack@eecs.umich.edukernel_pte_lookup(PhysicalMemory *pmem, Addr ptbr, AlphaISA::VAddr vaddr) 417160Sgblack@eecs.umich.edu{ 427160Sgblack@eecs.umich.edu Addr level1_pte = ptbr + vaddr.level1(); 437160Sgblack@eecs.umich.edu AlphaISA::PageTableEntry level1 = pmem->phys_read_qword(level1_pte); 447160Sgblack@eecs.umich.edu if (!level1.valid()) { 457160Sgblack@eecs.umich.edu DPRINTF(VtoPhys, "level 1 PTE not valid, va = %#\n", vaddr); 467160Sgblack@eecs.umich.edu return 0; 478302SAli.Saidi@ARM.com } 487160Sgblack@eecs.umich.edu 497160Sgblack@eecs.umich.edu Addr level2_pte = level1.paddr() + vaddr.level2(); 507160Sgblack@eecs.umich.edu AlphaISA::PageTableEntry level2 = pmem->phys_read_qword(level2_pte); 517160Sgblack@eecs.umich.edu if (!level2.valid()) { 527160Sgblack@eecs.umich.edu DPRINTF(VtoPhys, "level 2 PTE not valid, va = %#x\n", vaddr); 537160Sgblack@eecs.umich.edu return 0; 547160Sgblack@eecs.umich.edu } 558303SAli.Saidi@ARM.com 567160Sgblack@eecs.umich.edu Addr level3_pte = level2.paddr() + vaddr.level3(); 577160Sgblack@eecs.umich.edu AlphaISA::PageTableEntry level3 = pmem->phys_read_qword(level3_pte); 587160Sgblack@eecs.umich.edu if (!level3.valid()) { 597160Sgblack@eecs.umich.edu DPRINTF(VtoPhys, "level 3 PTE not valid, va = %#x\n", vaddr); 607160Sgblack@eecs.umich.edu return 0; 617160Sgblack@eecs.umich.edu } 627160Sgblack@eecs.umich.edu return level3; 637160Sgblack@eecs.umich.edu} 647160Sgblack@eecs.umich.edu 657160Sgblack@eecs.umich.eduAddr 667160Sgblack@eecs.umich.eduvtophys(PhysicalMemory *xc, Addr vaddr) 677160Sgblack@eecs.umich.edu{ 687160Sgblack@eecs.umich.edu Addr paddr = 0; 697160Sgblack@eecs.umich.edu if (AlphaISA::IsUSeg(vaddr)) 707160Sgblack@eecs.umich.edu DPRINTF(VtoPhys, "vtophys: invalid vaddr %#x", vaddr); 717160Sgblack@eecs.umich.edu else if (AlphaISA::IsK0Seg(vaddr)) 727160Sgblack@eecs.umich.edu paddr = AlphaISA::K0Seg2Phys(vaddr); 737160Sgblack@eecs.umich.edu else 747160Sgblack@eecs.umich.edu panic("vtophys: ptbr is not set on virtual lookup"); 757160Sgblack@eecs.umich.edu 767160Sgblack@eecs.umich.edu DPRINTF(VtoPhys, "vtophys(%#x) -> %#x\n", vaddr, paddr); 777160Sgblack@eecs.umich.edu 787160Sgblack@eecs.umich.edu return paddr; 797160Sgblack@eecs.umich.edu} 807160Sgblack@eecs.umich.edu 817160Sgblack@eecs.umich.eduAddr 827160Sgblack@eecs.umich.eduvtophys(ExecContext *xc, Addr addr) 837160Sgblack@eecs.umich.edu{ 847160Sgblack@eecs.umich.edu AlphaISA::VAddr vaddr = addr; 857160Sgblack@eecs.umich.edu Addr ptbr = xc->regs.ipr[AlphaISA::IPR_PALtemp20]; 867162Sgblack@eecs.umich.edu Addr paddr = 0; 877160Sgblack@eecs.umich.edu //@todo Andrew couldn't remember why he commented some of this code 887160Sgblack@eecs.umich.edu //so I put it back in. Perhaps something to do with gdb debugging? 897160Sgblack@eecs.umich.edu if (AlphaISA::PcPAL(vaddr) && (vaddr < EV5::PalMax)) { 907160Sgblack@eecs.umich.edu paddr = vaddr & ~ULL(1); 917760SGiacomo.Gabrielli@arm.com } else { 927760SGiacomo.Gabrielli@arm.com if (AlphaISA::IsK0Seg(vaddr)) { 937160Sgblack@eecs.umich.edu paddr = AlphaISA::K0Seg2Phys(vaddr); 947160Sgblack@eecs.umich.edu } else if (!ptbr) { 957160Sgblack@eecs.umich.edu paddr = vaddr; 967760SGiacomo.Gabrielli@arm.com } else { 977760SGiacomo.Gabrielli@arm.com AlphaISA::PageTableEntry pte = 987160Sgblack@eecs.umich.edu kernel_pte_lookup(xc->physmem, ptbr, vaddr); 997160Sgblack@eecs.umich.edu if (pte.valid()) 1007160Sgblack@eecs.umich.edu paddr = pte.paddr() | vaddr.offset(); 1017160Sgblack@eecs.umich.edu } 1027160Sgblack@eecs.umich.edu } 1037160Sgblack@eecs.umich.edu 1047160Sgblack@eecs.umich.edu 1057160Sgblack@eecs.umich.edu DPRINTF(VtoPhys, "vtophys(%#x) -> %#x\n", vaddr, paddr); 1067160Sgblack@eecs.umich.edu 1077160Sgblack@eecs.umich.edu return paddr; 1087160Sgblack@eecs.umich.edu} 1097160Sgblack@eecs.umich.edu 1107160Sgblack@eecs.umich.eduuint8_t * 1117160Sgblack@eecs.umich.eduptomem(ExecContext *xc, Addr paddr, size_t len) 1127160Sgblack@eecs.umich.edu{ 1137160Sgblack@eecs.umich.edu return xc->physmem->dma_addr(paddr, len); 1147160Sgblack@eecs.umich.edu} 1157160Sgblack@eecs.umich.edu 1167160Sgblack@eecs.umich.eduuint8_t * 1177160Sgblack@eecs.umich.eduvtomem(ExecContext *xc, Addr vaddr, size_t len) 1187160Sgblack@eecs.umich.edu{ 1197160Sgblack@eecs.umich.edu Addr paddr = vtophys(xc, vaddr); 1207160Sgblack@eecs.umich.edu return xc->physmem->dma_addr(paddr, len); 1217160Sgblack@eecs.umich.edu} 1227160Sgblack@eecs.umich.edu 1237160Sgblack@eecs.umich.eduvoid 1247160Sgblack@eecs.umich.eduCopyOut(ExecContext *xc, void *dest, Addr src, size_t cplen) 1257160Sgblack@eecs.umich.edu{ 1267160Sgblack@eecs.umich.edu Addr paddr; 1277160Sgblack@eecs.umich.edu char *dmaaddr; 1287160Sgblack@eecs.umich.edu char *dst = (char *)dest; 1297160Sgblack@eecs.umich.edu int len; 1307160Sgblack@eecs.umich.edu 1317160Sgblack@eecs.umich.edu paddr = vtophys(xc, src); 1327160Sgblack@eecs.umich.edu len = min((int)(AlphaISA::PageBytes - (paddr & AlphaISA::PageOffset)), 1337160Sgblack@eecs.umich.edu (int)cplen); 1347160Sgblack@eecs.umich.edu dmaaddr = (char *)xc->physmem->dma_addr(paddr, len); 1357160Sgblack@eecs.umich.edu assert(dmaaddr); 1367160Sgblack@eecs.umich.edu 1377160Sgblack@eecs.umich.edu memcpy(dst, dmaaddr, len); 1387196Sgblack@eecs.umich.edu if (len == cplen) 1397160Sgblack@eecs.umich.edu return; 1407196Sgblack@eecs.umich.edu 1417196Sgblack@eecs.umich.edu cplen -= len; 1427160Sgblack@eecs.umich.edu dst += len; 1437160Sgblack@eecs.umich.edu src += len; 1447160Sgblack@eecs.umich.edu 1457196Sgblack@eecs.umich.edu while (cplen > AlphaISA::PageBytes) { 1467160Sgblack@eecs.umich.edu paddr = vtophys(xc, src); 1477196Sgblack@eecs.umich.edu dmaaddr = (char *)xc->physmem->dma_addr(paddr, AlphaISA::PageBytes); 1487196Sgblack@eecs.umich.edu assert(dmaaddr); 1497160Sgblack@eecs.umich.edu 1507160Sgblack@eecs.umich.edu memcpy(dst, dmaaddr, AlphaISA::PageBytes); 1517160Sgblack@eecs.umich.edu cplen -= AlphaISA::PageBytes; 1527196Sgblack@eecs.umich.edu dst += AlphaISA::PageBytes; 1537160Sgblack@eecs.umich.edu src += AlphaISA::PageBytes; 1547196Sgblack@eecs.umich.edu } 1557196Sgblack@eecs.umich.edu 1567160Sgblack@eecs.umich.edu if (cplen > 0) { 1577160Sgblack@eecs.umich.edu paddr = vtophys(xc, src); 1587160Sgblack@eecs.umich.edu dmaaddr = (char *)xc->physmem->dma_addr(paddr, cplen); 1597196Sgblack@eecs.umich.edu assert(dmaaddr); 1607160Sgblack@eecs.umich.edu 1617196Sgblack@eecs.umich.edu memcpy(dst, dmaaddr, cplen); 1627196Sgblack@eecs.umich.edu } 1637160Sgblack@eecs.umich.edu} 1647160Sgblack@eecs.umich.edu 1657160Sgblack@eecs.umich.eduvoid 1667160Sgblack@eecs.umich.eduCopyIn(ExecContext *xc, Addr dest, void *source, size_t cplen) 1677160Sgblack@eecs.umich.edu{ 1687160Sgblack@eecs.umich.edu Addr paddr; 1697160Sgblack@eecs.umich.edu char *dmaaddr; 1707228Sgblack@eecs.umich.edu char *src = (char *)source; 1717228Sgblack@eecs.umich.edu int len; 1727160Sgblack@eecs.umich.edu 1737160Sgblack@eecs.umich.edu paddr = vtophys(xc, dest); 1747160Sgblack@eecs.umich.edu len = min((int)(AlphaISA::PageBytes - (paddr & AlphaISA::PageOffset)), 1757160Sgblack@eecs.umich.edu (int)cplen); 1767160Sgblack@eecs.umich.edu dmaaddr = (char *)xc->physmem->dma_addr(paddr, len); 1777160Sgblack@eecs.umich.edu assert(dmaaddr); 1787160Sgblack@eecs.umich.edu 1797228Sgblack@eecs.umich.edu memcpy(dmaaddr, src, len); 1807228Sgblack@eecs.umich.edu if (len == cplen) 1817160Sgblack@eecs.umich.edu return; 1827160Sgblack@eecs.umich.edu 1837160Sgblack@eecs.umich.edu cplen -= len; 1847160Sgblack@eecs.umich.edu src += len; 1857160Sgblack@eecs.umich.edu dest += len; 1867160Sgblack@eecs.umich.edu 1877160Sgblack@eecs.umich.edu while (cplen > AlphaISA::PageBytes) { 1887160Sgblack@eecs.umich.edu paddr = vtophys(xc, dest); 1897160Sgblack@eecs.umich.edu dmaaddr = (char *)xc->physmem->dma_addr(paddr, AlphaISA::PageBytes); 1907160Sgblack@eecs.umich.edu assert(dmaaddr); 1917160Sgblack@eecs.umich.edu 1927160Sgblack@eecs.umich.edu memcpy(dmaaddr, src, AlphaISA::PageBytes); 1937160Sgblack@eecs.umich.edu cplen -= AlphaISA::PageBytes; 1947160Sgblack@eecs.umich.edu src += AlphaISA::PageBytes; 1957160Sgblack@eecs.umich.edu dest += AlphaISA::PageBytes; 1967160Sgblack@eecs.umich.edu } 1977160Sgblack@eecs.umich.edu 1987160Sgblack@eecs.umich.edu if (cplen > 0) { 1997160Sgblack@eecs.umich.edu paddr = vtophys(xc, dest); 2007160Sgblack@eecs.umich.edu dmaaddr = (char *)xc->physmem->dma_addr(paddr, cplen); 2017160Sgblack@eecs.umich.edu assert(dmaaddr); 2027160Sgblack@eecs.umich.edu 2037160Sgblack@eecs.umich.edu memcpy(dmaaddr, src, cplen); 2047160Sgblack@eecs.umich.edu } 2057160Sgblack@eecs.umich.edu} 2067160Sgblack@eecs.umich.edu 2077160Sgblack@eecs.umich.eduvoid 2087160Sgblack@eecs.umich.eduCopyString(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen) 2097160Sgblack@eecs.umich.edu{ 2107160Sgblack@eecs.umich.edu Addr paddr; 2117160Sgblack@eecs.umich.edu char *dmaaddr; 2127160Sgblack@eecs.umich.edu int len; 2137160Sgblack@eecs.umich.edu 2147160Sgblack@eecs.umich.edu paddr = vtophys(xc, vaddr); 2157160Sgblack@eecs.umich.edu len = min((int)(AlphaISA::PageBytes - (paddr & AlphaISA::PageOffset)), 2167160Sgblack@eecs.umich.edu (int)maxlen); 2177160Sgblack@eecs.umich.edu dmaaddr = (char *)xc->physmem->dma_addr(paddr, len); 2187160Sgblack@eecs.umich.edu assert(dmaaddr); 2197160Sgblack@eecs.umich.edu 2207160Sgblack@eecs.umich.edu char *term = (char *)memchr(dmaaddr, 0, len); 2217160Sgblack@eecs.umich.edu if (term) 2227160Sgblack@eecs.umich.edu len = term - dmaaddr + 1; 2237160Sgblack@eecs.umich.edu 2247160Sgblack@eecs.umich.edu memcpy(dst, dmaaddr, len); 2257160Sgblack@eecs.umich.edu 2267160Sgblack@eecs.umich.edu if (term || len == maxlen) 2277160Sgblack@eecs.umich.edu return; 2287160Sgblack@eecs.umich.edu 2297160Sgblack@eecs.umich.edu maxlen -= len; 2307160Sgblack@eecs.umich.edu dst += len; 2317160Sgblack@eecs.umich.edu vaddr += len; 2327160Sgblack@eecs.umich.edu 2337160Sgblack@eecs.umich.edu while (maxlen > AlphaISA::PageBytes) { 2347160Sgblack@eecs.umich.edu paddr = vtophys(xc, vaddr); 2357160Sgblack@eecs.umich.edu dmaaddr = (char *)xc->physmem->dma_addr(paddr, AlphaISA::PageBytes); 2367160Sgblack@eecs.umich.edu assert(dmaaddr); 2377160Sgblack@eecs.umich.edu 2387196Sgblack@eecs.umich.edu char *term = (char *)memchr(dmaaddr, 0, AlphaISA::PageBytes); 2397196Sgblack@eecs.umich.edu len = term ? (term - dmaaddr + 1) : AlphaISA::PageBytes; 2407196Sgblack@eecs.umich.edu 2417160Sgblack@eecs.umich.edu memcpy(dst, dmaaddr, len); 2427160Sgblack@eecs.umich.edu if (term) 2437160Sgblack@eecs.umich.edu return; 2447160Sgblack@eecs.umich.edu 2457196Sgblack@eecs.umich.edu maxlen -= AlphaISA::PageBytes; 2467196Sgblack@eecs.umich.edu dst += AlphaISA::PageBytes; 2477196Sgblack@eecs.umich.edu vaddr += AlphaISA::PageBytes; 2487160Sgblack@eecs.umich.edu } 2497160Sgblack@eecs.umich.edu 2507160Sgblack@eecs.umich.edu if (maxlen > 0) { 2517160Sgblack@eecs.umich.edu paddr = vtophys(xc, vaddr); 2527160Sgblack@eecs.umich.edu dmaaddr = (char *)xc->physmem->dma_addr(paddr, maxlen); 2537160Sgblack@eecs.umich.edu assert(dmaaddr); 2547160Sgblack@eecs.umich.edu 2557228Sgblack@eecs.umich.edu char *term = (char *)memchr(dmaaddr, 0, maxlen); 2567228Sgblack@eecs.umich.edu len = term ? (term - dmaaddr + 1) : maxlen; 2577160Sgblack@eecs.umich.edu 2587160Sgblack@eecs.umich.edu memcpy(dst, dmaaddr, len); 2597160Sgblack@eecs.umich.edu 2607160Sgblack@eecs.umich.edu maxlen -= len; 2617160Sgblack@eecs.umich.edu } 2627160Sgblack@eecs.umich.edu 2637160Sgblack@eecs.umich.edu if (maxlen == 0) 2647228Sgblack@eecs.umich.edu dst[maxlen] = '\0'; 2657228Sgblack@eecs.umich.edu} 2667160Sgblack@eecs.umich.edu