2c2
< * Copyright (c) 2010 ARM Limited
---
> * Copyright (c) 2010-2013 ARM Limited
46a47
> #include "arch/arm/system.hh"
57a59,61
> bool aarch64;
> uint8_t intWidth;
>
67a72,76
> int64_t shiftReg64(uint64_t base, uint64_t shiftAmt,
> ArmShiftType type, uint8_t width) const;
> int64_t extendReg64(uint64_t base, ArmExtendType type,
> uint64_t shiftAmt, uint8_t width) const;
>
137a147,151
> aarch64 = machInst.aarch64;
> if (bits(machInst, 28, 24) == 0x10)
> intWidth = 64; // Force 64-bit width for ADR/ADRP
> else
> intWidth = (aarch64 && bits(machInst, 31)) ? 64 : 32;
145c159,165
< bool withPred = true) const;
---
> bool withPred = true,
> bool withCond64 = false,
> ConditionCode cond64 = COND_UC) const;
> void printTarget(std::ostream &os, Addr target,
> const SymbolTable *symtab) const;
> void printCondition(std::ostream &os, unsigned code,
> bool noImplicit=false) const;
151a172,174
> void printExtendOperand(bool firstOperand, std::ostream &os,
> IntRegIndex rm, ArmExtendType type,
> int64_t shiftAmt) const;
169,170c192,193
< cpsrWriteByInstr(CPSR cpsr, uint32_t val,
< uint8_t byteMask, bool affectState, bool nmfi)
---
> cpsrWriteByInstr(CPSR cpsr, uint32_t val, SCR scr, NSACR nsacr,
> uint8_t byteMask, bool affectState, bool nmfi, ThreadContext *tc)
172c195,198
< bool privileged = (cpsr.mode != MODE_USER);
---
> bool privileged = (cpsr.mode != MODE_USER);
> bool haveVirt = ArmSystem::haveVirtualization(tc);
> bool haveSecurity = ArmSystem::haveSecurity(tc);
> bool isSecure = inSecureState(scr, cpsr) || !haveSecurity;
185c211,212
< unsigned lowIdx = privileged ? 8 : 9;
---
> unsigned lowIdx = (privileged && (isSecure || scr.aw || haveVirt))
> ? 8 : 9;
190,192c217,257
< bitMask = bitMask | mask(7, 6);
< if (!badMode((OperatingMode)(val & mask(5)))) {
< bitMask = bitMask | mask(5);
---
> bitMask |= 1 << 7;
> if ( (!nmfi || !((val >> 6) & 0x1)) &&
> (isSecure || scr.fw || haveVirt) ) {
> bitMask |= 1 << 6;
> }
> // Now check the new mode is allowed
> OperatingMode newMode = (OperatingMode) (val & mask(5));
> OperatingMode oldMode = (OperatingMode)(uint32_t)cpsr.mode;
> if (!badMode(newMode)) {
> bool validModeChange = true;
> // Check for attempts to enter modes only permitted in
> // Secure state from Non-secure state. These are Monitor
> // mode ('10110'), and FIQ mode ('10001') if the Security
> // Extensions have reserved it.
> if (!isSecure && newMode == MODE_MON)
> validModeChange = false;
> if (!isSecure && newMode == MODE_FIQ && nsacr.rfr == '1')
> validModeChange = false;
> // There is no Hyp mode ('11010') in Secure state, so that
> // is UNPREDICTABLE
> if (scr.ns == '0' && newMode == MODE_HYP)
> validModeChange = false;
> // Cannot move into Hyp mode directly from a Non-secure
> // PL1 mode
> if (!isSecure && oldMode != MODE_HYP && newMode == MODE_HYP)
> validModeChange = false;
> // Cannot move out of Hyp mode with this function except
> // on an exception return
> if (oldMode == MODE_HYP && newMode != MODE_HYP && !affectState)
> validModeChange = false;
> // Must not change to 64 bit when running in 32 bit mode
> if (!opModeIs64(oldMode) && opModeIs64(newMode))
> validModeChange = false;
>
> // If we passed all of the above then set the bit mask to
> // copy the mode accross
> if (validModeChange) {
> bitMask = bitMask | mask(5);
> } else {
> warn_once("Illegal change to CPSR mode attempted\n");
> }
201,205c266
< bool cpsr_f = cpsr.f;
< uint32_t new_cpsr = ((uint32_t)cpsr & ~bitMask) | (val & bitMask);
< if (nmfi && !cpsr_f)
< new_cpsr &= ~(1 << 6);
< return new_cpsr;
---
> return ((uint32_t)cpsr & ~bitMask) | (val & bitMask);
299,303c360
< if (FullSystem) {
< return new UndefinedInstruction();
< } else {
< return new UndefinedInstruction(machInst, false, mnemonic, true);
< }
---
> return new UndefinedInstruction(machInst, false, mnemonic, true);
304a362,365
>
> public:
> virtual void
> annotateFault(ArmFault *fault) {}