arch-arm: Add Illegal Execution flag to PCState

This patch moves the detection of the Illegal Execution flag (PSTATE.IL)
from the tlb translation stage (fetch) to the decoding stage.  This is
done by adding the illegalExecution field to the PCState.

Change-Id: I9c1c4e9c6bd5ded905c1d56b3034e4e9322582fa
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/10813
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
This commit is contained in:
Giacomo Travaglini
2018-05-29 16:30:33 +01:00
parent 831184d294
commit fe8faa62b7
10 changed files with 77 additions and 21 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2014 ARM Limited
* Copyright (c) 2012-2014,2018 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -179,6 +179,8 @@ Decoder::decode(ArmISA::PCState &pc)
if (foundIt)
pc.nextItstate(itBits);
this_emi.itstate = pc.itstate();
this_emi.illegalExecution = pc.illegalExec() ? 1 : 0;
pc.size(inst_size);
emi = 0;

View File

@@ -601,6 +601,7 @@ ArmFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
pc.nextJazelle(pc.jazelle());
pc.aarch64(!cpsr.width);
pc.nextAArch64(!cpsr.width);
pc.illegalExec(false);
tc->pcState(pc);
}
@@ -684,6 +685,7 @@ ArmFault::invoke64(ThreadContext *tc, const StaticInstPtr &inst)
PCState pc(new_pc);
pc.aarch64(!cpsr.width);
pc.nextAArch64(!cpsr.width);
pc.illegalExec(false);
tc->pcState(pc);
// If we have a valid instruction then use it to annotate this fault with

View File

@@ -249,3 +249,13 @@ McrMrcImplDefined::generateDisassembly(Addr pc,
{
return csprintf("%-10s (implementation defined)", mnemonic);
}
IllegalExecInst::IllegalExecInst(ExtMachInst _machInst)
: ArmStaticInst("Illegal Execution", _machInst, No_OpClass)
{}
Fault
IllegalExecInst::execute(ExecContext *xc, Trace::InstRecord *traceData) const
{
return std::make_shared<IllegalInstSetStateFault>();
}

View File

@@ -161,4 +161,19 @@ class McrMrcImplDefined : public McrMrcMiscInst
};
/**
* This class is modelling instructions which are not going to be
* executed since they are flagged as Illegal Execution Instructions
* (PSTATE.IL = 1 or CPSR.IL = 1).
* The sole purpose of this instruction is to generate an appropriate
* fault when executed.
*/
class IllegalExecInst : public ArmStaticInst
{
public:
IllegalExecInst(ExtMachInst _machInst);
Fault execute(ExecContext *xc, Trace::InstRecord *traceData) const;
};
#endif

View File

@@ -704,6 +704,7 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
PCState pc = tc->pcState();
pc.nextThumb(cpsr.t);
pc.nextJazelle(cpsr.j);
pc.illegalExec(cpsr.il == 1);
// Follow slightly different semantics if a CheckerCPU object
// is connected

View File

@@ -1,6 +1,6 @@
// -*- mode:c++ -*-
// Copyright (c) 2010, 2011 ARM Limited
// Copyright (c) 2010, 2011, 2018 ARM Limited
// All rights reserved
//
// The license below extends only to copyright in the software and shall
@@ -47,6 +47,7 @@
// Opcode fields
def bitfield DECODERFAULT decoderFault;
def bitfield ILLEGALEXEC illegalExecution;
def bitfield ENCODING encoding;
def bitfield OPCODE opcode;

View File

@@ -1,6 +1,6 @@
// -*- mode:c++ -*-
// Copyright (c) 2010-2011 ARM Limited
// Copyright (c) 2010-2011,2018 ARM Limited
// All rights reserved
//
// The license below extends only to copyright in the software and shall
@@ -40,15 +40,17 @@
//
// Authors: Gabe Black
decode DECODERFAULT default DecoderFault::decoderFault() {
0: decode THUMB default Unknown::unknown() {
0: decode AARCH64 {
0:
##include "arm.isa"
decode ILLEGALEXEC default IllegalExec::illegalExec() {
0: decode DECODERFAULT default DecoderFault::decoderFault() {
0: decode THUMB default Unknown::unknown() {
0: decode AARCH64 {
0:
##include "arm.isa"
1:
##include "aarch64.isa"
}
1:
##include "aarch64.isa"
##include "thumb.isa"
}
1:
##include "thumb.isa"
}
}

View File

@@ -1,6 +1,6 @@
// -*- mode:c++ -*-
// Copyright (c) 2014 ARM Limited
// Copyright (c) 2014, 2018 ARM Limited
// All rights reserved
//
// The license below extends only to copyright in the software and shall
@@ -53,6 +53,15 @@ def format DecoderFault() {{
'''
}};
////////////////////////////////////////////////////////////////////
//
// Illegal execution handling
//
def format IllegalExec() {{
decode_block = 'return new IllegalExecInst(machInst);\n'
}};
////////////////////////////////////////////////////////////////////
//
// Unknown instruction handling

View File

@@ -1145,11 +1145,6 @@ TLB::translateFs(const RequestPtr &req, ThreadContext *tc, Mode mode,
}
if (fault == NoFault) {
// Generate Illegal Inst Set State fault if IL bit is set in CPSR
if (aarch64 && is_fetch && cpsr.il == 1) {
return std::make_shared<IllegalInstSetStateFault>();
}
// Don't try to finalize a physical address unless the
// translation has completed (i.e., there is a table entry).
return te ? finalizePhysical(req, tc, mode) : NoFault;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2012-2013, 2017 ARM Limited
* Copyright (c) 2010, 2012-2013, 2017-2018 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -70,6 +70,7 @@ namespace ArmISA
BitUnion64(ExtMachInst)
// Decoder state
Bitfield<63, 62> decoderFault; // See DecoderFault
Bitfield<61> illegalExecution;
// ITSTATE bits
Bitfield<55, 48> itstate;
@@ -218,14 +219,16 @@ namespace ArmISA
JazelleBit = (1 << 1),
AArch64Bit = (1 << 2)
};
uint8_t flags;
uint8_t nextFlags;
uint8_t _itstate;
uint8_t _nextItstate;
uint8_t _size;
bool _illegalExec;
public:
PCState() : flags(0), nextFlags(0), _itstate(0), _nextItstate(0),
_size(0)
_size(0), _illegalExec(false)
{}
void
@@ -236,9 +239,21 @@ namespace ArmISA
}
PCState(Addr val) : flags(0), nextFlags(0), _itstate(0),
_nextItstate(0), _size(0)
_nextItstate(0), _size(0), _illegalExec(false)
{ set(val); }
bool
illegalExec() const
{
return _illegalExec;
}
void
illegalExec(bool val)
{
_illegalExec = val;
}
bool
thumb() const
{
@@ -472,7 +487,9 @@ namespace ArmISA
{
return Base::operator == (opc) &&
flags == opc.flags && nextFlags == opc.nextFlags &&
_itstate == opc._itstate && _nextItstate == opc._nextItstate;
_itstate == opc._itstate &&
_nextItstate == opc._nextItstate &&
_illegalExec == opc._illegalExec;
}
bool
@@ -490,6 +507,7 @@ namespace ArmISA
SERIALIZE_SCALAR(nextFlags);
SERIALIZE_SCALAR(_itstate);
SERIALIZE_SCALAR(_nextItstate);
SERIALIZE_SCALAR(_illegalExec);
}
void
@@ -501,6 +519,7 @@ namespace ArmISA
UNSERIALIZE_SCALAR(nextFlags);
UNSERIALIZE_SCALAR(_itstate);
UNSERIALIZE_SCALAR(_nextItstate);
UNSERIALIZE_SCALAR(_illegalExec);
}
};