diff options
Diffstat (limited to 'src/arch')
-rw-r--r-- | src/arch/arm/SConscript | 1 | ||||
-rw-r--r-- | src/arch/arm/isa.cc | 280 | ||||
-rw-r--r-- | src/arch/arm/isa.hh | 233 | ||||
-rw-r--r-- | src/arch/arm/miscregs.cc | 2 |
4 files changed, 287 insertions, 229 deletions
diff --git a/src/arch/arm/SConscript b/src/arch/arm/SConscript index 67997f4e0..06554a6fd 100644 --- a/src/arch/arm/SConscript +++ b/src/arch/arm/SConscript @@ -55,6 +55,7 @@ if env['TARGET_ISA'] == 'arm': Source('insts/pred_inst.cc') Source('insts/static_inst.cc') Source('insts/vfp.cc') + Source('isa.cc') Source('miscregs.cc') Source('nativetrace.cc') Source('tlb.cc') diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc new file mode 100644 index 000000000..3fcd25fe5 --- /dev/null +++ b/src/arch/arm/isa.cc @@ -0,0 +1,280 @@ +/* + * Copyright (c) 2010 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + * Ali Saidi + */ + +#include "arch/arm/isa.hh" + +namespace ArmISA +{ + +MiscReg +ISA::readMiscRegNoEffect(int misc_reg) +{ + assert(misc_reg < NumMiscRegs); + if (misc_reg == MISCREG_SPSR) { + CPSR cpsr = miscRegs[MISCREG_CPSR]; + switch (cpsr.mode) { + case MODE_USER: + return miscRegs[MISCREG_SPSR]; + case MODE_FIQ: + return miscRegs[MISCREG_SPSR_FIQ]; + case MODE_IRQ: + return miscRegs[MISCREG_SPSR_IRQ]; + case MODE_SVC: + return miscRegs[MISCREG_SPSR_SVC]; + case MODE_MON: + return miscRegs[MISCREG_SPSR_MON]; + case MODE_ABORT: + return miscRegs[MISCREG_SPSR_ABT]; + case MODE_UNDEFINED: + return miscRegs[MISCREG_SPSR_UND]; + default: + return miscRegs[MISCREG_SPSR]; + } + } + return miscRegs[misc_reg]; +} + + +MiscReg +ISA::readMiscReg(int misc_reg, ThreadContext *tc) +{ + if (misc_reg == MISCREG_CPSR) { + CPSR cpsr = miscRegs[misc_reg]; + Addr pc = tc->readPC(); + if (pc & (ULL(1) << PcJBitShift)) + cpsr.j = 1; + else + cpsr.j = 0; + if (pc & (ULL(1) << PcTBitShift)) + cpsr.t = 1; + else + cpsr.t = 0; + return cpsr; + } + if (misc_reg >= MISCREG_CP15_UNIMP_START && + misc_reg < MISCREG_CP15_END) { + panic("Unimplemented CP15 register %s read.\n", + miscRegName[misc_reg]); + } + switch (misc_reg) { + case MISCREG_CLIDR: + warn("The clidr register always reports 0 caches.\n"); + break; + case MISCREG_CCSIDR: + warn("The ccsidr register isn't implemented and " + "always reads as 0.\n"); + break; + case MISCREG_ID_PFR0: + return 0x1031; // ThumbEE | !Jazelle | Thumb | ARM + } + return readMiscRegNoEffect(misc_reg); +} + +void +ISA::setMiscRegNoEffect(int misc_reg, const MiscReg &val) +{ + assert(misc_reg < NumMiscRegs); + if (misc_reg == MISCREG_SPSR) { + CPSR cpsr = miscRegs[MISCREG_CPSR]; + switch (cpsr.mode) { + case MODE_USER: + miscRegs[MISCREG_SPSR] = val; + return; + case MODE_FIQ: + miscRegs[MISCREG_SPSR_FIQ] = val; + return; + case MODE_IRQ: + miscRegs[MISCREG_SPSR_IRQ] = val; + return; + case MODE_SVC: + miscRegs[MISCREG_SPSR_SVC] = val; + return; + case MODE_MON: + miscRegs[MISCREG_SPSR_MON] = val; + return; + case MODE_ABORT: + miscRegs[MISCREG_SPSR_ABT] = val; + return; + case MODE_UNDEFINED: + miscRegs[MISCREG_SPSR_UND] = val; + return; + default: + miscRegs[MISCREG_SPSR] = val; + return; + } + } + miscRegs[misc_reg] = val; +} + +void +ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc) +{ + MiscReg newVal = val; + if (misc_reg == MISCREG_CPSR) { + updateRegMap(val); + CPSR cpsr = val; + DPRINTF(Arm, "Updating CPSR to %#x f:%d i:%d a:%d mode:%#x\n", + cpsr, cpsr.f, cpsr.i, cpsr.a, cpsr.mode); + Addr npc = tc->readNextPC() & ~PcModeMask; + if (cpsr.j) + npc = npc | (ULL(1) << PcJBitShift); + if (cpsr.t) + npc = npc | (ULL(1) << PcTBitShift); + + tc->setNextPC(npc); + } + if (misc_reg >= MISCREG_CP15_UNIMP_START && + misc_reg < MISCREG_CP15_END) { + panic("Unimplemented CP15 register %s wrote with %#x.\n", + miscRegName[misc_reg], val); + } + switch (misc_reg) { + case MISCREG_CPACR: + { + CPACR newCpacr = 0; + CPACR valCpacr = val; + newCpacr.cp10 = valCpacr.cp10; + newCpacr.cp11 = valCpacr.cp11; + if (newCpacr.cp10 != 0x3 || newCpacr.cp11 != 3) { + panic("Disabling coprocessors isn't implemented.\n"); + } + newVal = newCpacr; + } + break; + case MISCREG_CSSELR: + warn("The csselr register isn't implemented.\n"); + break; + case MISCREG_FPSCR: + { + const uint32_t ones = (uint32_t)(-1); + FPSCR fpscrMask = 0; + fpscrMask.ioc = ones; + fpscrMask.dzc = ones; + fpscrMask.ofc = ones; + fpscrMask.ufc = ones; + fpscrMask.ixc = ones; + fpscrMask.idc = ones; + fpscrMask.len = ones; + fpscrMask.stride = ones; + fpscrMask.rMode = ones; + fpscrMask.fz = ones; + fpscrMask.dn = ones; + fpscrMask.ahp = ones; + fpscrMask.qc = ones; + fpscrMask.v = ones; + fpscrMask.c = ones; + fpscrMask.z = ones; + fpscrMask.n = ones; + newVal = (newVal & (uint32_t)fpscrMask) | + (miscRegs[MISCREG_FPSCR] & ~(uint32_t)fpscrMask); + } + break; + case MISCREG_FPEXC: + { + const uint32_t fpexcMask = 0x60000000; + newVal = (newVal & fpexcMask) | + (miscRegs[MISCREG_FPEXC] & ~fpexcMask); + } + break; + case MISCREG_SCTLR: + { + SCTLR sctlr = miscRegs[MISCREG_SCTLR]; + SCTLR new_sctlr = newVal; + new_sctlr.nmfi = (bool)sctlr.nmfi; + miscRegs[MISCREG_SCTLR] = (MiscReg)new_sctlr; + return; + } + case MISCREG_TLBTR: + case MISCREG_MVFR0: + case MISCREG_MVFR1: + case MISCREG_MPIDR: + case MISCREG_FPSID: + return; + case MISCREG_TLBIALLIS: + case MISCREG_TLBIALL: + warn("Need to flush all TLBs in MP\n"); + tc->getITBPtr()->flushAll(); + tc->getDTBPtr()->flushAll(); + return; + case MISCREG_ITLBIALL: + tc->getITBPtr()->flushAll(); + return; + case MISCREG_DTLBIALL: + tc->getDTBPtr()->flushAll(); + return; + case MISCREG_TLBIMVAIS: + case MISCREG_TLBIMVA: + warn("Need to flush all TLBs in MP\n"); + tc->getITBPtr()->flushMvaAsid(mbits(newVal, 31, 12), + bits(newVal, 7,0)); + tc->getDTBPtr()->flushMvaAsid(mbits(newVal, 31, 12), + bits(newVal, 7,0)); + return; + case MISCREG_TLBIASIDIS: + case MISCREG_TLBIASID: + warn("Need to flush all TLBs in MP\n"); + tc->getITBPtr()->flushAsid(bits(newVal, 7,0)); + tc->getDTBPtr()->flushAsid(bits(newVal, 7,0)); + return; + case MISCREG_TLBIMVAAIS: + case MISCREG_TLBIMVAA: + warn("Need to flush all TLBs in MP\n"); + tc->getITBPtr()->flushMva(mbits(newVal, 31,12)); + tc->getDTBPtr()->flushMva(mbits(newVal, 31,12)); + return; + case MISCREG_ITLBIMVA: + tc->getITBPtr()->flushMvaAsid(mbits(newVal, 31, 12), + bits(newVal, 7,0)); + return; + case MISCREG_DTLBIMVA: + tc->getDTBPtr()->flushMvaAsid(mbits(newVal, 31, 12), + bits(newVal, 7,0)); + return; + case MISCREG_ITLBIASID: + tc->getITBPtr()->flushAsid(bits(newVal, 7,0)); + return; + case MISCREG_DTLBIASID: + tc->getDTBPtr()->flushAsid(bits(newVal, 7,0)); + return; + } + setMiscRegNoEffect(misc_reg, newVal); +} + +} diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh index 51503dbf6..ec6479f50 100644 --- a/src/arch/arm/isa.hh +++ b/src/arch/arm/isa.hh @@ -167,238 +167,13 @@ namespace ArmISA //XXX We need to initialize the rest of the state. } - MiscReg - readMiscRegNoEffect(int misc_reg) - { - assert(misc_reg < NumMiscRegs); - if (misc_reg == MISCREG_SPSR) { - CPSR cpsr = miscRegs[MISCREG_CPSR]; - switch (cpsr.mode) { - case MODE_USER: - return miscRegs[MISCREG_SPSR]; - case MODE_FIQ: - return miscRegs[MISCREG_SPSR_FIQ]; - case MODE_IRQ: - return miscRegs[MISCREG_SPSR_IRQ]; - case MODE_SVC: - return miscRegs[MISCREG_SPSR_SVC]; - case MODE_MON: - return miscRegs[MISCREG_SPSR_MON]; - case MODE_ABORT: - return miscRegs[MISCREG_SPSR_ABT]; - case MODE_UNDEFINED: - return miscRegs[MISCREG_SPSR_UND]; - default: - return miscRegs[MISCREG_SPSR]; - } - } - return miscRegs[misc_reg]; - } + MiscReg readMiscRegNoEffect(int misc_reg); - MiscReg - readMiscReg(int misc_reg, ThreadContext *tc) - { - if (misc_reg == MISCREG_CPSR) { - CPSR cpsr = miscRegs[misc_reg]; - Addr pc = tc->readPC(); - if (pc & (ULL(1) << PcJBitShift)) - cpsr.j = 1; - else - cpsr.j = 0; - if (pc & (ULL(1) << PcTBitShift)) - cpsr.t = 1; - else - cpsr.t = 0; - return cpsr; - } - if (misc_reg >= MISCREG_CP15_UNIMP_START && - misc_reg < MISCREG_CP15_END) { - panic("Unimplemented CP15 register %s read.\n", - miscRegName[misc_reg]); - } - switch (misc_reg) { - case MISCREG_CLIDR: - warn("The clidr register always reports 0 caches.\n"); - break; - case MISCREG_CCSIDR: - warn("The ccsidr register isn't implemented and " - "always reads as 0.\n"); - break; - case MISCREG_ID_PFR0: - return 0x1031; // ThumbEE | !Jazelle | Thumb | ARM - } - return readMiscRegNoEffect(misc_reg); - } + MiscReg readMiscReg(int misc_reg, ThreadContext *tc); - void - setMiscRegNoEffect(int misc_reg, const MiscReg &val) - { - assert(misc_reg < NumMiscRegs); - if (misc_reg == MISCREG_SPSR) { - CPSR cpsr = miscRegs[MISCREG_CPSR]; - switch (cpsr.mode) { - case MODE_USER: - miscRegs[MISCREG_SPSR] = val; - return; - case MODE_FIQ: - miscRegs[MISCREG_SPSR_FIQ] = val; - return; - case MODE_IRQ: - miscRegs[MISCREG_SPSR_IRQ] = val; - return; - case MODE_SVC: - miscRegs[MISCREG_SPSR_SVC] = val; - return; - case MODE_MON: - miscRegs[MISCREG_SPSR_MON] = val; - return; - case MODE_ABORT: - miscRegs[MISCREG_SPSR_ABT] = val; - return; - case MODE_UNDEFINED: - miscRegs[MISCREG_SPSR_UND] = val; - return; - default: - miscRegs[MISCREG_SPSR] = val; - return; - } - } - miscRegs[misc_reg] = val; - } - - void - setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc) - { - MiscReg newVal = val; - if (misc_reg == MISCREG_CPSR) { - updateRegMap(val); - CPSR cpsr = val; - DPRINTF(Arm, "Updating CPSR to %#x f:%d i:%d a:%d mode:%#x\n", - cpsr, cpsr.f, cpsr.i, cpsr.a, cpsr.mode); - Addr npc = tc->readNextPC() & ~PcModeMask; - if (cpsr.j) - npc = npc | (ULL(1) << PcJBitShift); - if (cpsr.t) - npc = npc | (ULL(1) << PcTBitShift); + void setMiscRegNoEffect(int misc_reg, const MiscReg &val); - tc->setNextPC(npc); - } - if (misc_reg >= MISCREG_CP15_UNIMP_START && - misc_reg < MISCREG_CP15_END) { - panic("Unimplemented CP15 register %s wrote with %#x.\n", - miscRegName[misc_reg], val); - } - switch (misc_reg) { - case MISCREG_CPACR: - { - CPACR newCpacr = 0; - CPACR valCpacr = val; - newCpacr.cp10 = valCpacr.cp10; - newCpacr.cp11 = valCpacr.cp11; - if (newCpacr.cp10 != 0x3 || newCpacr.cp11 != 3) { - panic("Disabling coprocessors isn't implemented.\n"); - } - newVal = newCpacr; - } - break; - case MISCREG_CSSELR: - warn("The csselr register isn't implemented.\n"); - break; - case MISCREG_FPSCR: - { - const uint32_t ones = (uint32_t)(-1); - FPSCR fpscrMask = 0; - fpscrMask.ioc = ones; - fpscrMask.dzc = ones; - fpscrMask.ofc = ones; - fpscrMask.ufc = ones; - fpscrMask.ixc = ones; - fpscrMask.idc = ones; - fpscrMask.len = ones; - fpscrMask.stride = ones; - fpscrMask.rMode = ones; - fpscrMask.fz = ones; - fpscrMask.dn = ones; - fpscrMask.ahp = ones; - fpscrMask.qc = ones; - fpscrMask.v = ones; - fpscrMask.c = ones; - fpscrMask.z = ones; - fpscrMask.n = ones; - newVal = (newVal & (uint32_t)fpscrMask) | - (miscRegs[MISCREG_FPSCR] & ~(uint32_t)fpscrMask); - } - break; - case MISCREG_FPEXC: - { - const uint32_t fpexcMask = 0x60000000; - newVal = (newVal & fpexcMask) | - (miscRegs[MISCREG_FPEXC] & ~fpexcMask); - } - break; - case MISCREG_SCTLR: - { - SCTLR sctlr = miscRegs[MISCREG_SCTLR]; - SCTLR new_sctlr = newVal; - new_sctlr.nmfi = (bool)sctlr.nmfi; - miscRegs[MISCREG_SCTLR] = (MiscReg)new_sctlr; - return; - } - case MISCREG_TLBTR: - case MISCREG_MVFR0: - case MISCREG_MVFR1: - case MISCREG_MPIDR: - case MISCREG_FPSID: - return; - case MISCREG_TLBIALLIS: - case MISCREG_TLBIALL: - warn("Need to flush all TLBs in MP\n"); - tc->getITBPtr()->flushAll(); - tc->getDTBPtr()->flushAll(); - return; - case MISCREG_ITLBIALL: - tc->getITBPtr()->flushAll(); - return; - case MISCREG_DTLBIALL: - tc->getDTBPtr()->flushAll(); - return; - case MISCREG_TLBIMVAIS: - case MISCREG_TLBIMVA: - warn("Need to flush all TLBs in MP\n"); - tc->getITBPtr()->flushMvaAsid(mbits(newVal, 31, 12), - bits(newVal, 7,0)); - tc->getDTBPtr()->flushMvaAsid(mbits(newVal, 31, 12), - bits(newVal, 7,0)); - return; - case MISCREG_TLBIASIDIS: - case MISCREG_TLBIASID: - warn("Need to flush all TLBs in MP\n"); - tc->getITBPtr()->flushAsid(bits(newVal, 7,0)); - tc->getDTBPtr()->flushAsid(bits(newVal, 7,0)); - return; - case MISCREG_TLBIMVAAIS: - case MISCREG_TLBIMVAA: - warn("Need to flush all TLBs in MP\n"); - tc->getITBPtr()->flushMva(mbits(newVal, 31,12)); - tc->getDTBPtr()->flushMva(mbits(newVal, 31,12)); - return; - case MISCREG_ITLBIMVA: - tc->getITBPtr()->flushMvaAsid(mbits(newVal, 31, 12), - bits(newVal, 7,0)); - return; - case MISCREG_DTLBIMVA: - tc->getDTBPtr()->flushMvaAsid(mbits(newVal, 31, 12), - bits(newVal, 7,0)); - return; - case MISCREG_ITLBIASID: - tc->getITBPtr()->flushAsid(bits(newVal, 7,0)); - return; - case MISCREG_DTLBIASID: - tc->getDTBPtr()->flushAsid(bits(newVal, 7,0)); - return; - } - setMiscRegNoEffect(misc_reg, newVal); - } + void setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc); int flattenIntIndex(int reg) diff --git a/src/arch/arm/miscregs.cc b/src/arch/arm/miscregs.cc index e4375fb8a..a6311e179 100644 --- a/src/arch/arm/miscregs.cc +++ b/src/arch/arm/miscregs.cc @@ -35,8 +35,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: Gabe Black + * Ali Saidi */ +#include "arch/arm/isa.hh" #include "arch/arm/miscregs.hh" #include "base/misc.hh" |