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