vtophys.cc revision 2521
12SN/A/* 21762SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan 32SN/A * All rights reserved. 42SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu */ 282665Ssaidi@eecs.umich.edu 292665Ssaidi@eecs.umich.edu#include <string> 302SN/A 312SN/A#include "arch/alpha/ev5.hh" 322090SN/A#include "arch/alpha/vtophys.hh" 332090SN/A#include "base/chunk_generator.hh" 342SN/A#include "base/trace.hh" 352502SN/A#include "cpu/exec_context.hh" 362090SN/A#include "mem/vport.hh" 372147SN/A 382166SN/Ausing namespace std; 392147SN/Ausing namespace AlphaISA; 402167SN/A 412167SN/AAlphaISA::PageTableEntry 422167SN/AAlphaISA::kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, AlphaISA::VAddr vaddr) 432147SN/A{ 442090SN/A Addr level1_pte = ptbr + vaddr.level1(); 452222SN/A AlphaISA::PageTableEntry level1 = mem->read<uint64_t>(level1_pte); 462090SN/A if (!level1.valid()) { 472201SN/A DPRINTF(VtoPhys, "level 1 PTE not valid, va = %#\n", vaddr); 482201SN/A return 0; 492201SN/A } 502112SN/A 512174SN/A Addr level2_pte = level1.paddr() + vaddr.level2(); 522680Sktlim@umich.edu AlphaISA::PageTableEntry level2 = mem->read<uint64_t>(level2_pte); 532174SN/A if (!level2.valid()) { 542175SN/A DPRINTF(VtoPhys, "level 2 PTE not valid, va = %#x\n", vaddr); 552222SN/A return 0; 562SN/A } 572SN/A 582203SN/A Addr level3_pte = level2.paddr() + vaddr.level3(); 592166SN/A AlphaISA::PageTableEntry level3 = mem->read<uint64_t>(level3_pte); 602166SN/A if (!level3.valid()) { 612203SN/A DPRINTF(VtoPhys, "level 3 PTE not valid, va = %#x\n", vaddr); 622166SN/A return 0; 632222SN/A } 642166SN/A return level3; 652203SN/A} 662166SN/A 672222SN/AAddr 682203SN/AAlphaISA::vtophys(Addr vaddr) 692166SN/A{ 702166SN/A Addr paddr = 0; 712203SN/A if (AlphaISA::IsUSeg(vaddr)) 722166SN/A DPRINTF(VtoPhys, "vtophys: invalid vaddr %#x", vaddr); 732166SN/A else if (AlphaISA::IsK0Seg(vaddr)) 742203SN/A paddr = AlphaISA::K0Seg2Phys(vaddr); 752166SN/A else 762222SN/A panic("vtophys: ptbr is not set on virtual lookup"); 772166SN/A 782203SN/A DPRINTF(VtoPhys, "vtophys(%#x) -> %#x\n", vaddr, paddr); 792166SN/A 802222SN/A return paddr; 812203SN/A} 822166SN/A 832166SN/AAddr 842166SN/AAlphaISA::vtophys(ExecContext *xc, Addr addr) 852166SN/A{ 862203SN/A AlphaISA::VAddr vaddr = addr; 872166SN/A Addr ptbr = xc->readMiscReg(AlphaISA::IPR_PALtemp20); 882166SN/A Addr paddr = 0; 892166SN/A //@todo Andrew couldn't remember why he commented some of this code 902166SN/A //so I put it back in. Perhaps something to do with gdb debugging? 912203SN/A if (AlphaISA::PcPAL(vaddr) && (vaddr < EV5::PalMax)) { 922166SN/A paddr = vaddr & ~ULL(1); 932166SN/A } else { 942147SN/A if (AlphaISA::IsK0Seg(vaddr)) { 952090SN/A paddr = AlphaISA::K0Seg2Phys(vaddr); 962147SN/A } else if (!ptbr) { 972147SN/A paddr = vaddr; 982147SN/A } else { 992222SN/A AlphaISA::PageTableEntry pte = 1002112SN/A kernel_pte_lookup(xc->getPhysPort(), ptbr, vaddr); 1012147SN/A if (pte.valid()) 1022147SN/A paddr = pte.paddr() | vaddr.offset(); 1032222SN/A } 1042147SN/A } 1052090SN/A 1062147SN/A 1072090SN/A DPRINTF(VtoPhys, "vtophys(%#x) -> %#x\n", vaddr, paddr); 1082201SN/A 1092201SN/A return paddr; 1102147SN/A} 1112147SN/A 1122147SN/A 1132222SN/Avoid 1142112SN/AAlphaISA::CopyOut(ExecContext *xc, void *dest, Addr src, size_t cplen) 1152147SN/A{ 1162147SN/A uint8_t *dst = (uint8_t *)dest; 1172222SN/A VirtualPort *vp = xc->getVirtPort(xc); 1182203SN/A 1192680Sktlim@umich.edu vp->readBlob(src, dst, cplen); 1202203SN/A 1212147SN/A xc->delVirtPort(vp); 1222090SN/A 1232147SN/A} 1242090SN/A 1252201SN/Avoid 1262201SN/AAlphaISA::CopyIn(ExecContext *xc, Addr dest, void *source, size_t cplen) 1272147SN/A{ 1282147SN/A uint8_t *src = (uint8_t *)source; 1292147SN/A VirtualPort *vp = xc->getVirtPort(xc); 1302222SN/A 1312112SN/A vp->writeBlob(dest, src, cplen); 1322147SN/A 1332147SN/A xc->delVirtPort(vp); 1342222SN/A} 1352147SN/A 1362090SN/Avoid 1372502SN/AAlphaISA::CopyStringOut(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen) 1382502SN/A{ 1392502SN/A int len = 0; 1402502SN/A VirtualPort *vp = xc->getVirtPort(xc); 1412502SN/A 1422502SN/A do { 1432502SN/A vp->readBlob(vaddr++, (uint8_t*)dst++, 1); 1442502SN/A len++; 1452502SN/A } while (len < maxlen && dst[len] != 0 ); 1462502SN/A 1472502SN/A xc->delVirtPort(vp); 1482502SN/A dst[len] = 0; 1492502SN/A} 1502502SN/A 1512502SN/Avoid 1522502SN/AAlphaISA::CopyStringIn(ExecContext *xc, char *src, Addr vaddr) 1532680Sktlim@umich.edu{ 1542502SN/A VirtualPort *vp = xc->getVirtPort(xc); 1552502SN/A for (ChunkGenerator gen(vaddr, strlen(src), AlphaISA::PageBytes); !gen.done(); 1562502SN/A gen.next()) 1572502SN/A { 1582090SN/A vp->writeBlob(gen.addr(), (uint8_t*)src, gen.size()); 1592147SN/A src += gen.size(); 1602147SN/A } 1612147SN/A xc->delVirtPort(vp); 1622222SN/A} 1632112SN/A