utility.cc revision 8286
12158SN/A/* 22158SN/A * Copyright (c) 2009-2010 ARM Limited 32158SN/A * All rights reserved. 42158SN/A * 52158SN/A * The license below extends only to copyright in the software and shall 62158SN/A * not be construed as granting a license to any other intellectual 72158SN/A * property including but not limited to intellectual property relating 82158SN/A * to a hardware implementation of the functionality of the software 92158SN/A * licensed hereunder. You may use the software subject to the license 102158SN/A * terms below provided that you ensure that this notice is replicated 112158SN/A * unmodified and in its entirety in all distributions of the software, 122158SN/A * modified or unmodified, in source code or in binary form. 132158SN/A * 142158SN/A * Redistribution and use in source and binary forms, with or without 152158SN/A * modification, are permitted provided that the following conditions are 162158SN/A * met: redistributions of source code must retain the above copyright 172158SN/A * notice, this list of conditions and the following disclaimer; 182158SN/A * redistributions in binary form must reproduce the above copyright 192158SN/A * notice, this list of conditions and the following disclaimer in the 202158SN/A * documentation and/or other materials provided with the distribution; 212158SN/A * neither the name of the copyright holders nor the names of its 222158SN/A * contributors may be used to endorse or promote products derived from 232158SN/A * this software without specific prior written permission. 242158SN/A * 252158SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 262158SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 272665Ssaidi@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 282665Ssaidi@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 292760Sbinkertn@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 302158SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 312158SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 323567Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 333567Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 342432SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 352158SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 362215SN/A * 372158SN/A * Authors: Ali Saidi 382158SN/A */ 392158SN/A 408232Snate@binkert.org 418706Sandreas.hansson@arm.com#include "arch/arm/faults.hh" 424762Snate@binkert.org#include "arch/arm/isa_traits.hh" 432158SN/A#include "arch/arm/utility.hh" 442158SN/A#include "cpu/thread_context.hh" 455568Snate@binkert.org 462158SN/A#if FULL_SYSTEM 472158SN/A#include "arch/arm/vtophys.hh" 482158SN/A#include "mem/vport.hh" 492158SN/A#endif 502158SN/A 512158SN/A#include "arch/arm/tlb.hh" 522158SN/A 532158SN/Anamespace ArmISA { 542158SN/A 552158SN/Avoid 562158SN/AinitCPU(ThreadContext *tc, int cpuId) 572158SN/A{ 584762Snate@binkert.org // Reset CP15?? What does that mean -- ali 592158SN/A 604762Snate@binkert.org // FPEXC.EN = 0 612158SN/A 622158SN/A static Fault reset = new Reset; 634762Snate@binkert.org reset->invoke(tc); 642158SN/A} 654762Snate@binkert.org 668706Sandreas.hansson@arm.comuint64_t 672158SN/AgetArgument(ThreadContext *tc, int &number, uint16_t size, bool fp) 688706Sandreas.hansson@arm.com{ 698706Sandreas.hansson@arm.com#if FULL_SYSTEM 708706Sandreas.hansson@arm.com if (size == (uint16_t)(-1)) 718706Sandreas.hansson@arm.com size = ArmISA::MachineBytes; 728706Sandreas.hansson@arm.com if (fp) 738706Sandreas.hansson@arm.com panic("getArgument(): Floating point arguments not implemented\n"); 748706Sandreas.hansson@arm.com 758706Sandreas.hansson@arm.com if (number < NumArgumentRegs) { 768706Sandreas.hansson@arm.com // If the argument is 64 bits, it must be in an even regiser number 778706Sandreas.hansson@arm.com // Increment the number here if it isn't even 788706Sandreas.hansson@arm.com if (size == sizeof(uint64_t)) { 798706Sandreas.hansson@arm.com if ((number % 2) != 0) 808706Sandreas.hansson@arm.com number++; 818706Sandreas.hansson@arm.com // Read the two halves of the data 828706Sandreas.hansson@arm.com // number is inc here to get the second half of the 64 bit reg 838706Sandreas.hansson@arm.com uint64_t tmp; 848706Sandreas.hansson@arm.com tmp = tc->readIntReg(number++); 858706Sandreas.hansson@arm.com tmp |= tc->readIntReg(number) << 32; 862158SN/A return tmp; 872158SN/A } else { 888706Sandreas.hansson@arm.com return tc->readIntReg(number); 898706Sandreas.hansson@arm.com } 902158SN/A } else { 912158SN/A Addr sp = tc->readIntReg(StackPointerReg); 922158SN/A VirtualPort *vp = tc->getVirtPort(); 932158SN/A uint64_t arg; 942158SN/A if (size == sizeof(uint64_t)) { 952158SN/A // If the argument is even it must be aligned 962158SN/A if ((number % 2) != 0) 972158SN/A number++; 982158SN/A arg = vp->read<uint64_t>(sp + 992158SN/A (number-NumArgumentRegs) * sizeof(uint32_t)); 1002158SN/A // since two 32 bit args == 1 64 bit arg, increment number 1012158SN/A number++; 1022158SN/A } else { 1032158SN/A arg = vp->read<uint32_t>(sp + 1042158SN/A (number-NumArgumentRegs) * sizeof(uint32_t)); 1052158SN/A } 1062158SN/A return arg; 1072158SN/A } 1082158SN/A#else 1092158SN/A panic("getArgument() only implemented for FULL_SYSTEM\n"); 1102158SN/A M5_DUMMY_RETURN 1112158SN/A#endif 1122158SN/A} 1132158SN/A 1142158SN/Avoid 1152158SN/AskipFunction(ThreadContext *tc) 1162158SN/A{ 1172158SN/A TheISA::PCState newPC = tc->pcState(); 1182158SN/A newPC.set(tc->readIntReg(ReturnAddressReg) & ~ULL(1)); 1192158SN/A tc->pcState(newPC); 1202158SN/A} 1212158SN/A 1228706Sandreas.hansson@arm.comvoid 1238706Sandreas.hansson@arm.comcopyRegs(ThreadContext *src, ThreadContext *dest) 1242158SN/A{ 1252158SN/A int i; 1262158SN/A 1272158SN/A int saved_mode = ((CPSR)src->readMiscReg(MISCREG_CPSR)).mode; 1282158SN/A 1292158SN/A // Make sure we're in user mode, so we can easily see all the registers 1302158SN/A // in the copy loop 1312521SN/A src->setMiscReg(MISCREG_CPSR_MODE, MODE_USER); 1322521SN/A dest->setMiscReg(MISCREG_CPSR_MODE, MODE_USER); 1338706Sandreas.hansson@arm.com 1342521SN/A for(i = 0; i < TheISA::NumIntRegs; i++) 1358706Sandreas.hansson@arm.com dest->setIntReg(i, src->readIntReg(i)); 1362158SN/A 1372158SN/A // Restore us back to the old mode 1382158SN/A src->setMiscReg(MISCREG_CPSR_MODE, saved_mode); 1392158SN/A dest->setMiscReg(MISCREG_CPSR_MODE, saved_mode); 1402158SN/A 1412158SN/A for(i = 0; i < TheISA::NumFloatRegs; i++) 1422158SN/A dest->setFloatReg(i, src->readFloatReg(i)); 1432158SN/A for(i = 0; i < TheISA::NumMiscRegs; i++) 1442158SN/A dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i)); 1452158SN/A 1462158SN/A // setMiscReg "with effect" will set the misc register mapping correctly. 1472158SN/A // e.g. updateRegMap(val) 1482158SN/A dest->setMiscReg(MISCREG_CPSR, src->readMiscRegNoEffect(MISCREG_CPSR)); 1492158SN/A 1502158SN/A // Copy over the PC State 1512158SN/A dest->pcState(src->pcState()); 1525543Ssaidi@eecs.umich.edu 1535543Ssaidi@eecs.umich.edu // Invalidate the tlb misc register cache 1545543Ssaidi@eecs.umich.edu dest->getITBPtr()->invalidateMiscReg(); 1552158SN/A dest->getDTBPtr()->invalidateMiscReg(); 1562158SN/A} 1572158SN/A 1582158SN/AAddr 1592158SN/AtruncPage(Addr addr) 1602158SN/A{ 1612158SN/A return addr & ~(PageBytes - 1); 1622158SN/A} 1632158SN/A 1642158SN/AAddr 1652158SN/AroundPage(Addr addr) 1662158SN/A{ 1672158SN/A return (addr + PageBytes - 1) & ~(PageBytes - 1); 1682158SN/A} 1692158SN/A 1702158SN/A} // namespace ArmISA 1712158SN/A