gem5/src/arch/mips/isa/formats/util.isa
Steve Reinhardt 4d77ea7a57 cpu: fix exec tracing memory corruption bug
Accessing traceData (to call setAddress() and/or setData())
after initiating a timing translation was causing crashes,
since a failed translation could delete the traceData
object before returning.

It turns out that there was never a need to access traceData
after initiating the translation, as the traced data was
always available earlier; this ordering was merely
historical.  Furthermore, traceData->setAddress() and
traceData->setData() were being called both from the CPU
model and the ISA definition, often redundantly.

This patch standardizes all setAddress and setData calls
for memory instructions to be in the CPU models and not
in the ISA definition.  It also moves those calls above
the translation calls to eliminate the crashes.
2010-03-23 08:50:57 -07:00

103 lines
4 KiB
C++

// -*- mode:c++ -*-
// Copyright (c) 2003-2005 The Regents of The University of Michigan
// Copyright (c) 2007 MIPS Technologies, Inc.
// All rights reserved.
//
// 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: Steve Reinhardt
// Korey Sewell
let {{
def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
postacc_code = '', base_class = 'Memory',
decode_template = BasicDecode, exec_template_base = ''):
# Make sure flags are in lists (convert to lists if not).
mem_flags = makeList(mem_flags)
inst_flags = makeList(inst_flags)
# Some CPU models execute the memory operation as an atomic unit,
# while others want to separate them into an effective address
# computation and a memory access operation. As a result, we need
# to generate three StaticInst objects. Note that the latter two
# are nested inside the larger "atomic" one.
# Generate InstObjParams for each of the three objects. Note that
# they differ only in the set of code objects contained (which in
# turn affects the object's overall operand list).
iop = InstObjParams(name, Name, base_class,
{ 'ea_code':ea_code, 'memacc_code':memacc_code, 'postacc_code':postacc_code },
inst_flags)
if mem_flags:
mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
iop.constructor += s
# select templates
# The InitiateAcc template is the same for StoreCond templates as the
# corresponding Store template..
StoreCondInitiateAcc = StoreInitiateAcc
fullExecTemplate = eval(exec_template_base + 'Execute')
initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
# (header_output, decoder_output, decode_block, exec_output)
return (LoadStoreDeclare.subst(iop),
LoadStoreConstructor.subst(iop),
decode_template.subst(iop),
fullExecTemplate.subst(iop)
+ EACompExecute.subst(iop)
+ initiateAccTemplate.subst(iop)
+ completeAccTemplate.subst(iop))
}};
output header {{
std::string inst2string(MachInst machInst);
}};
output decoder {{
std::string inst2string(MachInst machInst)
{
string str = "";
uint32_t mask = 0x80000000;
for(int i=0; i < 32; i++) {
if ((machInst & mask) == 0) {
str += "0";
} else {
str += "1";
}
mask = mask >> 1;
}
return str;
}
}};