Adding gem5 source to svn.

git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1819 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
This commit is contained in:
friemel
2012-10-24 19:18:57 +00:00
parent f7ff71bd46
commit b41eec3f65
3222 changed files with 658579 additions and 1 deletions

1127
simulators/gem5/src/Doxyfile Normal file

File diff suppressed because it is too large Load Diff

1013
simulators/gem5/src/SConscript Executable file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,139 @@
# -*- mode:python -*-
# Copyright (c) 2006 The Regents of The University of Michigan
# 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
import sys
import os
Import('*')
#################################################################
#
# ISA "switch header" generation.
#
# Auto-generate arch headers that include the right ISA-specific
# header based on the setting of THE_ISA preprocessor variable.
#
#################################################################
# List of headers to generate
isa_switch_hdrs = Split('''
decoder.hh
interrupts.hh
isa.hh
isa_traits.hh
kernel_stats.hh
locked_mem.hh
microcode_rom.hh
mmapped_ipr.hh
mt.hh
process.hh
registers.hh
remote_gdb.hh
stacktrace.hh
tlb.hh
types.hh
utility.hh
vtophys.hh
''')
# Set up this directory to support switching headers
make_switching_dir('arch', isa_switch_hdrs, env)
#################################################################
#
# Include architecture-specific files.
#
#################################################################
#
# Build a SCons scanner for ISA files
#
import SCons.Scanner
isa_scanner = SCons.Scanner.Classic("ISAScan",
[".isa", ".ISA"],
"SRCDIR",
r'^\s*##include\s+"([\w/.-]*)"')
env.Append(SCANNERS = isa_scanner)
#
# Now create a Builder object that uses isa_parser.py to generate C++
# output from the ISA description (*.isa) files.
#
isa_parser = File('isa_parser.py')
# The emitter patches up the sources & targets to include the
# autogenerated files as targets and isa parser itself as a source.
def isa_desc_emitter(target, source, env):
cpu_models = list(env['CPU_MODELS'])
cpu_models.append('CheckerCPU')
# Several files are generated from the ISA description.
# We always get the basic decoder and header file.
target = [ 'decoder.cc', 'decoder.hh', 'max_inst_regs.hh' ]
# We also get an execute file for each selected CPU model.
target += [CpuModel.dict[cpu].filename for cpu in cpu_models]
# List the isa parser as a source.
source += [ isa_parser ]
# Add in the CPU models.
source += [ Value(m) for m in cpu_models ]
return [os.path.join("generated", t) for t in target], source
ARCH_DIR = Dir('.')
# import ply here because SCons screws with sys.path when performing actions.
import ply
def isa_desc_action_func(target, source, env):
# Add the current directory to the system path so we can import files
sys.path[0:0] = [ ARCH_DIR.srcnode().abspath ]
import isa_parser
# Skip over the ISA description itself and the parser to the CPU models.
models = [ s.get_contents() for s in source[2:] ]
cpu_models = [CpuModel.dict[cpu] for cpu in models]
parser = isa_parser.ISAParser(target[0].dir.abspath, cpu_models)
parser.parse_isa_desc(source[0].abspath)
isa_desc_action = MakeAction(isa_desc_action_func, Transform("ISA DESC", 1))
# Also include the CheckerCPU as one of the models if it is being
# enabled via command line.
isa_desc_builder = Builder(action=isa_desc_action, emitter=isa_desc_emitter)
env.Append(BUILDERS = { 'ISADesc' : isa_desc_builder })
DebugFlag('IntRegs')
DebugFlag('FloatRegs')
DebugFlag('MiscRegs')
CompoundFlag('Registers', [ 'IntRegs', 'FloatRegs', 'MiscRegs' ])

View File

@ -0,0 +1,33 @@
# Copyright (c) 2008 The Regents of The University of Michigan
# 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: Gabe Black
from m5.SimObject import SimObject
class AlphaInterrupts(SimObject):
type = 'AlphaInterrupts'
cxx_class = 'AlphaISA::Interrupts'

View File

@ -0,0 +1,57 @@
# Copyright (c) 2007 The Regents of The University of Michigan
# 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: Nathan Binkert
from m5.params import *
from m5.proxy import *
from System import System
class AlphaSystem(System):
type = 'AlphaSystem'
console = Param.String("file that contains the console code")
pal = Param.String("file that contains palcode")
system_type = Param.UInt64("Type of system we are emulating")
system_rev = Param.UInt64("Revision of system we are emulating")
load_addr_mask = 0xffffffffff
class LinuxAlphaSystem(AlphaSystem):
type = 'LinuxAlphaSystem'
system_type = 34
system_rev = 1 << 10
boot_cpu_frequency = Param.Frequency(Self.cpu[0].clock.frequency,
"boot processor frequency")
class FreebsdAlphaSystem(AlphaSystem):
type = 'FreebsdAlphaSystem'
system_type = 34
system_rev = 1 << 10
class Tru64AlphaSystem(AlphaSystem):
type = 'Tru64AlphaSystem'
system_type = 12
system_rev = 2<<1

View File

@ -0,0 +1,43 @@
# Copyright (c) 2005-2007 The Regents of The University of Michigan
# 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: Nathan Binkert
from m5.SimObject import SimObject
from m5.params import *
from BaseTLB import BaseTLB
class AlphaTLB(BaseTLB):
type = 'AlphaTLB'
cxx_class = 'AlphaISA::TLB'
size = Param.Int("TLB size")
class AlphaDTB(AlphaTLB):
size = 64
class AlphaITB(AlphaTLB):
size = 48

View File

@ -0,0 +1,71 @@
# -*- mode:python -*-
# Copyright (c) 2004-2005 The Regents of The University of Michigan
# 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: Gabe Black
# Steve Reinhardt
Import('*')
if env['TARGET_ISA'] == 'alpha':
Source('decoder.cc')
Source('ev5.cc')
Source('faults.cc')
Source('freebsd/system.cc')
Source('idle_event.cc')
Source('interrupts.cc')
Source('ipr.cc')
Source('isa.cc')
Source('kernel_stats.cc')
Source('linux/linux.cc')
Source('linux/process.cc')
Source('linux/system.cc')
Source('osfpal.cc')
Source('pagetable.cc')
Source('process.cc')
Source('regredir.cc')
Source('remote_gdb.cc')
Source('stacktrace.cc')
Source('system.cc')
Source('tlb.cc')
Source('tru64/process.cc')
Source('tru64/system.cc')
Source('tru64/tru64.cc')
Source('utility.cc')
Source('vtophys.cc')
SimObject('AlphaInterrupts.py')
SimObject('AlphaSystem.py')
SimObject('AlphaTLB.py')
# Add in files generated by the ISA description.
isa_desc_files = env.ISADesc('isa/main.isa')
# Only non-header files need to be compiled.
for f in isa_desc_files:
if not f.path.endswith('.hh'):
Source(f)

View File

@ -0,0 +1,33 @@
# -*- mode:python -*-
# Copyright (c) 2004-2005 The Regents of The University of Michigan
# 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: Nathan Binkert
Import('*')
all_isa_list.append('alpha')

View File

@ -0,0 +1,70 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* 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
* Nathan Binkert
*/
#ifndef __AOUT_MACHDEP_H__
#define __AOUT_MACHDEP_H__
///
/// Funky Alpha 64-bit a.out header used for PAL code.
///
struct aout_exechdr {
uint16_t magic; ///< magic number
uint16_t vstamp; ///< version stamp?
uint16_t bldrev; ///< ???
uint16_t padcell; ///< padding
uint64_t tsize; ///< text segment size
uint64_t dsize; ///< data segment size
uint64_t bsize; ///< bss segment size
uint64_t entry; ///< entry point
uint64_t text_start; ///< text base address
uint64_t data_start; ///< data base address
uint64_t bss_start; ///< bss base address
uint32_t gprmask; ///< GPR mask (unused, AFAIK)
uint32_t fprmask; ///< FPR mask (unused, AFAIK)
uint64_t gp_value; ///< global pointer reg value
};
#define AOUT_LDPGSZ 8192
#define N_GETMAGIC(ex) ((ex).magic)
#define N_BADMAX
#define N_TXTADDR(ex) ((ex).text_start)
#define N_DATADDR(ex) ((ex).data_start)
#define N_BSSADDR(ex) ((ex).bss_start)
#define N_TXTOFF(ex) \
(N_GETMAGIC(ex) == ZMAGIC ? 0 : sizeof(struct aout_exechdr))
#define N_DATOFF(ex) N_ALIGN(ex, N_TXTOFF(ex) + (ex).tsize)
#endif /* !__AOUT_MACHDEP_H__*/

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2011 Google
* 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: Gabe Black
*/
#include "arch/alpha/decoder.hh"
namespace AlphaISA
{
GenericISA::BasicDecodeCache Decoder::defaultCache;
}

View File

@ -0,0 +1,130 @@
/*
* Copyright (c) 2012 Google
* 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: Gabe Black
*/
#ifndef __ARCH_ALPHA_DECODER_HH__
#define __ARCH_ALPHA_DECODER_HH__
#include "arch/generic/decode_cache.hh"
#include "arch/types.hh"
#include "cpu/static_inst.hh"
#include "sim/full_system.hh"
class ThreadContext;
namespace AlphaISA
{
class Decoder
{
protected:
ThreadContext *tc;
// The extended machine instruction being generated
ExtMachInst ext_inst;
bool instDone;
public:
Decoder(ThreadContext * _tc) : tc(_tc), instDone(false)
{}
ThreadContext *
getTC()
{
return tc;
}
void
setTC(ThreadContext * _tc)
{
tc = _tc;
}
void
process()
{ }
void
reset()
{
instDone = false;
}
// Use this to give data to the predecoder. This should be used
// when there is control flow.
void
moreBytes(const PCState &pc, Addr fetchPC, MachInst inst)
{
ext_inst = inst;
instDone = true;
if (FullSystem)
ext_inst |= (static_cast<ExtMachInst>(pc.pc() & 0x1) << 32);
}
bool
needMoreBytes()
{
return true;
}
bool
instReady()
{
return instDone;
}
protected:
/// A cache of decoded instruction objects.
static GenericISA::BasicDecodeCache defaultCache;
public:
StaticInstPtr decodeInst(ExtMachInst mach_inst);
/// Decode a machine instruction.
/// @param mach_inst The binary instruction to decode.
/// @retval A pointer to the corresponding StaticInst object.
StaticInstPtr
decode(ExtMachInst mach_inst, Addr addr)
{
return defaultCache.decode(this, mach_inst, addr);
}
StaticInstPtr
decode(AlphaISA::PCState &nextPC)
{
if (!instDone)
return NULL;
instDone = false;
return decode(ext_inst, nextPC.instAddr());
}
};
} // namespace AlphaISA
#endif // __ARCH_ALPHA_DECODER_HH__

View File

@ -0,0 +1,73 @@
/*
* Taken from NetBSD arch/alpha/ecoff_machdep.h
*/
/* $NetBSD: ecoff_machdep.h,v 1.5 1999/04/27 02:32:33 cgd Exp $ */
/*
* Copyright (c) 1994 Adam Glass
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Adam Glass.
* 4. The name of the Author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY Adam Glass ``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 Adam Glass 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.
*/
//
// Define COFF/ECOFF integer type sizes
//
typedef int16_t coff_short;
typedef uint16_t coff_ushort;
typedef int32_t coff_int;
typedef uint32_t coff_uint;
typedef int64_t coff_long;
typedef uint64_t coff_ulong;
typedef uint64_t coff_addr;
#define ECOFF_LDPGSZ 4096
#define ECOFF_PAD \
coff_ushort bldrev; /* XXX */
#define ECOFF_MACHDEP \
coff_uint gprmask; \
coff_uint fprmask; \
coff_ulong gp_value
#define ECOFF_MAGIC_ALPHA 0603
#define ECOFF_MAGIC_NETBSD_ALPHA 0605
#define ECOFF_BADMAG(ep) \
((ep)->f.f_magic != ECOFF_MAGIC_ALPHA && \
(ep)->f.f_magic != ECOFF_MAGIC_NETBSD_ALPHA)
#define ECOFF_FLAG_EXEC 0002
#define ECOFF_SEGMENT_ALIGNMENT(ep) \
(((ep)->f.f_flags & ECOFF_FLAG_EXEC) == 0 ? 8 : 16)
#define ECOFF_FLAG_OBJECT_TYPE_MASK 0x3000
#define ECOFF_OBJECT_TYPE_NO_SHARED 0x1000
#define ECOFF_OBJECT_TYPE_SHARABLE 0x2000
#define ECOFF_OBJECT_TYPE_CALL_SHARED 0x3000

View File

@ -0,0 +1,521 @@
/*
* Copyright (c) 2002-2005 The Regents of The University of Michigan
* 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
* Nathan Binkert
*/
#include "arch/alpha/faults.hh"
#include "arch/alpha/isa_traits.hh"
#include "arch/alpha/kernel_stats.hh"
#include "arch/alpha/osfpal.hh"
#include "arch/alpha/tlb.hh"
#include "base/cp_annotate.hh"
#include "base/debug.hh"
#include "cpu/base.hh"
#include "cpu/simple_thread.hh"
#include "cpu/thread_context.hh"
#include "sim/sim_exit.hh"
namespace AlphaISA {
////////////////////////////////////////////////////////////////////////
//
// Machine dependent functions
//
void
initCPU(ThreadContext *tc, int cpuId)
{
initIPRs(tc, cpuId);
tc->setIntReg(16, cpuId);
tc->setIntReg(0, cpuId);
AlphaFault *reset = new ResetFault;
tc->pcState(tc->readMiscRegNoEffect(IPR_PAL_BASE) + reset->vect());
delete reset;
}
template <class CPU>
void
zeroRegisters(CPU *cpu)
{
// Insure ISA semantics
// (no longer very clean due to the change in setIntReg() in the
// cpu model. Consider changing later.)
cpu->thread->setIntReg(ZeroReg, 0);
cpu->thread->setFloatReg(ZeroReg, 0.0);
}
////////////////////////////////////////////////////////////////////////
//
//
//
void
initIPRs(ThreadContext *tc, int cpuId)
{
for (int i = 0; i < NumInternalProcRegs; ++i) {
tc->setMiscRegNoEffect(i, 0);
}
tc->setMiscRegNoEffect(IPR_PAL_BASE, PalBase);
tc->setMiscRegNoEffect(IPR_MCSR, 0x6);
tc->setMiscRegNoEffect(IPR_PALtemp16, cpuId);
}
MiscReg
ISA::readIpr(int idx, ThreadContext *tc)
{
uint64_t retval = 0; // return value, default 0
switch (idx) {
case IPR_PALtemp0:
case IPR_PALtemp1:
case IPR_PALtemp2:
case IPR_PALtemp3:
case IPR_PALtemp4:
case IPR_PALtemp5:
case IPR_PALtemp6:
case IPR_PALtemp7:
case IPR_PALtemp8:
case IPR_PALtemp9:
case IPR_PALtemp10:
case IPR_PALtemp11:
case IPR_PALtemp12:
case IPR_PALtemp13:
case IPR_PALtemp14:
case IPR_PALtemp15:
case IPR_PALtemp16:
case IPR_PALtemp17:
case IPR_PALtemp18:
case IPR_PALtemp19:
case IPR_PALtemp20:
case IPR_PALtemp21:
case IPR_PALtemp22:
case IPR_PALtemp23:
case IPR_PAL_BASE:
case IPR_IVPTBR:
case IPR_DC_MODE:
case IPR_MAF_MODE:
case IPR_ISR:
case IPR_EXC_ADDR:
case IPR_IC_PERR_STAT:
case IPR_DC_PERR_STAT:
case IPR_MCSR:
case IPR_ASTRR:
case IPR_ASTER:
case IPR_SIRR:
case IPR_ICSR:
case IPR_ICM:
case IPR_DTB_CM:
case IPR_IPLR:
case IPR_INTID:
case IPR_PMCTR:
// no side-effect
retval = ipr[idx];
break;
case IPR_CC:
retval |= ipr[idx] & ULL(0xffffffff00000000);
retval |= tc->getCpuPtr()->curCycle() & ULL(0x00000000ffffffff);
break;
case IPR_VA:
retval = ipr[idx];
break;
case IPR_VA_FORM:
case IPR_MM_STAT:
case IPR_IFAULT_VA_FORM:
case IPR_EXC_MASK:
case IPR_EXC_SUM:
retval = ipr[idx];
break;
case IPR_DTB_PTE:
{
TlbEntry &entry
= tc->getDTBPtr()->index(!tc->misspeculating());
retval |= ((uint64_t)entry.ppn & ULL(0x7ffffff)) << 32;
retval |= ((uint64_t)entry.xre & ULL(0xf)) << 8;
retval |= ((uint64_t)entry.xwe & ULL(0xf)) << 12;
retval |= ((uint64_t)entry.fonr & ULL(0x1)) << 1;
retval |= ((uint64_t)entry.fonw & ULL(0x1))<< 2;
retval |= ((uint64_t)entry.asma & ULL(0x1)) << 4;
retval |= ((uint64_t)entry.asn & ULL(0x7f)) << 57;
}
break;
// write only registers
case IPR_HWINT_CLR:
case IPR_SL_XMIT:
case IPR_DC_FLUSH:
case IPR_IC_FLUSH:
case IPR_ALT_MODE:
case IPR_DTB_IA:
case IPR_DTB_IAP:
case IPR_ITB_IA:
case IPR_ITB_IAP:
panic("Tried to read write only register %d\n", idx);
break;
default:
// invalid IPR
panic("Tried to read from invalid ipr %d\n", idx);
break;
}
return retval;
}
// Cause the simulator to break when changing to the following IPL
int break_ipl = -1;
void
ISA::setIpr(int idx, uint64_t val, ThreadContext *tc)
{
if (tc->misspeculating())
return;
switch (idx) {
case IPR_PALtemp0:
case IPR_PALtemp1:
case IPR_PALtemp2:
case IPR_PALtemp3:
case IPR_PALtemp4:
case IPR_PALtemp5:
case IPR_PALtemp6:
case IPR_PALtemp7:
case IPR_PALtemp8:
case IPR_PALtemp9:
case IPR_PALtemp10:
case IPR_PALtemp11:
case IPR_PALtemp12:
case IPR_PALtemp13:
case IPR_PALtemp14:
case IPR_PALtemp15:
case IPR_PALtemp16:
case IPR_PALtemp17:
case IPR_PALtemp18:
case IPR_PALtemp19:
case IPR_PALtemp20:
case IPR_PALtemp21:
case IPR_PALtemp22:
case IPR_PAL_BASE:
case IPR_IC_PERR_STAT:
case IPR_DC_PERR_STAT:
case IPR_PMCTR:
// write entire quad w/ no side-effect
ipr[idx] = val;
break;
case IPR_CC_CTL:
// This IPR resets the cycle counter. We assume this only
// happens once... let's verify that.
assert(ipr[idx] == 0);
ipr[idx] = 1;
break;
case IPR_CC:
// This IPR only writes the upper 64 bits. It's ok to write
// all 64 here since we mask out the lower 32 in rpcc (see
// isa_desc).
ipr[idx] = val;
break;
case IPR_PALtemp23:
// write entire quad w/ no side-effect
if (tc->getKernelStats())
tc->getKernelStats()->context(ipr[idx], val, tc);
ipr[idx] = val;
break;
case IPR_DTB_PTE:
// write entire quad w/ no side-effect, tag is forthcoming
ipr[idx] = val;
break;
case IPR_EXC_ADDR:
// second least significant bit in PC is always zero
ipr[idx] = val & ~2;
break;
case IPR_ASTRR:
case IPR_ASTER:
// only write least significant four bits - privilege mask
ipr[idx] = val & 0xf;
break;
case IPR_IPLR:
#ifdef DEBUG
if (break_ipl != -1 && break_ipl == (int)(val & 0x1f))
Debug::breakpoint();
#endif
// only write least significant five bits - interrupt level
ipr[idx] = val & 0x1f;
if (tc->getKernelStats())
tc->getKernelStats()->swpipl(ipr[idx]);
break;
case IPR_DTB_CM:
if (val & 0x18) {
if (tc->getKernelStats())
tc->getKernelStats()->mode(Kernel::user, tc);
} else {
if (tc->getKernelStats())
tc->getKernelStats()->mode(Kernel::kernel, tc);
}
case IPR_ICM:
// only write two mode bits - processor mode
ipr[idx] = val & 0x18;
break;
case IPR_ALT_MODE:
// only write two mode bits - processor mode
ipr[idx] = val & 0x18;
break;
case IPR_MCSR:
// more here after optimization...
ipr[idx] = val;
break;
case IPR_SIRR:
// only write software interrupt mask
ipr[idx] = val & 0x7fff0;
break;
case IPR_ICSR:
ipr[idx] = val & ULL(0xffffff0300);
break;
case IPR_IVPTBR:
case IPR_MVPTBR:
ipr[idx] = val & ULL(0xffffffffc0000000);
break;
case IPR_DC_TEST_CTL:
ipr[idx] = val & 0x1ffb;
break;
case IPR_DC_MODE:
case IPR_MAF_MODE:
ipr[idx] = val & 0x3f;
break;
case IPR_ITB_ASN:
ipr[idx] = val & 0x7f0;
break;
case IPR_DTB_ASN:
ipr[idx] = val & ULL(0xfe00000000000000);
break;
case IPR_EXC_SUM:
case IPR_EXC_MASK:
// any write to this register clears it
ipr[idx] = 0;
break;
case IPR_INTID:
case IPR_SL_RCV:
case IPR_MM_STAT:
case IPR_ITB_PTE_TEMP:
case IPR_DTB_PTE_TEMP:
// read-only registers
panic("Tried to write read only ipr %d\n", idx);
case IPR_HWINT_CLR:
case IPR_SL_XMIT:
case IPR_DC_FLUSH:
case IPR_IC_FLUSH:
// the following are write only
ipr[idx] = val;
break;
case IPR_DTB_IA:
// really a control write
ipr[idx] = 0;
tc->getDTBPtr()->flushAll();
break;
case IPR_DTB_IAP:
// really a control write
ipr[idx] = 0;
tc->getDTBPtr()->flushProcesses();
break;
case IPR_DTB_IS:
// really a control write
ipr[idx] = val;
tc->getDTBPtr()->flushAddr(val, DTB_ASN_ASN(ipr[IPR_DTB_ASN]));
break;
case IPR_DTB_TAG: {
struct TlbEntry entry;
// FIXME: granularity hints NYI...
if (DTB_PTE_GH(ipr[IPR_DTB_PTE]) != 0)
panic("PTE GH field != 0");
// write entire quad
ipr[idx] = val;
// construct PTE for new entry
entry.ppn = DTB_PTE_PPN(ipr[IPR_DTB_PTE]);
entry.xre = DTB_PTE_XRE(ipr[IPR_DTB_PTE]);
entry.xwe = DTB_PTE_XWE(ipr[IPR_DTB_PTE]);
entry.fonr = DTB_PTE_FONR(ipr[IPR_DTB_PTE]);
entry.fonw = DTB_PTE_FONW(ipr[IPR_DTB_PTE]);
entry.asma = DTB_PTE_ASMA(ipr[IPR_DTB_PTE]);
entry.asn = DTB_ASN_ASN(ipr[IPR_DTB_ASN]);
// insert new TAG/PTE value into data TLB
tc->getDTBPtr()->insert(val, entry);
}
break;
case IPR_ITB_PTE: {
struct TlbEntry entry;
// FIXME: granularity hints NYI...
if (ITB_PTE_GH(val) != 0)
panic("PTE GH field != 0");
// write entire quad
ipr[idx] = val;
// construct PTE for new entry
entry.ppn = ITB_PTE_PPN(val);
entry.xre = ITB_PTE_XRE(val);
entry.xwe = 0;
entry.fonr = ITB_PTE_FONR(val);
entry.fonw = ITB_PTE_FONW(val);
entry.asma = ITB_PTE_ASMA(val);
entry.asn = ITB_ASN_ASN(ipr[IPR_ITB_ASN]);
// insert new TAG/PTE value into data TLB
tc->getITBPtr()->insert(ipr[IPR_ITB_TAG], entry);
}
break;
case IPR_ITB_IA:
// really a control write
ipr[idx] = 0;
tc->getITBPtr()->flushAll();
break;
case IPR_ITB_IAP:
// really a control write
ipr[idx] = 0;
tc->getITBPtr()->flushProcesses();
break;
case IPR_ITB_IS:
// really a control write
ipr[idx] = val;
tc->getITBPtr()->flushAddr(val, ITB_ASN_ASN(ipr[IPR_ITB_ASN]));
break;
default:
// invalid IPR
panic("Tried to write to invalid ipr %d\n", idx);
}
// no error...
}
void
copyIprs(ThreadContext *src, ThreadContext *dest)
{
for (int i = 0; i < NumInternalProcRegs; ++i)
dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i));
}
} // namespace AlphaISA
using namespace AlphaISA;
Fault
SimpleThread::hwrei()
{
PCState pc = pcState();
if (!(pc.pc() & 0x3))
return new UnimplementedOpcodeFault;
pc.npc(readMiscRegNoEffect(IPR_EXC_ADDR));
pcState(pc);
CPA::cpa()->swAutoBegin(tc, pc.npc());
if (!misspeculating()) {
if (kernelStats)
kernelStats->hwrei();
}
// FIXME: XXX check for interrupts? XXX
return NoFault;
}
/**
* Check for special simulator handling of specific PAL calls.
* If return value is false, actual PAL call will be suppressed.
*/
bool
SimpleThread::simPalCheck(int palFunc)
{
if (kernelStats)
kernelStats->callpal(palFunc, tc);
switch (palFunc) {
case PAL::halt:
halt();
if (--System::numSystemsRunning == 0)
exitSimLoop("all cpus halted");
break;
case PAL::bpt:
case PAL::bugchk:
if (system->breakpoint())
return false;
break;
}
return true;
}

View File

@ -0,0 +1,115 @@
/*
* Copyright (c) 2002-2005 The Regents of The University of Michigan
* 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
* Nathan Binkert
* Ali Saidi
*/
#ifndef __ARCH_ALPHA_EV5_HH__
#define __ARCH_ALPHA_EV5_HH__
#include "arch/alpha/isa_traits.hh"
class ThreadContext;
namespace AlphaISA {
const uint64_t AsnMask = ULL(0xff);
const int VAddrImplBits = 43;
const Addr VAddrImplMask = (ULL(1) << VAddrImplBits) - 1;
const Addr VAddrUnImplMask = ~VAddrImplMask;
inline Addr VAddrImpl(Addr a) { return a & VAddrImplMask; }
inline Addr VAddrVPN(Addr a) { return a >> PageShift; }
inline Addr VAddrOffset(Addr a) { return a & PageOffset; }
inline Addr VAddrSpaceEV5(Addr a) { return a >> 41 & 0x3; }
inline Addr VAddrSpaceEV6(Addr a) { return a >> 41 & 0x7f; }
inline bool PAddrIprSpace(Addr a) { return a >= ULL(0xFFFFFF00000); }
const int PAddrImplBits = 44; // for Tsunami
const Addr PAddrImplMask = (ULL(1) << PAddrImplBits) - 1;
const Addr PAddrUncachedBit39 = ULL(0x8000000000);
const Addr PAddrUncachedBit40 = ULL(0x10000000000);
const Addr PAddrUncachedBit43 = ULL(0x80000000000);
const Addr PAddrUncachedMask = ULL(0x807ffffffff); // Clear PA<42:35>
inline Addr
Phys2K0Seg(Addr addr)
{
if (addr & PAddrUncachedBit43) {
addr &= PAddrUncachedMask;
addr |= PAddrUncachedBit40;
}
return addr | K0SegBase;
}
inline int DTB_ASN_ASN(uint64_t reg) { return reg >> 57 & AsnMask; }
inline Addr DTB_PTE_PPN(uint64_t reg)
{ return reg >> 32 & ((ULL(1) << (PAddrImplBits - PageShift)) - 1); }
inline int DTB_PTE_XRE(uint64_t reg) { return reg >> 8 & 0xf; }
inline int DTB_PTE_XWE(uint64_t reg) { return reg >> 12 & 0xf; }
inline int DTB_PTE_FONR(uint64_t reg) { return reg >> 1 & 0x1; }
inline int DTB_PTE_FONW(uint64_t reg) { return reg >> 2 & 0x1; }
inline int DTB_PTE_GH(uint64_t reg) { return reg >> 5 & 0x3; }
inline int DTB_PTE_ASMA(uint64_t reg) { return reg >> 4 & 0x1; }
inline int ITB_ASN_ASN(uint64_t reg) { return reg >> 4 & AsnMask; }
inline Addr ITB_PTE_PPN(uint64_t reg)
{ return reg >> 32 & ((ULL(1) << (PAddrImplBits - PageShift)) - 1); }
inline int ITB_PTE_XRE(uint64_t reg) { return reg >> 8 & 0xf; }
inline bool ITB_PTE_FONR(uint64_t reg) { return reg >> 1 & 0x1; }
inline bool ITB_PTE_FONW(uint64_t reg) { return reg >> 2 & 0x1; }
inline int ITB_PTE_GH(uint64_t reg) { return reg >> 5 & 0x3; }
inline bool ITB_PTE_ASMA(uint64_t reg) { return reg >> 4 & 0x1; }
inline uint64_t MCSR_SP(uint64_t reg) { return reg >> 1 & 0x3; }
inline bool ICSR_SDE(uint64_t reg) { return reg >> 30 & 0x1; }
inline int ICSR_SPE(uint64_t reg) { return reg >> 28 & 0x3; }
inline bool ICSR_FPE(uint64_t reg) { return reg >> 26 & 0x1; }
inline uint64_t ALT_MODE_AM(uint64_t reg) { return reg >> 3 & 0x3; }
inline uint64_t DTB_CM_CM(uint64_t reg) { return reg >> 3 & 0x3; }
inline uint64_t ICM_CM(uint64_t reg) { return reg >> 3 & 0x3; }
const uint64_t MM_STAT_BAD_VA_MASK = ULL(0x0020);
const uint64_t MM_STAT_DTB_MISS_MASK = ULL(0x0010);
const uint64_t MM_STAT_FONW_MASK = ULL(0x0008);
const uint64_t MM_STAT_FONR_MASK = ULL(0x0004);
const uint64_t MM_STAT_ACV_MASK = ULL(0x0002);
const uint64_t MM_STAT_WR_MASK = ULL(0x0001);
inline int Opcode(MachInst inst) { return inst >> 26 & 0x3f; }
inline int Ra(MachInst inst) { return inst >> 21 & 0x1f; }
const Addr PalBase = 0x4000;
const Addr PalMax = 0x10000;
void copyIprs(ThreadContext *src, ThreadContext *dest);
} // namespace AlphaISA
#endif // __ARCH_ALPHA_EV5_HH__

View File

@ -0,0 +1,227 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* 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: Gabe Black
* Kevin Lim
*/
#include "arch/alpha/ev5.hh"
#include "arch/alpha/faults.hh"
#include "arch/alpha/tlb.hh"
#include "base/trace.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
#include "mem/page_table.hh"
#include "sim/process.hh"
#include "sim/full_system.hh"
namespace AlphaISA {
FaultName MachineCheckFault::_name = "mchk";
FaultVect MachineCheckFault::_vect = 0x0401;
FaultStat MachineCheckFault::_count;
FaultName AlignmentFault::_name = "unalign";
FaultVect AlignmentFault::_vect = 0x0301;
FaultStat AlignmentFault::_count;
FaultName ResetFault::_name = "reset";
FaultVect ResetFault::_vect = 0x0001;
FaultStat ResetFault::_count;
FaultName ArithmeticFault::_name = "arith";
FaultVect ArithmeticFault::_vect = 0x0501;
FaultStat ArithmeticFault::_count;
FaultName InterruptFault::_name = "interrupt";
FaultVect InterruptFault::_vect = 0x0101;
FaultStat InterruptFault::_count;
FaultName NDtbMissFault::_name = "dtb_miss_single";
FaultVect NDtbMissFault::_vect = 0x0201;
FaultStat NDtbMissFault::_count;
FaultName PDtbMissFault::_name = "dtb_miss_double";
FaultVect PDtbMissFault::_vect = 0x0281;
FaultStat PDtbMissFault::_count;
FaultName DtbPageFault::_name = "dtb_page_fault";
FaultVect DtbPageFault::_vect = 0x0381;
FaultStat DtbPageFault::_count;
FaultName DtbAcvFault::_name = "dtb_acv_fault";
FaultVect DtbAcvFault::_vect = 0x0381;
FaultStat DtbAcvFault::_count;
FaultName DtbAlignmentFault::_name = "unalign";
FaultVect DtbAlignmentFault::_vect = 0x0301;
FaultStat DtbAlignmentFault::_count;
FaultName ItbPageFault::_name = "itbmiss";
FaultVect ItbPageFault::_vect = 0x0181;
FaultStat ItbPageFault::_count;
FaultName ItbAcvFault::_name = "iaccvio";
FaultVect ItbAcvFault::_vect = 0x0081;
FaultStat ItbAcvFault::_count;
FaultName UnimplementedOpcodeFault::_name = "opdec";
FaultVect UnimplementedOpcodeFault::_vect = 0x0481;
FaultStat UnimplementedOpcodeFault::_count;
FaultName FloatEnableFault::_name = "fen";
FaultVect FloatEnableFault::_vect = 0x0581;
FaultStat FloatEnableFault::_count;
FaultName PalFault::_name = "pal";
FaultVect PalFault::_vect = 0x2001;
FaultStat PalFault::_count;
FaultName IntegerOverflowFault::_name = "intover";
FaultVect IntegerOverflowFault::_vect = 0x0501;
FaultStat IntegerOverflowFault::_count;
void
AlphaFault::invoke(ThreadContext *tc, StaticInstPtr inst)
{
FaultBase::invoke(tc);
if (!FullSystem)
return;
countStat()++;
PCState pc = tc->pcState();
// exception restart address
if (setRestartAddress() || !(pc.pc() & 0x3))
tc->setMiscRegNoEffect(IPR_EXC_ADDR, pc.pc());
if (skipFaultingInstruction()) {
// traps... skip faulting instruction.
tc->setMiscRegNoEffect(IPR_EXC_ADDR,
tc->readMiscRegNoEffect(IPR_EXC_ADDR) + 4);
}
pc.set(tc->readMiscRegNoEffect(IPR_PAL_BASE) + vect());
tc->pcState(pc);
}
void
ArithmeticFault::invoke(ThreadContext *tc, StaticInstPtr inst)
{
FaultBase::invoke(tc);
if (!FullSystem)
return;
panic("Arithmetic traps are unimplemented!");
}
void
DtbFault::invoke(ThreadContext *tc, StaticInstPtr inst)
{
if (FullSystem) {
// Set fault address and flags. Even though we're modeling an
// EV5, we use the EV6 technique of not latching fault registers
// on VPTE loads (instead of locking the registers until IPR_VA is
// read, like the EV5). The EV6 approach is cleaner and seems to
// work with EV5 PAL code, but not the other way around.
if (!tc->misspeculating() &&
reqFlags.noneSet(Request::VPTE | Request::PREFETCH)) {
// set VA register with faulting address
tc->setMiscRegNoEffect(IPR_VA, vaddr);
// set MM_STAT register flags
MachInst machInst = inst->machInst;
tc->setMiscRegNoEffect(IPR_MM_STAT,
(((Opcode(machInst) & 0x3f) << 11) |
((Ra(machInst) & 0x1f) << 6) |
(flags & 0x3f)));
// set VA_FORM register with faulting formatted address
tc->setMiscRegNoEffect(IPR_VA_FORM,
tc->readMiscRegNoEffect(IPR_MVPTBR) | (vaddr.vpn() << 3));
}
}
AlphaFault::invoke(tc);
}
void
ItbFault::invoke(ThreadContext *tc, StaticInstPtr inst)
{
if (FullSystem) {
if (!tc->misspeculating()) {
tc->setMiscRegNoEffect(IPR_ITB_TAG, pc);
tc->setMiscRegNoEffect(IPR_IFAULT_VA_FORM,
tc->readMiscRegNoEffect(IPR_IVPTBR) | (VAddr(pc).vpn() << 3));
}
}
AlphaFault::invoke(tc);
}
void
ItbPageFault::invoke(ThreadContext *tc, StaticInstPtr inst)
{
if (FullSystem) {
ItbFault::invoke(tc);
return;
}
Process *p = tc->getProcessPtr();
TlbEntry entry;
bool success = p->pTable->lookup(pc, entry);
if (!success) {
panic("Tried to execute unmapped address %#x.\n", pc);
} else {
VAddr vaddr(pc);
tc->getITBPtr()->insert(vaddr.page(), entry);
}
}
void
NDtbMissFault::invoke(ThreadContext *tc, StaticInstPtr inst)
{
if (FullSystem) {
DtbFault::invoke(tc, inst);
return;
}
Process *p = tc->getProcessPtr();
TlbEntry entry;
bool success = p->pTable->lookup(vaddr, entry);
if (!success) {
if (p->fixupStackFault(vaddr))
success = p->pTable->lookup(vaddr, entry);
}
if (!success) {
panic("Tried to access unmapped address %#x.\n", (Addr)vaddr);
} else {
tc->getDTBPtr()->insert(vaddr.page(), entry);
}
}
} // namespace AlphaISA

View File

@ -0,0 +1,332 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* 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: Gabe Black
* Kevin Lim
*/
#ifndef __ARCH_ALPHA_FAULTS_HH__
#define __ARCH_ALPHA_FAULTS_HH__
#include "arch/alpha/pagetable.hh"
#include "mem/request.hh"
#include "sim/faults.hh"
// The design of the "name" and "vect" functions is in sim/faults.hh
namespace AlphaISA {
typedef const Addr FaultVect;
class AlphaFault : public FaultBase
{
protected:
virtual bool skipFaultingInstruction() {return false;}
virtual bool setRestartAddress() {return true;}
public:
void invoke(ThreadContext * tc,
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
virtual FaultVect vect() = 0;
virtual FaultStat & countStat() = 0;
};
class MachineCheckFault : public AlphaFault
{
private:
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
public:
FaultName name() const {return _name;}
FaultVect vect() {return _vect;}
FaultStat & countStat() {return _count;}
};
class AlignmentFault : public AlphaFault
{
private:
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
public:
FaultName name() const {return _name;}
FaultVect vect() {return _vect;}
FaultStat & countStat() {return _count;}
bool isAlignmentFault() const {return true;}
};
class ResetFault : public AlphaFault
{
private:
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
public:
FaultName name() const {return _name;}
FaultVect vect() {return _vect;}
FaultStat & countStat() {return _count;}
};
class ArithmeticFault : public AlphaFault
{
private:
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
protected:
bool skipFaultingInstruction() {return true;}
public:
FaultName name() const {return _name;}
FaultVect vect() {return _vect;}
FaultStat & countStat() {return _count;}
void invoke(ThreadContext * tc,
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
};
class InterruptFault : public AlphaFault
{
private:
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
protected:
bool setRestartAddress() {return false;}
public:
FaultName name() const {return _name;}
FaultVect vect() {return _vect;}
FaultStat & countStat() {return _count;}
};
class DtbFault : public AlphaFault
{
protected:
VAddr vaddr;
Request::Flags reqFlags;
uint64_t flags;
public:
DtbFault(VAddr _vaddr, Request::Flags _reqFlags, uint64_t _flags)
: vaddr(_vaddr), reqFlags(_reqFlags), flags(_flags)
{ }
FaultName name() const = 0;
FaultVect vect() = 0;
FaultStat & countStat() = 0;
void invoke(ThreadContext * tc,
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
};
class NDtbMissFault : public DtbFault
{
private:
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
public:
NDtbMissFault(VAddr vaddr, Request::Flags reqFlags, uint64_t flags)
: DtbFault(vaddr, reqFlags, flags)
{ }
FaultName name() const {return _name;}
FaultVect vect() {return _vect;}
FaultStat & countStat() {return _count;}
void invoke(ThreadContext * tc,
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
};
class PDtbMissFault : public DtbFault
{
private:
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
public:
PDtbMissFault(VAddr vaddr, Request::Flags reqFlags, uint64_t flags)
: DtbFault(vaddr, reqFlags, flags)
{ }
FaultName name() const {return _name;}
FaultVect vect() {return _vect;}
FaultStat & countStat() {return _count;}
};
class DtbPageFault : public DtbFault
{
private:
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
public:
DtbPageFault(VAddr vaddr, Request::Flags reqFlags, uint64_t flags)
: DtbFault(vaddr, reqFlags, flags)
{ }
FaultName name() const {return _name;}
FaultVect vect() {return _vect;}
FaultStat & countStat() {return _count;}
};
class DtbAcvFault : public DtbFault
{
private:
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
public:
DtbAcvFault(VAddr vaddr, Request::Flags reqFlags, uint64_t flags)
: DtbFault(vaddr, reqFlags, flags)
{ }
FaultName name() const {return _name;}
FaultVect vect() {return _vect;}
FaultStat & countStat() {return _count;}
};
class DtbAlignmentFault : public DtbFault
{
private:
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
public:
DtbAlignmentFault(VAddr vaddr, Request::Flags reqFlags, uint64_t flags)
: DtbFault(vaddr, reqFlags, flags)
{ }
FaultName name() const {return _name;}
FaultVect vect() {return _vect;}
FaultStat & countStat() {return _count;}
};
class ItbFault : public AlphaFault
{
protected:
Addr pc;
public:
ItbFault(Addr _pc) : pc(_pc) { }
FaultName name() const = 0;
FaultVect vect() = 0;
FaultStat & countStat() = 0;
void invoke(ThreadContext * tc,
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
};
class ItbPageFault : public ItbFault
{
private:
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
public:
ItbPageFault(Addr pc) : ItbFault(pc) { }
FaultName name() const {return _name;}
FaultVect vect() {return _vect;}
FaultStat & countStat() {return _count;}
void invoke(ThreadContext * tc,
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
};
class ItbAcvFault : public ItbFault
{
private:
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
public:
ItbAcvFault(Addr pc) : ItbFault(pc) { }
FaultName name() const {return _name;}
FaultVect vect() {return _vect;}
FaultStat & countStat() {return _count;}
};
class UnimplementedOpcodeFault : public AlphaFault
{
private:
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
public:
FaultName name() const {return _name;}
FaultVect vect() {return _vect;}
FaultStat & countStat() {return _count;}
};
class FloatEnableFault : public AlphaFault
{
private:
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
public:
FaultName name() const {return _name;}
FaultVect vect() {return _vect;}
FaultStat & countStat() {return _count;}
};
class PalFault : public AlphaFault
{
private:
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
protected:
bool skipFaultingInstruction() {return true;}
public:
FaultName name() const {return _name;}
FaultVect vect() {return _vect;}
FaultStat & countStat() {return _count;}
};
class IntegerOverflowFault : public AlphaFault
{
private:
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
public:
FaultName name() const {return _name;}
FaultVect vect() {return _vect;}
FaultStat & countStat() {return _count;}
};
} // namespace AlphaISA
#endif // __ARCH_ALPHA_FAULTS_HH__

View File

@ -0,0 +1,94 @@
/*
* Copyright (c) 2004-2005 The Regents of The University of Michigan
* 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: Ben Nash
*/
/**
* @file
* Modifications for the FreeBSD kernel.
* Based on kern/linux/linux_system.cc.
*
*/
#include "arch/alpha/freebsd/system.hh"
#include "arch/alpha/system.hh"
#include "arch/isa_traits.hh"
#include "arch/vtophys.hh"
#include "base/loader/symtab.hh"
#include "cpu/thread_context.hh"
#include "mem/fs_translating_port_proxy.hh"
#include "sim/byteswap.hh"
#define TIMER_FREQUENCY 1193180
using namespace std;
using namespace AlphaISA;
FreebsdAlphaSystem::FreebsdAlphaSystem(Params *p)
: AlphaSystem(p)
{
/**
* Any time DELAY is called just skip the function.
* Shouldn't we actually emulate the delay?
*/
skipDelayEvent = addKernelFuncEvent<SkipFuncEvent>("DELAY");
skipCalibrateClocks =
addKernelFuncEvent<SkipCalibrateClocksEvent>("calibrate_clocks");
}
FreebsdAlphaSystem::~FreebsdAlphaSystem()
{
delete skipDelayEvent;
delete skipCalibrateClocks;
}
void
FreebsdAlphaSystem::doCalibrateClocks(ThreadContext *tc)
{
Addr ppc_vaddr = 0;
Addr timer_vaddr = 0;
ppc_vaddr = (Addr)tc->readIntReg(17);
timer_vaddr = (Addr)tc->readIntReg(18);
virtProxy.write(ppc_vaddr, (uint32_t)SimClock::Frequency);
virtProxy.write(timer_vaddr, (uint32_t)TIMER_FREQUENCY);
}
void
FreebsdAlphaSystem::SkipCalibrateClocksEvent::process(ThreadContext *tc)
{
SkipFuncEvent::process(tc);
((FreebsdAlphaSystem *)tc->getSystemPtr())->doCalibrateClocks(tc);
}
FreebsdAlphaSystem *
FreebsdAlphaSystemParams::create()
{
return new FreebsdAlphaSystem(this);
}

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2004-2005 The Regents of The University of Michigan
* 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: Ben Nash
*/
#ifndef __ARCH_ALPHA_FREEBSD_SYSTEM_HH__
#define __ARCH_ALPHA_FREEBSD_SYSTEM_HH__
#include "arch/alpha/system.hh"
#include "kern/system_events.hh"
#include "params/FreebsdAlphaSystem.hh"
#include "sim/system.hh"
class FreebsdAlphaSystem : public AlphaSystem
{
private:
class SkipCalibrateClocksEvent : public SkipFuncEvent
{
public:
SkipCalibrateClocksEvent(PCEventQueue *q, const std::string &desc,
Addr addr)
: SkipFuncEvent(q, desc, addr) {}
virtual void process(ThreadContext *tc);
};
SkipFuncEvent *skipDelayEvent;
SkipCalibrateClocksEvent *skipCalibrateClocks;
public:
typedef FreebsdAlphaSystemParams Params;
FreebsdAlphaSystem(Params *p);
~FreebsdAlphaSystem();
void doCalibrateClocks(ThreadContext *tc);
};
#endif // __ARCH_ALPHA_FREEBSD_SYSTEM_HH__

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2004-2005 The Regents of The University of Michigan
* 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: Lisa Hsu
* Nathan Binkert
*/
#include "arch/alpha/idle_event.hh"
#include "arch/alpha/kernel_stats.hh"
#include "cpu/thread_context.hh"
using namespace AlphaISA;
void
IdleStartEvent::process(ThreadContext *tc)
{
if (tc->getKernelStats()) {
MiscReg val = tc->readMiscRegNoEffect(IPR_PALtemp23);
tc->getKernelStats()->setIdleProcess(val, tc);
}
remove();
}

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2004-2005 The Regents of The University of Michigan
* 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: Nathan Binkert
* Lisa Hsu
* Ali Saidi
*/
#ifndef __KERN_ALPHA_IDLE_EVENT_HH__
#define __KERN_ALPHA_IDLE_EVENT_HH__
#include "cpu/pc_event.hh"
class IdleStartEvent : public PCEvent
{
public:
IdleStartEvent(PCEventQueue *q, const std::string &desc, Addr addr)
: PCEvent(q, desc, addr)
{}
virtual void process(ThreadContext *tc);
};
#endif // __KERN_ALPHA_IDLE_EVENT_HH__

View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2008 The Regents of The University of Michigan
* 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: Gabe Black
*/
#include "arch/alpha/interrupts.hh"
AlphaISA::Interrupts *
AlphaInterruptsParams::create()
{
return new AlphaISA::Interrupts(this);
}

View File

@ -0,0 +1,199 @@
/*
* Copyright (c) 2006 The Regents of The University of Michigan
* 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
* Kevin Lim
*/
#ifndef __ARCH_ALPHA_INTERRUPT_HH__
#define __ARCH_ALPHA_INTERRUPT_HH__
#include "arch/alpha/faults.hh"
#include "arch/alpha/isa_traits.hh"
#include "base/compiler.hh"
#include "base/trace.hh"
#include "cpu/thread_context.hh"
#include "debug/Flow.hh"
#include "debug/Interrupt.hh"
#include "params/AlphaInterrupts.hh"
#include "sim/sim_object.hh"
namespace AlphaISA {
class Interrupts : public SimObject
{
private:
bool newInfoSet;
int newIpl;
int newSummary;
BaseCPU * cpu;
protected:
uint64_t interrupts[NumInterruptLevels];
uint64_t intstatus;
public:
typedef AlphaInterruptsParams Params;
const Params *
params() const
{
return dynamic_cast<const Params *>(_params);
}
Interrupts(Params * p) : SimObject(p), cpu(NULL)
{
memset(interrupts, 0, sizeof(interrupts));
intstatus = 0;
newInfoSet = false;
}
void
setCPU(BaseCPU * _cpu)
{
cpu = _cpu;
}
void
post(int int_num, int index)
{
DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
if (int_num < 0 || int_num >= NumInterruptLevels)
panic("int_num out of bounds\n");
if (index < 0 || index >= (int)sizeof(uint64_t) * 8)
panic("int_num out of bounds\n");
interrupts[int_num] |= 1 << index;
intstatus |= (ULL(1) << int_num);
}
void
clear(int int_num, int index)
{
DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
if (int_num < 0 || int_num >= NumInterruptLevels)
panic("int_num out of bounds\n");
if (index < 0 || index >= (int)sizeof(uint64_t) * 8)
panic("int_num out of bounds\n");
interrupts[int_num] &= ~(1 << index);
if (interrupts[int_num] == 0)
intstatus &= ~(ULL(1) << int_num);
}
void
clearAll()
{
DPRINTF(Interrupt, "Interrupts all cleared\n");
memset(interrupts, 0, sizeof(interrupts));
intstatus = 0;
}
void
serialize(std::ostream &os)
{
SERIALIZE_ARRAY(interrupts, NumInterruptLevels);
SERIALIZE_SCALAR(intstatus);
}
void
unserialize(Checkpoint *cp, const std::string &section)
{
UNSERIALIZE_ARRAY(interrupts, NumInterruptLevels);
UNSERIALIZE_SCALAR(intstatus);
}
bool
checkInterrupts(ThreadContext *tc) const
{
return (intstatus != 0) && !(tc->pcState().pc() & 0x3);
}
Fault
getInterrupt(ThreadContext *tc)
{
uint64_t ipl = 0;
uint64_t summary = 0;
if (tc->readMiscRegNoEffect(IPR_ASTRR))
panic("asynchronous traps not implemented\n");
if (tc->readMiscRegNoEffect(IPR_SIRR)) {
for (uint64_t i = INTLEVEL_SOFTWARE_MIN;
i < INTLEVEL_SOFTWARE_MAX; i++) {
if (tc->readMiscRegNoEffect(IPR_SIRR) & (ULL(1) << i)) {
// See table 4-19 of 21164 hardware reference
ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1;
summary |= (ULL(1) << i);
}
}
}
uint64_t interrupts = intstatus;
if (interrupts) {
for (uint64_t i = INTLEVEL_EXTERNAL_MIN;
i < INTLEVEL_EXTERNAL_MAX; i++) {
if (interrupts & (ULL(1) << i)) {
// See table 4-19 of 21164 hardware reference
ipl = i;
summary |= (ULL(1) << i);
}
}
}
if (ipl && ipl > tc->readMiscRegNoEffect(IPR_IPLR)) {
newIpl = ipl;
newSummary = summary;
newInfoSet = true;
DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
tc->readMiscRegNoEffect(IPR_IPLR), ipl, summary);
return new InterruptFault;
} else {
return NoFault;
}
}
void
updateIntrInfo(ThreadContext *tc)
{
assert(newInfoSet);
tc->setMiscRegNoEffect(IPR_ISR, newSummary);
tc->setMiscRegNoEffect(IPR_INTID, newIpl);
newInfoSet = false;
}
};
} // namespace AlphaISA
#endif // __ARCH_ALPHA_INTERRUPT_HH__

View File

@ -0,0 +1,142 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* 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: Gabe Black
*/
#include <cassert>
#include <cstring>
#include "arch/alpha/ipr.hh"
namespace AlphaISA {
md_ipr_names MiscRegIndexToIpr[NumInternalProcRegs] = {
//Write only
RAW_IPR_HWINT_CLR, // H/W interrupt clear register
RAW_IPR_SL_XMIT, // serial line transmit register
RAW_IPR_DC_FLUSH,
RAW_IPR_IC_FLUSH, // instruction cache flush control
RAW_IPR_ALT_MODE, // alternate mode register
RAW_IPR_DTB_IA, // DTLB invalidate all register
RAW_IPR_DTB_IAP, // DTLB invalidate all process register
RAW_IPR_ITB_IA, // ITLB invalidate all register
RAW_IPR_ITB_IAP, // ITLB invalidate all process register
//Read only
RAW_IPR_INTID, // interrupt ID register
RAW_IPR_SL_RCV, // serial line receive register
RAW_IPR_MM_STAT, // data MMU fault status register
RAW_IPR_ITB_PTE_TEMP, // ITLB page table entry temp register
RAW_IPR_DTB_PTE_TEMP, // DTLB page table entry temporary register
RAW_IPR_ISR, // interrupt summary register
RAW_IPR_ITB_TAG, // ITLB tag register
RAW_IPR_ITB_PTE, // ITLB page table entry register
RAW_IPR_ITB_ASN, // ITLB address space register
RAW_IPR_ITB_IS, // ITLB invalidate select register
RAW_IPR_SIRR, // software interrupt request register
RAW_IPR_ASTRR, // asynchronous system trap request register
RAW_IPR_ASTER, // asynchronous system trap enable register
RAW_IPR_EXC_ADDR, // exception address register
RAW_IPR_EXC_SUM, // exception summary register
RAW_IPR_EXC_MASK, // exception mask register
RAW_IPR_PAL_BASE, // PAL base address register
RAW_IPR_ICM, // instruction current mode
RAW_IPR_IPLR, // interrupt priority level register
RAW_IPR_IFAULT_VA_FORM, // formatted faulting virtual addr register
RAW_IPR_IVPTBR, // virtual page table base register
RAW_IPR_ICSR, // instruction control and status register
RAW_IPR_IC_PERR_STAT, // inst cache parity error status register
RAW_IPR_PMCTR, // performance counter register
// PAL temporary registers...
// register meanings gleaned from osfpal.s source code
RAW_IPR_PALtemp0, // local scratch
RAW_IPR_PALtemp1, // local scratch
RAW_IPR_PALtemp2, // entUna
RAW_IPR_PALtemp3, // CPU specific impure area pointer
RAW_IPR_PALtemp4, // memory management temp
RAW_IPR_PALtemp5, // memory management temp
RAW_IPR_PALtemp6, // memory management temp
RAW_IPR_PALtemp7, // entIF
RAW_IPR_PALtemp8, // intmask
RAW_IPR_PALtemp9, // entSys
RAW_IPR_PALtemp10, // ??
RAW_IPR_PALtemp11, // entInt
RAW_IPR_PALtemp12, // entArith
RAW_IPR_PALtemp13, // reserved for platform specific PAL
RAW_IPR_PALtemp14, // reserved for platform specific PAL
RAW_IPR_PALtemp15, // reserved for platform specific PAL
RAW_IPR_PALtemp16, // scratch / whami<7:0> / mces<4:0>
RAW_IPR_PALtemp17, // sysval
RAW_IPR_PALtemp18, // usp
RAW_IPR_PALtemp19, // ksp
RAW_IPR_PALtemp20, // PTBR
RAW_IPR_PALtemp21, // entMM
RAW_IPR_PALtemp22, // kgp
RAW_IPR_PALtemp23, // PCBB
RAW_IPR_DTB_ASN, // DTLB address space number register
RAW_IPR_DTB_CM, // DTLB current mode register
RAW_IPR_DTB_TAG, // DTLB tag register
RAW_IPR_DTB_PTE, // DTLB page table entry register
RAW_IPR_VA, // fault virtual address register
RAW_IPR_VA_FORM, // formatted virtual address register
RAW_IPR_MVPTBR, // MTU virtual page table base register
RAW_IPR_DTB_IS, // DTLB invalidate single register
RAW_IPR_CC, // cycle counter register
RAW_IPR_CC_CTL, // cycle counter control register
RAW_IPR_MCSR, // MTU control register
RAW_IPR_DC_PERR_STAT, // Dcache parity error status register
RAW_IPR_DC_TEST_CTL, // Dcache test tag control register
RAW_IPR_DC_TEST_TAG, // Dcache test tag register
RAW_IPR_DC_TEST_TAG_TEMP, // Dcache test tag temporary register
RAW_IPR_DC_MODE, // Dcache mode register
RAW_IPR_MAF_MODE // miss address file mode register
};
int IprToMiscRegIndex[MaxInternalProcRegs];
void
initializeIprTable()
{
static bool initialized = false;
if (initialized)
return;
memset(IprToMiscRegIndex, -1, MaxInternalProcRegs * sizeof(int));
for (int x = 0; x < NumInternalProcRegs; x++)
IprToMiscRegIndex[MiscRegIndexToIpr[x]] = x;
}
} // namespace AlphaISA

View File

@ -0,0 +1,239 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* 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
* Gabe Black
*/
#ifndef __ARCH_ALPHA_IPR_HH__
#define __ARCH_ALPHA_IPR_HH__
namespace AlphaISA {
////////////////////////////////////////////////////////////////////////
//
// Internal Processor Reigsters
//
enum md_ipr_names {
RAW_IPR_ISR = 0x100, // interrupt summary
RAW_IPR_ITB_TAG = 0x101, // ITLB tag
RAW_IPR_ITB_PTE = 0x102, // ITLB page table entry
RAW_IPR_ITB_ASN = 0x103, // ITLB address space
RAW_IPR_ITB_PTE_TEMP = 0x104, // ITLB page table entry temp
RAW_IPR_ITB_IA = 0x105, // ITLB invalidate all
RAW_IPR_ITB_IAP = 0x106, // ITLB invalidate all process
RAW_IPR_ITB_IS = 0x107, // ITLB invalidate select
RAW_IPR_SIRR = 0x108, // software interrupt request
RAW_IPR_ASTRR = 0x109, // asynchronous system trap request
RAW_IPR_ASTER = 0x10a, // asynchronous system trap enable
RAW_IPR_EXC_ADDR = 0x10b, // exception address
RAW_IPR_EXC_SUM = 0x10c, // exception summary
RAW_IPR_EXC_MASK = 0x10d, // exception mask
RAW_IPR_PAL_BASE = 0x10e, // PAL base address
RAW_IPR_ICM = 0x10f, // instruction current mode
RAW_IPR_IPLR = 0x110, // interrupt priority level
RAW_IPR_INTID = 0x111, // interrupt ID
RAW_IPR_IFAULT_VA_FORM = 0x112, // formatted faulting virtual addr
RAW_IPR_IVPTBR = 0x113, // virtual page table base
RAW_IPR_HWINT_CLR = 0x115, // H/W interrupt clear
RAW_IPR_SL_XMIT = 0x116, // serial line transmit
RAW_IPR_SL_RCV = 0x117, // serial line receive
RAW_IPR_ICSR = 0x118, // instruction control and status
RAW_IPR_IC_FLUSH = 0x119, // instruction cache flush control
RAW_IPR_IC_PERR_STAT = 0x11a, // inst cache parity error status
RAW_IPR_PMCTR = 0x11c, // performance counter
// PAL temporary registers...
// register meanings gleaned from osfpal.s source code
RAW_IPR_PALtemp0 = 0x140, // local scratch
RAW_IPR_PALtemp1 = 0x141, // local scratch
RAW_IPR_PALtemp2 = 0x142, // entUna
RAW_IPR_PALtemp3 = 0x143, // CPU specific impure area pointer
RAW_IPR_PALtemp4 = 0x144, // memory management temp
RAW_IPR_PALtemp5 = 0x145, // memory management temp
RAW_IPR_PALtemp6 = 0x146, // memory management temp
RAW_IPR_PALtemp7 = 0x147, // entIF
RAW_IPR_PALtemp8 = 0x148, // intmask
RAW_IPR_PALtemp9 = 0x149, // entSys
RAW_IPR_PALtemp10 = 0x14a, // ??
RAW_IPR_PALtemp11 = 0x14b, // entInt
RAW_IPR_PALtemp12 = 0x14c, // entArith
RAW_IPR_PALtemp13 = 0x14d, // reserved for platform specific PAL
RAW_IPR_PALtemp14 = 0x14e, // reserved for platform specific PAL
RAW_IPR_PALtemp15 = 0x14f, // reserved for platform specific PAL
RAW_IPR_PALtemp16 = 0x150, // scratch / whami<7:0> / mces<4:0>
RAW_IPR_PALtemp17 = 0x151, // sysval
RAW_IPR_PALtemp18 = 0x152, // usp
RAW_IPR_PALtemp19 = 0x153, // ksp
RAW_IPR_PALtemp20 = 0x154, // PTBR
RAW_IPR_PALtemp21 = 0x155, // entMM
RAW_IPR_PALtemp22 = 0x156, // kgp
RAW_IPR_PALtemp23 = 0x157, // PCBB
RAW_IPR_DTB_ASN = 0x200, // DTLB address space number
RAW_IPR_DTB_CM = 0x201, // DTLB current mode
RAW_IPR_DTB_TAG = 0x202, // DTLB tag
RAW_IPR_DTB_PTE = 0x203, // DTLB page table entry
RAW_IPR_DTB_PTE_TEMP = 0x204, // DTLB page table entry temporary
RAW_IPR_MM_STAT = 0x205, // data MMU fault status
RAW_IPR_VA = 0x206, // fault virtual address
RAW_IPR_VA_FORM = 0x207, // formatted virtual address
RAW_IPR_MVPTBR = 0x208, // MTU virtual page table base
RAW_IPR_DTB_IAP = 0x209, // DTLB invalidate all process
RAW_IPR_DTB_IA = 0x20a, // DTLB invalidate all
RAW_IPR_DTB_IS = 0x20b, // DTLB invalidate single
RAW_IPR_ALT_MODE = 0x20c, // alternate mode
RAW_IPR_CC = 0x20d, // cycle counter
RAW_IPR_CC_CTL = 0x20e, // cycle counter control
RAW_IPR_MCSR = 0x20f, // MTU control
RAW_IPR_DC_FLUSH = 0x210,
RAW_IPR_DC_PERR_STAT = 0x212, // Dcache parity error status
RAW_IPR_DC_TEST_CTL = 0x213, // Dcache test tag control
RAW_IPR_DC_TEST_TAG = 0x214, // Dcache test tag
RAW_IPR_DC_TEST_TAG_TEMP = 0x215, // Dcache test tag temporary
RAW_IPR_DC_MODE = 0x216, // Dcache mode
RAW_IPR_MAF_MODE = 0x217, // miss address file mode
MaxInternalProcRegs // number of IPRs
};
enum MiscRegIpr
{
//Write only
MinWriteOnlyIpr,
IPR_HWINT_CLR = MinWriteOnlyIpr,
IPR_SL_XMIT,
IPR_DC_FLUSH,
IPR_IC_FLUSH,
IPR_ALT_MODE,
IPR_DTB_IA,
IPR_DTB_IAP,
IPR_ITB_IA,
MaxWriteOnlyIpr,
IPR_ITB_IAP = MaxWriteOnlyIpr,
//Read only
MinReadOnlyIpr,
IPR_INTID = MinReadOnlyIpr,
IPR_SL_RCV,
IPR_MM_STAT,
IPR_ITB_PTE_TEMP,
MaxReadOnlyIpr,
IPR_DTB_PTE_TEMP = MaxReadOnlyIpr,
IPR_ISR,
IPR_ITB_TAG,
IPR_ITB_PTE,
IPR_ITB_ASN,
IPR_ITB_IS,
IPR_SIRR,
IPR_ASTRR,
IPR_ASTER,
IPR_EXC_ADDR,
IPR_EXC_SUM,
IPR_EXC_MASK,
IPR_PAL_BASE,
IPR_ICM,
IPR_IPLR,
IPR_IFAULT_VA_FORM,
IPR_IVPTBR,
IPR_ICSR,
IPR_IC_PERR_STAT,
IPR_PMCTR,
// PAL temporary registers...
// register meanings gleaned from osfpal.s source code
IPR_PALtemp0,
IPR_PALtemp1,
IPR_PALtemp2,
IPR_PALtemp3,
IPR_PALtemp4,
IPR_PALtemp5,
IPR_PALtemp6,
IPR_PALtemp7,
IPR_PALtemp8,
IPR_PALtemp9,
IPR_PALtemp10,
IPR_PALtemp11,
IPR_PALtemp12,
IPR_PALtemp13,
IPR_PALtemp14,
IPR_PALtemp15,
IPR_PALtemp16,
IPR_PALtemp17,
IPR_PALtemp18,
IPR_PALtemp19,
IPR_PALtemp20,
IPR_PALtemp21,
IPR_PALtemp22,
IPR_PALtemp23,
IPR_DTB_ASN,
IPR_DTB_CM,
IPR_DTB_TAG,
IPR_DTB_PTE,
IPR_VA,
IPR_VA_FORM,
IPR_MVPTBR,
IPR_DTB_IS,
IPR_CC,
IPR_CC_CTL,
IPR_MCSR,
IPR_DC_PERR_STAT,
IPR_DC_TEST_CTL,
IPR_DC_TEST_TAG,
IPR_DC_TEST_TAG_TEMP,
IPR_DC_MODE,
IPR_MAF_MODE,
NumInternalProcRegs // number of IPR registers
};
inline bool
IprIsWritable(int index)
{
return index < MinReadOnlyIpr || index > MaxReadOnlyIpr;
}
inline bool
IprIsReadable(int index)
{
return index < MinWriteOnlyIpr || index > MaxWriteOnlyIpr;
}
extern md_ipr_names MiscRegIndexToIpr[NumInternalProcRegs];
extern int IprToMiscRegIndex[MaxInternalProcRegs];
void initializeIprTable();
} // namespace AlphaISA
#endif // __ARCH_ALPHA_IPR_HH__

View File

@ -0,0 +1,153 @@
/*
* Copyright (c) 2009 The Regents of The University of Michigan
* 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: Gabe Black
*/
#include <cassert>
#include "arch/alpha/isa.hh"
#include "base/misc.hh"
#include "cpu/thread_context.hh"
#include "sim/serialize.hh"
namespace AlphaISA
{
void
ISA::serialize(EventManager *em, std::ostream &os)
{
SERIALIZE_SCALAR(fpcr);
SERIALIZE_SCALAR(uniq);
SERIALIZE_SCALAR(lock_flag);
SERIALIZE_SCALAR(lock_addr);
SERIALIZE_ARRAY(ipr, NumInternalProcRegs);
}
void
ISA::unserialize(EventManager *em, Checkpoint *cp, const std::string &section)
{
UNSERIALIZE_SCALAR(fpcr);
UNSERIALIZE_SCALAR(uniq);
UNSERIALIZE_SCALAR(lock_flag);
UNSERIALIZE_SCALAR(lock_addr);
UNSERIALIZE_ARRAY(ipr, NumInternalProcRegs);
}
MiscReg
ISA::readMiscRegNoEffect(int misc_reg, ThreadID tid)
{
switch (misc_reg) {
case MISCREG_FPCR:
return fpcr;
case MISCREG_UNIQ:
return uniq;
case MISCREG_LOCKFLAG:
return lock_flag;
case MISCREG_LOCKADDR:
return lock_addr;
case MISCREG_INTR:
return intr_flag;
default:
assert(misc_reg < NumInternalProcRegs);
return ipr[misc_reg];
}
}
MiscReg
ISA::readMiscReg(int misc_reg, ThreadContext *tc, ThreadID tid)
{
switch (misc_reg) {
case MISCREG_FPCR:
return fpcr;
case MISCREG_UNIQ:
return uniq;
case MISCREG_LOCKFLAG:
return lock_flag;
case MISCREG_LOCKADDR:
return lock_addr;
case MISCREG_INTR:
return intr_flag;
default:
return readIpr(misc_reg, tc);
}
}
void
ISA::setMiscRegNoEffect(int misc_reg, const MiscReg &val, ThreadID tid)
{
switch (misc_reg) {
case MISCREG_FPCR:
fpcr = val;
return;
case MISCREG_UNIQ:
uniq = val;
return;
case MISCREG_LOCKFLAG:
lock_flag = val;
return;
case MISCREG_LOCKADDR:
lock_addr = val;
return;
case MISCREG_INTR:
intr_flag = val;
return;
default:
assert(misc_reg < NumInternalProcRegs);
ipr[misc_reg] = val;
return;
}
}
void
ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc,
ThreadID tid)
{
switch (misc_reg) {
case MISCREG_FPCR:
fpcr = val;
return;
case MISCREG_UNIQ:
uniq = val;
return;
case MISCREG_LOCKFLAG:
lock_flag = val;
return;
case MISCREG_LOCKADDR:
lock_addr = val;
return;
case MISCREG_INTR:
intr_flag = val;
return;
default:
setIpr(misc_reg, val, tc);
return;
}
}
}

View File

@ -0,0 +1,112 @@
/*
* Copyright (c) 2009 The Regents of The University of Michigan
* 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: Gabe Black
*/
#ifndef __ARCH_ALPHA_ISA_HH__
#define __ARCH_ALPHA_ISA_HH__
#include <cstring>
#include <iostream>
#include <string>
#include "arch/alpha/registers.hh"
#include "arch/alpha/types.hh"
#include "base/types.hh"
class BaseCPU;
class Checkpoint;
class EventManager;
class ThreadContext;
namespace AlphaISA
{
class ISA
{
public:
typedef uint64_t InternalProcReg;
protected:
uint64_t fpcr; // floating point condition codes
uint64_t uniq; // process-unique register
bool lock_flag; // lock flag for LL/SC
Addr lock_addr; // lock address for LL/SC
int intr_flag;
InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs
protected:
InternalProcReg readIpr(int idx, ThreadContext *tc);
void setIpr(int idx, InternalProcReg val, ThreadContext *tc);
public:
MiscReg readMiscRegNoEffect(int misc_reg, ThreadID tid = 0);
MiscReg readMiscReg(int misc_reg, ThreadContext *tc, ThreadID tid = 0);
void setMiscRegNoEffect(int misc_reg, const MiscReg &val,
ThreadID tid = 0);
void setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc,
ThreadID tid = 0);
void
clear()
{
fpcr = 0;
uniq = 0;
lock_flag = 0;
lock_addr = 0;
intr_flag = 0;
memset(ipr, 0, sizeof(ipr));
}
void serialize(EventManager *em, std::ostream &os);
void unserialize(EventManager *em, Checkpoint *cp,
const std::string &section);
int
flattenIntIndex(int reg)
{
return reg;
}
int
flattenFloatIndex(int reg)
{
return reg;
}
ISA()
{
clear();
initializeIprTable();
}
};
}
#endif

View File

@ -0,0 +1,274 @@
// -*- mode:c++ -*-
// Copyright (c) 2003-2005 The Regents of The University of Michigan
// 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
////////////////////////////////////////////////////////////////////
//
// Control transfer instructions
//
output header {{
/**
* Base class for instructions whose disassembly is not purely a
* function of the machine instruction (i.e., it depends on the
* PC). This class overrides the disassemble() method to check
* the PC and symbol table values before re-using a cached
* disassembly string. This is necessary for branches and jumps,
* where the disassembly string includes the target address (which
* may depend on the PC and/or symbol table).
*/
class PCDependentDisassembly : public AlphaStaticInst
{
protected:
/// Cached program counter from last disassembly
mutable Addr cachedPC;
/// Cached symbol table pointer from last disassembly
mutable const SymbolTable *cachedSymtab;
/// Constructor
PCDependentDisassembly(const char *mnem, ExtMachInst _machInst,
OpClass __opClass)
: AlphaStaticInst(mnem, _machInst, __opClass),
cachedPC(0), cachedSymtab(0)
{
}
const std::string &
disassemble(Addr pc, const SymbolTable *symtab) const;
};
/**
* Base class for branches (PC-relative control transfers),
* conditional or unconditional.
*/
class Branch : public PCDependentDisassembly
{
protected:
/// Displacement to target address (signed).
int32_t disp;
/// Constructor.
Branch(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
: PCDependentDisassembly(mnem, _machInst, __opClass),
disp(BRDISP << 2)
{
}
AlphaISA::PCState branchTarget(const AlphaISA::PCState &branchPC) const;
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
/**
* Base class for jumps (register-indirect control transfers). In
* the Alpha ISA, these are always unconditional.
*/
class Jump : public PCDependentDisassembly
{
protected:
/// Displacement to target address (signed).
int32_t disp;
public:
/// Constructor
Jump(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
: PCDependentDisassembly(mnem, _machInst, __opClass),
disp(BRDISP)
{
}
AlphaISA::PCState branchTarget(ThreadContext *tc) const;
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
output decoder {{
AlphaISA::PCState
Branch::branchTarget(const AlphaISA::PCState &branchPC) const
{
return branchPC.pc() + 4 + disp;
}
AlphaISA::PCState
Jump::branchTarget(ThreadContext *tc) const
{
PCState pc = tc->pcState();
uint64_t Rb = tc->readIntReg(_srcRegIdx[0]);
pc.set((Rb & ~3) | (pc.pc() & 1));
return pc;
}
const std::string &
PCDependentDisassembly::disassemble(Addr pc,
const SymbolTable *symtab) const
{
if (!cachedDisassembly ||
pc != cachedPC || symtab != cachedSymtab)
{
if (cachedDisassembly)
delete cachedDisassembly;
cachedDisassembly =
new std::string(generateDisassembly(pc, symtab));
cachedPC = pc;
cachedSymtab = symtab;
}
return *cachedDisassembly;
}
std::string
Branch::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
ccprintf(ss, "%-10s ", mnemonic);
// There's only one register arg (RA), but it could be
// either a source (the condition for conditional
// branches) or a destination (the link reg for
// unconditional branches)
if (_numSrcRegs > 0) {
printReg(ss, _srcRegIdx[0]);
ss << ",";
}
else if (_numDestRegs > 0) {
printReg(ss, _destRegIdx[0]);
ss << ",";
}
#ifdef SS_COMPATIBLE_DISASSEMBLY
if (_numSrcRegs == 0 && _numDestRegs == 0) {
printReg(ss, 31);
ss << ",";
}
#endif
Addr target = pc + 4 + disp;
std::string str;
if (symtab && symtab->findSymbol(target, str))
ss << str;
else
ccprintf(ss, "0x%x", target);
return ss.str();
}
std::string
Jump::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
ccprintf(ss, "%-10s ", mnemonic);
#ifdef SS_COMPATIBLE_DISASSEMBLY
if (_numDestRegs == 0) {
printReg(ss, 31);
ss << ",";
}
#endif
if (_numDestRegs > 0) {
printReg(ss, _destRegIdx[0]);
ss << ",";
}
ccprintf(ss, "(r%d)", RB);
return ss.str();
}
}};
def template JumpOrBranchDecode {{
return (RA == 31)
? (StaticInst *)new %(class_name)s(machInst)
: (StaticInst *)new %(class_name)sAndLink(machInst);
}};
def format CondBranch(code) {{
code = '''
bool cond;
%(code)s;
if (cond)
NPC = NPC + disp;
else
NPC = NPC;
''' % { "code" : code }
iop = InstObjParams(name, Name, 'Branch', code,
('IsDirectControl', 'IsCondControl'))
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};
let {{
def UncondCtrlBase(name, Name, base_class, npc_expr, flags):
# Declare basic control transfer w/o link (i.e. link reg is R31)
nolink_code = 'NPC = %s;\n' % npc_expr
nolink_iop = InstObjParams(name, Name, base_class,
nolink_code, flags)
header_output = BasicDeclare.subst(nolink_iop)
decoder_output = BasicConstructor.subst(nolink_iop)
exec_output = BasicExecute.subst(nolink_iop)
# Generate declaration of '*AndLink' version, append to decls
link_code = 'Ra = NPC & ~3;\n' + nolink_code
link_iop = InstObjParams(name, Name + 'AndLink', base_class,
link_code, flags)
header_output += BasicDeclare.subst(link_iop)
decoder_output += BasicConstructor.subst(link_iop)
exec_output += BasicExecute.subst(link_iop)
# need to use link_iop for the decode template since it is expecting
# the shorter version of class_name (w/o "AndLink")
return (header_output, decoder_output,
JumpOrBranchDecode.subst(nolink_iop), exec_output)
}};
def format UncondBranch(*flags) {{
flags += ('IsUncondControl', 'IsDirectControl')
(header_output, decoder_output, decode_block, exec_output) = \
UncondCtrlBase(name, Name, 'Branch', 'NPC + disp', flags)
}};
def format Jump(*flags) {{
flags += ('IsUncondControl', 'IsIndirectControl')
(header_output, decoder_output, decode_block, exec_output) = \
UncondCtrlBase(name, Name, 'Jump', '(Rb & ~3) | (NPC & 1)', flags)
}};

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,305 @@
// -*- mode:c++ -*-
// Copyright (c) 2003-2005 The Regents of The University of Michigan
// 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
////////////////////////////////////////////////////////////////////
//
// Floating-point instructions
//
// Note that many FP-type instructions which do not support all the
// various rounding & trapping modes use the simpler format
// BasicOperateWithNopCheck.
//
output exec {{
/// Check "FP enabled" machine status bit. Called when executing any FP
/// instruction in full-system mode.
/// @retval Full-system mode: NoFault if FP is enabled, FenFault
/// if not. Non-full-system mode: always returns NoFault.
inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
{
Fault fault = NoFault; // dummy... this ipr access should not fault
if (FullSystem && !ICSR_FPE(xc->readMiscReg(IPR_ICSR))) {
fault = new FloatEnableFault;
}
return fault;
}
}};
output header {{
/**
* Base class for general floating-point instructions. Includes
* support for various Alpha rounding and trapping modes. Only FP
* instructions that require this support are derived from this
* class; the rest derive directly from AlphaStaticInst.
*/
class AlphaFP : public AlphaStaticInst
{
public:
/// Alpha FP rounding modes.
enum RoundingMode {
Chopped = 0, ///< round toward zero
Minus_Infinity = 1, ///< round toward minus infinity
Normal = 2, ///< round to nearest (default)
Dynamic = 3, ///< use FPCR setting (in instruction)
Plus_Infinity = 3 ///< round to plus inifinity (in FPCR)
};
/// Alpha FP trapping modes.
/// For instructions that produce integer results, the
/// "Underflow Enable" modes really mean "Overflow Enable", and
/// the assembly modifier is V rather than U.
enum TrappingMode {
/// default: nothing enabled
Imprecise = 0, ///< no modifier
/// underflow/overflow traps enabled, inexact disabled
Underflow_Imprecise = 1, ///< /U or /V
Underflow_Precise = 5, ///< /SU or /SV
/// underflow/overflow and inexact traps enabled
Underflow_Inexact_Precise = 7 ///< /SUI or /SVI
};
protected:
/// Map Alpha rounding mode to C99 constants from <fenv.h>.
static const int alphaToC99RoundingMode[];
/// Map enum RoundingMode values to disassembly suffixes.
static const char *roundingModeSuffix[];
/// Map enum TrappingMode values to FP disassembly suffixes.
static const char *fpTrappingModeSuffix[];
/// Map enum TrappingMode values to integer disassembly suffixes.
static const char *intTrappingModeSuffix[];
/// This instruction's rounding mode.
RoundingMode roundingMode;
/// This instruction's trapping mode.
TrappingMode trappingMode;
/// Have we warned about this instruction's unsupported
/// rounding mode (if applicable)?
mutable bool warnedOnRounding;
/// Have we warned about this instruction's unsupported
/// trapping mode (if applicable)?
mutable bool warnedOnTrapping;
/// Constructor
AlphaFP(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
: AlphaStaticInst(mnem, _machInst, __opClass),
roundingMode((enum RoundingMode)FP_ROUNDMODE),
trappingMode((enum TrappingMode)FP_TRAPMODE),
warnedOnRounding(false),
warnedOnTrapping(false)
{
}
int getC99RoundingMode(uint64_t fpcr_val) const;
// This differs from the AlphaStaticInst version only in
// printing suffixes for non-default rounding & trapping modes.
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
output decoder {{
int
AlphaFP::getC99RoundingMode(uint64_t fpcr_val) const
{
if (roundingMode == Dynamic) {
return alphaToC99RoundingMode[bits(fpcr_val, 59, 58)];
}
else {
return alphaToC99RoundingMode[roundingMode];
}
}
std::string
AlphaFP::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::string mnem_str(mnemonic);
#ifndef SS_COMPATIBLE_DISASSEMBLY
std::string suffix("");
suffix += ((_destRegIdx[0] >= FP_Base_DepTag)
? fpTrappingModeSuffix[trappingMode]
: intTrappingModeSuffix[trappingMode]);
suffix += roundingModeSuffix[roundingMode];
if (suffix != "") {
mnem_str = csprintf("%s/%s", mnemonic, suffix);
}
#endif
std::stringstream ss;
ccprintf(ss, "%-10s ", mnem_str.c_str());
// just print the first two source regs... if there's
// a third one, it's a read-modify-write dest (Rc),
// e.g. for CMOVxx
if (_numSrcRegs > 0) {
printReg(ss, _srcRegIdx[0]);
}
if (_numSrcRegs > 1) {
ss << ",";
printReg(ss, _srcRegIdx[1]);
}
// just print the first dest... if there's a second one,
// it's generally implicit
if (_numDestRegs > 0) {
if (_numSrcRegs > 0)
ss << ",";
printReg(ss, _destRegIdx[0]);
}
return ss.str();
}
const int AlphaFP::alphaToC99RoundingMode[] = {
M5_FE_TOWARDZERO, // Chopped
M5_FE_DOWNWARD, // Minus_Infinity
M5_FE_TONEAREST, // Normal
M5_FE_UPWARD // Dynamic in inst, Plus_Infinity in FPCR
};
const char *AlphaFP::roundingModeSuffix[] = { "c", "m", "", "d" };
// mark invalid trapping modes, but don't fail on them, because
// you could decode anything on a misspeculated path
const char *AlphaFP::fpTrappingModeSuffix[] =
{ "", "u", "INVTM2", "INVTM3", "INVTM4", "su", "INVTM6", "sui" };
const char *AlphaFP::intTrappingModeSuffix[] =
{ "", "v", "INVTM2", "INVTM3", "INVTM4", "sv", "INVTM6", "svi" };
}};
// FP instruction class execute method template. Handles non-standard
// rounding modes.
def template FloatingPointExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
if (trappingMode != Imprecise && !warnedOnTrapping) {
warn("%s: non-standard trapping mode not supported",
generateDisassembly(0, NULL));
warnedOnTrapping = true;
}
Fault fault = NoFault;
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
#if USE_FENV
if (roundingMode == Normal) {
%(code)s;
} else {
m5_fesetround(getC99RoundingMode(
xc->readMiscReg(MISCREG_FPCR)));
%(code)s;
m5_fesetround(M5_FE_TONEAREST);
}
#else
if (roundingMode != Normal && !warnedOnRounding) {
warn("%s: non-standard rounding mode not supported",
generateDisassembly(0, NULL));
warnedOnRounding = true;
}
%(code)s;
#endif
if (fault == NoFault) {
%(op_wb)s;
}
return fault;
}
}};
// FP instruction class execute method template where no dynamic
// rounding mode control is needed. Like BasicExecute, but includes
// check & warning for non-standard trapping mode.
def template FPFixedRoundingExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
if (trappingMode != Imprecise && !warnedOnTrapping) {
warn("%s: non-standard trapping mode not supported",
generateDisassembly(0, NULL));
warnedOnTrapping = true;
}
Fault fault = NoFault;
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(code)s;
if (fault == NoFault) {
%(op_wb)s;
}
return fault;
}
}};
def template FloatingPointDecode {{
{
AlphaStaticInst *i = new %(class_name)s(machInst);
if (FC == 31) {
i = makeNop(i);
}
return i;
}
}};
// General format for floating-point operate instructions:
// - Checks trapping and rounding mode flags. Trapping modes
// currently unimplemented (will fail).
// - Generates NOP if FC == 31.
def format FloatingPointOperate(code, *opt_args) {{
iop = InstObjParams(name, Name, 'AlphaFP', code, opt_args)
decode_block = FloatingPointDecode.subst(iop)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
exec_output = FloatingPointExecute.subst(iop)
}};
// Special format for cvttq where rounding mode is pre-decoded
def format FPFixedRounding(code, class_suffix, *opt_args) {{
Name += class_suffix
iop = InstObjParams(name, Name, 'AlphaFP', code, opt_args)
decode_block = FloatingPointDecode.subst(iop)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
exec_output = FPFixedRoundingExecute.subst(iop)
}};

View File

@ -0,0 +1,133 @@
// -*- mode:c++ -*-
// Copyright (c) 2003-2005 The Regents of The University of Michigan
// 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
////////////////////////////////////////////////////////////////////
//
// Integer operate instructions
//
output header {{
/**
* Base class for integer immediate instructions.
*/
class IntegerImm : public AlphaStaticInst
{
protected:
/// Immediate operand value (unsigned 8-bit int).
uint8_t imm;
/// Constructor
IntegerImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
: AlphaStaticInst(mnem, _machInst, __opClass), imm(INTIMM)
{
}
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
output decoder {{
std::string
IntegerImm::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
ccprintf(ss, "%-10s ", mnemonic);
// just print the first source reg... if there's
// a second one, it's a read-modify-write dest (Rc),
// e.g. for CMOVxx
if (_numSrcRegs > 0) {
printReg(ss, _srcRegIdx[0]);
ss << ",";
}
ss << (int)imm;
if (_numDestRegs > 0) {
ss << ",";
printReg(ss, _destRegIdx[0]);
}
return ss.str();
}
}};
def template RegOrImmDecode {{
{
AlphaStaticInst *i =
(IMM) ? (AlphaStaticInst *)new %(class_name)sImm(machInst)
: (AlphaStaticInst *)new %(class_name)s(machInst);
if (RC == 31) {
i = makeNop(i);
}
return i;
}
}};
// Primary format for integer operate instructions:
// - Generates both reg-reg and reg-imm versions if Rb_or_imm is used.
// - Generates NOP if RC == 31.
def format IntegerOperate(code, *opt_flags) {{
# If the code block contains 'Rb_or_imm', we define two instructions,
# one using 'Rb' and one using 'imm', and have the decoder select
# the right one.
uses_imm = (code.find('Rb_or_imm') != -1)
if uses_imm:
orig_code = code
# base code is reg version:
# rewrite by substituting 'Rb' for 'Rb_or_imm'
code = re.sub(r'Rb_or_imm', 'Rb', orig_code)
# generate immediate version by substituting 'imm'
# note that imm takes no extenstion, so we extend
# the regexp to replace any extension as well
imm_code = re.sub(r'Rb_or_imm(_\w+)?', 'imm', orig_code)
# generate declaration for register version
iop = InstObjParams(name, Name, 'AlphaStaticInst', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
exec_output = BasicExecute.subst(iop)
if uses_imm:
# append declaration for imm version
imm_iop = InstObjParams(name, Name + 'Imm', 'IntegerImm', imm_code,
opt_flags)
header_output += BasicDeclare.subst(imm_iop)
decoder_output += BasicConstructor.subst(imm_iop)
exec_output += BasicExecute.subst(imm_iop)
# decode checks IMM bit to pick correct version
decode_block = RegOrImmDecode.subst(iop)
else:
# no imm version: just check for nop
decode_block = OperateNopCheckDecode.subst(iop)
}};

View File

@ -0,0 +1,477 @@
// -*- mode:c++ -*-
// Copyright (c) 2003-2005 The Regents of The University of Michigan
// 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
////////////////////////////////////////////////////////////////////
//
// Alpha ISA description file.
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
//
// Output include file directives.
//
output header {{
#include <iomanip>
#include <iostream>
#include <sstream>
#include "arch/alpha/faults.hh"
#include "arch/alpha/types.hh"
#include "config/ss_compatible_fp.hh"
#include "cpu/static_inst.hh"
#include "mem/packet.hh"
#include "mem/request.hh" // some constructors use MemReq flags
}};
output decoder {{
#include <cmath>
#include "arch/alpha/decoder.hh"
#include "arch/alpha/registers.hh"
#include "arch/alpha/regredir.hh"
#include "base/loader/symtab.hh"
#include "base/cprintf.hh"
#include "base/fenv.hh"
#include "config/ss_compatible_fp.hh"
#include "cpu/thread_context.hh" // for Jump::branchTarget()
#include "mem/packet.hh"
#include "sim/full_system.hh"
using namespace AlphaISA;
}};
output exec {{
#include <cmath>
#include "arch/alpha/decoder.hh"
#include "arch/alpha/registers.hh"
#include "arch/alpha/regredir.hh"
#include "arch/generic/memhelpers.hh"
#include "base/cp_annotate.hh"
#include "base/fenv.hh"
#include "config/ss_compatible_fp.hh"
#include "cpu/base.hh"
#include "cpu/exetrace.hh"
#include "mem/packet.hh"
#include "mem/packet_access.hh"
#include "sim/full_system.hh"
#include "sim/pseudo_inst.hh"
#include "sim/sim_exit.hh"
using namespace AlphaISA;
}};
////////////////////////////////////////////////////////////////////
//
// Namespace statement. Everything below this line will be in the
// AlphaISAInst namespace.
//
namespace AlphaISA;
////////////////////////////////////////////////////////////////////
//
// Bitfield definitions.
//
// Universal (format-independent) fields
def bitfield PALMODE <32:32>;
def bitfield OPCODE <31:26>;
def bitfield RA <25:21>;
def bitfield RB <20:16>;
// Memory format
def signed bitfield MEMDISP <15: 0>; // displacement
def bitfield MEMFUNC <15: 0>; // function code (same field, unsigned)
// Memory-format jumps
def bitfield JMPFUNC <15:14>; // function code (disp<15:14>)
def bitfield JMPHINT <13: 0>; // tgt Icache idx hint (disp<13:0>)
// Branch format
def signed bitfield BRDISP <20: 0>; // displacement
// Integer operate format(s>;
def bitfield INTIMM <20:13>; // integer immediate (literal)
def bitfield IMM <12:12>; // immediate flag
def bitfield INTFUNC <11: 5>; // function code
def bitfield RC < 4: 0>; // dest reg
// Floating-point operate format
def bitfield FA <25:21>;
def bitfield FB <20:16>;
def bitfield FP_FULLFUNC <15: 5>; // complete function code
def bitfield FP_TRAPMODE <15:13>; // trapping mode
def bitfield FP_ROUNDMODE <12:11>; // rounding mode
def bitfield FP_TYPEFUNC <10: 5>; // type+func: handiest for decoding
def bitfield FP_SRCTYPE <10: 9>; // source reg type
def bitfield FP_SHORTFUNC < 8: 5>; // short function code
def bitfield FP_SHORTFUNC_TOP2 <8:7>; // top 2 bits of short func code
def bitfield FC < 4: 0>; // dest reg
// PALcode format
def bitfield PALFUNC <25: 0>; // function code
// EV5 PAL instructions:
// HW_LD/HW_ST
def bitfield HW_LDST_PHYS <15>; // address is physical
def bitfield HW_LDST_ALT <14>; // use ALT_MODE IPR
def bitfield HW_LDST_WRTCK <13>; // HW_LD only: fault if no write acc
def bitfield HW_LDST_QUAD <12>; // size: 0=32b, 1=64b
def bitfield HW_LDST_VPTE <11>; // HW_LD only: is PTE fetch
def bitfield HW_LDST_LOCK <10>; // HW_LD only: is load locked
def bitfield HW_LDST_COND <10>; // HW_ST only: is store conditional
def signed bitfield HW_LDST_DISP <9:0>; // signed displacement
// HW_REI
def bitfield HW_REI_TYP <15:14>; // type: stalling vs. non-stallingk
def bitfield HW_REI_MBZ <13: 0>; // must be zero
// HW_MTPR/MW_MFPR
def bitfield HW_IPR_IDX <15:0>; // IPR index
// M5 instructions
def bitfield M5FUNC <7:0>;
def operand_types {{
'sb' : 'int8_t',
'ub' : 'uint8_t',
'sw' : 'int16_t',
'uw' : 'uint16_t',
'sl' : 'int32_t',
'ul' : 'uint32_t',
'sq' : 'int64_t',
'uq' : 'uint64_t',
'sf' : 'float',
'df' : 'double'
}};
def operands {{
# Int regs default to unsigned, but code should not count on this.
# For clarity, descriptions that depend on unsigned behavior should
# explicitly specify '_uq'.
'Ra': ('IntReg', 'uq', 'PALMODE ? reg_redir[RA] : RA',
'IsInteger', 1),
'Rb': ('IntReg', 'uq', 'PALMODE ? reg_redir[RB] : RB',
'IsInteger', 2),
'Rc': ('IntReg', 'uq', 'PALMODE ? reg_redir[RC] : RC',
'IsInteger', 3),
'Fa': ('FloatReg', 'df', 'FA', 'IsFloating', 1),
'Fb': ('FloatReg', 'df', 'FB', 'IsFloating', 2),
'Fc': ('FloatReg', 'df', 'FC', 'IsFloating', 3),
'Mem': ('Mem', 'uq', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4),
'PC': ('PCState', 'uq', 'pc', ( None, None, 'IsControl' ), 4),
'NPC': ('PCState', 'uq', 'npc', ( None, None, 'IsControl' ), 4),
'Runiq': ('ControlReg', 'uq', 'MISCREG_UNIQ', None, 1),
'FPCR': ('ControlReg', 'uq', 'MISCREG_FPCR', None, 1),
'IntrFlag': ('ControlReg', 'uq', 'MISCREG_INTR', None, 1),
# The next two are hacks for non-full-system call-pal emulation
'R0': ('IntReg', 'uq', '0', None, 1),
'R16': ('IntReg', 'uq', '16', None, 1),
'R17': ('IntReg', 'uq', '17', None, 1),
'R18': ('IntReg', 'uq', '18', None, 1)
}};
////////////////////////////////////////////////////////////////////
//
// Basic instruction classes/templates/formats etc.
//
output header {{
// uncomment the following to get SimpleScalar-compatible disassembly
// (useful for diffing output traces).
// #define SS_COMPATIBLE_DISASSEMBLY
/**
* Base class for all Alpha static instructions.
*/
class AlphaStaticInst : public StaticInst
{
protected:
/// Make AlphaISA register dependence tags directly visible in
/// this class and derived classes. Maybe these should really
/// live here and not in the AlphaISA namespace.
enum DependenceTags {
FP_Base_DepTag = AlphaISA::FP_Base_DepTag
};
/// Constructor.
AlphaStaticInst(const char *mnem, ExtMachInst _machInst,
OpClass __opClass)
: StaticInst(mnem, _machInst, __opClass)
{
}
/// Print a register name for disassembly given the unique
/// dependence tag number (FP or int).
void printReg(std::ostream &os, int reg) const;
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
void
advancePC(AlphaISA::PCState &pcState) const
{
pcState.advance();
}
};
}};
output decoder {{
void
AlphaStaticInst::printReg(std::ostream &os, int reg) const
{
if (reg < FP_Base_DepTag) {
ccprintf(os, "r%d", reg);
}
else {
ccprintf(os, "f%d", reg - FP_Base_DepTag);
}
}
std::string
AlphaStaticInst::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
std::stringstream ss;
ccprintf(ss, "%-10s ", mnemonic);
// just print the first two source regs... if there's
// a third one, it's a read-modify-write dest (Rc),
// e.g. for CMOVxx
if (_numSrcRegs > 0) {
printReg(ss, _srcRegIdx[0]);
}
if (_numSrcRegs > 1) {
ss << ",";
printReg(ss, _srcRegIdx[1]);
}
// just print the first dest... if there's a second one,
// it's generally implicit
if (_numDestRegs > 0) {
if (_numSrcRegs > 0)
ss << ",";
printReg(ss, _destRegIdx[0]);
}
return ss.str();
}
}};
// Declarations for execute() methods.
def template BasicExecDeclare {{
Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const;
}};
// Basic instruction class declaration template.
def template BasicDeclare {{
/**
* Static instruction class for "%(mnemonic)s".
*/
class %(class_name)s : public %(base_class)s
{
public:
/// Constructor.
%(class_name)s(ExtMachInst machInst);
%(BasicExecDeclare)s
};
}};
// Basic instruction class constructor template.
def template BasicConstructor {{
inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
{
%(constructor)s;
}
}};
// Basic instruction class execute method template.
def template BasicExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(code)s;
if (fault == NoFault) {
%(op_wb)s;
}
return fault;
}
}};
// Basic decode template.
def template BasicDecode {{
return new %(class_name)s(machInst);
}};
// Basic decode template, passing mnemonic in as string arg to constructor.
def template BasicDecodeWithMnemonic {{
return new %(class_name)s("%(mnemonic)s", machInst);
}};
// The most basic instruction format... used only for a few misc. insts
def format BasicOperate(code, *flags) {{
iop = InstObjParams(name, Name, 'AlphaStaticInst', code, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};
////////////////////////////////////////////////////////////////////
//
// Nop
//
output header {{
/**
* Static instruction class for no-ops. This is a leaf class.
*/
class Nop : public AlphaStaticInst
{
/// Disassembly of original instruction.
const std::string originalDisassembly;
public:
/// Constructor
Nop(const std::string _originalDisassembly, ExtMachInst _machInst)
: AlphaStaticInst("nop", _machInst, No_OpClass),
originalDisassembly(_originalDisassembly)
{
flags[IsNop] = true;
}
~Nop() { }
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
%(BasicExecDeclare)s
};
/// Helper function for decoding nops. Substitute Nop object
/// for original inst passed in as arg (and delete latter).
static inline
AlphaStaticInst *
makeNop(AlphaStaticInst *inst)
{
AlphaStaticInst *nop = new Nop(inst->disassemble(0), inst->machInst);
delete inst;
return nop;
}
}};
output decoder {{
std::string Nop::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
#ifdef SS_COMPATIBLE_DISASSEMBLY
return originalDisassembly;
#else
return csprintf("%-10s (%s)", "nop", originalDisassembly);
#endif
}
}};
output exec {{
Fault
Nop::execute(%(CPU_exec_context)s *, Trace::InstRecord *) const
{
return NoFault;
}
}};
// integer & FP operate instructions use Rc as dest, so check for
// Rc == 31 to detect nops
def template OperateNopCheckDecode {{
{
AlphaStaticInst *i = new %(class_name)s(machInst);
if (RC == 31) {
i = makeNop(i);
}
return i;
}
}};
// Like BasicOperate format, but generates NOP if RC/FC == 31
def format BasicOperateWithNopCheck(code, *opt_args) {{
iop = InstObjParams(name, Name, 'AlphaStaticInst', code, opt_args)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = OperateNopCheckDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};
// Integer instruction templates, formats, etc.
##include "int.isa"
// Floating-point instruction templates, formats, etc.
##include "fp.isa"
// Memory instruction templates, formats, etc.
##include "mem.isa"
// Branch/jump instruction templates, formats, etc.
##include "branch.isa"
// PAL instruction templates, formats, etc.
##include "pal.isa"
// Opcdec fault instruction templates, formats, etc.
##include "opcdec.isa"
// Unimplemented instruction templates, formats, etc.
##include "unimp.isa"
// Unknown instruction templates, formats, etc.
##include "unknown.isa"
// Execution utility functions
##include "util.isa"
// The actual decoder
##include "decoder.isa"

View File

@ -0,0 +1,573 @@
// -*- mode:c++ -*-
// Copyright (c) 2003-2005 The Regents of The University of Michigan
// 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
// Kevin Lim
////////////////////////////////////////////////////////////////////
//
// Memory-format instructions: LoadAddress, Load, Store
//
output header {{
/**
* Base class for general Alpha memory-format instructions.
*/
class Memory : public AlphaStaticInst
{
protected:
/// Memory request flags. See mem_req_base.hh.
Request::Flags memAccessFlags;
/// Constructor
Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
: AlphaStaticInst(mnem, _machInst, __opClass)
{
}
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
/**
* Base class for memory-format instructions using a 32-bit
* displacement (i.e. most of them).
*/
class MemoryDisp32 : public Memory
{
protected:
/// Displacement for EA calculation (signed).
int32_t disp;
/// Constructor.
MemoryDisp32(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
: Memory(mnem, _machInst, __opClass),
disp(MEMDISP)
{
}
};
/**
* Base class for a few miscellaneous memory-format insts
* that don't interpret the disp field: wh64, fetch, fetch_m, ecb.
* None of these instructions has a destination register either.
*/
class MemoryNoDisp : public Memory
{
protected:
/// Constructor
MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
: Memory(mnem, _machInst, __opClass)
{
}
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
output decoder {{
std::string
Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
return csprintf("%-10s %c%d,%d(r%d)", mnemonic,
flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB);
}
std::string
MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
return csprintf("%-10s (r%d)", mnemonic, RB);
}
}};
def format LoadAddress(code) {{
iop = InstObjParams(name, Name, 'MemoryDisp32', code)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};
def template LoadStoreDeclare {{
/**
* Static instruction class for "%(mnemonic)s".
*/
class %(class_name)s : public %(base_class)s
{
public:
/// Constructor.
%(class_name)s(ExtMachInst machInst);
%(BasicExecDeclare)s
%(EACompDeclare)s
%(InitiateAccDeclare)s
%(CompleteAccDeclare)s
};
}};
def template EACompDeclare {{
Fault eaComp(%(CPU_exec_context)s *, Trace::InstRecord *) const;
}};
def template InitiateAccDeclare {{
Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
}};
def template CompleteAccDeclare {{
Fault completeAcc(PacketPtr, %(CPU_exec_context)s *,
Trace::InstRecord *) const;
}};
def template LoadStoreConstructor {{
inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
{
%(constructor)s;
}
}};
def template EACompExecute {{
Fault %(class_name)s::eaComp(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = NoFault;
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
if (fault == NoFault) {
%(op_wb)s;
xc->setEA(EA);
}
return fault;
}
}};
def template LoadExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = NoFault;
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
if (fault == NoFault) {
fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags);
%(memacc_code)s;
}
if (fault == NoFault) {
%(op_wb)s;
}
return fault;
}
}};
def template LoadInitiateAcc {{
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = NoFault;
%(fp_enable_check)s;
%(op_src_decl)s;
%(op_rd)s;
%(ea_code)s;
if (fault == NoFault) {
fault = readMemTiming(xc, traceData, EA, Mem, memAccessFlags);
}
return fault;
}
}};
def template LoadCompleteAcc {{
Fault %(class_name)s::completeAcc(PacketPtr pkt,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
%(fp_enable_check)s;
%(op_decl)s;
getMem(pkt, Mem, traceData);
if (fault == NoFault) {
%(memacc_code)s;
}
if (fault == NoFault) {
%(op_wb)s;
}
return fault;
}
}};
def template StoreExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = NoFault;
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
if (fault == NoFault) {
%(memacc_code)s;
}
if (fault == NoFault) {
fault = writeMemAtomic(xc, traceData, Mem, EA,
memAccessFlags, NULL);
}
if (fault == NoFault) {
%(postacc_code)s;
}
if (fault == NoFault) {
%(op_wb)s;
}
return fault;
}
}};
def template StoreCondExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = NoFault;
uint64_t write_result = 0;
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
if (fault == NoFault) {
%(memacc_code)s;
}
if (fault == NoFault) {
fault = writeMemAtomic(xc, traceData, Mem, EA,
memAccessFlags, &write_result);
}
if (fault == NoFault) {
%(postacc_code)s;
}
if (fault == NoFault) {
%(op_wb)s;
}
return fault;
}
}};
def template StoreInitiateAcc {{
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = NoFault;
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
if (fault == NoFault) {
%(memacc_code)s;
}
if (fault == NoFault) {
fault = writeMemTiming(xc, traceData, Mem, EA,
memAccessFlags, NULL);
}
return fault;
}
}};
def template StoreCompleteAcc {{
Fault %(class_name)s::completeAcc(PacketPtr pkt,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
return NoFault;
}
}};
def template StoreCondCompleteAcc {{
Fault %(class_name)s::completeAcc(PacketPtr pkt,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
%(fp_enable_check)s;
%(op_dest_decl)s;
uint64_t write_result = pkt->req->getExtraData();
if (fault == NoFault) {
%(postacc_code)s;
}
if (fault == NoFault) {
%(op_wb)s;
}
return fault;
}
}};
def template MiscExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA M5_VAR_USED;
Fault fault = NoFault;
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
warn_once("Prefetch instructions in Alpha do not do anything\n");
if (fault == NoFault) {
%(memacc_code)s;
}
return NoFault;
}
}};
// Prefetches in Alpha don't actually do anything
// They just build an effective address and complete
def template MiscInitiateAcc {{
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
warn("initiateAcc undefined: Misc instruction does not support split "
"access method!");
return NoFault;
}
}};
def template MiscCompleteAcc {{
Fault %(class_name)s::completeAcc(PacketPtr pkt,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
warn("completeAcc undefined: Misc instruction does not support split "
"access method!");
return NoFault;
}
}};
// load instructions use Ra as dest, so check for
// Ra == 31 to detect nops
def template LoadNopCheckDecode {{
{
AlphaStaticInst *i = new %(class_name)s(machInst);
if (RA == 31) {
i = makeNop(i);
}
return i;
}
}};
// for some load instructions, Ra == 31 indicates a prefetch (not a nop)
def template LoadPrefetchCheckDecode {{
{
if (RA != 31) {
return new %(class_name)s(machInst);
}
else {
return new %(class_name)sPrefetch(machInst);
}
}
}};
let {{
def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
postacc_code = '', base_class = 'MemoryDisp32',
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)
memacc_iop = InstObjParams(name, Name, base_class,
{ '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
memacc_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))
}};
def format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }},
mem_flags = [], inst_flags = []) {{
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
decode_template = LoadNopCheckDecode,
exec_template_base = 'Load')
}};
// Note that the flags passed in apply only to the prefetch version
def format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }},
mem_flags = [], pf_flags = [], inst_flags = []) {{
# declare the load instruction object and generate the decode block
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
decode_template = LoadPrefetchCheckDecode,
exec_template_base = 'Load')
# Declare the prefetch instruction object.
# Make sure flag args are lists so we can mess with them.
mem_flags = makeList(mem_flags)
pf_flags = makeList(pf_flags)
inst_flags = makeList(inst_flags)
pf_mem_flags = mem_flags + pf_flags + ['PREFETCH']
pf_inst_flags = inst_flags
(pf_header_output, pf_decoder_output, _, pf_exec_output) = \
LoadStoreBase(name, Name + 'Prefetch', ea_code, ';',
pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc')
header_output += pf_header_output
decoder_output += pf_decoder_output
exec_output += pf_exec_output
}};
def format Store(memacc_code, ea_code = {{ EA = Rb + disp; }},
mem_flags = [], inst_flags = []) {{
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
exec_template_base = 'Store')
}};
def format StoreCond(memacc_code, postacc_code,
ea_code = {{ EA = Rb + disp; }},
mem_flags = [], inst_flags = []) {{
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
postacc_code, exec_template_base = 'StoreCond')
}};
// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb
def format MiscPrefetch(ea_code, memacc_code,
mem_flags = [], inst_flags = []) {{
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
base_class = 'MemoryNoDisp', exec_template_base = 'Misc')
}};

View File

@ -0,0 +1,79 @@
// -*- mode:c++ -*-
// Copyright (c) 2003-2005 The Regents of The University of Michigan
// 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: Kevin Lim
////////////////////////////////////////////////////////////////////
//
// OPCDEC fault instructions
//
output header {{
/**
* Static instruction class for instructions that cause an OPCDEC fault
* when executed. This is currently only for PAL mode instructions
* executed in non-PAL mode.
*/
class OpcdecFault : public AlphaStaticInst
{
public:
/// Constructor
OpcdecFault(ExtMachInst _machInst)
: AlphaStaticInst("opcdec fault", _machInst, No_OpClass)
{
}
%(BasicExecDeclare)s
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
output decoder {{
std::string
OpcdecFault::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
return csprintf("%-10s (inst 0x%x, opcode 0x%x)",
" OPCDEC fault", machInst, OPCODE);
}
}};
output exec {{
Fault
OpcdecFault::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
return new UnimplementedOpcodeFault;
}
}};
def format OpcdecFault() {{
decode_block = 'return new OpcdecFault(machInst);\n'
}};

View File

@ -0,0 +1,274 @@
// -*- mode:c++ -*-
// Copyright (c) 2003-2005 The Regents of The University of Michigan
// 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
////////////////////////////////////////////////////////////////////
//
// PAL calls & PAL-specific instructions
//
output header {{
/**
* Base class for emulated call_pal calls (used only in
* non-full-system mode).
*/
class EmulatedCallPal : public AlphaStaticInst
{
protected:
/// Constructor.
EmulatedCallPal(const char *mnem, ExtMachInst _machInst,
OpClass __opClass)
: AlphaStaticInst(mnem, _machInst, __opClass)
{
}
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
output decoder {{
std::string
EmulatedCallPal::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
#ifdef SS_COMPATIBLE_DISASSEMBLY
return csprintf("%s %s", "call_pal", mnemonic);
#else
return csprintf("%-10s %s", "call_pal", mnemonic);
#endif
}
}};
def format EmulatedCallPal(code, *flags) {{
iop = InstObjParams(name, Name, 'EmulatedCallPal', code, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};
output header {{
/**
* Base class for full-system-mode call_pal instructions.
* Probably could turn this into a leaf class and get rid of the
* parser template.
*/
class CallPalBase : public AlphaStaticInst
{
protected:
int palFunc; ///< Function code part of instruction
int palOffset; ///< Target PC, offset from IPR_PAL_BASE
bool palValid; ///< is the function code valid?
bool palPriv; ///< is this call privileged?
/// Constructor.
CallPalBase(const char *mnem, ExtMachInst _machInst,
OpClass __opClass);
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
output decoder {{
inline
CallPalBase::CallPalBase(const char *mnem, ExtMachInst _machInst,
OpClass __opClass)
: AlphaStaticInst(mnem, _machInst, __opClass),
palFunc(PALFUNC)
{
// From the 21164 HRM (paraphrased):
// Bit 7 of the function code (mask 0x80) indicates
// whether the call is privileged (bit 7 == 0) or
// unprivileged (bit 7 == 1). The privileged call table
// starts at 0x2000, the unprivielged call table starts at
// 0x3000. Bits 5-0 (mask 0x3f) are used to calculate the
// offset.
const int palPrivMask = 0x80;
const int palOffsetMask = 0x3f;
// Pal call is invalid unless all other bits are 0
palValid = ((machInst & ~(palPrivMask | palOffsetMask)) == 0);
palPriv = ((machInst & palPrivMask) == 0);
int shortPalFunc = (machInst & palOffsetMask);
// Add 1 to base to set pal-mode bit
palOffset = (palPriv ? 0x2001 : 0x3001) + (shortPalFunc << 6);
}
std::string
CallPalBase::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
return csprintf("%-10s %#x", "call_pal", palFunc);
}
}};
def format CallPal(code, *flags) {{
iop = InstObjParams(name, Name, 'CallPalBase', code, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};
////////////////////////////////////////////////////////////////////
//
// hw_ld, hw_st
//
output header {{
/**
* Base class for hw_ld and hw_st.
*/
class HwLoadStore : public Memory
{
protected:
/// Displacement for EA calculation (signed).
int16_t disp;
/// Constructor
HwLoadStore(const char *mnem, ExtMachInst _machInst, OpClass __opClass);
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
output decoder {{
inline
HwLoadStore::HwLoadStore(const char *mnem, ExtMachInst _machInst,
OpClass __opClass)
: Memory(mnem, _machInst, __opClass), disp(HW_LDST_DISP)
{
memAccessFlags.clear();
if (HW_LDST_PHYS) memAccessFlags.set(Request::PHYSICAL);
if (HW_LDST_ALT) memAccessFlags.set(Request::ALTMODE);
if (HW_LDST_VPTE) memAccessFlags.set(Request::VPTE);
if (HW_LDST_LOCK) memAccessFlags.set(Request::LLSC);
}
std::string
HwLoadStore::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
#ifdef SS_COMPATIBLE_DISASSEMBLY
return csprintf("%-10s r%d,%d(r%d)", mnemonic, RA, disp, RB);
#else
// HW_LDST_LOCK and HW_LDST_COND are the same bit.
const char *lock_str =
(HW_LDST_LOCK) ? (flags[IsLoad] ? ",LOCK" : ",COND") : "";
return csprintf("%-10s r%d,%d(r%d)%s%s%s%s%s",
mnemonic, RA, disp, RB,
HW_LDST_PHYS ? ",PHYS" : "",
HW_LDST_ALT ? ",ALT" : "",
HW_LDST_QUAD ? ",QUAD" : "",
HW_LDST_VPTE ? ",VPTE" : "",
lock_str);
#endif
}
}};
def format HwLoad(ea_code, memacc_code, class_ext, *flags) {{
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name + class_ext, ea_code, memacc_code,
mem_flags = [], inst_flags = flags,
base_class = 'HwLoadStore', exec_template_base = 'Load')
}};
def format HwStore(ea_code, memacc_code, class_ext, *flags) {{
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name + class_ext, ea_code, memacc_code,
mem_flags = [], inst_flags = flags,
base_class = 'HwLoadStore', exec_template_base = 'Store')
}};
def format HwStoreCond(ea_code, memacc_code, postacc_code, class_ext,
*flags) {{
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name + class_ext, ea_code, memacc_code,
postacc_code, mem_flags = [], inst_flags = flags,
base_class = 'HwLoadStore')
}};
output header {{
/**
* Base class for hw_mfpr and hw_mtpr.
*/
class HwMoveIPR : public AlphaStaticInst
{
protected:
/// Index of internal processor register.
int ipr_index;
/// Constructor
HwMoveIPR(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
: AlphaStaticInst(mnem, _machInst, __opClass),
ipr_index(HW_IPR_IDX)
{
}
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
output decoder {{
std::string
HwMoveIPR::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
if (_numSrcRegs > 0) {
// must be mtpr
return csprintf("%-10s r%d,IPR(%#x)",
mnemonic, RA, ipr_index);
}
else {
// must be mfpr
return csprintf("%-10s IPR(%#x),r%d",
mnemonic, ipr_index, RA);
}
}
}};
def format HwMoveIPR(code, *flags) {{
all_flags = ['IprAccessOp']
all_flags += flags
iop = InstObjParams(name, Name, 'HwMoveIPR', code, all_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};

View File

@ -0,0 +1,172 @@
// -*- mode:c++ -*-
// Copyright (c) 2003-2005 The Regents of The University of Michigan
// 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
////////////////////////////////////////////////////////////////////
//
// Unimplemented instructions
//
output header {{
/**
* Static instruction class for unimplemented instructions that
* cause simulator termination. Note that these are recognized
* (legal) instructions that the simulator does not support; the
* 'Unknown' class is used for unrecognized/illegal instructions.
* This is a leaf class.
*/
class FailUnimplemented : public AlphaStaticInst
{
public:
/// Constructor
FailUnimplemented(const char *_mnemonic, ExtMachInst _machInst)
: AlphaStaticInst(_mnemonic, _machInst, No_OpClass)
{
// don't call execute() (which panics) if we're on a
// speculative path
flags[IsNonSpeculative] = true;
}
%(BasicExecDeclare)s
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
/**
* Base class for unimplemented instructions that cause a warning
* to be printed (but do not terminate simulation). This
* implementation is a little screwy in that it will print a
* warning for each instance of a particular unimplemented machine
* instruction, not just for each unimplemented opcode. Should
* probably make the 'warned' flag a static member of the derived
* class.
*/
class WarnUnimplemented : public AlphaStaticInst
{
private:
/// Have we warned on this instruction yet?
mutable bool warned;
public:
/// Constructor
WarnUnimplemented(const char *_mnemonic, ExtMachInst _machInst)
: AlphaStaticInst(_mnemonic, _machInst, No_OpClass), warned(false)
{
// don't call execute() (which panics) if we're on a
// speculative path
flags[IsNonSpeculative] = true;
}
%(BasicExecDeclare)s
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
output decoder {{
std::string
FailUnimplemented::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
return csprintf("%-10s (unimplemented)", mnemonic);
}
std::string
WarnUnimplemented::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
#ifdef SS_COMPATIBLE_DISASSEMBLY
return csprintf("%-10s", mnemonic);
#else
return csprintf("%-10s (unimplemented)", mnemonic);
#endif
}
}};
output exec {{
Fault
FailUnimplemented::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
panic("attempt to execute unimplemented instruction '%s' "
"(inst 0x%08x, opcode 0x%x)", mnemonic, machInst, OPCODE);
return new UnimplementedOpcodeFault;
}
Fault
WarnUnimplemented::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
if (!warned) {
warn("instruction '%s' unimplemented\n", mnemonic);
warned = true;
}
return NoFault;
}
}};
def format FailUnimpl() {{
iop = InstObjParams(name, 'FailUnimplemented')
decode_block = BasicDecodeWithMnemonic.subst(iop)
}};
def format WarnUnimpl() {{
iop = InstObjParams(name, 'WarnUnimplemented')
decode_block = BasicDecodeWithMnemonic.subst(iop)
}};
output header {{
/**
* Static instruction class for unknown (illegal) instructions.
* These cause simulator termination if they are executed in a
* non-speculative mode. This is a leaf class.
*/
class Unknown : public AlphaStaticInst
{
public:
/// Constructor
Unknown(ExtMachInst _machInst)
: AlphaStaticInst("unknown", _machInst, No_OpClass)
{
// don't call execute() (which panics) if we're on a
// speculative path
flags[IsNonSpeculative] = true;
}
%(BasicExecDeclare)s
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};

View File

@ -0,0 +1,59 @@
// -*- mode:c++ -*-
// Copyright (c) 2003-2005 The Regents of The University of Michigan
// 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
////////////////////////////////////////////////////////////////////
//
// Unknown instructions
//
output decoder {{
std::string
Unknown::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
return csprintf("%-10s (inst 0x%x, opcode 0x%x)",
"unknown", machInst, OPCODE);
}
}};
output exec {{
Fault
Unknown::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
panic("attempt to execute unknown instruction "
"(inst 0x%08x, opcode 0x%x)", machInst, OPCODE);
return new UnimplementedOpcodeFault;
}
}};
def format Unknown() {{
decode_block = 'return new Unknown(machInst);\n'
}};

View File

@ -0,0 +1,119 @@
// -*- mode:c++ -*-
// Copyright (c) 2003-2005 The Regents of The University of Michigan
// 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
////////////////////////////////////////////////////////////////////
//
// Utility functions for execute methods
//
output exec {{
/// Return opa + opb, summing carry into third arg.
inline uint64_t
addc(uint64_t opa, uint64_t opb, int &carry)
{
uint64_t res = opa + opb;
if (res < opa || res < opb)
++carry;
return res;
}
/// Multiply two 64-bit values (opa * opb), returning the 128-bit
/// product in res_hi and res_lo.
inline void
mul128(uint64_t opa, uint64_t opb, uint64_t &res_hi, uint64_t &res_lo)
{
// do a 64x64 --> 128 multiply using four 32x32 --> 64 multiplies
uint64_t opa_hi = opa<63:32>;
uint64_t opa_lo = opa<31:0>;
uint64_t opb_hi = opb<63:32>;
uint64_t opb_lo = opb<31:0>;
res_lo = opa_lo * opb_lo;
// The middle partial products logically belong in bit
// positions 95 to 32. Thus the lower 32 bits of each product
// sum into the upper 32 bits of the low result, while the
// upper 32 sum into the low 32 bits of the upper result.
uint64_t partial1 = opa_hi * opb_lo;
uint64_t partial2 = opa_lo * opb_hi;
uint64_t partial1_lo = partial1<31:0> << 32;
uint64_t partial1_hi = partial1<63:32>;
uint64_t partial2_lo = partial2<31:0> << 32;
uint64_t partial2_hi = partial2<63:32>;
// Add partial1_lo and partial2_lo to res_lo, keeping track
// of any carries out
int carry_out = 0;
res_lo = addc(partial1_lo, res_lo, carry_out);
res_lo = addc(partial2_lo, res_lo, carry_out);
// Now calculate the high 64 bits...
res_hi = (opa_hi * opb_hi) + partial1_hi + partial2_hi + carry_out;
}
/// Map 8-bit S-floating exponent to 11-bit T-floating exponent.
/// See Table 2-2 of Alpha AHB.
inline int
map_s(int old_exp)
{
int hibit = old_exp<7:>;
int lobits = old_exp<6:0>;
if (hibit == 1) {
return (lobits == 0x7f) ? 0x7ff : (0x400 | lobits);
}
else {
return (lobits == 0) ? 0 : (0x380 | lobits);
}
}
/// Convert a 32-bit S-floating value to the equivalent 64-bit
/// representation to be stored in an FP reg.
inline uint64_t
s_to_t(uint32_t s_val)
{
uint64_t tmp = s_val;
return (tmp<31:> << 63 // sign bit
| (uint64_t)map_s(tmp<30:23>) << 52 // exponent
| tmp<22:0> << 29); // fraction
}
/// Convert a 64-bit T-floating value to the equivalent 32-bit
/// S-floating representation to be stored in memory.
inline int32_t
t_to_s(uint64_t t_val)
{
return (t_val<63:62> << 30 // sign bit & hi exp bit
| t_val<58:29>); // rest of exp & fraction
}
}};

View File

@ -0,0 +1,134 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* 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
* Gabe Black
*/
#ifndef __ARCH_ALPHA_ISA_TRAITS_HH__
#define __ARCH_ALPHA_ISA_TRAITS_HH__
namespace LittleEndianGuest {}
#include "arch/alpha/types.hh"
#include "base/types.hh"
#include "cpu/static_inst_fwd.hh"
namespace AlphaISA {
using namespace LittleEndianGuest;
StaticInstPtr decodeInst(ExtMachInst);
// Alpha Does NOT have a delay slot
#define ISA_HAS_DELAY_SLOT 0
const Addr PageShift = 13;
const Addr PageBytes = ULL(1) << PageShift;
const Addr PageMask = ~(PageBytes - 1);
const Addr PageOffset = PageBytes - 1;
////////////////////////////////////////////////////////////////////////
//
// Translation stuff
//
const Addr PteShift = 3;
const Addr NPtePageShift = PageShift - PteShift;
const Addr NPtePage = ULL(1) << NPtePageShift;
const Addr PteMask = NPtePage - 1;
// User Virtual
const Addr USegBase = ULL(0x0);
const Addr USegEnd = ULL(0x000003ffffffffff);
// Kernel Direct Mapped
const Addr K0SegBase = ULL(0xfffffc0000000000);
const Addr K0SegEnd = ULL(0xfffffdffffffffff);
// Kernel Virtual
const Addr K1SegBase = ULL(0xfffffe0000000000);
const Addr K1SegEnd = ULL(0xffffffffffffffff);
////////////////////////////////////////////////////////////////////////
//
// Interrupt levels
//
enum InterruptLevels
{
INTLEVEL_SOFTWARE_MIN = 4,
INTLEVEL_SOFTWARE_MAX = 19,
INTLEVEL_EXTERNAL_MIN = 20,
INTLEVEL_EXTERNAL_MAX = 34,
INTLEVEL_IRQ0 = 20,
INTLEVEL_IRQ1 = 21,
INTINDEX_ETHERNET = 0,
INTINDEX_SCSI = 1,
INTLEVEL_IRQ2 = 22,
INTLEVEL_IRQ3 = 23,
INTLEVEL_SERIAL = 33,
NumInterruptLevels = INTLEVEL_EXTERNAL_MAX
};
// EV5 modes
enum mode_type
{
mode_kernel = 0, // kernel
mode_executive = 1, // executive (unused by unix)
mode_supervisor = 2, // supervisor (unused by unix)
mode_user = 3, // user mode
mode_number // number of modes
};
// Constants Related to the number of registers
enum {
LogVMPageSize = 13, // 8K bytes
VMPageSize = (1 << LogVMPageSize),
BranchPredAddrShiftAmt = 2, // instructions are 4-byte aligned
MachineBytes = 8,
WordBytes = 4,
HalfwordBytes = 2,
ByteBytes = 1
};
// return a no-op instruction... used for instruction fetch faults
// Alpha UNOP (ldq_u r31,0(r0))
const ExtMachInst NoopMachInst = 0x2ffe0000;
// Memory accesses cannot be unaligned
const bool HasUnalignedMemAcc = false;
} // namespace AlphaISA
#endif // __ARCH_ALPHA_ISA_TRAITS_HH__

View File

@ -0,0 +1,218 @@
/*
* Copyright (c) 2004-2005 The Regents of The University of Michigan
* 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: Lisa Hsu
* Nathan Binkert
*/
#include <map>
#include <stack>
#include <string>
#include "arch/alpha/linux/threadinfo.hh"
#include "arch/alpha/kernel_stats.hh"
#include "arch/alpha/osfpal.hh"
#include "base/trace.hh"
#include "cpu/thread_context.hh"
#include "debug/Context.hh"
#include "kern/tru64/tru64_syscalls.hh"
#include "sim/system.hh"
using namespace std;
using namespace Stats;
namespace AlphaISA {
namespace Kernel {
const char *modestr[] = { "kernel", "user", "idle" };
Statistics::Statistics(System *system)
: ::Kernel::Statistics(system),
idleProcess((Addr)-1), themode(kernel), lastModeTick(0)
{
}
void
Statistics::regStats(const string &_name)
{
::Kernel::Statistics::regStats(_name);
_callpal
.init(256)
.name(name() + ".callpal")
.desc("number of callpals executed")
.flags(total | pdf | nozero | nonan)
;
for (int i = 0; i < PAL::NumCodes; ++i) {
const char *str = PAL::name(i);
if (str)
_callpal.subname(i, str);
}
_hwrei
.name(name() + ".inst.hwrei")
.desc("number of hwrei instructions executed")
;
_mode
.init(cpu_mode_num)
.name(name() + ".mode_switch")
.desc("number of protection mode switches")
;
for (int i = 0; i < cpu_mode_num; ++i)
_mode.subname(i, modestr[i]);
_modeGood
.init(cpu_mode_num)
.name(name() + ".mode_good")
;
for (int i = 0; i < cpu_mode_num; ++i)
_modeGood.subname(i, modestr[i]);
_modeFraction
.name(name() + ".mode_switch_good")
.desc("fraction of useful protection mode switches")
.flags(total)
;
for (int i = 0; i < cpu_mode_num; ++i)
_modeFraction.subname(i, modestr[i]);
_modeFraction = _modeGood / _mode;
_modeTicks
.init(cpu_mode_num)
.name(name() + ".mode_ticks")
.desc("number of ticks spent at the given mode")
.flags(pdf)
;
for (int i = 0; i < cpu_mode_num; ++i)
_modeTicks.subname(i, modestr[i]);
_swap_context
.name(name() + ".swap_context")
.desc("number of times the context was actually changed")
;
}
void
Statistics::setIdleProcess(Addr idlepcbb, ThreadContext *tc)
{
assert(themode == kernel);
idleProcess = idlepcbb;
themode = idle;
changeMode(themode, tc);
}
void
Statistics::changeMode(cpu_mode newmode, ThreadContext *tc)
{
_mode[newmode]++;
if (newmode == themode)
return;
DPRINTF(Context, "old mode=%s new mode=%s pid=%d\n",
modestr[themode], modestr[newmode],
Linux::ThreadInfo(tc).curTaskPID());
_modeGood[newmode]++;
_modeTicks[themode] += curTick() - lastModeTick;
lastModeTick = curTick();
themode = newmode;
}
void
Statistics::mode(cpu_mode newmode, ThreadContext *tc)
{
Addr pcbb = tc->readMiscRegNoEffect(IPR_PALtemp23);
if (newmode == kernel && pcbb == idleProcess)
newmode = idle;
changeMode(newmode, tc);
}
void
Statistics::context(Addr oldpcbb, Addr newpcbb, ThreadContext *tc)
{
assert(themode != user);
_swap_context++;
changeMode(newpcbb == idleProcess ? idle : kernel, tc);
DPRINTF(Context, "Context Switch old pid=%d new pid=%d\n",
Linux::ThreadInfo(tc, oldpcbb).curTaskPID(),
Linux::ThreadInfo(tc, newpcbb).curTaskPID());
}
void
Statistics::callpal(int code, ThreadContext *tc)
{
if (!PAL::name(code))
return;
_callpal[code]++;
switch (code) {
case PAL::callsys: {
int number = tc->readIntReg(0);
if (SystemCalls<Tru64>::validSyscallNumber(number)) {
int cvtnum = SystemCalls<Tru64>::convert(number);
_syscall[cvtnum]++;
}
} break;
}
}
void
Statistics::serialize(ostream &os)
{
::Kernel::Statistics::serialize(os);
int exemode = themode;
SERIALIZE_SCALAR(exemode);
SERIALIZE_SCALAR(idleProcess);
SERIALIZE_SCALAR(lastModeTick);
}
void
Statistics::unserialize(Checkpoint *cp, const string &section)
{
::Kernel::Statistics::unserialize(cp, section);
int exemode;
UNSERIALIZE_SCALAR(exemode);
UNSERIALIZE_SCALAR(idleProcess);
UNSERIALIZE_SCALAR(lastModeTick);
themode = (cpu_mode)exemode;
}
} // namespace Kernel
} // namespace AlphaISA

View File

@ -0,0 +1,96 @@
/*
* Copyright (c) 2004-2005 The Regents of The University of Michigan
* 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: Lisa Hsu
* Nathan Binkert
*/
#ifndef __ARCH_ALPHA_KERNEL_STATS_HH__
#define __ARCH_ALPHA_KERNEL_STATS_HH__
#include <map>
#include <stack>
#include <string>
#include <vector>
#include "cpu/static_inst.hh"
#include "kern/kernel_stats.hh"
class BaseCPU;
class ThreadContext;
class FnEvent;
// What does kernel stats expect is included?
class System;
namespace AlphaISA {
namespace Kernel {
enum cpu_mode { kernel, user, idle, cpu_mode_num };
extern const char *modestr[];
class Statistics : public ::Kernel::Statistics
{
protected:
Addr idleProcess;
cpu_mode themode;
Tick lastModeTick;
void changeMode(cpu_mode newmode, ThreadContext *tc);
private:
Stats::Vector _callpal;
// Stats::Vector _faults;
Stats::Vector _mode;
Stats::Vector _modeGood;
Stats::Formula _modeFraction;
Stats::Vector _modeTicks;
Stats::Scalar _swap_context;
public:
Statistics(System *system);
void regStats(const std::string &name);
public:
void mode(cpu_mode newmode, ThreadContext *tc);
void context(Addr oldpcbb, Addr newpcbb, ThreadContext *tc);
void callpal(int code, ThreadContext *tc);
void hwrei() { _hwrei++; }
void setIdleProcess(Addr idle, ThreadContext *tc);
public:
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
};
} // namespace Kernel
} // namespace AlphaISA
#endif // __ARCH_ALPHA_KERNEL_STATS_HH__

View File

@ -0,0 +1,163 @@
/*
* Copyright (c) 1992, 1993 The Regents of the University of California
* All rights reserved.
*
* This software was developed by the Computer Systems Engineering group
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
* contributed to Berkeley.
*
* All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Lawrence Berkeley Laboratories.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
*
* @(#)remote-sl.h 8.1 (Berkeley) 6/11/93
*/
/* $NetBSD: kgdb.h,v 1.4 1998/08/13 02:10:59 eeh Exp $ */
#ifndef __KGDB_H__
#define __KGDB_H__
/*
* Message types.
*/
#define KGDB_SIGNAL '?' // last sigal
#define KGDB_SET_BAUD 'b' // set baud (deprecated)
#define KGDB_SET_BREAK 'B' // set breakpoint (deprecated)
#define KGDB_CONT 'c' // resume
#define KGDB_ASYNC_CONT 'C' // continue with signal
#define KGDB_DEBUG 'd' // toggle debug flags (deprecated)
#define KGDB_DETACH 'D' // detach remote gdb
#define KGDB_REG_R 'g' // read general registers
#define KGDB_REG_W 'G' // write general registers
#define KGDB_SET_THREAD 'H' // set thread
#define KGDB_CYCLE_STEP 'i' // step a single cycle
#define KGDB_SIG_CYCLE_STEP 'I' // signal then single cycle step
#define KGDB_KILL 'k' // kill program
#define KGDB_MEM_R 'm' // read memory
#define KGDB_MEM_W 'M' // write memory
#define KGDB_READ_REG 'p' // read register
#define KGDB_SET_REG 'P' // write register
#define KGDB_QUERY_VAR 'q' // query variable
#define KGDB_SET_VAR 'Q' // set variable
#define KGDB_RESET 'r' // reset system. (Deprecated)
#define KGDB_STEP 's' // step
#define KGDB_ASYNC_STEP 'S' // signal and step
#define KGDB_THREAD_ALIVE 'T' // find out if the thread is alive.
#define KGDB_TARGET_EXIT 'W' // target exited
#define KGDB_BINARY_DLOAD 'X' // write memory
#define KGDB_CLR_HW_BKPT 'z' // remove breakpoint or watchpoint
#define KGDB_SET_HW_BKPT 'Z' // insert breakpoint or watchpoint
/*
* start of frame/end of frame
*/
#define KGDB_START '$'
#define KGDB_END '#'
#define KGDB_GOODP '+'
#define KGDB_BADP '-'
/*
* Stuff for KGDB.
*/
#define KGDB_NUMREGS 66 /* from tm-alpha.h, NUM_REGS */
#define KGDB_REG_V0 0
#define KGDB_REG_T0 1
#define KGDB_REG_T1 2
#define KGDB_REG_T2 3
#define KGDB_REG_T3 4
#define KGDB_REG_T4 5
#define KGDB_REG_T5 6
#define KGDB_REG_T6 7
#define KGDB_REG_T7 8
#define KGDB_REG_S0 9
#define KGDB_REG_S1 10
#define KGDB_REG_S2 11
#define KGDB_REG_S3 12
#define KGDB_REG_S4 13
#define KGDB_REG_S5 14
#define KGDB_REG_S6 15 /* FP */
#define KGDB_REG_A0 16
#define KGDB_REG_A1 17
#define KGDB_REG_A2 18
#define KGDB_REG_A3 19
#define KGDB_REG_A4 20
#define KGDB_REG_A5 21
#define KGDB_REG_T8 22
#define KGDB_REG_T9 23
#define KGDB_REG_T10 24
#define KGDB_REG_T11 25
#define KGDB_REG_RA 26
#define KGDB_REG_T12 27
#define KGDB_REG_AT 28
#define KGDB_REG_GP 29
#define KGDB_REG_SP 30
#define KGDB_REG_ZERO 31
#define KGDB_REG_F0 32
#define KGDB_REG_F1 33
#define KGDB_REG_F2 34
#define KGDB_REG_F3 35
#define KGDB_REG_F4 36
#define KGDB_REG_F5 37
#define KGDB_REG_F6 38
#define KGDB_REG_F7 39
#define KGDB_REG_F8 40
#define KGDB_REG_F9 41
#define KGDB_REG_F10 42
#define KGDB_REG_F11 43
#define KGDB_REG_F12 44
#define KGDB_REG_F13 45
#define KGDB_REG_F14 46
#define KGDB_REG_F15 47
#define KGDB_REG_F16 48
#define KGDB_REG_F17 49
#define KGDB_REG_F18 50
#define KGDB_REG_F19 51
#define KGDB_REG_F20 52
#define KGDB_REG_F21 53
#define KGDB_REG_F22 54
#define KGDB_REG_F23 55
#define KGDB_REG_F24 56
#define KGDB_REG_F25 57
#define KGDB_REG_F26 58
#define KGDB_REG_F27 59
#define KGDB_REG_F28 60
#define KGDB_REG_F29 61
#define KGDB_REG_F30 62
#define KGDB_REG_F31 63
#define KGDB_REG_PC 64
#define KGDB_REG_VFP 65
/* Too much? Must be large enough for register transfer. */
#define KGDB_BUFLEN 1024
#endif /* __KGDB_H__ */

View File

@ -0,0 +1,71 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* 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: Korey Sewell
*/
#include <fcntl.h>
#include "arch/alpha/linux/linux.hh"
// open(2) flags translation table
OpenFlagTransTable AlphaLinux::openFlagTable[] = {
#ifdef _MSC_VER
{ AlphaLinux::TGT_O_RDONLY, _O_RDONLY },
{ AlphaLinux::TGT_O_WRONLY, _O_WRONLY },
{ AlphaLinux::TGT_O_RDWR, _O_RDWR },
{ AlphaLinux::TGT_O_APPEND, _O_APPEND },
{ AlphaLinux::TGT_O_CREAT, _O_CREAT },
{ AlphaLinux::TGT_O_TRUNC, _O_TRUNC },
{ AlphaLinux::TGT_O_EXCL, _O_EXCL },
#ifdef _O_NONBLOCK
{ AlphaLinux::TGT_O_NONBLOCK, _O_NONBLOCK },
#endif
#ifdef _O_NOCTTY
{ AlphaLinux::TGT_O_NOCTTY, _O_NOCTTY },
#endif
#ifdef _O_SYNC
{ AlphaLinux::TGT_O_SYNC, _O_SYNC },
#endif
#else /* !_MSC_VER */
{ AlphaLinux::TGT_O_RDONLY, O_RDONLY },
{ AlphaLinux::TGT_O_WRONLY, O_WRONLY },
{ AlphaLinux::TGT_O_RDWR, O_RDWR },
{ AlphaLinux::TGT_O_APPEND, O_APPEND },
{ AlphaLinux::TGT_O_CREAT, O_CREAT },
{ AlphaLinux::TGT_O_TRUNC, O_TRUNC },
{ AlphaLinux::TGT_O_EXCL, O_EXCL },
{ AlphaLinux::TGT_O_NONBLOCK, O_NONBLOCK },
{ AlphaLinux::TGT_O_NOCTTY, O_NOCTTY },
#ifdef O_SYNC
{ AlphaLinux::TGT_O_SYNC, O_SYNC },
#endif
#endif /* _MSC_VER */
};
const int AlphaLinux::NUM_OPEN_FLAGS =
(sizeof(AlphaLinux::openFlagTable)/sizeof(AlphaLinux::openFlagTable[0]));

View File

@ -0,0 +1,147 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* 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: Korey Sewell
*/
#ifndef __ALPHA_ALPHA_LINUX_LINUX_HH__
#define __ALPHA_ALPHA_LINUX_LINUX_HH__
#include "kern/linux/linux.hh"
/* AlphaLinux class contains static constants/definitions/misc.
* structures which are specific to the Linux OS AND the Alpha
* architecture
*/
class AlphaLinux : public Linux
{
public:
/// This table maps the target open() flags to the corresponding
/// host open() flags.
static OpenFlagTransTable openFlagTable[];
/// Number of entries in openFlagTable[].
static const int NUM_OPEN_FLAGS;
//@{
/// open(2) flag values.
static const int TGT_O_RDONLY = 00000000; //!< O_RDONLY
static const int TGT_O_WRONLY = 00000001; //!< O_WRONLY
static const int TGT_O_RDWR = 00000002; //!< O_RDWR
static const int TGT_O_NONBLOCK = 00000004; //!< O_NONBLOCK
static const int TGT_O_APPEND = 00000010; //!< O_APPEND
static const int TGT_O_CREAT = 00001000; //!< O_CREAT
static const int TGT_O_TRUNC = 00002000; //!< O_TRUNC
static const int TGT_O_EXCL = 00004000; //!< O_EXCL
static const int TGT_O_NOCTTY = 00010000; //!< O_NOCTTY
static const int TGT_O_SYNC = 00040000; //!< O_SYNC
static const int TGT_O_DRD = 00100000; //!< O_DRD
static const int TGT_O_DIRECTIO = 00200000; //!< O_DIRECTIO
static const int TGT_O_CACHE = 00400000; //!< O_CACHE
static const int TGT_O_DSYNC = 02000000; //!< O_DSYNC
static const int TGT_O_RSYNC = 04000000; //!< O_RSYNC
//@}
/// For mmap().
static const unsigned TGT_MAP_ANONYMOUS = 0x10;
static const unsigned TGT_MAP_FIXED = 0x100;
//@{
/// For getsysinfo().
static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string
static const unsigned GSI_CPU_INFO = 59; //!< CPU information
static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type
static const unsigned GSI_MAX_CPU = 30; //!< max # CPUs on machine
static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system
static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB
static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz
static const unsigned GSI_IEEE_FP_CONTROL = 45;
//@}
//@{
/// For getrusage().
static const int TGT_RUSAGE_SELF = 0;
static const int TGT_RUSAGE_CHILDREN = -1;
static const int TGT_RUSAGE_BOTH = -2;
//@}
//@{
/// For setsysinfo().
static const unsigned SSI_IEEE_FP_CONTROL = 14; //!< ieee_set_fp_control()
//@}
//@{
/// ioctl() command codes.
static const unsigned TIOCGETP_ = 0x40067408;
static const unsigned TIOCSETP_ = 0x80067409;
static const unsigned TIOCSETN_ = 0x8006740a;
static const unsigned TIOCSETC_ = 0x80067411;
static const unsigned TIOCGETC_ = 0x40067412;
static const unsigned FIONREAD_ = 0x4004667f;
static const unsigned TIOCISATTY_ = 0x2000745e;
static const unsigned TIOCGETS_ = 0x402c7413;
static const unsigned TIOCGETA_ = 0x40127417;
static const unsigned TCSETAW_ = 0x80147419; // 2.6.15 kernel
//@}
/// For table().
static const int TBL_SYSINFO = 12;
/// Resource enumeration for getrlimit().
enum rlimit_resources {
TGT_RLIMIT_CPU = 0,
TGT_RLIMIT_FSIZE = 1,
TGT_RLIMIT_DATA = 2,
TGT_RLIMIT_STACK = 3,
TGT_RLIMIT_CORE = 4,
TGT_RLIMIT_RSS = 5,
TGT_RLIMIT_NOFILE = 6,
TGT_RLIMIT_AS = 7,
TGT_RLIMIT_VMEM = 7,
TGT_RLIMIT_NPROC = 8,
TGT_RLIMIT_MEMLOCK = 9,
TGT_RLIMIT_LOCKS = 10
};
typedef struct {
int64_t uptime; /* Seconds since boot */
uint64_t loads[3]; /* 1, 5, and 15 minute load averages */
uint64_t totalram; /* Total usable main memory size */
uint64_t freeram; /* Available memory size */
uint64_t sharedram; /* Amount of shared memory */
uint64_t bufferram; /* Memory used by buffers */
uint64_t totalswap; /* Total swap space size */
uint64_t freeswap; /* swap space still available */
uint16_t procs; /* Number of current processes */
uint64_t totalhigh; /* Total high memory size */
uint64_t freehigh; /* Available high memory size */
uint64_t mem_unit; /* Memory unit size in bytes */
} tgt_sysinfo;
};
#endif // __ALPHA_ALPHA_LINUX_LINUX_HH__

View File

@ -0,0 +1,589 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* 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
* Ali Saidi
*/
#include "arch/alpha/linux/linux.hh"
#include "arch/alpha/linux/process.hh"
#include "arch/alpha/isa_traits.hh"
#include "base/trace.hh"
#include "cpu/thread_context.hh"
#include "debug/SyscallVerbose.hh"
#include "kern/linux/linux.hh"
#include "sim/process.hh"
#include "sim/syscall_emul.hh"
using namespace std;
using namespace AlphaISA;
/// Target uname() handler.
static SyscallReturn
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
int index = 0;
TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, index));
strcpy(name->sysname, "Linux");
strcpy(name->nodename, "m5.eecs.umich.edu");
strcpy(name->release, "2.6.26");
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
strcpy(name->machine, "alpha");
name.copyOut(tc->getMemProxy());
return 0;
}
/// Target osf_getsysyinfo() handler. Even though this call is
/// borrowed from Tru64, the subcases that get used appear to be
/// different in practice from those used by Tru64 processes.
static SyscallReturn
osf_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
int index = 0;
unsigned op = process->getSyscallArg(tc, index);
Addr bufPtr = process->getSyscallArg(tc, index);
// unsigned nbytes = process->getSyscallArg(tc, 2);
switch (op) {
case 45: { // GSI_IEEE_FP_CONTROL
TypedBufferArg<uint64_t> fpcr(bufPtr);
// I don't think this exactly matches the HW FPCR
*fpcr = 0;
fpcr.copyOut(tc->getMemProxy());
return 0;
}
default:
cerr << "osf_getsysinfo: unknown op " << op << endl;
abort();
break;
}
return 1;
}
/// Target osf_setsysinfo() handler.
static SyscallReturn
osf_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
int index = 0;
unsigned op = process->getSyscallArg(tc, index);
Addr bufPtr = process->getSyscallArg(tc, index);
// unsigned nbytes = process->getSyscallArg(tc, 2);
switch (op) {
case 14: { // SSI_IEEE_FP_CONTROL
TypedBufferArg<uint64_t> fpcr(bufPtr);
// I don't think this exactly matches the HW FPCR
fpcr.copyIn(tc->getMemProxy());
DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): "
" setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr));
return 0;
}
default:
cerr << "osf_setsysinfo: unknown op " << op << endl;
abort();
break;
}
return 1;
}
SyscallDesc AlphaLinuxProcess::syscallDescs[] = {
/* 0 */ SyscallDesc("osf_syscall", unimplementedFunc),
/* 1 */ SyscallDesc("exit", exitFunc),
/* 2 */ SyscallDesc("fork", unimplementedFunc),
/* 3 */ SyscallDesc("read", readFunc),
/* 4 */ SyscallDesc("write", writeFunc),
/* 5 */ SyscallDesc("osf_old_open", unimplementedFunc),
/* 6 */ SyscallDesc("close", closeFunc),
/* 7 */ SyscallDesc("osf_wait4", unimplementedFunc),
/* 8 */ SyscallDesc("osf_old_creat", unimplementedFunc),
/* 9 */ SyscallDesc("link", unimplementedFunc),
/* 10 */ SyscallDesc("unlink", unlinkFunc),
/* 11 */ SyscallDesc("osf_execve", unimplementedFunc),
/* 12 */ SyscallDesc("chdir", unimplementedFunc),
/* 13 */ SyscallDesc("fchdir", unimplementedFunc),
/* 14 */ SyscallDesc("mknod", unimplementedFunc),
/* 15 */ SyscallDesc("chmod", chmodFunc<AlphaLinux>),
/* 16 */ SyscallDesc("chown", chownFunc),
/* 17 */ SyscallDesc("brk", brkFunc),
/* 18 */ SyscallDesc("osf_getfsstat", unimplementedFunc),
/* 19 */ SyscallDesc("lseek", lseekFunc),
/* 20 */ SyscallDesc("getxpid", getpidPseudoFunc),
/* 21 */ SyscallDesc("osf_mount", unimplementedFunc),
/* 22 */ SyscallDesc("umount", unimplementedFunc),
/* 23 */ SyscallDesc("setuid", setuidFunc),
/* 24 */ SyscallDesc("getxuid", getuidPseudoFunc),
/* 25 */ SyscallDesc("exec_with_loader", unimplementedFunc),
/* 26 */ SyscallDesc("osf_ptrace", unimplementedFunc),
/* 27 */ SyscallDesc("osf_nrecvmsg", unimplementedFunc),
/* 28 */ SyscallDesc("osf_nsendmsg", unimplementedFunc),
/* 29 */ SyscallDesc("osf_nrecvfrom", unimplementedFunc),
/* 30 */ SyscallDesc("osf_naccept", unimplementedFunc),
/* 31 */ SyscallDesc("osf_ngetpeername", unimplementedFunc),
/* 32 */ SyscallDesc("osf_ngetsockname", unimplementedFunc),
/* 33 */ SyscallDesc("access", unimplementedFunc),
/* 34 */ SyscallDesc("osf_chflags", unimplementedFunc),
/* 35 */ SyscallDesc("osf_fchflags", unimplementedFunc),
/* 36 */ SyscallDesc("sync", unimplementedFunc),
/* 37 */ SyscallDesc("kill", unimplementedFunc),
/* 38 */ SyscallDesc("osf_old_stat", unimplementedFunc),
/* 39 */ SyscallDesc("setpgid", unimplementedFunc),
/* 40 */ SyscallDesc("osf_old_lstat", unimplementedFunc),
/* 41 */ SyscallDesc("dup", dupFunc),
/* 42 */ SyscallDesc("pipe", pipePseudoFunc),
/* 43 */ SyscallDesc("osf_set_program_attributes", unimplementedFunc),
/* 44 */ SyscallDesc("osf_profil", unimplementedFunc),
/* 45 */ SyscallDesc("open", openFunc<AlphaLinux>),
/* 46 */ SyscallDesc("osf_old_sigaction", unimplementedFunc),
/* 47 */ SyscallDesc("getxgid", getgidPseudoFunc),
/* 48 */ SyscallDesc("osf_sigprocmask", ignoreFunc),
/* 49 */ SyscallDesc("osf_getlogin", unimplementedFunc),
/* 50 */ SyscallDesc("osf_setlogin", unimplementedFunc),
/* 51 */ SyscallDesc("acct", unimplementedFunc),
/* 52 */ SyscallDesc("sigpending", unimplementedFunc),
/* 53 */ SyscallDesc("osf_classcntl", unimplementedFunc),
/* 54 */ SyscallDesc("ioctl", ioctlFunc<AlphaLinux>),
/* 55 */ SyscallDesc("osf_reboot", unimplementedFunc),
/* 56 */ SyscallDesc("osf_revoke", unimplementedFunc),
/* 57 */ SyscallDesc("symlink", unimplementedFunc),
/* 58 */ SyscallDesc("readlink", readlinkFunc),
/* 59 */ SyscallDesc("execve", unimplementedFunc),
/* 60 */ SyscallDesc("umask", umaskFunc),
/* 61 */ SyscallDesc("chroot", unimplementedFunc),
/* 62 */ SyscallDesc("osf_old_fstat", unimplementedFunc),
/* 63 */ SyscallDesc("getpgrp", unimplementedFunc),
/* 64 */ SyscallDesc("getpagesize", getpagesizeFunc),
/* 65 */ SyscallDesc("osf_mremap", unimplementedFunc),
/* 66 */ SyscallDesc("vfork", unimplementedFunc),
/* 67 */ SyscallDesc("stat", statFunc<AlphaLinux>),
/* 68 */ SyscallDesc("lstat", lstatFunc<AlphaLinux>),
/* 69 */ SyscallDesc("osf_sbrk", unimplementedFunc),
/* 70 */ SyscallDesc("osf_sstk", unimplementedFunc),
/* 71 */ SyscallDesc("mmap", mmapFunc<AlphaLinux>),
/* 72 */ SyscallDesc("osf_old_vadvise", unimplementedFunc),
/* 73 */ SyscallDesc("munmap", munmapFunc),
/* 74 */ SyscallDesc("mprotect", ignoreFunc),
/* 75 */ SyscallDesc("madvise", unimplementedFunc),
/* 76 */ SyscallDesc("vhangup", unimplementedFunc),
/* 77 */ SyscallDesc("osf_kmodcall", unimplementedFunc),
/* 78 */ SyscallDesc("osf_mincore", unimplementedFunc),
/* 79 */ SyscallDesc("getgroups", unimplementedFunc),
/* 80 */ SyscallDesc("setgroups", unimplementedFunc),
/* 81 */ SyscallDesc("osf_old_getpgrp", unimplementedFunc),
/* 82 */ SyscallDesc("setpgrp", unimplementedFunc),
/* 83 */ SyscallDesc("osf_setitimer", unimplementedFunc),
/* 84 */ SyscallDesc("osf_old_wait", unimplementedFunc),
/* 85 */ SyscallDesc("osf_table", unimplementedFunc),
/* 86 */ SyscallDesc("osf_getitimer", unimplementedFunc),
/* 87 */ SyscallDesc("gethostname", gethostnameFunc),
/* 88 */ SyscallDesc("sethostname", unimplementedFunc),
/* 89 */ SyscallDesc("getdtablesize", unimplementedFunc),
/* 90 */ SyscallDesc("dup2", unimplementedFunc),
/* 91 */ SyscallDesc("fstat", fstatFunc<AlphaLinux>),
/* 92 */ SyscallDesc("fcntl", fcntlFunc),
/* 93 */ SyscallDesc("osf_select", unimplementedFunc),
/* 94 */ SyscallDesc("poll", unimplementedFunc),
/* 95 */ SyscallDesc("fsync", unimplementedFunc),
/* 96 */ SyscallDesc("setpriority", unimplementedFunc),
/* 97 */ SyscallDesc("socket", unimplementedFunc),
/* 98 */ SyscallDesc("connect", unimplementedFunc),
/* 99 */ SyscallDesc("accept", unimplementedFunc),
/* 100 */ SyscallDesc("getpriority", unimplementedFunc),
/* 101 */ SyscallDesc("send", unimplementedFunc),
/* 102 */ SyscallDesc("recv", unimplementedFunc),
/* 103 */ SyscallDesc("sigreturn", unimplementedFunc),
/* 104 */ SyscallDesc("bind", unimplementedFunc),
/* 105 */ SyscallDesc("setsockopt", unimplementedFunc),
/* 106 */ SyscallDesc("listen", unimplementedFunc),
/* 107 */ SyscallDesc("osf_plock", unimplementedFunc),
/* 108 */ SyscallDesc("osf_old_sigvec", unimplementedFunc),
/* 109 */ SyscallDesc("osf_old_sigblock", unimplementedFunc),
/* 110 */ SyscallDesc("osf_old_sigsetmask", unimplementedFunc),
/* 111 */ SyscallDesc("sigsuspend", unimplementedFunc),
/* 112 */ SyscallDesc("osf_sigstack", ignoreFunc),
/* 113 */ SyscallDesc("recvmsg", unimplementedFunc),
/* 114 */ SyscallDesc("sendmsg", unimplementedFunc),
/* 115 */ SyscallDesc("osf_old_vtrace", unimplementedFunc),
/* 116 */ SyscallDesc("osf_gettimeofday", unimplementedFunc),
/* 117 */ SyscallDesc("osf_getrusage", unimplementedFunc),
/* 118 */ SyscallDesc("getsockopt", unimplementedFunc),
/* 119 */ SyscallDesc("numa_syscalls", unimplementedFunc),
/* 120 */ SyscallDesc("readv", unimplementedFunc),
/* 121 */ SyscallDesc("writev", writevFunc<AlphaLinux>),
/* 122 */ SyscallDesc("osf_settimeofday", unimplementedFunc),
/* 123 */ SyscallDesc("fchown", fchownFunc),
/* 124 */ SyscallDesc("fchmod", fchmodFunc<AlphaLinux>),
/* 125 */ SyscallDesc("recvfrom", unimplementedFunc),
/* 126 */ SyscallDesc("setreuid", unimplementedFunc),
/* 127 */ SyscallDesc("setregid", unimplementedFunc),
/* 128 */ SyscallDesc("rename", renameFunc),
/* 129 */ SyscallDesc("truncate", truncateFunc),
/* 130 */ SyscallDesc("ftruncate", ftruncateFunc),
/* 131 */ SyscallDesc("flock", unimplementedFunc),
/* 132 */ SyscallDesc("setgid", unimplementedFunc),
/* 133 */ SyscallDesc("sendto", unimplementedFunc),
/* 134 */ SyscallDesc("shutdown", unimplementedFunc),
/* 135 */ SyscallDesc("socketpair", unimplementedFunc),
/* 136 */ SyscallDesc("mkdir", mkdirFunc),
/* 137 */ SyscallDesc("rmdir", unimplementedFunc),
/* 138 */ SyscallDesc("osf_utimes", unimplementedFunc),
/* 139 */ SyscallDesc("osf_old_sigreturn", unimplementedFunc),
/* 140 */ SyscallDesc("osf_adjtime", unimplementedFunc),
/* 141 */ SyscallDesc("getpeername", unimplementedFunc),
/* 142 */ SyscallDesc("osf_gethostid", unimplementedFunc),
/* 143 */ SyscallDesc("osf_sethostid", unimplementedFunc),
/* 144 */ SyscallDesc("getrlimit", getrlimitFunc<AlphaLinux>),
/* 145 */ SyscallDesc("setrlimit", ignoreFunc),
/* 146 */ SyscallDesc("osf_old_killpg", unimplementedFunc),
/* 147 */ SyscallDesc("setsid", unimplementedFunc),
/* 148 */ SyscallDesc("quotactl", unimplementedFunc),
/* 149 */ SyscallDesc("osf_oldquota", unimplementedFunc),
/* 150 */ SyscallDesc("getsockname", unimplementedFunc),
/* 151 */ SyscallDesc("osf_pread", unimplementedFunc),
/* 152 */ SyscallDesc("osf_pwrite", unimplementedFunc),
/* 153 */ SyscallDesc("osf_pid_block", unimplementedFunc),
/* 154 */ SyscallDesc("osf_pid_unblock", unimplementedFunc),
/* 155 */ SyscallDesc("osf_signal_urti", unimplementedFunc),
/* 156 */ SyscallDesc("sigaction", ignoreFunc),
/* 157 */ SyscallDesc("osf_sigwaitprim", unimplementedFunc),
/* 158 */ SyscallDesc("osf_nfssvc", unimplementedFunc),
/* 159 */ SyscallDesc("osf_getdirentries", unimplementedFunc),
/* 160 */ SyscallDesc("osf_statfs", unimplementedFunc),
/* 161 */ SyscallDesc("osf_fstatfs", unimplementedFunc),
/* 162 */ SyscallDesc("unknown #162", unimplementedFunc),
/* 163 */ SyscallDesc("osf_async_daemon", unimplementedFunc),
/* 164 */ SyscallDesc("osf_getfh", unimplementedFunc),
/* 165 */ SyscallDesc("osf_getdomainname", unimplementedFunc),
/* 166 */ SyscallDesc("setdomainname", unimplementedFunc),
/* 167 */ SyscallDesc("unknown #167", unimplementedFunc),
/* 168 */ SyscallDesc("unknown #168", unimplementedFunc),
/* 169 */ SyscallDesc("osf_exportfs", unimplementedFunc),
/* 170 */ SyscallDesc("unknown #170", unimplementedFunc),
/* 171 */ SyscallDesc("unknown #171", unimplementedFunc),
/* 172 */ SyscallDesc("unknown #172", unimplementedFunc),
/* 173 */ SyscallDesc("unknown #173", unimplementedFunc),
/* 174 */ SyscallDesc("unknown #174", unimplementedFunc),
/* 175 */ SyscallDesc("unknown #175", unimplementedFunc),
/* 176 */ SyscallDesc("unknown #176", unimplementedFunc),
/* 177 */ SyscallDesc("unknown #177", unimplementedFunc),
/* 178 */ SyscallDesc("unknown #178", unimplementedFunc),
/* 179 */ SyscallDesc("unknown #179", unimplementedFunc),
/* 180 */ SyscallDesc("unknown #180", unimplementedFunc),
/* 181 */ SyscallDesc("osf_alt_plock", unimplementedFunc),
/* 182 */ SyscallDesc("unknown #182", unimplementedFunc),
/* 183 */ SyscallDesc("unknown #183", unimplementedFunc),
/* 184 */ SyscallDesc("osf_getmnt", unimplementedFunc),
/* 185 */ SyscallDesc("unknown #185", unimplementedFunc),
/* 186 */ SyscallDesc("unknown #186", unimplementedFunc),
/* 187 */ SyscallDesc("osf_alt_sigpending", unimplementedFunc),
/* 188 */ SyscallDesc("osf_alt_setsid", unimplementedFunc),
/* 189 */ SyscallDesc("unknown #189", unimplementedFunc),
/* 190 */ SyscallDesc("unknown #190", unimplementedFunc),
/* 191 */ SyscallDesc("unknown #191", unimplementedFunc),
/* 192 */ SyscallDesc("unknown #192", unimplementedFunc),
/* 193 */ SyscallDesc("unknown #193", unimplementedFunc),
/* 194 */ SyscallDesc("unknown #194", unimplementedFunc),
/* 195 */ SyscallDesc("unknown #195", unimplementedFunc),
/* 196 */ SyscallDesc("unknown #196", unimplementedFunc),
/* 197 */ SyscallDesc("unknown #197", unimplementedFunc),
/* 198 */ SyscallDesc("unknown #198", unimplementedFunc),
/* 199 */ SyscallDesc("osf_swapon", unimplementedFunc),
/* 200 */ SyscallDesc("msgctl", unimplementedFunc),
/* 201 */ SyscallDesc("msgget", unimplementedFunc),
/* 202 */ SyscallDesc("msgrcv", unimplementedFunc),
/* 203 */ SyscallDesc("msgsnd", unimplementedFunc),
/* 204 */ SyscallDesc("semctl", unimplementedFunc),
/* 205 */ SyscallDesc("semget", unimplementedFunc),
/* 206 */ SyscallDesc("semop", unimplementedFunc),
/* 207 */ SyscallDesc("osf_utsname", unimplementedFunc),
/* 208 */ SyscallDesc("lchown", unimplementedFunc),
/* 209 */ SyscallDesc("osf_shmat", unimplementedFunc),
/* 210 */ SyscallDesc("shmctl", unimplementedFunc),
/* 211 */ SyscallDesc("shmdt", unimplementedFunc),
/* 212 */ SyscallDesc("shmget", unimplementedFunc),
/* 213 */ SyscallDesc("osf_mvalid", unimplementedFunc),
/* 214 */ SyscallDesc("osf_getaddressconf", unimplementedFunc),
/* 215 */ SyscallDesc("osf_msleep", unimplementedFunc),
/* 216 */ SyscallDesc("osf_mwakeup", unimplementedFunc),
/* 217 */ SyscallDesc("msync", unimplementedFunc),
/* 218 */ SyscallDesc("osf_signal", unimplementedFunc),
/* 219 */ SyscallDesc("osf_utc_gettime", unimplementedFunc),
/* 220 */ SyscallDesc("osf_utc_adjtime", unimplementedFunc),
/* 221 */ SyscallDesc("unknown #221", unimplementedFunc),
/* 222 */ SyscallDesc("osf_security", unimplementedFunc),
/* 223 */ SyscallDesc("osf_kloadcall", unimplementedFunc),
/* 224 */ SyscallDesc("unknown #224", unimplementedFunc),
/* 225 */ SyscallDesc("unknown #225", unimplementedFunc),
/* 226 */ SyscallDesc("unknown #226", unimplementedFunc),
/* 227 */ SyscallDesc("unknown #227", unimplementedFunc),
/* 228 */ SyscallDesc("unknown #228", unimplementedFunc),
/* 229 */ SyscallDesc("unknown #229", unimplementedFunc),
/* 230 */ SyscallDesc("unknown #230", unimplementedFunc),
/* 231 */ SyscallDesc("unknown #231", unimplementedFunc),
/* 232 */ SyscallDesc("unknown #232", unimplementedFunc),
/* 233 */ SyscallDesc("getpgid", unimplementedFunc),
/* 234 */ SyscallDesc("getsid", unimplementedFunc),
/* 235 */ SyscallDesc("sigaltstack", ignoreFunc),
/* 236 */ SyscallDesc("osf_waitid", unimplementedFunc),
/* 237 */ SyscallDesc("osf_priocntlset", unimplementedFunc),
/* 238 */ SyscallDesc("osf_sigsendset", unimplementedFunc),
/* 239 */ SyscallDesc("osf_set_speculative", unimplementedFunc),
/* 240 */ SyscallDesc("osf_msfs_syscall", unimplementedFunc),
/* 241 */ SyscallDesc("osf_sysinfo", unimplementedFunc),
/* 242 */ SyscallDesc("osf_uadmin", unimplementedFunc),
/* 243 */ SyscallDesc("osf_fuser", unimplementedFunc),
/* 244 */ SyscallDesc("osf_proplist_syscall", unimplementedFunc),
/* 245 */ SyscallDesc("osf_ntp_adjtime", unimplementedFunc),
/* 246 */ SyscallDesc("osf_ntp_gettime", unimplementedFunc),
/* 247 */ SyscallDesc("osf_pathconf", unimplementedFunc),
/* 248 */ SyscallDesc("osf_fpathconf", unimplementedFunc),
/* 249 */ SyscallDesc("unknown #249", unimplementedFunc),
/* 250 */ SyscallDesc("osf_uswitch", unimplementedFunc),
/* 251 */ SyscallDesc("osf_usleep_thread", unimplementedFunc),
/* 252 */ SyscallDesc("osf_audcntl", unimplementedFunc),
/* 253 */ SyscallDesc("osf_audgen", unimplementedFunc),
/* 254 */ SyscallDesc("sysfs", unimplementedFunc),
/* 255 */ SyscallDesc("osf_subsys_info", unimplementedFunc),
/* 256 */ SyscallDesc("osf_getsysinfo", osf_getsysinfoFunc),
/* 257 */ SyscallDesc("osf_setsysinfo", osf_setsysinfoFunc),
/* 258 */ SyscallDesc("osf_afs_syscall", unimplementedFunc),
/* 259 */ SyscallDesc("osf_swapctl", unimplementedFunc),
/* 260 */ SyscallDesc("osf_memcntl", unimplementedFunc),
/* 261 */ SyscallDesc("osf_fdatasync", unimplementedFunc),
/* 262 */ SyscallDesc("unknown #262", unimplementedFunc),
/* 263 */ SyscallDesc("unknown #263", unimplementedFunc),
/* 264 */ SyscallDesc("unknown #264", unimplementedFunc),
/* 265 */ SyscallDesc("unknown #265", unimplementedFunc),
/* 266 */ SyscallDesc("unknown #266", unimplementedFunc),
/* 267 */ SyscallDesc("unknown #267", unimplementedFunc),
/* 268 */ SyscallDesc("unknown #268", unimplementedFunc),
/* 269 */ SyscallDesc("unknown #269", unimplementedFunc),
/* 270 */ SyscallDesc("unknown #270", unimplementedFunc),
/* 271 */ SyscallDesc("unknown #271", unimplementedFunc),
/* 272 */ SyscallDesc("unknown #272", unimplementedFunc),
/* 273 */ SyscallDesc("unknown #273", unimplementedFunc),
/* 274 */ SyscallDesc("unknown #274", unimplementedFunc),
/* 275 */ SyscallDesc("unknown #275", unimplementedFunc),
/* 276 */ SyscallDesc("unknown #276", unimplementedFunc),
/* 277 */ SyscallDesc("unknown #277", unimplementedFunc),
/* 278 */ SyscallDesc("unknown #278", unimplementedFunc),
/* 279 */ SyscallDesc("unknown #279", unimplementedFunc),
/* 280 */ SyscallDesc("unknown #280", unimplementedFunc),
/* 281 */ SyscallDesc("unknown #281", unimplementedFunc),
/* 282 */ SyscallDesc("unknown #282", unimplementedFunc),
/* 283 */ SyscallDesc("unknown #283", unimplementedFunc),
/* 284 */ SyscallDesc("unknown #284", unimplementedFunc),
/* 285 */ SyscallDesc("unknown #285", unimplementedFunc),
/* 286 */ SyscallDesc("unknown #286", unimplementedFunc),
/* 287 */ SyscallDesc("unknown #287", unimplementedFunc),
/* 288 */ SyscallDesc("unknown #288", unimplementedFunc),
/* 289 */ SyscallDesc("unknown #289", unimplementedFunc),
/* 290 */ SyscallDesc("unknown #290", unimplementedFunc),
/* 291 */ SyscallDesc("unknown #291", unimplementedFunc),
/* 292 */ SyscallDesc("unknown #292", unimplementedFunc),
/* 293 */ SyscallDesc("unknown #293", unimplementedFunc),
/* 294 */ SyscallDesc("unknown #294", unimplementedFunc),
/* 295 */ SyscallDesc("unknown #295", unimplementedFunc),
/* 296 */ SyscallDesc("unknown #296", unimplementedFunc),
/* 297 */ SyscallDesc("unknown #297", unimplementedFunc),
/* 298 */ SyscallDesc("unknown #298", unimplementedFunc),
/* 299 */ SyscallDesc("unknown #299", unimplementedFunc),
/*
* Linux-specific system calls begin at 300
*/
/* 300 */ SyscallDesc("bdflush", unimplementedFunc),
/* 301 */ SyscallDesc("sethae", unimplementedFunc),
/* 302 */ SyscallDesc("mount", unimplementedFunc),
/* 303 */ SyscallDesc("old_adjtimex", unimplementedFunc),
/* 304 */ SyscallDesc("swapoff", unimplementedFunc),
/* 305 */ SyscallDesc("getdents", unimplementedFunc),
/* 306 */ SyscallDesc("create_module", unimplementedFunc),
/* 307 */ SyscallDesc("init_module", unimplementedFunc),
/* 308 */ SyscallDesc("delete_module", unimplementedFunc),
/* 309 */ SyscallDesc("get_kernel_syms", unimplementedFunc),
/* 310 */ SyscallDesc("syslog", unimplementedFunc),
/* 311 */ SyscallDesc("reboot", unimplementedFunc),
/* 312 */ SyscallDesc("clone", cloneFunc),
/* 313 */ SyscallDesc("uselib", unimplementedFunc),
/* 314 */ SyscallDesc("mlock", unimplementedFunc),
/* 315 */ SyscallDesc("munlock", unimplementedFunc),
/* 316 */ SyscallDesc("mlockall", unimplementedFunc),
/* 317 */ SyscallDesc("munlockall", unimplementedFunc),
/* 318 */ SyscallDesc("sysinfo", sysinfoFunc<AlphaLinux>),
/* 319 */ SyscallDesc("_sysctl", unimplementedFunc),
/* 320 */ SyscallDesc("was sys_idle", unimplementedFunc),
/* 321 */ SyscallDesc("oldumount", unimplementedFunc),
/* 322 */ SyscallDesc("swapon", unimplementedFunc),
/* 323 */ SyscallDesc("times", ignoreFunc),
/* 324 */ SyscallDesc("personality", unimplementedFunc),
/* 325 */ SyscallDesc("setfsuid", unimplementedFunc),
/* 326 */ SyscallDesc("setfsgid", unimplementedFunc),
/* 327 */ SyscallDesc("ustat", unimplementedFunc),
/* 328 */ SyscallDesc("statfs", unimplementedFunc),
/* 329 */ SyscallDesc("fstatfs", unimplementedFunc),
/* 330 */ SyscallDesc("sched_setparam", unimplementedFunc),
/* 331 */ SyscallDesc("sched_getparam", unimplementedFunc),
/* 332 */ SyscallDesc("sched_setscheduler", unimplementedFunc),
/* 333 */ SyscallDesc("sched_getscheduler", unimplementedFunc),
/* 334 */ SyscallDesc("sched_yield", unimplementedFunc),
/* 335 */ SyscallDesc("sched_get_priority_max", unimplementedFunc),
/* 336 */ SyscallDesc("sched_get_priority_min", unimplementedFunc),
/* 337 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc),
/* 338 */ SyscallDesc("afs_syscall", unimplementedFunc),
/* 339 */ SyscallDesc("uname", unameFunc),
/* 340 */ SyscallDesc("nanosleep", unimplementedFunc),
/* 341 */ SyscallDesc("mremap", mremapFunc<AlphaLinux>),
/* 342 */ SyscallDesc("nfsservctl", unimplementedFunc),
/* 343 */ SyscallDesc("setresuid", unimplementedFunc),
/* 344 */ SyscallDesc("getresuid", unimplementedFunc),
/* 345 */ SyscallDesc("pciconfig_read", unimplementedFunc),
/* 346 */ SyscallDesc("pciconfig_write", unimplementedFunc),
/* 347 */ SyscallDesc("query_module", unimplementedFunc),
/* 348 */ SyscallDesc("prctl", unimplementedFunc),
/* 349 */ SyscallDesc("pread", unimplementedFunc),
/* 350 */ SyscallDesc("pwrite", unimplementedFunc),
/* 351 */ SyscallDesc("rt_sigreturn", unimplementedFunc),
/* 352 */ SyscallDesc("rt_sigaction", ignoreFunc),
/* 353 */ SyscallDesc("rt_sigprocmask", unimplementedFunc),
/* 354 */ SyscallDesc("rt_sigpending", unimplementedFunc),
/* 355 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc),
/* 356 */ SyscallDesc("rt_sigqueueinfo", unimplementedFunc),
/* 357 */ SyscallDesc("rt_sigsuspend", unimplementedFunc),
/* 358 */ SyscallDesc("select", unimplementedFunc),
/* 359 */ SyscallDesc("gettimeofday", gettimeofdayFunc<AlphaLinux>),
/* 360 */ SyscallDesc("settimeofday", unimplementedFunc),
/* 361 */ SyscallDesc("getitimer", unimplementedFunc),
/* 362 */ SyscallDesc("setitimer", unimplementedFunc),
/* 363 */ SyscallDesc("utimes", utimesFunc<AlphaLinux>),
/* 364 */ SyscallDesc("getrusage", getrusageFunc<AlphaLinux>),
/* 365 */ SyscallDesc("wait4", unimplementedFunc),
/* 366 */ SyscallDesc("adjtimex", unimplementedFunc),
/* 367 */ SyscallDesc("getcwd", getcwdFunc),
/* 368 */ SyscallDesc("capget", unimplementedFunc),
/* 369 */ SyscallDesc("capset", unimplementedFunc),
/* 370 */ SyscallDesc("sendfile", unimplementedFunc),
/* 371 */ SyscallDesc("setresgid", unimplementedFunc),
/* 372 */ SyscallDesc("getresgid", unimplementedFunc),
/* 373 */ SyscallDesc("dipc", unimplementedFunc),
/* 374 */ SyscallDesc("pivot_root", unimplementedFunc),
/* 375 */ SyscallDesc("mincore", unimplementedFunc),
/* 376 */ SyscallDesc("pciconfig_iobase", unimplementedFunc),
/* 377 */ SyscallDesc("getdents64", unimplementedFunc),
/* 378 */ SyscallDesc("gettid", unimplementedFunc),
/* 379 */ SyscallDesc("readahead", unimplementedFunc),
/* 380 */ SyscallDesc("security", unimplementedFunc),
/* 381 */ SyscallDesc("tkill", unimplementedFunc),
/* 382 */ SyscallDesc("setxattr", unimplementedFunc),
/* 383 */ SyscallDesc("lsetxattr", unimplementedFunc),
/* 384 */ SyscallDesc("fsetxattr", unimplementedFunc),
/* 385 */ SyscallDesc("getxattr", unimplementedFunc),
/* 386 */ SyscallDesc("lgetxattr", unimplementedFunc),
/* 387 */ SyscallDesc("fgetxattr", unimplementedFunc),
/* 388 */ SyscallDesc("listxattr", unimplementedFunc),
/* 389 */ SyscallDesc("llistxattr", unimplementedFunc),
/* 390 */ SyscallDesc("flistxattr", unimplementedFunc),
/* 391 */ SyscallDesc("removexattr", unimplementedFunc),
/* 392 */ SyscallDesc("lremovexattr", unimplementedFunc),
/* 393 */ SyscallDesc("fremovexattr", unimplementedFunc),
/* 394 */ SyscallDesc("futex", unimplementedFunc),
/* 395 */ SyscallDesc("sched_setaffinity", unimplementedFunc),
/* 396 */ SyscallDesc("sched_getaffinity", unimplementedFunc),
/* 397 */ SyscallDesc("tuxcall", unimplementedFunc),
/* 398 */ SyscallDesc("io_setup", unimplementedFunc),
/* 399 */ SyscallDesc("io_destroy", unimplementedFunc),
/* 400 */ SyscallDesc("io_getevents", unimplementedFunc),
/* 401 */ SyscallDesc("io_submit", unimplementedFunc),
/* 402 */ SyscallDesc("io_cancel", unimplementedFunc),
/* 403 */ SyscallDesc("unknown #403", unimplementedFunc),
/* 404 */ SyscallDesc("unknown #404", unimplementedFunc),
/* 405 */ SyscallDesc("exit_group", exitGroupFunc), // exit all threads...
/* 406 */ SyscallDesc("lookup_dcookie", unimplementedFunc),
/* 407 */ SyscallDesc("sys_epoll_create", unimplementedFunc),
/* 408 */ SyscallDesc("sys_epoll_ctl", unimplementedFunc),
/* 409 */ SyscallDesc("sys_epoll_wait", unimplementedFunc),
/* 410 */ SyscallDesc("remap_file_pages", unimplementedFunc),
/* 411 */ SyscallDesc("set_tid_address", unimplementedFunc),
/* 412 */ SyscallDesc("restart_syscall", unimplementedFunc),
/* 413 */ SyscallDesc("fadvise64", unimplementedFunc),
/* 414 */ SyscallDesc("timer_create", unimplementedFunc),
/* 415 */ SyscallDesc("timer_settime", unimplementedFunc),
/* 416 */ SyscallDesc("timer_gettime", unimplementedFunc),
/* 417 */ SyscallDesc("timer_getoverrun", unimplementedFunc),
/* 418 */ SyscallDesc("timer_delete", unimplementedFunc),
/* 419 */ SyscallDesc("clock_settime", unimplementedFunc),
/* 420 */ SyscallDesc("clock_gettime", unimplementedFunc),
/* 421 */ SyscallDesc("clock_getres", unimplementedFunc),
/* 422 */ SyscallDesc("clock_nanosleep", unimplementedFunc),
/* 423 */ SyscallDesc("semtimedop", unimplementedFunc),
/* 424 */ SyscallDesc("tgkill", unimplementedFunc),
/* 425 */ SyscallDesc("stat64", stat64Func<AlphaLinux>),
/* 426 */ SyscallDesc("lstat64", lstat64Func<AlphaLinux>),
/* 427 */ SyscallDesc("fstat64", fstat64Func<AlphaLinux>),
/* 428 */ SyscallDesc("vserver", unimplementedFunc),
/* 429 */ SyscallDesc("mbind", unimplementedFunc),
/* 430 */ SyscallDesc("get_mempolicy", unimplementedFunc),
/* 431 */ SyscallDesc("set_mempolicy", unimplementedFunc),
/* 432 */ SyscallDesc("mq_open", unimplementedFunc),
/* 433 */ SyscallDesc("mq_unlink", unimplementedFunc),
/* 434 */ SyscallDesc("mq_timedsend", unimplementedFunc),
/* 435 */ SyscallDesc("mq_timedreceive", unimplementedFunc),
/* 436 */ SyscallDesc("mq_notify", unimplementedFunc),
/* 437 */ SyscallDesc("mq_getsetattr", unimplementedFunc),
/* 438 */ SyscallDesc("waitid", unimplementedFunc),
/* 439 */ SyscallDesc("add_key", unimplementedFunc),
/* 440 */ SyscallDesc("request_key", unimplementedFunc),
/* 441 */ SyscallDesc("keyctl", unimplementedFunc)
};
AlphaLinuxProcess::AlphaLinuxProcess(LiveProcessParams * params,
ObjectFile *objFile)
: AlphaLiveProcess(params, objFile),
Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc))
{
//init_regs->intRegFile[0] = 0;
}
SyscallDesc*
AlphaLinuxProcess::getDesc(int callnum)
{
if (callnum < 0 || callnum >= Num_Syscall_Descs)
return NULL;
return &syscallDescs[callnum];
}

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2003-2004 The Regents of The University of Michigan
* 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
*/
#ifndef __ALPHA_LINUX_PROCESS_HH__
#define __ALPHA_LINUX_PROCESS_HH__
#include "arch/alpha/process.hh"
namespace AlphaISA {
/// A process with emulated Alpha/Linux syscalls.
class AlphaLinuxProcess : public AlphaLiveProcess
{
public:
/// Constructor.
AlphaLinuxProcess(LiveProcessParams * params, ObjectFile *objFile);
virtual SyscallDesc* getDesc(int callnum);
/// Array of syscall descriptors, indexed by call number.
static SyscallDesc syscallDescs[];
const int Num_Syscall_Descs;
};
} // namespace AlphaISA
#endif // __ALPHA_LINUX_PROCESS_HH__

View File

@ -0,0 +1,212 @@
/*
* Copyright (c) 2004-2005 The Regents of The University of Michigan
* 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: Ali Saidi
* Lisa Hsu
* Nathan Binkert
* Steve Reinhardt
*/
/**
* @file
* This code loads the linux kernel, console, pal and patches certain
* functions. The symbol tables are loaded so that traces can show
* the executing function and we can skip functions. Various delay
* loops are skipped and their final values manually computed to speed
* up boot time.
*/
#include "arch/alpha/linux/system.hh"
#include "arch/alpha/linux/threadinfo.hh"
#include "arch/alpha/idle_event.hh"
#include "arch/alpha/system.hh"
#include "arch/vtophys.hh"
#include "base/loader/symtab.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
#include "debug/Thread.hh"
#include "kern/linux/events.hh"
#include "kern/linux/printk.hh"
#include "mem/physical.hh"
#include "mem/port.hh"
#include "sim/arguments.hh"
#include "sim/byteswap.hh"
using namespace std;
using namespace AlphaISA;
using namespace Linux;
LinuxAlphaSystem::LinuxAlphaSystem(Params *p)
: AlphaSystem(p)
{
}
void
LinuxAlphaSystem::initState()
{
// Moved from the constructor to here since it relies on the
// address map being resolved in the interconnect
// Call the initialisation of the super class
AlphaSystem::initState();
Addr addr = 0;
/**
* The symbol swapper_pg_dir marks the beginning of the kernel and
* the location of bootloader passed arguments
*/
if (!kernelSymtab->findAddress("swapper_pg_dir", KernelStart)) {
panic("Could not determine start location of kernel");
}
/**
* Since we aren't using a bootloader, we have to copy the
* kernel arguments directly into the kernel's memory.
*/
virtProxy.writeBlob(CommandLine(),
(uint8_t*)params()->boot_osflags.c_str(),
params()->boot_osflags.length()+1);
/**
* find the address of the est_cycle_freq variable and insert it
* so we don't through the lengthly process of trying to
* calculated it by using the PIT, RTC, etc.
*/
if (kernelSymtab->findAddress("est_cycle_freq", addr))
virtProxy.write(addr, (uint64_t)(SimClock::Frequency /
params()->boot_cpu_frequency));
/**
* EV5 only supports 127 ASNs so we are going to tell the kernel that the
* paritiuclar EV6 we have only supports 127 asns.
* @todo At some point we should change ev5.hh and the palcode to support
* 255 ASNs.
*/
if (kernelSymtab->findAddress("dp264_mv", addr))
virtProxy.write(addr + 0x18, LittleEndianGuest::htog((uint32_t)127));
else
panic("could not find dp264_mv\n");
}
void
LinuxAlphaSystem::setupFuncEvents()
{
AlphaSystem::setupFuncEvents();
#ifndef NDEBUG
kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic");
if (!kernelPanicEvent)
panic("could not find kernel symbol \'panic\'");
#if 0
kernelDieEvent = addKernelFuncEvent<BreakPCEvent>("die_if_kernel");
if (!kernelDieEvent)
panic("could not find kernel symbol \'die_if_kernel\'");
#endif
#endif
/**
* Any time ide_delay_50ms, calibarte_delay or
* determine_cpu_caches is called just skip the
* function. Currently determine_cpu_caches only is used put
* information in proc, however if that changes in the future we
* will have to fill in the cache size variables appropriately.
*/
skipIdeDelay50msEvent =
addKernelFuncEvent<SkipFuncEvent>("ide_delay_50ms");
skipDelayLoopEvent =
addKernelFuncEvent<SkipDelayLoopEvent>("calibrate_delay");
skipCacheProbeEvent =
addKernelFuncEvent<SkipFuncEvent>("determine_cpu_caches");
debugPrintkEvent = addKernelFuncEvent<DebugPrintkEvent>("dprintk");
idleStartEvent = addKernelFuncEvent<IdleStartEvent>("cpu_idle");
// Disable for now as it runs into panic() calls in VPTr methods
// (see sim/vptr.hh). Once those bugs are fixed, we can
// re-enable, but we should find a better way to turn it on than
// using DTRACE(Thread), since looking at a trace flag at tick 0
// leads to non-intuitive behavior with --trace-start.
Addr addr = 0;
if (false && kernelSymtab->findAddress("alpha_switch_to", addr)) {
printThreadEvent = new PrintThreadInfo(&pcEventQueue, "threadinfo",
addr + sizeof(MachInst) * 6);
} else {
printThreadEvent = NULL;
}
}
LinuxAlphaSystem::~LinuxAlphaSystem()
{
#ifndef NDEBUG
delete kernelPanicEvent;
#endif
delete skipIdeDelay50msEvent;
delete skipDelayLoopEvent;
delete skipCacheProbeEvent;
delete debugPrintkEvent;
delete idleStartEvent;
delete printThreadEvent;
}
void
LinuxAlphaSystem::setDelayLoop(ThreadContext *tc)
{
Addr addr = 0;
if (kernelSymtab->findAddress("loops_per_jiffy", addr)) {
Tick cpuFreq = tc->getCpuPtr()->frequency();
assert(intrFreq);
FSTranslatingPortProxy &vp = tc->getVirtProxy();
vp.writeHtoG(addr, (uint32_t)((cpuFreq / intrFreq) * 0.9988));
}
}
void
LinuxAlphaSystem::SkipDelayLoopEvent::process(ThreadContext *tc)
{
SkipFuncEvent::process(tc);
// calculate and set loops_per_jiffy
((LinuxAlphaSystem *)tc->getSystemPtr())->setDelayLoop(tc);
}
void
LinuxAlphaSystem::PrintThreadInfo::process(ThreadContext *tc)
{
Linux::ThreadInfo ti(tc);
DPRINTF(Thread, "Currently Executing Thread %s, pid %d, started at: %d\n",
ti.curTaskName(), ti.curTaskPID(), ti.curTaskStart());
}
LinuxAlphaSystem *
LinuxAlphaSystemParams::create()
{
return new LinuxAlphaSystem(this);
}

View File

@ -0,0 +1,147 @@
/*
* Copyright (c) 2004-2006 The Regents of The University of Michigan
* 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: Ali Saidi
* Lisa Hsu
* Nathan Binkert
*/
#ifndef __ARCH_ALPHA_LINUX_SYSTEM_HH__
#define __ARCH_ALPHA_LINUX_SYSTEM_HH__
class ThreadContext;
class BreakPCEvent;
class IdleStartEvent;
#include "arch/alpha/idle_event.hh"
#include "arch/alpha/system.hh"
#include "kern/linux/events.hh"
#include "params/LinuxAlphaSystem.hh"
/**
* This class contains linux specific system code (Loading, Events).
* It points to objects that are the system binaries to load and patches them
* appropriately to work in simulator.
*/
class LinuxAlphaSystem : public AlphaSystem
{
private:
struct SkipDelayLoopEvent : public SkipFuncEvent
{
SkipDelayLoopEvent(PCEventQueue *q, const std::string &desc, Addr addr)
: SkipFuncEvent(q, desc, addr) {}
virtual void process(ThreadContext *tc);
};
struct PrintThreadInfo : public PCEvent
{
PrintThreadInfo(PCEventQueue *q, const std::string &desc, Addr addr)
: PCEvent(q, desc, addr) {}
virtual void process(ThreadContext *tc);
};
/**
* Addresses defining where the kernel bootloader places various
* elements. Details found in include/asm-alpha/system.h
*/
Addr KernelStart; // Lookup the symbol swapper_pg_dir
public:
Addr InitStack() const { return KernelStart + 0x02000; }
Addr EmptyPGT() const { return KernelStart + 0x04000; }
Addr EmptyPGE() const { return KernelStart + 0x08000; }
Addr ZeroPGE() const { return KernelStart + 0x0A000; }
Addr StartAddr() const { return KernelStart + 0x10000; }
Addr Param() const { return ZeroPGE() + 0x0; }
Addr CommandLine() const { return Param() + 0x0; }
Addr InitrdStart() const { return Param() + 0x100; }
Addr InitrdSize() const { return Param() + 0x108; }
static const int CommandLineSize = 256;
private:
#ifndef NDEBUG
/** Event to halt the simulator if the kernel calls panic() */
BreakPCEvent *kernelPanicEvent;
/** Event to halt the simulator if the kernel calls die_if_kernel */
BreakPCEvent *kernelDieEvent;
#endif
/**
* Event to skip determine_cpu_caches() because we don't support
* the IPRs that the code can access to figure out cache sizes
*/
SkipFuncEvent *skipCacheProbeEvent;
/** PC based event to skip the ide_delay_50ms() call */
SkipFuncEvent *skipIdeDelay50msEvent;
/**
* PC based event to skip the dprink() call and emulate its
* functionality
*/
Linux::DebugPrintkEvent *debugPrintkEvent;
/**
* Skip calculate_delay_loop() rather than waiting for this to be
* calculated
*/
SkipDelayLoopEvent *skipDelayLoopEvent;
/**
* Event to print information about thread switches if the trace flag
* Thread is set
*/
PrintThreadInfo *printThreadEvent;
/** Grab the PCBB of the idle process when it starts */
IdleStartEvent *idleStartEvent;
protected:
/** Setup all the function events. Must be done after init() for Alpha since
* fixFuncEvent() requires a function port
*/
virtual void setupFuncEvents();
public:
typedef LinuxAlphaSystemParams Params;
LinuxAlphaSystem(Params *p);
~LinuxAlphaSystem();
/**
* Initialise the system
*/
virtual void initState();
void setDelayLoop(ThreadContext *tc);
const Params *params() const { return (const Params *)_params; }
};
#endif // __ARCH_ALPHA_LINUX_SYSTEM_HH__

View File

@ -0,0 +1,152 @@
/*
* Copyright (c) 2004 The Regents of The University of Michigan
* 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: Ali Saidi
* Nathan Binkert
*/
#ifndef __ARCH_ALPHA_LINUX_LINUX_TREADNIFO_HH__
#define __ARCH_ALPHA_LINUX_LINUX_TREADNIFO_HH__
#include "cpu/thread_context.hh"
#include "sim/system.hh"
#include "sim/vptr.hh"
namespace Linux {
class ThreadInfo
{
private:
ThreadContext *tc;
System *sys;
Addr pcbb;
template <typename T>
bool
get_data(const char *symbol, T &data)
{
Addr addr = 0;
if (!sys->kernelSymtab->findAddress(symbol, addr))
return false;
CopyOut(tc, &data, addr, sizeof(T));
data = AlphaISA::gtoh(data);
return true;
}
public:
ThreadInfo(ThreadContext *_tc, Addr _pcbb = 0)
: tc(_tc), sys(tc->getSystemPtr()), pcbb(_pcbb)
{
}
~ThreadInfo()
{}
inline Addr
curThreadInfo()
{
Addr addr = pcbb;
Addr sp;
if (!addr)
addr = tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp23);
PortProxy &p = tc->getPhysProxy();
p.readBlob(addr, (uint8_t *)&sp, sizeof(Addr));
return sp & ~ULL(0x3fff);
}
inline Addr
curTaskInfo(Addr thread_info = 0)
{
int32_t offset;
if (!get_data("thread_info_task", offset))
return 0;
if (!thread_info)
thread_info = curThreadInfo();
Addr addr;
CopyOut(tc, &addr, thread_info + offset, sizeof(addr));
return addr;
}
int32_t
curTaskPID(Addr thread_info = 0)
{
int32_t offset;
if (!get_data("task_struct_pid", offset))
return -1;
int32_t pid;
CopyOut(tc, &pid, curTaskInfo(thread_info) + offset, sizeof(pid));
return pid;
}
int64_t
curTaskStart(Addr thread_info = 0)
{
int32_t offset;
if (!get_data("task_struct_start_time", offset))
return -1;
int64_t data;
// start_time is actually of type timespec, but if we just
// grab the first long, we'll get the seconds out of it
CopyOut(tc, &data, curTaskInfo(thread_info) + offset, sizeof(data));
return data;
}
std::string
curTaskName(Addr thread_info = 0)
{
int32_t offset;
int32_t size;
if (!get_data("task_struct_comm", offset))
return "FailureIn_curTaskName";
if (!get_data("task_struct_comm_size", size))
return "FailureIn_curTaskName";
char buffer[size + 1];
CopyStringOut(tc, buffer, curTaskInfo(thread_info) + offset, size);
return buffer;
}
};
} // namespace Linux
#endif // __ARCH_ALPHA_LINUX_LINUX_THREADINFO_HH__

View File

@ -0,0 +1,103 @@
/*
* Copyright (c) 2006 The Regents of The University of Michigan
* 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
*/
#ifndef __ARCH_ALPHA_LOCKED_MEM_HH__
#define __ARCH_ALPHA_LOCKED_MEM_HH__
/**
* @file
*
* ISA-specific helper functions for locked memory accesses.
*
* Note that these functions are not embedded in the ISA description
* because they operate on the *physical* address rather than the
* virtual address. In the current M5 design, the physical address is
* not accessible from the ISA description, only from the CPU model.
* Thus the CPU is responsible for calling back to the ISA (here)
* after the address translation has been performed to allow the ISA
* to do these manipulations based on the physical address.
*/
#include "arch/alpha/registers.hh"
#include "base/misc.hh"
#include "mem/request.hh"
namespace AlphaISA {
template <class XC>
inline void
handleLockedRead(XC *xc, Request *req)
{
xc->setMiscReg(MISCREG_LOCKADDR, req->getPaddr() & ~0xf);
xc->setMiscReg(MISCREG_LOCKFLAG, true);
}
template <class XC>
inline bool
handleLockedWrite(XC *xc, Request *req)
{
if (req->isUncacheable()) {
// Funky Turbolaser mailbox access...don't update
// result register (see stq_c in decoder.isa)
req->setExtraData(2);
} else {
// standard store conditional
bool lock_flag = xc->readMiscReg(MISCREG_LOCKFLAG);
Addr lock_addr = xc->readMiscReg(MISCREG_LOCKADDR);
if (!lock_flag || (req->getPaddr() & ~0xf) != lock_addr) {
// Lock flag not set or addr mismatch in CPU;
// don't even bother sending to memory system
req->setExtraData(0);
xc->setMiscReg(MISCREG_LOCKFLAG, false);
// the rest of this code is not architectural;
// it's just a debugging aid to help detect
// livelock by warning on long sequences of failed
// store conditionals
int stCondFailures = xc->readStCondFailures();
stCondFailures++;
xc->setStCondFailures(stCondFailures);
if (stCondFailures % 100000 == 0) {
warn("context %d: %d consecutive "
"store conditional failures\n",
xc->contextId(), stCondFailures);
}
// store conditional failed already, so don't issue it to mem
return false;
}
}
return true;
}
} // namespace AlphaISA
#endif // __ARCH_ALPHA_LOCKED_MEM_HH__

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2008 The Regents of The University of Michigan
* 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: Gabe Black
*/
#ifndef __ARCH_ALPHA_MICROCODE_ROM_HH__
#define __ARCH_ALPHA_MICROCODE_ROM_HH__
#include "sim/microcode_rom.hh"
namespace AlphaISA
{
using ::MicrocodeRom;
}
#endif // __ARCH_ALPHA_MICROCODE_ROM_HH__

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2006 The Regents of The University of Michigan
* 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: Ali Saidi
*/
#ifndef __ARCH_ALPHA_MMAPPED_IPR_HH__
#define __ARCH_ALPHA_MMAPPED_IPR_HH__
/**
* @file
*
* ISA-specific helper functions for memory mapped IPR accesses.
*/
#include "base/types.hh"
#include "mem/packet.hh"
class ThreadContext;
namespace AlphaISA {
inline Tick
handleIprRead(ThreadContext *xc, Packet *pkt)
{
panic("No handleIprRead implementation in Alpha\n");
}
inline Tick
handleIprWrite(ThreadContext *xc, Packet *pkt)
{
panic("No handleIprWrite implementation in Alpha\n");
}
} // namespace AlphaISA
#endif // __ARCH_ALPHA_MMAPPED_IPR_HH__

View File

@ -0,0 +1,70 @@
/*
* Copyright (c) 2009 The Regents of The University of Michigan
* 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: Korey Sewell
*
*/
#ifndef __ARCH_ALPHA_MT_HH__
#define __ARCH_ALPHA_MT_HH__
/**
* @file
*
* ISA-specific helper functions for multithreaded execution.
*/
#include <iostream>
#include "arch/isa_traits.hh"
#include "base/bitfield.hh"
#include "base/misc.hh"
#include "base/trace.hh"
namespace AlphaISA
{
template <class TC>
inline unsigned
getVirtProcNum(TC *tc)
{
fatal("Alpha is not setup for multithreaded ISA extensions");
return 0;
}
template <class TC>
inline unsigned
getTargetThread(TC *tc)
{
fatal("Alpha is not setup for multithreaded ISA extensions");
return 0;
}
} // namespace AlphaISA
#endif

View File

@ -0,0 +1,304 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* 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: Nathan Binkert
*/
#include "arch/alpha/osfpal.hh"
const char *
PAL::name(int index)
{
static const char *strings[PAL::NumCodes] = {
// Priviledged PAL instructions
"halt", // 0x00
"cflush", // 0x01
"draina", // 0x02
0, // 0x03
0, // 0x04
0, // 0x05
0, // 0x06
0, // 0x07
0, // 0x08
"cserve", // 0x09
"swppal", // 0x0a
0, // 0x0b
0, // 0x0c
"wripir", // 0x0d
0, // 0x0e
0, // 0x0f
"rdmces", // 0x10
"wrmces", // 0x11
0, // 0x12
0, // 0x13
0, // 0x14
0, // 0x15
0, // 0x16
0, // 0x17
0, // 0x18
0, // 0x19
0, // 0x1a
0, // 0x1b
0, // 0x1c
0, // 0x1d
0, // 0x1e
0, // 0x1f
0, // 0x20
0, // 0x21
0, // 0x22
0, // 0x23
0, // 0x24
0, // 0x25
0, // 0x26
0, // 0x27
0, // 0x28
0, // 0x29
0, // 0x2a
"wrfen", // 0x2b
0, // 0x2c
"wrvptptr", // 0x2d
0, // 0x2e
0, // 0x2f
"swpctx", // 0x30
"wrval", // 0x31
"rdval", // 0x32
"tbi", // 0x33
"wrent", // 0x34
"swpipl", // 0x35
"rdps", // 0x36
"wrkgp", // 0x37
"wrusp", // 0x38
"wrperfmon", // 0x39
"rdusp", // 0x3a
0, // 0x3b
"whami", // 0x3c
"retsys", // 0x3d
"wtint", // 0x3e
"rti", // 0x3f
0, // 0x40
0, // 0x41
0, // 0x42
0, // 0x43
0, // 0x44
0, // 0x45
0, // 0x46
0, // 0x47
0, // 0x48
0, // 0x49
0, // 0x4a
0, // 0x4b
0, // 0x4c
0, // 0x4d
0, // 0x4e
0, // 0x4f
0, // 0x50
0, // 0x51
0, // 0x52
0, // 0x53
0, // 0x54
0, // 0x55
0, // 0x56
0, // 0x57
0, // 0x58
0, // 0x59
0, // 0x5a
0, // 0x5b
0, // 0x5c
0, // 0x5d
0, // 0x5e
0, // 0x5f
0, // 0x60
0, // 0x61
0, // 0x62
0, // 0x63
0, // 0x64
0, // 0x65
0, // 0x66
0, // 0x67
0, // 0x68
0, // 0x69
0, // 0x6a
0, // 0x6b
0, // 0x6c
0, // 0x6d
0, // 0x6e
0, // 0x6f
0, // 0x70
0, // 0x71
0, // 0x72
0, // 0x73
0, // 0x74
0, // 0x75
0, // 0x76
0, // 0x77
0, // 0x78
0, // 0x79
0, // 0x7a
0, // 0x7b
0, // 0x7c
0, // 0x7d
0, // 0x7e
0, // 0x7f
// Unpriviledged PAL instructions
"bpt", // 0x80
"bugchk", // 0x81
0, // 0x82
"callsys", // 0x83
0, // 0x84
0, // 0x85
"imb", // 0x86
0, // 0x87
0, // 0x88
0, // 0x89
0, // 0x8a
0, // 0x8b
0, // 0x8c
0, // 0x8d
0, // 0x8e
0, // 0x8f
0, // 0x90
0, // 0x91
"urti", // 0x92
0, // 0x93
0, // 0x94
0, // 0x95
0, // 0x96
0, // 0x97
0, // 0x98
0, // 0x99
0, // 0x9a
0, // 0x9b
0, // 0x9c
0, // 0x9d
"rdunique", // 0x9e
"wrunique", // 0x9f
0, // 0xa0
0, // 0xa1
0, // 0xa2
0, // 0xa3
0, // 0xa4
0, // 0xa5
0, // 0xa6
0, // 0xa7
0, // 0xa8
0, // 0xa9
"gentrap", // 0xaa
0, // 0xab
0, // 0xac
0, // 0xad
"clrfen", // 0xae
0, // 0xaf
0, // 0xb0
0, // 0xb1
0, // 0xb2
0, // 0xb3
0, // 0xb4
0, // 0xb5
0, // 0xb6
0, // 0xb7
0, // 0xb8
0, // 0xb9
0, // 0xba
0, // 0xbb
0, // 0xbc
0, // 0xbd
"nphalt", // 0xbe
"copypal", // 0xbf
#if 0
0, // 0xc0
0, // 0xc1
0, // 0xc2
0, // 0xc3
0, // 0xc4
0, // 0xc5
0, // 0xc6
0, // 0xc7
0, // 0xc8
0, // 0xc9
0, // 0xca
0, // 0xcb
0, // 0xcc
0, // 0xcd
0, // 0xce
0, // 0xcf
0, // 0xd0
0, // 0xd1
0, // 0xd2
0, // 0xd3
0, // 0xd4
0, // 0xd5
0, // 0xd6
0, // 0xd7
0, // 0xd8
0, // 0xd9
0, // 0xda
0, // 0xdb
0, // 0xdc
0, // 0xdd
0, // 0xde
0, // 0xdf
0, // 0xe0
0, // 0xe1
0, // 0xe2
0, // 0xe3
0, // 0xe4
0, // 0xe5
0, // 0xe6
0, // 0xe7
0, // 0xe8
0, // 0xe9
0, // 0xea
0, // 0xeb
0, // 0xec
0, // 0xed
0, // 0xee
0, // 0xef
0, // 0xf0
0, // 0xf1
0, // 0xf2
0, // 0xf3
0, // 0xf4
0, // 0xf5
0, // 0xf6
0, // 0xf7
0, // 0xf8
0, // 0xf9
0, // 0xfa
0, // 0xfb
0, // 0xfc
0, // 0xfd
0, // 0xfe
0 // 0xff
#endif
};
if (index > NumCodes || index < 0)
return 0;
return strings[index];
}

View File

@ -0,0 +1,82 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* 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: Nathan Binkert
*/
#ifndef __ARCH_ALPHA_OSFPAL_HH__
#define __ARCH_ALPHA_OSFPAL_HH__
struct PAL
{
enum {
// Privileged PAL functions
halt = 0x00,
cflush = 0x01,
draina = 0x02,
cserve = 0x09,
swppal = 0x0a,
wripir = 0x0d,
rdmces = 0x10,
wrmces = 0x11,
wrfen = 0x2b,
wrvptptr = 0x2d,
swpctx = 0x30,
wrval = 0x31,
rdval = 0x32,
tbi = 0x33,
wrent = 0x34,
swpipl = 0x35,
rdps = 0x36,
wrkgp = 0x37,
wrusp = 0x38,
wrperfmon = 0x39,
rdusp = 0x3a,
whami = 0x3c,
retsys = 0x3d,
wtint = 0x3e,
rti = 0x3f,
// unprivileged pal functions
bpt = 0x80,
bugchk = 0x81,
callsys = 0x83,
imb = 0x86,
urti = 0x92,
rdunique = 0x9e,
wrunique = 0x9f,
gentrap = 0xaa,
clrfen = 0xae,
nphalt = 0xbe,
copypal = 0xbf,
NumCodes
};
static const char *name(int index);
};
#endif // __ARCH_ALPHA_OSFPAL_HH__

View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2006-2007 The Regents of The University of Michigan
* 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: Gabe Black
*/
#include "arch/alpha/pagetable.hh"
#include "sim/serialize.hh"
namespace AlphaISA {
void
TlbEntry::serialize(std::ostream &os)
{
SERIALIZE_SCALAR(tag);
SERIALIZE_SCALAR(ppn);
SERIALIZE_SCALAR(xre);
SERIALIZE_SCALAR(xwe);
SERIALIZE_SCALAR(asn);
SERIALIZE_SCALAR(asma);
SERIALIZE_SCALAR(fonr);
SERIALIZE_SCALAR(fonw);
SERIALIZE_SCALAR(valid);
}
void
TlbEntry::unserialize(Checkpoint *cp, const std::string &section)
{
UNSERIALIZE_SCALAR(tag);
UNSERIALIZE_SCALAR(ppn);
UNSERIALIZE_SCALAR(xre);
UNSERIALIZE_SCALAR(xwe);
UNSERIALIZE_SCALAR(asn);
UNSERIALIZE_SCALAR(asma);
UNSERIALIZE_SCALAR(fonr);
UNSERIALIZE_SCALAR(fonw);
UNSERIALIZE_SCALAR(valid);
}
} // namespace AlphaISA

View File

@ -0,0 +1,145 @@
/*
* Copyright (c) 2002-2005 The Regents of The University of Michigan
* 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: Nathan Binkert
* Steve Reinhardt
*/
#ifndef __ARCH_ALPHA_PAGETABLE_H__
#define __ARCH_ALPHA_PAGETABLE_H__
#include "arch/alpha/isa_traits.hh"
#include "arch/alpha/utility.hh"
namespace AlphaISA {
struct VAddr
{
static const int ImplBits = 43;
static const Addr ImplMask = (ULL(1) << ImplBits) - 1;
static const Addr UnImplMask = ~ImplMask;
Addr addr;
VAddr(Addr a) : addr(a) {}
operator Addr() const { return addr; }
const VAddr &operator=(Addr a) { addr = a; return *this; }
Addr vpn() const { return (addr & ImplMask) >> PageShift; }
Addr page() const { return addr & PageMask; }
Addr offset() const { return addr & PageOffset; }
Addr level3() const
{ return PteAddr(addr >> PageShift); }
Addr level2() const
{ return PteAddr(addr >> (NPtePageShift + PageShift)); }
Addr level1() const
{ return PteAddr(addr >> (2 * NPtePageShift + PageShift)); }
};
struct PageTableEntry
{
PageTableEntry(uint64_t e) : entry(e) {}
uint64_t entry;
operator uint64_t() const { return entry; }
const PageTableEntry &operator=(uint64_t e) { entry = e; return *this; }
const PageTableEntry &operator=(const PageTableEntry &e)
{ entry = e.entry; return *this; }
Addr _pfn() const { return (entry >> 32) & 0xffffffff; }
Addr _sw() const { return (entry >> 16) & 0xffff; }
int _rsv0() const { return (entry >> 14) & 0x3; }
bool _uwe() const { return (entry >> 13) & 0x1; }
bool _kwe() const { return (entry >> 12) & 0x1; }
int _rsv1() const { return (entry >> 10) & 0x3; }
bool _ure() const { return (entry >> 9) & 0x1; }
bool _kre() const { return (entry >> 8) & 0x1; }
bool _nomb() const { return (entry >> 7) & 0x1; }
int _gh() const { return (entry >> 5) & 0x3; }
bool _asm_() const { return (entry >> 4) & 0x1; }
bool _foe() const { return (entry >> 3) & 0x1; }
bool _fow() const { return (entry >> 2) & 0x1; }
bool _for() const { return (entry >> 1) & 0x1; }
bool valid() const { return (entry >> 0) & 0x1; }
Addr paddr() const { return _pfn() << PageShift; }
};
// ITB/DTB table entry
struct TlbEntry
{
Addr tag; // virtual page number tag
Addr ppn; // physical page number
uint8_t xre; // read permissions - VMEM_PERM_* mask
uint8_t xwe; // write permissions - VMEM_PERM_* mask
uint8_t asn; // address space number
bool asma; // address space match
bool fonr; // fault on read
bool fonw; // fault on write
bool valid; // valid page table entry
//Construct an entry that maps to physical address addr.
TlbEntry(Addr _asn, Addr _vaddr, Addr _paddr)
{
VAddr vaddr(_vaddr);
VAddr paddr(_paddr);
tag = vaddr.vpn();
ppn = paddr.vpn();
xre = 15;
xwe = 15;
asn = _asn;
asma = false;
fonr = false;
fonw = false;
valid = true;
}
TlbEntry()
{}
void
updateVaddr(Addr new_vaddr)
{
VAddr vaddr(new_vaddr);
tag = vaddr.vpn();
}
Addr
pageStart()
{
return ppn << PageShift;
}
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
};
} // namespace AlphaISA
#endif // __ARCH_ALPHA_PAGETABLE_H__

View File

@ -0,0 +1,238 @@
/*
* Copyright (c) 2003-2004 The Regents of The University of Michigan
* 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: Gabe Black
* Ali Saidi
*/
#include "arch/alpha/isa_traits.hh"
#include "arch/alpha/process.hh"
#include "base/loader/elf_object.hh"
#include "base/loader/object_file.hh"
#include "base/misc.hh"
#include "cpu/thread_context.hh"
#include "debug/Loader.hh"
#include "mem/page_table.hh"
#include "sim/byteswap.hh"
#include "sim/process_impl.hh"
#include "sim/system.hh"
using namespace AlphaISA;
using namespace std;
AlphaLiveProcess::AlphaLiveProcess(LiveProcessParams *params,
ObjectFile *objFile)
: LiveProcess(params, objFile)
{
brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize();
brk_point = roundUp(brk_point, VMPageSize);
// Set up stack. On Alpha, stack goes below text section. This
// code should get moved to some architecture-specific spot.
stack_base = objFile->textBase() - (409600+4096);
// Set up region for mmaps. Tru64 seems to start just above 0 and
// grow up from there.
mmap_start = mmap_end = 0x10000;
// Set pointer for next thread stack. Reserve 8M for main stack.
next_thread_stack_base = stack_base - (8 * 1024 * 1024);
}
void
AlphaLiveProcess::argsInit(int intSize, int pageSize)
{
objFile->loadSections(initVirtMem);
typedef AuxVector<uint64_t> auxv_t;
std::vector<auxv_t> auxv;
ElfObject * elfObject = dynamic_cast<ElfObject *>(objFile);
if(elfObject)
{
// modern glibc uses a bunch of auxiliary vectors to set up
// TLS as well as do a bunch of other stuff
// these vectors go on the bottom of the stack, below argc/argv/envp
// pointers but above actual arg strings
// I don't have all the ones glibc looks at here, but so far it doesn't
// seem to be a problem.
// check out _dl_aux_init() in glibc/elf/dl-support.c for details
// --Lisa
auxv.push_back(auxv_t(M5_AT_PAGESZ, AlphaISA::VMPageSize));
auxv.push_back(auxv_t(M5_AT_CLKTCK, 100));
auxv.push_back(auxv_t(M5_AT_PHDR, elfObject->programHeaderTable()));
DPRINTF(Loader, "auxv at PHDR %08p\n", elfObject->programHeaderTable());
auxv.push_back(auxv_t(M5_AT_PHNUM, elfObject->programHeaderCount()));
auxv.push_back(auxv_t(M5_AT_ENTRY, objFile->entryPoint()));
auxv.push_back(auxv_t(M5_AT_UID, uid()));
auxv.push_back(auxv_t(M5_AT_EUID, euid()));
auxv.push_back(auxv_t(M5_AT_GID, gid()));
auxv.push_back(auxv_t(M5_AT_EGID, egid()));
}
// Calculate how much space we need for arg & env & auxv arrays.
int argv_array_size = intSize * (argv.size() + 1);
int envp_array_size = intSize * (envp.size() + 1);
int auxv_array_size = intSize * 2 * (auxv.size() + 1);
int arg_data_size = 0;
for (vector<string>::size_type i = 0; i < argv.size(); ++i) {
arg_data_size += argv[i].size() + 1;
}
int env_data_size = 0;
for (vector<string>::size_type i = 0; i < envp.size(); ++i) {
env_data_size += envp[i].size() + 1;
}
int space_needed =
argv_array_size +
envp_array_size +
auxv_array_size +
arg_data_size +
env_data_size;
if (space_needed < 32*1024)
space_needed = 32*1024;
// set bottom of stack
stack_min = stack_base - space_needed;
// align it
stack_min = roundDown(stack_min, pageSize);
stack_size = stack_base - stack_min;
// map memory
allocateMem(stack_min, roundUp(stack_size, pageSize));
// map out initial stack contents
Addr argv_array_base = stack_min + intSize; // room for argc
Addr envp_array_base = argv_array_base + argv_array_size;
Addr auxv_array_base = envp_array_base + envp_array_size;
Addr arg_data_base = auxv_array_base + auxv_array_size;
Addr env_data_base = arg_data_base + arg_data_size;
// write contents to stack
uint64_t argc = argv.size();
if (intSize == 8)
argc = htog((uint64_t)argc);
else if (intSize == 4)
argc = htog((uint32_t)argc);
else
panic("Unknown int size");
initVirtMem.writeBlob(stack_min, (uint8_t*)&argc, intSize);
copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem);
copyStringArray(envp, envp_array_base, env_data_base, initVirtMem);
//Copy the aux stuff
for (vector<auxv_t>::size_type x = 0; x < auxv.size(); x++) {
initVirtMem.writeBlob(auxv_array_base + x * 2 * intSize,
(uint8_t*)&(auxv[x].a_type), intSize);
initVirtMem.writeBlob(auxv_array_base + (x * 2 + 1) * intSize,
(uint8_t*)&(auxv[x].a_val), intSize);
}
ThreadContext *tc = system->getThreadContext(contextIds[0]);
setSyscallArg(tc, 0, argc);
setSyscallArg(tc, 1, argv_array_base);
tc->setIntReg(StackPointerReg, stack_min);
tc->pcState(objFile->entryPoint());
}
void
AlphaLiveProcess::setupASNReg()
{
ThreadContext *tc = system->getThreadContext(contextIds[0]);
tc->setMiscRegNoEffect(IPR_DTB_ASN, M5_pid << 57);
}
void
AlphaLiveProcess::loadState(Checkpoint *cp)
{
LiveProcess::loadState(cp);
// need to set up ASN after unserialization since M5_pid value may
// come from checkpoint
setupASNReg();
}
void
AlphaLiveProcess::initState()
{
// need to set up ASN before further initialization since init
// will involve writing to virtual memory addresses
setupASNReg();
LiveProcess::initState();
argsInit(MachineBytes, VMPageSize);
ThreadContext *tc = system->getThreadContext(contextIds[0]);
tc->setIntReg(GlobalPointerReg, objFile->globalPointer());
//Operate in user mode
tc->setMiscRegNoEffect(IPR_ICM, mode_user << 3);
tc->setMiscRegNoEffect(IPR_DTB_CM, mode_user << 3);
//No super page mapping
tc->setMiscRegNoEffect(IPR_MCSR, 0);
}
AlphaISA::IntReg
AlphaLiveProcess::getSyscallArg(ThreadContext *tc, int &i)
{
assert(i < 6);
return tc->readIntReg(FirstArgumentReg + i++);
}
void
AlphaLiveProcess::setSyscallArg(ThreadContext *tc,
int i, AlphaISA::IntReg val)
{
assert(i < 6);
tc->setIntReg(FirstArgumentReg + i, val);
}
void
AlphaLiveProcess::setSyscallReturn(ThreadContext *tc,
SyscallReturn return_value)
{
// check for error condition. Alpha syscall convention is to
// indicate success/failure in reg a3 (r19) and put the
// return value itself in the standard return value reg (v0).
if (return_value.successful()) {
// no error
tc->setIntReg(SyscallSuccessReg, 0);
tc->setIntReg(ReturnValueReg, return_value.value());
} else {
// got an error, return details
tc->setIntReg(SyscallSuccessReg, (IntReg)-1);
tc->setIntReg(ReturnValueReg, -return_value.value());
}
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2003-2004 The Regents of The University of Michigan
* 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: Gabe Black
* Ali Saidi
*/
#ifndef __ARCH_ALPHA_PROCESS_HH__
#define __ARCH_ALPHA_PROCESS_HH__
#include "sim/process.hh"
class AlphaLiveProcess : public LiveProcess
{
private:
void setupASNReg();
protected:
AlphaLiveProcess(LiveProcessParams *params, ObjectFile *objFile);
void loadState(Checkpoint *cp);
void initState();
void argsInit(int intSize, int pageSize);
public:
AlphaISA::IntReg getSyscallArg(ThreadContext *tc, int &i);
void setSyscallArg(ThreadContext *tc, int i, AlphaISA::IntReg val);
void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value);
};
#endif // __ARCH_ALPHA_PROCESS_HH__

View File

@ -0,0 +1,113 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* 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: Gabe Black
*/
#ifndef __ARCH_ALPHA_REGISTERS_HH__
#define __ARCH_ALPHA_REGISTERS_HH__
#include "arch/alpha/generated/max_inst_regs.hh"
#include "arch/alpha/ipr.hh"
#include "base/types.hh"
namespace AlphaISA {
using AlphaISAInst::MaxInstSrcRegs;
using AlphaISAInst::MaxInstDestRegs;
// Locked read/write flags are can't be detected by the ISA parser
const int MaxMiscDestRegs = AlphaISAInst::MaxMiscDestRegs + 1;
typedef uint8_t RegIndex;
typedef uint64_t IntReg;
// floating point register file entry type
typedef double FloatReg;
typedef uint64_t FloatRegBits;
// control register file contents
typedef uint64_t MiscReg;
union AnyReg
{
IntReg intreg;
FloatReg fpreg;
MiscReg ctrlreg;
};
enum MiscRegIndex
{
MISCREG_FPCR = NumInternalProcRegs,
MISCREG_UNIQ,
MISCREG_LOCKFLAG,
MISCREG_LOCKADDR,
MISCREG_INTR,
NUM_MISCREGS
};
// semantically meaningful register indices
const RegIndex ZeroReg = 31; // architecturally meaningful
// the rest of these depend on the ABI
const RegIndex StackPointerReg = 30;
const RegIndex GlobalPointerReg = 29;
const RegIndex ProcedureValueReg = 27;
const RegIndex ReturnAddressReg = 26;
const RegIndex ReturnValueReg = 0;
const RegIndex FramePointerReg = 15;
const RegIndex SyscallNumReg = 0;
const RegIndex FirstArgumentReg = 16;
const RegIndex SyscallPseudoReturnReg = 20;
const RegIndex SyscallSuccessReg = 19;
const int NumIntArchRegs = 32;
const int NumPALShadowRegs = 8;
const int NumFloatArchRegs = 32;
const int NumMiscArchRegs = NUM_MISCREGS;
const int NumIntRegs = NumIntArchRegs + NumPALShadowRegs;
const int NumFloatRegs = NumFloatArchRegs;
const int NumMiscRegs = NumMiscArchRegs;
const int TotalNumRegs =
NumIntRegs + NumFloatRegs + NumMiscRegs;
const int TotalDataRegs = NumIntRegs + NumFloatRegs;
// These enumerate all the registers for dependence tracking.
enum DependenceTags {
// 0..31 are the integer regs 0..31
// 32..63 are the FP regs 0..31, i.e. use (reg + FP_Base_DepTag)
FP_Base_DepTag = 40,
Ctrl_Base_DepTag = 72,
Max_DepTag = Ctrl_Base_DepTag + NumMiscRegs + NumInternalProcRegs
};
} // namespace AlphaISA
#endif // __ARCH_ALPHA_REGFILE_HH__

View File

@ -0,0 +1,43 @@
/*
* Copyright (c) 2003-2009 The Regents of The University of Michigan
* 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
* Gabe Black
* Kevin Lim
*/
#include "arch/alpha/regredir.hh"
namespace AlphaISA {
const int reg_redir[NumIntRegs] = {
/* 0 */ 0, 1, 2, 3, 4, 5, 6, 7,
/* 8 */ 32, 33, 34, 35, 36, 37, 38, 15,
/* 16 */ 16, 17, 18, 19, 20, 21, 22, 23,
/* 24 */ 24, 39, 26, 27, 28, 29, 30, 31 };
} // namespace AlphaISA

View File

@ -0,0 +1,43 @@
/*
* Copyright (c) 2003-2009 The Regents of The University of Michigan
* 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: Gabe Black
*/
#ifndef __ARCH_ALPHA_REGREDIR_HH__
#define __ARCH_ALPHA_REGREDIR_HH__
#include "arch/alpha/registers.hh"
namespace AlphaISA {
// redirected register map, really only used for the full system case.
extern const int reg_redir[NumIntRegs];
} // namespace AlphaISA
#endif // __ARCH_ALPHA_REGREDIR_HH__

View File

@ -0,0 +1,321 @@
/*
* Copyright (c) 2002-2005 The Regents of The University of Michigan
* 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: Nathan Binkert
*/
/*
* Copyright (c) 1990, 1993 The Regents of the University of California
* All rights reserved.
*
* This software was developed by the Computer Systems Engineering group
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
* contributed to Berkeley.
*
* All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Lawrence Berkeley Laboratories.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
*
* @(#)kgdb_stub.c 8.4 (Berkeley) 1/12/94
*/
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
/*
* $NetBSD: kgdb_stub.c,v 1.8 2001/07/07 22:58:00 wdk Exp $
*
* Taken from NetBSD
*
* "Stub" to allow remote cpu to debug over a serial line using gdb.
*/
#include <sys/signal.h>
#include <unistd.h>
#include <string>
#include "arch/alpha/decoder.hh"
#include "arch/alpha/kgdb.h"
#include "arch/alpha/regredir.hh"
#include "arch/alpha/remote_gdb.hh"
#include "arch/alpha/utility.hh"
#include "arch/alpha/vtophys.hh"
#include "base/intmath.hh"
#include "base/remote_gdb.hh"
#include "base/socket.hh"
#include "base/trace.hh"
#include "cpu/static_inst.hh"
#include "cpu/thread_context.hh"
#include "debug/GDBAcc.hh"
#include "debug/GDBMisc.hh"
#include "mem/physical.hh"
#include "mem/port.hh"
#include "sim/system.hh"
#include "sim/full_system.hh"
using namespace std;
using namespace AlphaISA;
RemoteGDB::RemoteGDB(System *_system, ThreadContext *tc)
: BaseRemoteGDB(_system, tc, KGDB_NUMREGS)
{
memset(gdbregs.regs, 0, gdbregs.bytes());
}
/*
* Determine if the mapping at va..(va+len) is valid.
*/
bool
RemoteGDB::acc(Addr va, size_t len)
{
if (!FullSystem)
panic("acc function needs to be rewritten for SE mode\n");
Addr last_va;
va = TruncPage(va);
last_va = RoundPage(va + len);
do {
if (IsK0Seg(va)) {
if (va < (K0SegBase + system->memSize())) {
DPRINTF(GDBAcc, "acc: Mapping is valid K0SEG <= "
"%#x < K0SEG + size\n", va);
return true;
} else {
DPRINTF(GDBAcc, "acc: Mapping invalid %#x "
"> K0SEG + size\n", va);
return false;
}
}
/**
* This code says that all accesses to palcode (instruction
* and data) are valid since there isn't a va->pa mapping
* because palcode is accessed physically. At some point this
* should probably be cleaned up but there is no easy way to
* do it.
*/
if (PcPAL(va) || va < 0x10000)
return true;
Addr ptbr = context->readMiscRegNoEffect(IPR_PALtemp20);
PageTableEntry pte =
kernel_pte_lookup(context->getPhysProxy(), ptbr, va);
if (!pte.valid()) {
DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va);
return false;
}
va += PageBytes;
} while (va < last_va);
DPRINTF(GDBAcc, "acc: %#x mapping is valid\n", va);
return true;
}
/*
* Translate the kernel debugger register format into the GDB register
* format.
*/
void
RemoteGDB::getregs()
{
memset(gdbregs.regs, 0, gdbregs.bytes());
gdbregs.regs[KGDB_REG_PC] = context->pcState().pc();
// @todo: Currently this is very Alpha specific.
if (PcPAL(gdbregs.regs[KGDB_REG_PC])) {
for (int i = 0; i < NumIntArchRegs; ++i) {
gdbregs.regs[i] = context->readIntReg(reg_redir[i]);
}
} else {
for (int i = 0; i < NumIntArchRegs; ++i) {
gdbregs.regs[i] = context->readIntReg(i);
}
}
#ifdef KGDB_FP_REGS
for (int i = 0; i < NumFloatArchRegs; ++i) {
gdbregs.regs[i + KGDB_REG_F0] = context->readFloatRegBits(i);
}
#endif
}
/*
* Translate the GDB register format into the kernel debugger register
* format.
*/
void
RemoteGDB::setregs()
{
// @todo: Currently this is very Alpha specific.
if (PcPAL(gdbregs.regs[KGDB_REG_PC])) {
for (int i = 0; i < NumIntArchRegs; ++i) {
context->setIntReg(reg_redir[i], gdbregs.regs[i]);
}
} else {
for (int i = 0; i < NumIntArchRegs; ++i) {
context->setIntReg(i, gdbregs.regs[i]);
}
}
#ifdef KGDB_FP_REGS
for (int i = 0; i < NumFloatArchRegs; ++i) {
context->setFloatRegBits(i, gdbregs.regs[i + KGDB_REG_F0]);
}
#endif
context->pcState(gdbregs.regs[KGDB_REG_PC]);
}
void
RemoteGDB::clearSingleStep()
{
DPRINTF(GDBMisc, "clearSingleStep bt_addr=%#x nt_addr=%#x\n",
takenBkpt, notTakenBkpt);
if (takenBkpt != 0)
clearTempBreakpoint(takenBkpt);
if (notTakenBkpt != 0)
clearTempBreakpoint(notTakenBkpt);
}
void
RemoteGDB::setSingleStep()
{
PCState pc = context->pcState();
PCState bpc;
bool set_bt = false;
// User was stopped at pc, e.g. the instruction at pc was not
// executed.
MachInst inst = read<MachInst>(pc.pc());
StaticInstPtr si = context->getDecoderPtr()->decode(inst, pc.pc());
if (si->hasBranchTarget(pc, context, bpc)) {
// Don't bother setting a breakpoint on the taken branch if it
// is the same as the next pc
if (bpc.pc() != pc.npc())
set_bt = true;
}
DPRINTF(GDBMisc, "setSingleStep bt_addr=%#x nt_addr=%#x\n",
takenBkpt, notTakenBkpt);
setTempBreakpoint(notTakenBkpt = pc.npc());
if (set_bt)
setTempBreakpoint(takenBkpt = bpc.pc());
}
// Write bytes to kernel address space for debugger.
bool
RemoteGDB::write(Addr vaddr, size_t size, const char *data)
{
if (BaseRemoteGDB::write(vaddr, size, data)) {
#ifdef IMB
alpha_pal_imb();
#endif
return true;
} else {
return false;
}
}
bool
RemoteGDB::insertHardBreak(Addr addr, size_t len)
{
warn_once("Breakpoints do not work in Alpha PAL mode.\n"
" See PCEventQueue::doService() in cpu/pc_event.cc.\n");
return BaseRemoteGDB::insertHardBreak(addr, len);
}

View File

@ -0,0 +1,73 @@
/*
* Copyright (c) 2002-2005 The Regents of The University of Michigan
* 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: Nathan Binkert
*/
#ifndef __ARCH_ALPHA_REMOTE_GDB_HH__
#define __ARCH_ALPHA_REMOTE_GDB_HH__
#include <map>
#include "arch/alpha/kgdb.h"
#include "arch/alpha/types.hh"
#include "base/pollevent.hh"
#include "base/remote_gdb.hh"
#include "base/socket.hh"
#include "cpu/pc_event.hh"
class System;
class ThreadContext;
namespace AlphaISA {
class RemoteGDB : public BaseRemoteGDB
{
protected:
Addr notTakenBkpt;
Addr takenBkpt;
protected:
void getregs();
void setregs();
void clearSingleStep();
void setSingleStep();
// Machine memory
bool acc(Addr addr, size_t len);
bool write(Addr addr, size_t size, const char *data);
virtual bool insertHardBreak(Addr addr, size_t len);
public:
RemoteGDB(System *system, ThreadContext *context);
};
} // namespace AlphaISA
#endif // __ARCH_ALPHA_REMOTE_GDB_HH__

View File

@ -0,0 +1,363 @@
/*
* Copyright (c) 2005 The Regents of The University of Michigan
* 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: Nathan Binkert
*/
#include <string>
#include "arch/alpha/isa_traits.hh"
#include "arch/alpha/stacktrace.hh"
#include "arch/alpha/vtophys.hh"
#include "base/bitfield.hh"
#include "base/trace.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
#include "mem/fs_translating_port_proxy.hh"
#include "sim/system.hh"
using namespace std;
namespace AlphaISA {
ProcessInfo::ProcessInfo(ThreadContext *_tc)
: tc(_tc)
{
Addr addr = 0;
FSTranslatingPortProxy &vp = tc->getVirtProxy();
SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
if (!symtab->findAddress("thread_info_size", addr))
panic("thread info not compiled into kernel\n");
thread_info_size = vp.readGtoH<int32_t>(addr);
if (!symtab->findAddress("task_struct_size", addr))
panic("thread info not compiled into kernel\n");
task_struct_size = vp.readGtoH<int32_t>(addr);
if (!symtab->findAddress("thread_info_task", addr))
panic("thread info not compiled into kernel\n");
task_off = vp.readGtoH<int32_t>(addr);
if (!symtab->findAddress("task_struct_pid", addr))
panic("thread info not compiled into kernel\n");
pid_off = vp.readGtoH<int32_t>(addr);
if (!symtab->findAddress("task_struct_comm", addr))
panic("thread info not compiled into kernel\n");
name_off = vp.readGtoH<int32_t>(addr);
}
Addr
ProcessInfo::task(Addr ksp) const
{
Addr base = ksp & ~0x3fff;
if (base == ULL(0xfffffc0000000000))
return 0;
Addr tsk;
FSTranslatingPortProxy &vp = tc->getVirtProxy();
tsk = vp.readGtoH<Addr>(base + task_off);
return tsk;
}
int
ProcessInfo::pid(Addr ksp) const
{
Addr task = this->task(ksp);
if (!task)
return -1;
uint16_t pd;
FSTranslatingPortProxy &vp = tc->getVirtProxy();
pd = vp.readGtoH<uint16_t>(task + pid_off);
return pd;
}
string
ProcessInfo::name(Addr ksp) const
{
Addr task = this->task(ksp);
if (!task)
return "console";
char comm[256];
CopyStringOut(tc, comm, task + name_off, sizeof(comm));
if (!comm[0])
return "startup";
return comm;
}
StackTrace::StackTrace()
: tc(0), stack(64)
{
}
StackTrace::StackTrace(ThreadContext *_tc, StaticInstPtr inst)
: tc(0), stack(64)
{
trace(_tc, inst);
}
StackTrace::~StackTrace()
{
}
void
StackTrace::trace(ThreadContext *_tc, bool is_call)
{
tc = _tc;
System *sys = tc->getSystemPtr();
bool usermode =
(tc->readMiscRegNoEffect(IPR_DTB_CM) & 0x18) != 0;
Addr pc = tc->pcState().pc();
bool kernel = sys->kernelStart <= pc && pc <= sys->kernelEnd;
if (usermode) {
stack.push_back(user);
return;
}
if (!kernel) {
stack.push_back(console);
return;
}
SymbolTable *symtab = sys->kernelSymtab;
Addr ksp = tc->readIntReg(StackPointerReg);
Addr bottom = ksp & ~0x3fff;
if (is_call) {
Addr addr;
if (!symtab->findNearestAddr(pc, addr))
panic("could not find address %#x", pc);
stack.push_back(addr);
pc = tc->pcState().pc();
}
while (ksp > bottom) {
Addr addr;
if (!symtab->findNearestAddr(pc, addr))
panic("could not find symbol for pc=%#x", pc);
assert(pc >= addr && "symbol botch: callpc < func");
stack.push_back(addr);
if (isEntry(addr))
return;
Addr ra;
int size;
if (decodePrologue(ksp, pc, addr, size, ra)) {
if (!ra)
return;
if (size <= 0) {
stack.push_back(unknown);
return;
}
pc = ra;
ksp += size;
} else {
stack.push_back(unknown);
return;
}
bool kernel = sys->kernelStart <= pc && pc <= sys->kernelEnd;
if (!kernel)
return;
if (stack.size() >= 1000)
panic("unwinding too far");
}
panic("unwinding too far");
}
bool
StackTrace::isEntry(Addr addr)
{
if (addr == tc->readMiscRegNoEffect(IPR_PALtemp12))
return true;
if (addr == tc->readMiscRegNoEffect(IPR_PALtemp7))
return true;
if (addr == tc->readMiscRegNoEffect(IPR_PALtemp11))
return true;
if (addr == tc->readMiscRegNoEffect(IPR_PALtemp21))
return true;
if (addr == tc->readMiscRegNoEffect(IPR_PALtemp9))
return true;
if (addr == tc->readMiscRegNoEffect(IPR_PALtemp2))
return true;
return false;
}
bool
StackTrace::decodeStack(MachInst inst, int &disp)
{
// lda $sp, -disp($sp)
//
// Opcode<31:26> == 0x08
// RA<25:21> == 30
// RB<20:16> == 30
// Disp<15:0>
const MachInst mem_mask = 0xffff0000;
const MachInst lda_pattern = 0x23de0000;
const MachInst lda_disp_mask = 0x0000ffff;
// subq $sp, disp, $sp
// addq $sp, disp, $sp
//
// Opcode<31:26> == 0x10
// RA<25:21> == 30
// Lit<20:13>
// One<12> = 1
// Func<11:5> == 0x20 (addq)
// Func<11:5> == 0x29 (subq)
// RC<4:0> == 30
const MachInst intop_mask = 0xffe01fff;
const MachInst addq_pattern = 0x43c0141e;
const MachInst subq_pattern = 0x43c0153e;
const MachInst intop_disp_mask = 0x001fe000;
const int intop_disp_shift = 13;
if ((inst & mem_mask) == lda_pattern)
disp = -sext<16>(inst & lda_disp_mask);
else if ((inst & intop_mask) == addq_pattern)
disp = -int((inst & intop_disp_mask) >> intop_disp_shift);
else if ((inst & intop_mask) == subq_pattern)
disp = int((inst & intop_disp_mask) >> intop_disp_shift);
else
return false;
return true;
}
bool
StackTrace::decodeSave(MachInst inst, int &reg, int &disp)
{
// lda $stq, disp($sp)
//
// Opcode<31:26> == 0x08
// RA<25:21> == ?
// RB<20:16> == 30
// Disp<15:0>
const MachInst stq_mask = 0xfc1f0000;
const MachInst stq_pattern = 0xb41e0000;
const MachInst stq_disp_mask = 0x0000ffff;
const MachInst reg_mask = 0x03e00000;
const int reg_shift = 21;
if ((inst & stq_mask) == stq_pattern) {
reg = (inst & reg_mask) >> reg_shift;
disp = sext<16>(inst & stq_disp_mask);
} else {
return false;
}
return true;
}
/*
* Decode the function prologue for the function we're in, and note
* which registers are stored where, and how large the stack frame is.
*/
bool
StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func, int &size,
Addr &ra)
{
size = 0;
ra = 0;
for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) {
MachInst inst;
CopyOut(tc, (uint8_t *)&inst, pc, sizeof(MachInst));
int reg, disp;
if (decodeStack(inst, disp)) {
if (size) {
// panic("decoding frame size again");
return true;
}
size += disp;
} else if (decodeSave(inst, reg, disp)) {
if (!ra && reg == ReturnAddressReg) {
CopyOut(tc, (uint8_t *)&ra, sp + disp, sizeof(Addr));
if (!ra) {
// panic("no return address value pc=%#x\n", pc);
return false;
}
}
}
}
return true;
}
#if TRACING_ON
void
StackTrace::dump()
{
StringWrap name(tc->getCpuPtr()->name());
SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
DPRINTFN("------ Stack ------\n");
string symbol;
for (int i = 0, size = stack.size(); i < size; ++i) {
Addr addr = stack[size - i - 1];
if (addr == user)
symbol = "user";
else if (addr == console)
symbol = "console";
else if (addr == unknown)
symbol = "unknown";
else
symtab->findSymbol(addr, symbol);
DPRINTFN("%#x: %s\n", addr, symbol);
}
}
#endif
} // namespace AlphaISA

View File

@ -0,0 +1,128 @@
/*
* Copyright (c) 2005 The Regents of The University of Michigan
* 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: Nathan Binkert
*/
#ifndef __ARCH_ALPHA_STACKTRACE_HH__
#define __ARCH_ALPHA_STACKTRACE_HH__
#include "base/trace.hh"
#include "cpu/static_inst.hh"
#include "debug/Stack.hh"
class ThreadContext;
namespace AlphaISA {
class StackTrace;
class ProcessInfo
{
private:
ThreadContext *tc;
int thread_info_size;
int task_struct_size;
int task_off;
int pid_off;
int name_off;
public:
ProcessInfo(ThreadContext *_tc);
Addr task(Addr ksp) const;
int pid(Addr ksp) const;
std::string name(Addr ksp) const;
};
class StackTrace
{
private:
ThreadContext *tc;
std::vector<Addr> stack;
private:
bool isEntry(Addr addr);
bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra);
bool decodeSave(MachInst inst, int &reg, int &disp);
bool decodeStack(MachInst inst, int &disp);
void trace(ThreadContext *tc, bool is_call);
public:
StackTrace();
StackTrace(ThreadContext *tc, StaticInstPtr inst);
~StackTrace();
void
clear()
{
tc = 0;
stack.clear();
}
bool valid() const { return tc != NULL; }
bool trace(ThreadContext *tc, StaticInstPtr inst);
public:
const std::vector<Addr> &getstack() const { return stack; }
enum {
user = 1,
console = 2,
unknown = 3
};
#if TRACING_ON
private:
void dump();
public:
void dprintf() { if (DTRACE(Stack)) dump(); }
#else
public:
void dprintf() {}
#endif
};
inline bool
StackTrace::trace(ThreadContext *tc, StaticInstPtr inst)
{
if (!inst->isCall() && !inst->isReturn())
return false;
if (valid())
clear();
trace(tc, !inst->isReturn());
return true;
}
} // namespace AlphaISA
#endif // __ARCH_ALPHA_STACKTRACE_HH__

View File

@ -0,0 +1,247 @@
/*
* Copyright (c) 2002-2005 The Regents of The University of Michigan
* 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: Ali Saidi
* Nathan Binkert
*/
#include <sys/signal.h>
#include "arch/alpha/ev5.hh"
#include "arch/alpha/system.hh"
#include "arch/vtophys.hh"
#include "base/loader/object_file.hh"
#include "base/loader/symtab.hh"
#include "base/trace.hh"
#include "debug/Loader.hh"
#include "mem/fs_translating_port_proxy.hh"
#include "params/AlphaSystem.hh"
#include "sim/byteswap.hh"
using namespace AlphaISA;
AlphaSystem::AlphaSystem(Params *p)
: System(p), intrFreq(0)
{
consoleSymtab = new SymbolTable;
palSymtab = new SymbolTable;
/**
* Load the pal, and console code into memory
*/
// Load Console Code
console = createObjectFile(params()->console);
if (console == NULL)
fatal("Could not load console file %s", params()->console);
// Load pal file
pal = createObjectFile(params()->pal);
if (pal == NULL)
fatal("Could not load PALcode file %s", params()->pal);
// load symbols
if (!console->loadGlobalSymbols(consoleSymtab))
panic("could not load console symbols\n");
if (!pal->loadGlobalSymbols(palSymtab))
panic("could not load pal symbols\n");
if (!pal->loadLocalSymbols(palSymtab))
panic("could not load pal symbols\n");
if (!console->loadGlobalSymbols(debugSymbolTable))
panic("could not load console symbols\n");
if (!pal->loadGlobalSymbols(debugSymbolTable))
panic("could not load pal symbols\n");
if (!pal->loadLocalSymbols(debugSymbolTable))
panic("could not load pal symbols\n");
}
AlphaSystem::~AlphaSystem()
{
delete consoleSymtab;
delete console;
delete pal;
#ifdef DEBUG
delete consolePanicEvent;
#endif
}
void
AlphaSystem::initState()
{
Addr addr = 0;
// Moved from the constructor to here since it relies on the
// address map being resolved in the interconnect
// Call the initialisation of the super class
System::initState();
// Load program sections into memory
pal->loadSections(physProxy, loadAddrMask);
console->loadSections(physProxy, loadAddrMask);
/**
* Copy the osflags (kernel arguments) into the consoles
* memory. (Presently Linux does not use the console service
* routine to get these command line arguments, but Tru64 and
* others do.)
*/
if (consoleSymtab->findAddress("env_booted_osflags", addr)) {
virtProxy.writeBlob(addr, (uint8_t*)params()->boot_osflags.c_str(),
strlen(params()->boot_osflags.c_str()));
}
/**
* Set the hardware reset parameter block system type and revision
* information to Tsunami.
*/
if (consoleSymtab->findAddress("m5_rpb", addr)) {
uint64_t data;
data = htog(params()->system_type);
virtProxy.write(addr+0x50, data);
data = htog(params()->system_rev);
virtProxy.write(addr+0x58, data);
} else
panic("could not find hwrpb\n");
// Setup all the function events now that we have a system and a symbol
// table
setupFuncEvents();
}
void
AlphaSystem::loadState(Checkpoint *cp)
{
System::loadState(cp);
// Setup all the function events now that we have a system and a symbol
// table
setupFuncEvents();
}
void
AlphaSystem::setupFuncEvents()
{
#ifndef NDEBUG
consolePanicEvent = addConsoleFuncEvent<BreakPCEvent>("panic");
#endif
}
/**
* This function fixes up addresses that are used to match PCs for
* hooking simulator events on to target function executions.
*
* Alpha binaries may have multiple global offset table (GOT)
* sections. A function that uses the GOT starts with a
* two-instruction prolog which sets the global pointer (gp == r29) to
* the appropriate GOT section. The proper gp value is calculated
* based on the function address, which must be passed by the caller
* in the procedure value register (pv aka t12 == r27). This sequence
* looks like the following:
*
* opcode Ra Rb offset
* ldah gp,X(pv) 09 29 27 X
* lda gp,Y(gp) 08 29 29 Y
*
* for some constant offsets X and Y. The catch is that the linker
* (or maybe even the compiler, I'm not sure) may recognize that the
* caller and callee are using the same GOT section, making this
* prolog redundant, and modify the call target to skip these
* instructions. If we check for execution of the first instruction
* of a function (the one the symbol points to) to detect when to skip
* it, we'll miss all these modified calls. It might work to
* unconditionally check for the third instruction, but not all
* functions have this prolog, and there's some chance that those
* first two instructions could have undesired consequences. So we do
* the Right Thing and pattern-match the first two instructions of the
* function to decide where to patch.
*
* Eventually this code should be moved into an ISA-specific file.
*/
Addr
AlphaSystem::fixFuncEventAddr(Addr addr)
{
// mask for just the opcode, Ra, and Rb fields (not the offset)
const uint32_t inst_mask = 0xffff0000;
// ldah gp,X(pv): opcode 9, Ra = 29, Rb = 27
const uint32_t gp_ldah_pattern = (9 << 26) | (29 << 21) | (27 << 16);
// lda gp,Y(gp): opcode 8, Ra = 29, rb = 29
const uint32_t gp_lda_pattern = (8 << 26) | (29 << 21) | (29 << 16);
uint32_t i1 = virtProxy.read<uint32_t>(addr);
uint32_t i2 = virtProxy.read<uint32_t>(addr + sizeof(MachInst));
if ((i1 & inst_mask) == gp_ldah_pattern &&
(i2 & inst_mask) == gp_lda_pattern) {
Addr new_addr = addr + 2 * sizeof(MachInst);
DPRINTF(Loader, "fixFuncEventAddr: %p -> %p", addr, new_addr);
return new_addr;
} else {
return addr;
}
}
void
AlphaSystem::setAlphaAccess(Addr access)
{
Addr addr = 0;
if (consoleSymtab->findAddress("m5AlphaAccess", addr)) {
virtProxy.write(addr, htog(Phys2K0Seg(access)));
} else {
panic("could not find m5AlphaAccess\n");
}
}
void
AlphaSystem::serialize(std::ostream &os)
{
System::serialize(os);
consoleSymtab->serialize("console_symtab", os);
palSymtab->serialize("pal_symtab", os);
}
void
AlphaSystem::unserialize(Checkpoint *cp, const std::string &section)
{
System::unserialize(cp,section);
consoleSymtab->unserialize("console_symtab", cp, section);
palSymtab->unserialize("pal_symtab", cp, section);
}
AlphaSystem *
AlphaSystemParams::create()
{
return new AlphaSystem(this);
}

View File

@ -0,0 +1,125 @@
/*
* Copyright (c) 2002-2005 The Regents of The University of Michigan
* 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: Ali Saidi
* Nathan Binkert
*/
#ifndef __ARCH_ALPHA_SYSTEM_HH__
#define __ARCH_ALPHA_SYSTEM_HH__
#include <string>
#include <vector>
#include "base/loader/symtab.hh"
#include "cpu/pc_event.hh"
#include "kern/system_events.hh"
#include "params/AlphaSystem.hh"
#include "sim/sim_object.hh"
#include "sim/system.hh"
class AlphaSystem : public System
{
public:
typedef AlphaSystemParams Params;
AlphaSystem(Params *p);
~AlphaSystem();
public:
/**
* Initialise the state of the system.
*/
virtual void initState();
/**
* Serialization stuff
*/
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string &section);
/** Override loadState to provide a path to call setupFuncEvents()
*/
virtual void loadState(Checkpoint *cp);
/**
* Set the m5AlphaAccess pointer in the console
*/
void setAlphaAccess(Addr access);
/** console symbol table */
SymbolTable *consoleSymtab;
/** pal symbol table */
SymbolTable *palSymtab;
/** Object pointer for the console code */
ObjectFile *console;
/** Object pointer for the PAL code */
ObjectFile *pal;
#ifndef NDEBUG
/** Event to halt the simulator if the console calls panic() */
BreakPCEvent *consolePanicEvent;
#endif
protected:
Tick intrFreq;
const Params *params() const { return (const Params *)_params; }
/** Setup all the function events. Must be done after init() for Alpha since
* fixFuncEvent() requires a function port
*/
virtual void setupFuncEvents();
/** Add a function-based event to PALcode. */
template <class T>
T *
addPalFuncEvent(const char *lbl)
{
return addFuncEvent<T>(palSymtab, lbl);
}
/** Add a function-based event to the console code. */
template <class T>
T *
addConsoleFuncEvent(const char *lbl)
{
return addFuncEvent<T>(consoleSymtab, lbl);
}
virtual Addr fixFuncEventAddr(Addr addr);
public:
void setIntrFreq(Tick freq) { intrFreq = freq; }
};
#endif // __ARCH_ALPHA_SYSTEM_HH__

View File

@ -0,0 +1,616 @@
/*
* Copyright (c) 2001-2005 The Regents of The University of Michigan
* 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: Nathan Binkert
* Steve Reinhardt
* Andrew Schultz
*/
#include <string>
#include <vector>
#include "arch/alpha/faults.hh"
#include "arch/alpha/pagetable.hh"
#include "arch/alpha/tlb.hh"
#include "arch/generic/debugfaults.hh"
#include "base/inifile.hh"
#include "base/str.hh"
#include "base/trace.hh"
#include "cpu/thread_context.hh"
#include "debug/TLB.hh"
#include "sim/full_system.hh"
using namespace std;
namespace AlphaISA {
///////////////////////////////////////////////////////////////////////
//
// Alpha TLB
//
#ifdef DEBUG
bool uncacheBit39 = false;
bool uncacheBit40 = false;
#endif
#define MODE2MASK(X) (1 << (X))
TLB::TLB(const Params *p)
: BaseTLB(p), size(p->size), nlu(0)
{
table = new TlbEntry[size];
memset(table, 0, sizeof(TlbEntry) * size);
flushCache();
}
TLB::~TLB()
{
if (table)
delete [] table;
}
void
TLB::regStats()
{
fetch_hits
.name(name() + ".fetch_hits")
.desc("ITB hits");
fetch_misses
.name(name() + ".fetch_misses")
.desc("ITB misses");
fetch_acv
.name(name() + ".fetch_acv")
.desc("ITB acv");
fetch_accesses
.name(name() + ".fetch_accesses")
.desc("ITB accesses");
fetch_accesses = fetch_hits + fetch_misses;
read_hits
.name(name() + ".read_hits")
.desc("DTB read hits")
;
read_misses
.name(name() + ".read_misses")
.desc("DTB read misses")
;
read_acv
.name(name() + ".read_acv")
.desc("DTB read access violations")
;
read_accesses
.name(name() + ".read_accesses")
.desc("DTB read accesses")
;
write_hits
.name(name() + ".write_hits")
.desc("DTB write hits")
;
write_misses
.name(name() + ".write_misses")
.desc("DTB write misses")
;
write_acv
.name(name() + ".write_acv")
.desc("DTB write access violations")
;
write_accesses
.name(name() + ".write_accesses")
.desc("DTB write accesses")
;
data_hits
.name(name() + ".data_hits")
.desc("DTB hits")
;
data_misses
.name(name() + ".data_misses")
.desc("DTB misses")
;
data_acv
.name(name() + ".data_acv")
.desc("DTB access violations")
;
data_accesses
.name(name() + ".data_accesses")
.desc("DTB accesses")
;
data_hits = read_hits + write_hits;
data_misses = read_misses + write_misses;
data_acv = read_acv + write_acv;
data_accesses = read_accesses + write_accesses;
}
// look up an entry in the TLB
TlbEntry *
TLB::lookup(Addr vpn, uint8_t asn)
{
// assume not found...
TlbEntry *retval = NULL;
if (EntryCache[0]) {
if (vpn == EntryCache[0]->tag &&
(EntryCache[0]->asma || EntryCache[0]->asn == asn))
retval = EntryCache[0];
else if (EntryCache[1]) {
if (vpn == EntryCache[1]->tag &&
(EntryCache[1]->asma || EntryCache[1]->asn == asn))
retval = EntryCache[1];
else if (EntryCache[2] && vpn == EntryCache[2]->tag &&
(EntryCache[2]->asma || EntryCache[2]->asn == asn))
retval = EntryCache[2];
}
}
if (retval == NULL) {
PageTable::const_iterator i = lookupTable.find(vpn);
if (i != lookupTable.end()) {
while (i->first == vpn) {
int index = i->second;
TlbEntry *entry = &table[index];
assert(entry->valid);
if (vpn == entry->tag && (entry->asma || entry->asn == asn)) {
retval = updateCache(entry);
break;
}
++i;
}
}
}
DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn,
retval ? "hit" : "miss", retval ? retval->ppn : 0);
return retval;
}
Fault
TLB::checkCacheability(RequestPtr &req, bool itb)
{
// in Alpha, cacheability is controlled by upper-level bits of the
// physical address
/*
* We support having the uncacheable bit in either bit 39 or bit
* 40. The Turbolaser platform (and EV5) support having the bit
* in 39, but Tsunami (which Linux assumes uses an EV6) generates
* accesses with the bit in 40. So we must check for both, but we
* have debug flags to catch a weird case where both are used,
* which shouldn't happen.
*/
if (req->getPaddr() & PAddrUncachedBit43) {
// IPR memory space not implemented
if (PAddrIprSpace(req->getPaddr())) {
return new UnimpFault("IPR memory space not implemented!");
} else {
// mark request as uncacheable
req->setFlags(Request::UNCACHEABLE);
// Clear bits 42:35 of the physical address (10-2 in
// Tsunami manual)
req->setPaddr(req->getPaddr() & PAddrUncachedMask);
}
// We shouldn't be able to read from an uncachable address in Alpha as
// we don't have a ROM and we don't want to try to fetch from a device
// register as we destroy any data that is clear-on-read.
if (req->isUncacheable() && itb)
return new UnimpFault("CPU trying to fetch from uncached I/O");
}
return NoFault;
}
// insert a new TLB entry
void
TLB::insert(Addr addr, TlbEntry &entry)
{
flushCache();
VAddr vaddr = addr;
if (table[nlu].valid) {
Addr oldvpn = table[nlu].tag;
PageTable::iterator i = lookupTable.find(oldvpn);
if (i == lookupTable.end())
panic("TLB entry not found in lookupTable");
int index;
while ((index = i->second) != nlu) {
if (table[index].tag != oldvpn)
panic("TLB entry not found in lookupTable");
++i;
}
DPRINTF(TLB, "remove @%d: %#x -> %#x\n", nlu, oldvpn, table[nlu].ppn);
lookupTable.erase(i);
}
DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vaddr.vpn(), entry.ppn);
table[nlu] = entry;
table[nlu].tag = vaddr.vpn();
table[nlu].valid = true;
lookupTable.insert(make_pair(vaddr.vpn(), nlu));
nextnlu();
}
void
TLB::flushAll()
{
DPRINTF(TLB, "flushAll\n");
memset(table, 0, sizeof(TlbEntry) * size);
flushCache();
lookupTable.clear();
nlu = 0;
}
void
TLB::flushProcesses()
{
flushCache();
PageTable::iterator i = lookupTable.begin();
PageTable::iterator end = lookupTable.end();
while (i != end) {
int index = i->second;
TlbEntry *entry = &table[index];
assert(entry->valid);
// we can't increment i after we erase it, so save a copy and
// increment it to get the next entry now
PageTable::iterator cur = i;
++i;
if (!entry->asma) {
DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index,
entry->tag, entry->ppn);
entry->valid = false;
lookupTable.erase(cur);
}
}
}
void
TLB::flushAddr(Addr addr, uint8_t asn)
{
flushCache();
VAddr vaddr = addr;
PageTable::iterator i = lookupTable.find(vaddr.vpn());
if (i == lookupTable.end())
return;
while (i != lookupTable.end() && i->first == vaddr.vpn()) {
int index = i->second;
TlbEntry *entry = &table[index];
assert(entry->valid);
if (vaddr.vpn() == entry->tag && (entry->asma || entry->asn == asn)) {
DPRINTF(TLB, "flushaddr @%d: %#x -> %#x\n", index, vaddr.vpn(),
entry->ppn);
// invalidate this entry
entry->valid = false;
lookupTable.erase(i++);
} else {
++i;
}
}
}
void
TLB::serialize(ostream &os)
{
SERIALIZE_SCALAR(size);
SERIALIZE_SCALAR(nlu);
for (int i = 0; i < size; i++) {
nameOut(os, csprintf("%s.Entry%d", name(), i));
table[i].serialize(os);
}
}
void
TLB::unserialize(Checkpoint *cp, const string &section)
{
UNSERIALIZE_SCALAR(size);
UNSERIALIZE_SCALAR(nlu);
for (int i = 0; i < size; i++) {
table[i].unserialize(cp, csprintf("%s.Entry%d", section, i));
if (table[i].valid) {
lookupTable.insert(make_pair(table[i].tag, i));
}
}
}
Fault
TLB::translateInst(RequestPtr req, ThreadContext *tc)
{
//If this is a pal pc, then set PHYSICAL
if (FullSystem && PcPAL(req->getPC()))
req->setFlags(Request::PHYSICAL);
if (PcPAL(req->getPC())) {
// strip off PAL PC marker (lsb is 1)
req->setPaddr((req->getVaddr() & ~3) & PAddrImplMask);
fetch_hits++;
return NoFault;
}
if (req->getFlags() & Request::PHYSICAL) {
req->setPaddr(req->getVaddr());
} else {
// verify that this is a good virtual address
if (!validVirtualAddress(req->getVaddr())) {
fetch_acv++;
return new ItbAcvFault(req->getVaddr());
}
// VA<42:41> == 2, VA<39:13> maps directly to PA<39:13> for EV5
// VA<47:41> == 0x7e, VA<40:13> maps directly to PA<40:13> for EV6
if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) {
// only valid in kernel mode
if (ICM_CM(tc->readMiscRegNoEffect(IPR_ICM)) !=
mode_kernel) {
fetch_acv++;
return new ItbAcvFault(req->getVaddr());
}
req->setPaddr(req->getVaddr() & PAddrImplMask);
// sign extend the physical address properly
if (req->getPaddr() & PAddrUncachedBit40)
req->setPaddr(req->getPaddr() | ULL(0xf0000000000));
else
req->setPaddr(req->getPaddr() & ULL(0xffffffffff));
} else {
// not a physical address: need to look up pte
int asn = DTB_ASN_ASN(tc->readMiscRegNoEffect(IPR_DTB_ASN));
TlbEntry *entry = lookup(VAddr(req->getVaddr()).vpn(),
asn);
if (!entry) {
fetch_misses++;
return new ItbPageFault(req->getVaddr());
}
req->setPaddr((entry->ppn << PageShift) +
(VAddr(req->getVaddr()).offset()
& ~3));
// check permissions for this access
if (!(entry->xre &
(1 << ICM_CM(tc->readMiscRegNoEffect(IPR_ICM))))) {
// instruction access fault
fetch_acv++;
return new ItbAcvFault(req->getVaddr());
}
fetch_hits++;
}
}
// check that the physical address is ok (catch bad physical addresses)
if (req->getPaddr() & ~PAddrImplMask) {
return new MachineCheckFault();
}
return checkCacheability(req, true);
}
Fault
TLB::translateData(RequestPtr req, ThreadContext *tc, bool write)
{
mode_type mode =
(mode_type)DTB_CM_CM(tc->readMiscRegNoEffect(IPR_DTB_CM));
/**
* Check for alignment faults
*/
if (req->getVaddr() & (req->getSize() - 1)) {
DPRINTF(TLB, "Alignment Fault on %#x, size = %d\n", req->getVaddr(),
req->getSize());
uint64_t flags = write ? MM_STAT_WR_MASK : 0;
return new DtbAlignmentFault(req->getVaddr(), req->getFlags(), flags);
}
if (PcPAL(req->getPC())) {
mode = (req->getFlags() & Request::ALTMODE) ?
(mode_type)ALT_MODE_AM(
tc->readMiscRegNoEffect(IPR_ALT_MODE))
: mode_kernel;
}
if (req->getFlags() & Request::PHYSICAL) {
req->setPaddr(req->getVaddr());
} else {
// verify that this is a good virtual address
if (!validVirtualAddress(req->getVaddr())) {
if (write) { write_acv++; } else { read_acv++; }
uint64_t flags = (write ? MM_STAT_WR_MASK : 0) |
MM_STAT_BAD_VA_MASK |
MM_STAT_ACV_MASK;
return new DtbPageFault(req->getVaddr(), req->getFlags(), flags);
}
// Check for "superpage" mapping
if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) {
// only valid in kernel mode
if (DTB_CM_CM(tc->readMiscRegNoEffect(IPR_DTB_CM)) !=
mode_kernel) {
if (write) { write_acv++; } else { read_acv++; }
uint64_t flags = ((write ? MM_STAT_WR_MASK : 0) |
MM_STAT_ACV_MASK);
return new DtbAcvFault(req->getVaddr(), req->getFlags(),
flags);
}
req->setPaddr(req->getVaddr() & PAddrImplMask);
// sign extend the physical address properly
if (req->getPaddr() & PAddrUncachedBit40)
req->setPaddr(req->getPaddr() | ULL(0xf0000000000));
else
req->setPaddr(req->getPaddr() & ULL(0xffffffffff));
} else {
if (write)
write_accesses++;
else
read_accesses++;
int asn = DTB_ASN_ASN(tc->readMiscRegNoEffect(IPR_DTB_ASN));
// not a physical address: need to look up pte
TlbEntry *entry = lookup(VAddr(req->getVaddr()).vpn(), asn);
if (!entry) {
// page fault
if (write) { write_misses++; } else { read_misses++; }
uint64_t flags = (write ? MM_STAT_WR_MASK : 0) |
MM_STAT_DTB_MISS_MASK;
return (req->getFlags() & Request::VPTE) ?
(Fault)(new PDtbMissFault(req->getVaddr(), req->getFlags(),
flags)) :
(Fault)(new NDtbMissFault(req->getVaddr(), req->getFlags(),
flags));
}
req->setPaddr((entry->ppn << PageShift) +
VAddr(req->getVaddr()).offset());
if (write) {
if (!(entry->xwe & MODE2MASK(mode))) {
// declare the instruction access fault
write_acv++;
uint64_t flags = MM_STAT_WR_MASK |
MM_STAT_ACV_MASK |
(entry->fonw ? MM_STAT_FONW_MASK : 0);
return new DtbPageFault(req->getVaddr(), req->getFlags(),
flags);
}
if (entry->fonw) {
write_acv++;
uint64_t flags = MM_STAT_WR_MASK | MM_STAT_FONW_MASK;
return new DtbPageFault(req->getVaddr(), req->getFlags(),
flags);
}
} else {
if (!(entry->xre & MODE2MASK(mode))) {
read_acv++;
uint64_t flags = MM_STAT_ACV_MASK |
(entry->fonr ? MM_STAT_FONR_MASK : 0);
return new DtbAcvFault(req->getVaddr(), req->getFlags(),
flags);
}
if (entry->fonr) {
read_acv++;
uint64_t flags = MM_STAT_FONR_MASK;
return new DtbPageFault(req->getVaddr(), req->getFlags(),
flags);
}
}
}
if (write)
write_hits++;
else
read_hits++;
}
// check that the physical address is ok (catch bad physical addresses)
if (req->getPaddr() & ~PAddrImplMask) {
return new MachineCheckFault();
}
return checkCacheability(req);
}
TlbEntry &
TLB::index(bool advance)
{
TlbEntry *entry = &table[nlu];
if (advance)
nextnlu();
return *entry;
}
Fault
TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode)
{
if (mode == Execute)
return translateInst(req, tc);
else
return translateData(req, tc, mode == Write);
}
void
TLB::translateTiming(RequestPtr req, ThreadContext *tc,
Translation *translation, Mode mode)
{
assert(translation);
translation->finish(translateAtomic(req, tc, mode), req, tc, mode);
}
Fault
TLB::translateFunctional(RequestPtr req, ThreadContext *tc, Mode mode)
{
panic("Not implemented\n");
return NoFault;
}
} // namespace AlphaISA
AlphaISA::TLB *
AlphaTLBParams::create()
{
return new AlphaISA::TLB(this);
}

View File

@ -0,0 +1,155 @@
/*
* Copyright (c) 2001-2005 The Regents of The University of Michigan
* 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: Nathan Binkert
* Steve Reinhardt
*/
#ifndef __ARCH_ALPHA_TLB_HH__
#define __ARCH_ALPHA_TLB_HH__
#include <map>
#include "arch/alpha/ev5.hh"
#include "arch/alpha/isa_traits.hh"
#include "arch/alpha/pagetable.hh"
#include "arch/alpha/utility.hh"
#include "arch/alpha/vtophys.hh"
#include "base/statistics.hh"
#include "mem/request.hh"
#include "params/AlphaTLB.hh"
#include "sim/fault_fwd.hh"
#include "sim/tlb.hh"
class ThreadContext;
namespace AlphaISA {
struct TlbEntry;
class TLB : public BaseTLB
{
protected:
mutable Stats::Scalar fetch_hits;
mutable Stats::Scalar fetch_misses;
mutable Stats::Scalar fetch_acv;
mutable Stats::Formula fetch_accesses;
mutable Stats::Scalar read_hits;
mutable Stats::Scalar read_misses;
mutable Stats::Scalar read_acv;
mutable Stats::Scalar read_accesses;
mutable Stats::Scalar write_hits;
mutable Stats::Scalar write_misses;
mutable Stats::Scalar write_acv;
mutable Stats::Scalar write_accesses;
Stats::Formula data_hits;
Stats::Formula data_misses;
Stats::Formula data_acv;
Stats::Formula data_accesses;
typedef std::multimap<Addr, int> PageTable;
PageTable lookupTable; // Quick lookup into page table
TlbEntry *table; // the Page Table
int size; // TLB Size
int nlu; // not last used entry (for replacement)
void nextnlu() { if (++nlu >= size) nlu = 0; }
TlbEntry *lookup(Addr vpn, uint8_t asn);
public:
typedef AlphaTLBParams Params;
TLB(const Params *p);
virtual ~TLB();
virtual void regStats();
int getsize() const { return size; }
TlbEntry &index(bool advance = true);
void insert(Addr vaddr, TlbEntry &entry);
void flushAll();
void flushProcesses();
void flushAddr(Addr addr, uint8_t asn);
void
demapPage(Addr vaddr, uint64_t asn)
{
assert(asn < (1 << 8));
flushAddr(vaddr, asn);
}
// static helper functions... really EV5 VM traits
static bool
validVirtualAddress(Addr vaddr)
{
// unimplemented bits must be all 0 or all 1
Addr unimplBits = vaddr & VAddrUnImplMask;
return unimplBits == 0 || unimplBits == VAddrUnImplMask;
}
static Fault checkCacheability(RequestPtr &req, bool itb = false);
// Checkpointing
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string &section);
// Most recently used page table entries
TlbEntry *EntryCache[3];
inline void
flushCache()
{
memset(EntryCache, 0, 3 * sizeof(TlbEntry*));
}
inline TlbEntry *
updateCache(TlbEntry *entry) {
EntryCache[2] = EntryCache[1];
EntryCache[1] = EntryCache[0];
EntryCache[0] = entry;
return entry;
}
protected:
Fault translateData(RequestPtr req, ThreadContext *tc, bool write);
Fault translateInst(RequestPtr req, ThreadContext *tc);
public:
Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode);
void translateTiming(RequestPtr req, ThreadContext *tc,
Translation *translation, Mode mode);
/**
* translateFunctional stub function for future CheckerCPU support
*/
Fault translateFunctional(RequestPtr req, ThreadContext *tc, Mode mode);
};
} // namespace AlphaISA
#endif // __ARCH_ALPHA_TLB_HH__

View File

@ -0,0 +1,584 @@
/*
* Copyright (c) 2001-2005 The Regents of The University of Michigan
* 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
* Ali Saidi
*/
#include "arch/alpha/tru64/process.hh"
#include "arch/alpha/tru64/tru64.hh"
#include "arch/alpha/isa_traits.hh"
#include "cpu/thread_context.hh"
#include "kern/tru64/tru64.hh"
#include "sim/byteswap.hh"
#include "sim/process.hh"
#include "sim/syscall_emul.hh"
using namespace std;
using namespace AlphaISA;
/// Target uname() handler.
static SyscallReturn
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
int index = 0;
TypedBufferArg<AlphaTru64::utsname> name(process->getSyscallArg(tc, index));
strcpy(name->sysname, "OSF1");
strcpy(name->nodename, "m5.eecs.umich.edu");
strcpy(name->release, "V5.1");
strcpy(name->version, "732");
strcpy(name->machine, "alpha");
name.copyOut(tc->getMemProxy());
return 0;
}
/// Target getsysyinfo() handler.
static SyscallReturn
getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
int index = 0;
unsigned op = process->getSyscallArg(tc, index);
Addr bufPtr = process->getSyscallArg(tc, index);
unsigned nbytes = process->getSyscallArg(tc, index);
switch (op) {
case AlphaTru64::GSI_MAX_CPU: {
TypedBufferArg<uint32_t> max_cpu(bufPtr);
*max_cpu = htog((uint32_t)process->numCpus());
max_cpu.copyOut(tc->getMemProxy());
return 1;
}
case AlphaTru64::GSI_CPUS_IN_BOX: {
TypedBufferArg<uint32_t> cpus_in_box(bufPtr);
*cpus_in_box = htog((uint32_t)process->numCpus());
cpus_in_box.copyOut(tc->getMemProxy());
return 1;
}
case AlphaTru64::GSI_PHYSMEM: {
TypedBufferArg<uint64_t> physmem(bufPtr);
*physmem = htog((uint64_t)1024 * 1024); // physical memory in KB
physmem.copyOut(tc->getMemProxy());
return 1;
}
case AlphaTru64::GSI_CPU_INFO: {
TypedBufferArg<AlphaTru64::cpu_info> infop(bufPtr);
infop->current_cpu = htog(0);
infop->cpus_in_box = htog(process->numCpus());
infop->cpu_type = htog(57);
infop->ncpus = htog(process->numCpus());
uint64_t cpumask = (1 << process->numCpus()) - 1;
infop->cpus_present = infop->cpus_running = htog(cpumask);
infop->cpu_binding = htog(0);
infop->cpu_ex_binding = htog(0);
infop->mhz = htog(667);
infop.copyOut(tc->getMemProxy());
return 1;
}
case AlphaTru64::GSI_PROC_TYPE: {
TypedBufferArg<uint64_t> proc_type(bufPtr);
*proc_type = htog((uint64_t)11);
proc_type.copyOut(tc->getMemProxy());
return 1;
}
case AlphaTru64::GSI_PLATFORM_NAME: {
BufferArg bufArg(bufPtr, nbytes);
strncpy((char *)bufArg.bufferPtr(),
"COMPAQ Professional Workstation XP1000",
nbytes);
bufArg.copyOut(tc->getMemProxy());
return 1;
}
case AlphaTru64::GSI_CLK_TCK: {
TypedBufferArg<uint64_t> clk_hz(bufPtr);
*clk_hz = htog((uint64_t)1024);
clk_hz.copyOut(tc->getMemProxy());
return 1;
}
default:
warn("getsysinfo: unknown op %d\n", op);
break;
}
return 0;
}
/// Target setsysyinfo() handler.
static SyscallReturn
setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
int index = 0;
unsigned op = process->getSyscallArg(tc, index);
switch (op) {
case AlphaTru64::SSI_IEEE_FP_CONTROL:
warn("setsysinfo: ignoring ieee_set_fp_control() arg 0x%x\n",
process->getSyscallArg(tc, index));
break;
default:
warn("setsysinfo: unknown op %d\n", op);
break;
}
return 0;
}
/// Target table() handler.
static SyscallReturn
tableFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
using namespace std;
int argIndex = 0;
int id = process->getSyscallArg(tc, argIndex); // table ID
int index = process->getSyscallArg(tc, argIndex); // index into table
Addr bufPtr = process->getSyscallArg(tc, argIndex);
// arg 2 is buffer pointer; type depends on table ID
int nel = process->getSyscallArg(tc, argIndex); // number of elements
int lel = process->getSyscallArg(tc, argIndex); // expected element size
switch (id) {
case AlphaTru64::TBL_SYSINFO: {
if (index != 0 || nel != 1 || lel != sizeof(Tru64::tbl_sysinfo))
return -EINVAL;
TypedBufferArg<Tru64::tbl_sysinfo> elp(bufPtr);
const int clk_hz = one_million;
elp->si_user = htog(curTick() / (SimClock::Frequency / clk_hz));
elp->si_nice = htog(0);
elp->si_sys = htog(0);
elp->si_idle = htog(0);
elp->wait = htog(0);
elp->si_hz = htog(clk_hz);
elp->si_phz = htog(clk_hz);
elp->si_boottime = htog(seconds_since_epoch); // seconds since epoch?
elp->si_max_procs = htog(process->numCpus());
elp.copyOut(tc->getMemProxy());
return 0;
}
default:
cerr << "table(): id " << id << " unknown." << endl;
return -EINVAL;
}
}
SyscallDesc AlphaTru64Process::syscallDescs[] = {
/* 0 */ SyscallDesc("syscall (#0)", AlphaTru64::indirectSyscallFunc,
SyscallDesc::SuppressReturnValue),
/* 1 */ SyscallDesc("exit", exitFunc),
/* 2 */ SyscallDesc("fork", unimplementedFunc),
/* 3 */ SyscallDesc("read", readFunc),
/* 4 */ SyscallDesc("write", writeFunc),
/* 5 */ SyscallDesc("old_open", unimplementedFunc),
/* 6 */ SyscallDesc("close", closeFunc),
/* 7 */ SyscallDesc("wait4", unimplementedFunc),
/* 8 */ SyscallDesc("old_creat", unimplementedFunc),
/* 9 */ SyscallDesc("link", unimplementedFunc),
/* 10 */ SyscallDesc("unlink", unlinkFunc),
/* 11 */ SyscallDesc("execv", unimplementedFunc),
/* 12 */ SyscallDesc("chdir", unimplementedFunc),
/* 13 */ SyscallDesc("fchdir", unimplementedFunc),
/* 14 */ SyscallDesc("mknod", unimplementedFunc),
/* 15 */ SyscallDesc("chmod", unimplementedFunc),
/* 16 */ SyscallDesc("chown", unimplementedFunc),
/* 17 */ SyscallDesc("obreak", brkFunc),
/* 18 */ SyscallDesc("pre_F64_getfsstat", unimplementedFunc),
/* 19 */ SyscallDesc("lseek", lseekFunc),
/* 20 */ SyscallDesc("getpid", getpidPseudoFunc),
/* 21 */ SyscallDesc("mount", unimplementedFunc),
/* 22 */ SyscallDesc("unmount", unimplementedFunc),
/* 23 */ SyscallDesc("setuid", setuidFunc),
/* 24 */ SyscallDesc("getuid", getuidPseudoFunc),
/* 25 */ SyscallDesc("exec_with_loader", unimplementedFunc),
/* 26 */ SyscallDesc("ptrace", unimplementedFunc),
/* 27 */ SyscallDesc("recvmsg", unimplementedFunc),
/* 28 */ SyscallDesc("sendmsg", unimplementedFunc),
/* 29 */ SyscallDesc("recvfrom", unimplementedFunc),
/* 30 */ SyscallDesc("accept", unimplementedFunc),
/* 31 */ SyscallDesc("getpeername", unimplementedFunc),
/* 32 */ SyscallDesc("getsockname", unimplementedFunc),
/* 33 */ SyscallDesc("access", unimplementedFunc),
/* 34 */ SyscallDesc("chflags", unimplementedFunc),
/* 35 */ SyscallDesc("fchflags", unimplementedFunc),
/* 36 */ SyscallDesc("sync", unimplementedFunc),
/* 37 */ SyscallDesc("kill", unimplementedFunc),
/* 38 */ SyscallDesc("old_stat", unimplementedFunc),
/* 39 */ SyscallDesc("setpgid", unimplementedFunc),
/* 40 */ SyscallDesc("old_lstat", unimplementedFunc),
/* 41 */ SyscallDesc("dup", unimplementedFunc),
/* 42 */ SyscallDesc("pipe", unimplementedFunc),
/* 43 */ SyscallDesc("set_program_attributes", unimplementedFunc),
/* 44 */ SyscallDesc("profil", unimplementedFunc),
/* 45 */ SyscallDesc("open", openFunc<AlphaTru64>),
/* 46 */ SyscallDesc("obsolete osigaction", unimplementedFunc),
/* 47 */ SyscallDesc("getgid", getgidPseudoFunc),
/* 48 */ SyscallDesc("sigprocmask", ignoreFunc),
/* 49 */ SyscallDesc("getlogin", unimplementedFunc),
/* 50 */ SyscallDesc("setlogin", unimplementedFunc),
/* 51 */ SyscallDesc("acct", unimplementedFunc),
/* 52 */ SyscallDesc("sigpending", unimplementedFunc),
/* 53 */ SyscallDesc("classcntl", unimplementedFunc),
/* 54 */ SyscallDesc("ioctl", ioctlFunc<AlphaTru64>),
/* 55 */ SyscallDesc("reboot", unimplementedFunc),
/* 56 */ SyscallDesc("revoke", unimplementedFunc),
/* 57 */ SyscallDesc("symlink", unimplementedFunc),
/* 58 */ SyscallDesc("readlink", readlinkFunc),
/* 59 */ SyscallDesc("execve", unimplementedFunc),
/* 60 */ SyscallDesc("umask", umaskFunc),
/* 61 */ SyscallDesc("chroot", unimplementedFunc),
/* 62 */ SyscallDesc("old_fstat", unimplementedFunc),
/* 63 */ SyscallDesc("getpgrp", unimplementedFunc),
/* 64 */ SyscallDesc("getpagesize", getpagesizeFunc),
/* 65 */ SyscallDesc("mremap", unimplementedFunc),
/* 66 */ SyscallDesc("vfork", unimplementedFunc),
/* 67 */ SyscallDesc("pre_F64_stat", statFunc<Tru64_PreF64>),
/* 68 */ SyscallDesc("pre_F64_lstat", lstatFunc<Tru64_PreF64>),
/* 69 */ SyscallDesc("sbrk", unimplementedFunc),
/* 70 */ SyscallDesc("sstk", unimplementedFunc),
/* 71 */ SyscallDesc("mmap", mmapFunc<AlphaTru64>),
/* 72 */ SyscallDesc("ovadvise", unimplementedFunc),
/* 73 */ SyscallDesc("munmap", munmapFunc),
/* 74 */ SyscallDesc("mprotect", ignoreFunc),
/* 75 */ SyscallDesc("madvise", unimplementedFunc),
/* 76 */ SyscallDesc("old_vhangup", unimplementedFunc),
/* 77 */ SyscallDesc("kmodcall", unimplementedFunc),
/* 78 */ SyscallDesc("mincore", unimplementedFunc),
/* 79 */ SyscallDesc("getgroups", unimplementedFunc),
/* 80 */ SyscallDesc("setgroups", unimplementedFunc),
/* 81 */ SyscallDesc("old_getpgrp", unimplementedFunc),
/* 82 */ SyscallDesc("setpgrp", unimplementedFunc),
/* 83 */ SyscallDesc("setitimer", unimplementedFunc),
/* 84 */ SyscallDesc("old_wait", unimplementedFunc),
/* 85 */ SyscallDesc("table", tableFunc),
/* 86 */ SyscallDesc("getitimer", unimplementedFunc),
/* 87 */ SyscallDesc("gethostname", gethostnameFunc),
/* 88 */ SyscallDesc("sethostname", unimplementedFunc),
/* 89 */ SyscallDesc("getdtablesize", unimplementedFunc),
/* 90 */ SyscallDesc("dup2", unimplementedFunc),
/* 91 */ SyscallDesc("pre_F64_fstat", fstatFunc<Tru64_PreF64>),
/* 92 */ SyscallDesc("fcntl", fcntlFunc),
/* 93 */ SyscallDesc("select", unimplementedFunc),
/* 94 */ SyscallDesc("poll", unimplementedFunc),
/* 95 */ SyscallDesc("fsync", unimplementedFunc),
/* 96 */ SyscallDesc("setpriority", unimplementedFunc),
/* 97 */ SyscallDesc("socket", unimplementedFunc),
/* 98 */ SyscallDesc("connect", unimplementedFunc),
/* 99 */ SyscallDesc("old_accept", unimplementedFunc),
/* 100 */ SyscallDesc("getpriority", unimplementedFunc),
/* 101 */ SyscallDesc("old_send", unimplementedFunc),
/* 102 */ SyscallDesc("old_recv", unimplementedFunc),
/* 103 */ SyscallDesc("sigreturn", AlphaTru64::sigreturnFunc,
SyscallDesc::SuppressReturnValue),
/* 104 */ SyscallDesc("bind", unimplementedFunc),
/* 105 */ SyscallDesc("setsockopt", unimplementedFunc),
/* 106 */ SyscallDesc("listen", unimplementedFunc),
/* 107 */ SyscallDesc("plock", unimplementedFunc),
/* 108 */ SyscallDesc("old_sigvec", unimplementedFunc),
/* 109 */ SyscallDesc("old_sigblock", unimplementedFunc),
/* 110 */ SyscallDesc("old_sigsetmask", unimplementedFunc),
/* 111 */ SyscallDesc("sigsuspend", unimplementedFunc),
/* 112 */ SyscallDesc("sigstack", ignoreFunc),
/* 113 */ SyscallDesc("old_recvmsg", unimplementedFunc),
/* 114 */ SyscallDesc("old_sendmsg", unimplementedFunc),
/* 115 */ SyscallDesc("obsolete vtrace", unimplementedFunc),
/* 116 */ SyscallDesc("gettimeofday", gettimeofdayFunc<AlphaTru64>),
/* 117 */ SyscallDesc("getrusage", getrusageFunc<AlphaTru64>),
/* 118 */ SyscallDesc("getsockopt", unimplementedFunc),
/* 119 */ SyscallDesc("numa_syscalls", unimplementedFunc),
/* 120 */ SyscallDesc("readv", unimplementedFunc),
/* 121 */ SyscallDesc("writev", unimplementedFunc),
/* 122 */ SyscallDesc("settimeofday", unimplementedFunc),
/* 123 */ SyscallDesc("fchown", unimplementedFunc),
/* 124 */ SyscallDesc("fchmod", unimplementedFunc),
/* 125 */ SyscallDesc("old_recvfrom", unimplementedFunc),
/* 126 */ SyscallDesc("setreuid", unimplementedFunc),
/* 127 */ SyscallDesc("setregid", unimplementedFunc),
/* 128 */ SyscallDesc("rename", renameFunc),
/* 129 */ SyscallDesc("truncate", truncateFunc),
/* 130 */ SyscallDesc("ftruncate", ftruncateFunc),
/* 131 */ SyscallDesc("flock", unimplementedFunc),
/* 132 */ SyscallDesc("setgid", unimplementedFunc),
/* 133 */ SyscallDesc("sendto", unimplementedFunc),
/* 134 */ SyscallDesc("shutdown", unimplementedFunc),
/* 135 */ SyscallDesc("socketpair", unimplementedFunc),
/* 136 */ SyscallDesc("mkdir", mkdirFunc),
/* 137 */ SyscallDesc("rmdir", unimplementedFunc),
/* 138 */ SyscallDesc("utimes", unimplementedFunc),
/* 139 */ SyscallDesc("obsolete 4.2 sigreturn", unimplementedFunc),
/* 140 */ SyscallDesc("adjtime", unimplementedFunc),
/* 141 */ SyscallDesc("old_getpeername", unimplementedFunc),
/* 142 */ SyscallDesc("gethostid", unimplementedFunc),
/* 143 */ SyscallDesc("sethostid", unimplementedFunc),
/* 144 */ SyscallDesc("getrlimit", getrlimitFunc<AlphaTru64>),
/* 145 */ SyscallDesc("setrlimit", ignoreFunc),
/* 146 */ SyscallDesc("old_killpg", unimplementedFunc),
/* 147 */ SyscallDesc("setsid", unimplementedFunc),
/* 148 */ SyscallDesc("quotactl", unimplementedFunc),
/* 149 */ SyscallDesc("oldquota", unimplementedFunc),
/* 150 */ SyscallDesc("old_getsockname", unimplementedFunc),
/* 151 */ SyscallDesc("pread", unimplementedFunc),
/* 152 */ SyscallDesc("pwrite", unimplementedFunc),
/* 153 */ SyscallDesc("pid_block", unimplementedFunc),
/* 154 */ SyscallDesc("pid_unblock", unimplementedFunc),
/* 155 */ SyscallDesc("signal_urti", unimplementedFunc),
/* 156 */ SyscallDesc("sigaction", ignoreFunc),
/* 157 */ SyscallDesc("sigwaitprim", unimplementedFunc),
/* 158 */ SyscallDesc("nfssvc", unimplementedFunc),
/* 159 */ SyscallDesc("getdirentries", AlphaTru64::getdirentriesFunc),
/* 160 */ SyscallDesc("pre_F64_statfs", statfsFunc<Tru64_PreF64>),
/* 161 */ SyscallDesc("pre_F64_fstatfs", fstatfsFunc<Tru64_PreF64>),
/* 162 */ SyscallDesc("unknown #162", unimplementedFunc),
/* 163 */ SyscallDesc("async_daemon", unimplementedFunc),
/* 164 */ SyscallDesc("getfh", unimplementedFunc),
/* 165 */ SyscallDesc("getdomainname", unimplementedFunc),
/* 166 */ SyscallDesc("setdomainname", unimplementedFunc),
/* 167 */ SyscallDesc("unknown #167", unimplementedFunc),
/* 168 */ SyscallDesc("unknown #168", unimplementedFunc),
/* 169 */ SyscallDesc("exportfs", unimplementedFunc),
/* 170 */ SyscallDesc("unknown #170", unimplementedFunc),
/* 171 */ SyscallDesc("unknown #171", unimplementedFunc),
/* 172 */ SyscallDesc("unknown #172", unimplementedFunc),
/* 173 */ SyscallDesc("unknown #173", unimplementedFunc),
/* 174 */ SyscallDesc("unknown #174", unimplementedFunc),
/* 175 */ SyscallDesc("unknown #175", unimplementedFunc),
/* 176 */ SyscallDesc("unknown #176", unimplementedFunc),
/* 177 */ SyscallDesc("unknown #177", unimplementedFunc),
/* 178 */ SyscallDesc("unknown #178", unimplementedFunc),
/* 179 */ SyscallDesc("unknown #179", unimplementedFunc),
/* 180 */ SyscallDesc("unknown #180", unimplementedFunc),
/* 181 */ SyscallDesc("alt_plock", unimplementedFunc),
/* 182 */ SyscallDesc("unknown #182", unimplementedFunc),
/* 183 */ SyscallDesc("unknown #183", unimplementedFunc),
/* 184 */ SyscallDesc("getmnt", unimplementedFunc),
/* 185 */ SyscallDesc("unknown #185", unimplementedFunc),
/* 186 */ SyscallDesc("unknown #186", unimplementedFunc),
/* 187 */ SyscallDesc("alt_sigpending", unimplementedFunc),
/* 188 */ SyscallDesc("alt_setsid", unimplementedFunc),
/* 189 */ SyscallDesc("unknown #189", unimplementedFunc),
/* 190 */ SyscallDesc("unknown #190", unimplementedFunc),
/* 191 */ SyscallDesc("unknown #191", unimplementedFunc),
/* 192 */ SyscallDesc("unknown #192", unimplementedFunc),
/* 193 */ SyscallDesc("unknown #193", unimplementedFunc),
/* 194 */ SyscallDesc("unknown #194", unimplementedFunc),
/* 195 */ SyscallDesc("unknown #195", unimplementedFunc),
/* 196 */ SyscallDesc("unknown #196", unimplementedFunc),
/* 197 */ SyscallDesc("unknown #197", unimplementedFunc),
/* 198 */ SyscallDesc("unknown #198", unimplementedFunc),
/* 199 */ SyscallDesc("swapon", unimplementedFunc),
/* 200 */ SyscallDesc("msgctl", unimplementedFunc),
/* 201 */ SyscallDesc("msgget", unimplementedFunc),
/* 202 */ SyscallDesc("msgrcv", unimplementedFunc),
/* 203 */ SyscallDesc("msgsnd", unimplementedFunc),
/* 204 */ SyscallDesc("semctl", unimplementedFunc),
/* 205 */ SyscallDesc("semget", unimplementedFunc),
/* 206 */ SyscallDesc("semop", unimplementedFunc),
/* 207 */ SyscallDesc("uname", unameFunc),
/* 208 */ SyscallDesc("lchown", unimplementedFunc),
/* 209 */ SyscallDesc("shmat", unimplementedFunc),
/* 210 */ SyscallDesc("shmctl", unimplementedFunc),
/* 211 */ SyscallDesc("shmdt", unimplementedFunc),
/* 212 */ SyscallDesc("shmget", unimplementedFunc),
/* 213 */ SyscallDesc("mvalid", unimplementedFunc),
/* 214 */ SyscallDesc("getaddressconf", unimplementedFunc),
/* 215 */ SyscallDesc("msleep", unimplementedFunc),
/* 216 */ SyscallDesc("mwakeup", unimplementedFunc),
/* 217 */ SyscallDesc("msync", unimplementedFunc),
/* 218 */ SyscallDesc("signal", unimplementedFunc),
/* 219 */ SyscallDesc("utc_gettime", unimplementedFunc),
/* 220 */ SyscallDesc("utc_adjtime", unimplementedFunc),
/* 221 */ SyscallDesc("unknown #221", unimplementedFunc),
/* 222 */ SyscallDesc("security", unimplementedFunc),
/* 223 */ SyscallDesc("kloadcall", unimplementedFunc),
/* 224 */ SyscallDesc("stat", statFunc<Tru64_F64>),
/* 225 */ SyscallDesc("lstat", lstatFunc<Tru64_F64>),
/* 226 */ SyscallDesc("fstat", fstatFunc<Tru64_F64>),
/* 227 */ SyscallDesc("statfs", statfsFunc<Tru64_F64>),
/* 228 */ SyscallDesc("fstatfs", fstatfsFunc<Tru64_F64>),
/* 229 */ SyscallDesc("getfsstat", unimplementedFunc),
/* 230 */ SyscallDesc("gettimeofday64", unimplementedFunc),
/* 231 */ SyscallDesc("settimeofday64", unimplementedFunc),
/* 232 */ SyscallDesc("unknown #232", unimplementedFunc),
/* 233 */ SyscallDesc("getpgid", unimplementedFunc),
/* 234 */ SyscallDesc("getsid", unimplementedFunc),
/* 235 */ SyscallDesc("sigaltstack", ignoreFunc),
/* 236 */ SyscallDesc("waitid", unimplementedFunc),
/* 237 */ SyscallDesc("priocntlset", unimplementedFunc),
/* 238 */ SyscallDesc("sigsendset", unimplementedFunc),
/* 239 */ SyscallDesc("set_speculative", unimplementedFunc),
/* 240 */ SyscallDesc("msfs_syscall", unimplementedFunc),
/* 241 */ SyscallDesc("sysinfo", unimplementedFunc),
/* 242 */ SyscallDesc("uadmin", unimplementedFunc),
/* 243 */ SyscallDesc("fuser", unimplementedFunc),
/* 244 */ SyscallDesc("proplist_syscall", unimplementedFunc),
/* 245 */ SyscallDesc("ntp_adjtime", unimplementedFunc),
/* 246 */ SyscallDesc("ntp_gettime", unimplementedFunc),
/* 247 */ SyscallDesc("pathconf", unimplementedFunc),
/* 248 */ SyscallDesc("fpathconf", unimplementedFunc),
/* 249 */ SyscallDesc("sync2", unimplementedFunc),
/* 250 */ SyscallDesc("uswitch", unimplementedFunc),
/* 251 */ SyscallDesc("usleep_thread", unimplementedFunc),
/* 252 */ SyscallDesc("audcntl", unimplementedFunc),
/* 253 */ SyscallDesc("audgen", unimplementedFunc),
/* 254 */ SyscallDesc("sysfs", unimplementedFunc),
/* 255 */ SyscallDesc("subsys_info", unimplementedFunc),
/* 256 */ SyscallDesc("getsysinfo", getsysinfoFunc),
/* 257 */ SyscallDesc("setsysinfo", setsysinfoFunc),
/* 258 */ SyscallDesc("afs_syscall", unimplementedFunc),
/* 259 */ SyscallDesc("swapctl", unimplementedFunc),
/* 260 */ SyscallDesc("memcntl", unimplementedFunc),
/* 261 */ SyscallDesc("fdatasync", unimplementedFunc),
/* 262 */ SyscallDesc("oflock", unimplementedFunc),
/* 263 */ SyscallDesc("F64_readv", unimplementedFunc),
/* 264 */ SyscallDesc("F64_writev", unimplementedFunc),
/* 265 */ SyscallDesc("cdslxlate", unimplementedFunc),
/* 266 */ SyscallDesc("sendfile", unimplementedFunc),
};
SyscallDesc AlphaTru64Process::machSyscallDescs[] = {
/* 0 */ SyscallDesc("kern_invalid", unimplementedFunc),
/* 1 */ SyscallDesc("m5_mutex_lock", AlphaTru64::m5_mutex_lockFunc),
/* 2 */ SyscallDesc("m5_mutex_trylock", AlphaTru64::m5_mutex_trylockFunc),
/* 3 */ SyscallDesc("m5_mutex_unlock", AlphaTru64::m5_mutex_unlockFunc),
/* 4 */ SyscallDesc("m5_cond_signal", AlphaTru64::m5_cond_signalFunc),
/* 5 */ SyscallDesc("m5_cond_broadcast",
AlphaTru64::m5_cond_broadcastFunc),
/* 6 */ SyscallDesc("m5_cond_wait", AlphaTru64::m5_cond_waitFunc),
/* 7 */ SyscallDesc("m5_thread_exit", AlphaTru64::m5_thread_exitFunc),
/* 8 */ SyscallDesc("kern_invalid", unimplementedFunc),
/* 9 */ SyscallDesc("kern_invalid", unimplementedFunc),
/* 10 */ SyscallDesc("task_self", unimplementedFunc),
/* 11 */ SyscallDesc("thread_reply", unimplementedFunc),
/* 12 */ SyscallDesc("task_notify", unimplementedFunc),
/* 13 */ SyscallDesc("thread_self", unimplementedFunc),
/* 14 */ SyscallDesc("kern_invalid", unimplementedFunc),
/* 15 */ SyscallDesc("kern_invalid", unimplementedFunc),
/* 16 */ SyscallDesc("kern_invalid", unimplementedFunc),
/* 17 */ SyscallDesc("kern_invalid", unimplementedFunc),
/* 18 */ SyscallDesc("kern_invalid", unimplementedFunc),
/* 19 */ SyscallDesc("kern_invalid", unimplementedFunc),
/* 20 */ SyscallDesc("msg_send_trap", unimplementedFunc),
/* 21 */ SyscallDesc("msg_receive_trap", unimplementedFunc),
/* 22 */ SyscallDesc("msg_rpc_trap", unimplementedFunc),
/* 23 */ SyscallDesc("kern_invalid", unimplementedFunc),
/* 24 */ SyscallDesc("nxm_block", AlphaTru64::nxm_blockFunc),
/* 25 */ SyscallDesc("nxm_unblock", AlphaTru64::nxm_unblockFunc),
/* 26 */ SyscallDesc("kern_invalid", unimplementedFunc),
/* 27 */ SyscallDesc("kern_invalid", unimplementedFunc),
/* 28 */ SyscallDesc("kern_invalid", unimplementedFunc),
/* 29 */ SyscallDesc("nxm_thread_destroy", unimplementedFunc),
/* 30 */ SyscallDesc("lw_wire", unimplementedFunc),
/* 31 */ SyscallDesc("lw_unwire", unimplementedFunc),
/* 32 */ SyscallDesc("nxm_thread_create",
AlphaTru64::nxm_thread_createFunc),
/* 33 */ SyscallDesc("nxm_task_init", AlphaTru64::nxm_task_initFunc),
/* 34 */ SyscallDesc("kern_invalid", unimplementedFunc),
/* 35 */ SyscallDesc("nxm_idle", AlphaTru64::nxm_idleFunc),
/* 36 */ SyscallDesc("nxm_wakeup_idle", unimplementedFunc),
/* 37 */ SyscallDesc("nxm_set_pthid", unimplementedFunc),
/* 38 */ SyscallDesc("nxm_thread_kill", unimplementedFunc),
/* 39 */ SyscallDesc("nxm_thread_block", AlphaTru64::nxm_thread_blockFunc),
/* 40 */ SyscallDesc("nxm_thread_wakeup", unimplementedFunc),
/* 41 */ SyscallDesc("init_process", unimplementedFunc),
/* 42 */ SyscallDesc("nxm_get_binding", unimplementedFunc),
/* 43 */ SyscallDesc("map_fd", unimplementedFunc),
/* 44 */ SyscallDesc("nxm_resched", unimplementedFunc),
/* 45 */ SyscallDesc("nxm_set_cancel", unimplementedFunc),
/* 46 */ SyscallDesc("nxm_set_binding", unimplementedFunc),
/* 47 */ SyscallDesc("stack_create", AlphaTru64::stack_createFunc),
/* 48 */ SyscallDesc("nxm_get_state", unimplementedFunc),
/* 49 */ SyscallDesc("nxm_thread_suspend", unimplementedFunc),
/* 50 */ SyscallDesc("nxm_thread_resume", unimplementedFunc),
/* 51 */ SyscallDesc("nxm_signal_check", unimplementedFunc),
/* 52 */ SyscallDesc("htg_unix_syscall", unimplementedFunc),
/* 53 */ SyscallDesc("kern_invalid", unimplementedFunc),
/* 54 */ SyscallDesc("kern_invalid", unimplementedFunc),
/* 55 */ SyscallDesc("host_self", unimplementedFunc),
/* 56 */ SyscallDesc("host_priv_self", unimplementedFunc),
/* 57 */ SyscallDesc("kern_invalid", unimplementedFunc),
/* 58 */ SyscallDesc("kern_invalid", unimplementedFunc),
/* 59 */ SyscallDesc("swtch_pri", AlphaTru64::swtch_priFunc),
/* 60 */ SyscallDesc("swtch", unimplementedFunc),
/* 61 */ SyscallDesc("thread_switch", unimplementedFunc),
/* 62 */ SyscallDesc("semop_fast", unimplementedFunc),
/* 63 */ SyscallDesc("nxm_pshared_init", unimplementedFunc),
/* 64 */ SyscallDesc("nxm_pshared_block", unimplementedFunc),
/* 65 */ SyscallDesc("nxm_pshared_unblock", unimplementedFunc),
/* 66 */ SyscallDesc("nxm_pshared_destroy", unimplementedFunc),
/* 67 */ SyscallDesc("nxm_swtch_pri", AlphaTru64::swtch_priFunc),
/* 68 */ SyscallDesc("lw_syscall", unimplementedFunc),
/* 69 */ SyscallDesc("kern_invalid", unimplementedFunc),
/* 70 */ SyscallDesc("mach_sctimes_0", unimplementedFunc),
/* 71 */ SyscallDesc("mach_sctimes_1", unimplementedFunc),
/* 72 */ SyscallDesc("mach_sctimes_2", unimplementedFunc),
/* 73 */ SyscallDesc("mach_sctimes_3", unimplementedFunc),
/* 74 */ SyscallDesc("mach_sctimes_4", unimplementedFunc),
/* 75 */ SyscallDesc("mach_sctimes_5", unimplementedFunc),
/* 76 */ SyscallDesc("mach_sctimes_6", unimplementedFunc),
/* 77 */ SyscallDesc("mach_sctimes_7", unimplementedFunc),
/* 78 */ SyscallDesc("mach_sctimes_8", unimplementedFunc),
/* 79 */ SyscallDesc("mach_sctimes_9", unimplementedFunc),
/* 80 */ SyscallDesc("mach_sctimes_10", unimplementedFunc),
/* 81 */ SyscallDesc("mach_sctimes_11", unimplementedFunc),
/* 82 */ SyscallDesc("mach_sctimes_port_alloc_dealloc", unimplementedFunc)
};
SyscallDesc*
AlphaTru64Process::getDesc(int callnum)
{
if (callnum < -Num_Mach_Syscall_Descs || callnum > Num_Syscall_Descs)
return NULL;
if (callnum < 0)
return &machSyscallDescs[-callnum];
else
return &syscallDescs[callnum];
}
AlphaTru64Process::AlphaTru64Process(LiveProcessParams *params,
ObjectFile *objFile)
: AlphaLiveProcess(params, objFile),
Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc)),
Num_Mach_Syscall_Descs(sizeof(machSyscallDescs) / sizeof(SyscallDesc))
{
}

View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 2003-2004 The Regents of The University of Michigan
* 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
*/
#ifndef __ARCH_ALPHA_TRU64_PROCESS_HH__
#define __ARCH_ALPHA_TRU64_PROCESS_HH__
#include "arch/alpha/process.hh"
namespace AlphaISA {
/// A process with emulated Alpha Tru64 syscalls.
class AlphaTru64Process : public AlphaLiveProcess
{
public:
/// Constructor.
AlphaTru64Process(LiveProcessParams * params,
ObjectFile *objFile);
/// Array of syscall descriptors, indexed by call number.
static SyscallDesc syscallDescs[];
/// Array of mach syscall descriptors, indexed by call number.
static SyscallDesc machSyscallDescs[];
const int Num_Syscall_Descs;
const int Num_Mach_Syscall_Descs;
virtual SyscallDesc *getDesc(int callnum);
};
} // namespace AlphaISA
#endif // __ARCH_ALPHA_TRU64_PROCESS_HH__

View File

@ -0,0 +1,96 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* 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: Nathan Binkert
* Lisa Hsu
*/
#include "arch/alpha/tru64/system.hh"
#include "arch/isa_traits.hh"
#include "arch/vtophys.hh"
#include "base/loader/symtab.hh"
#include "base/trace.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
#include "kern/tru64/tru64_events.hh"
#include "kern/system_events.hh"
#include "mem/fs_translating_port_proxy.hh"
using namespace std;
Tru64AlphaSystem::Tru64AlphaSystem(Tru64AlphaSystem::Params *p)
: AlphaSystem(p)
{
Addr addr = 0;
if (kernelSymtab->findAddress("enable_async_printf", addr)) {
virtProxy.write(addr, (uint32_t)0);
}
#ifdef DEBUG
kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic");
if (!kernelPanicEvent)
panic("could not find kernel symbol \'panic\'");
#endif
badaddrEvent = addKernelFuncEvent<BadAddrEvent>("badaddr");
if (!badaddrEvent)
panic("could not find kernel symbol \'badaddr\'");
skipPowerStateEvent =
addKernelFuncEvent<SkipFuncEvent>("tl_v48_capture_power_state");
skipScavengeBootEvent =
addKernelFuncEvent<SkipFuncEvent>("pmap_scavenge_boot");
#if TRACING_ON
printfEvent = addKernelFuncEvent<PrintfEvent>("printf");
debugPrintfEvent = addKernelFuncEvent<DebugPrintfEvent>("m5printf");
debugPrintfrEvent = addKernelFuncEvent<DebugPrintfrEvent>("m5printfr");
dumpMbufEvent = addKernelFuncEvent<DumpMbufEvent>("m5_dump_mbuf");
#endif
}
Tru64AlphaSystem::~Tru64AlphaSystem()
{
#ifdef DEBUG
delete kernelPanicEvent;
#endif
delete badaddrEvent;
delete skipPowerStateEvent;
delete skipScavengeBootEvent;
#if TRACING_ON
delete printfEvent;
delete debugPrintfEvent;
delete debugPrintfrEvent;
delete dumpMbufEvent;
#endif
}
Tru64AlphaSystem *
Tru64AlphaSystemParams::create()
{
return new Tru64AlphaSystem(this);
}

View File

@ -0,0 +1,76 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* 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: Nathan Binkert
* Lisa Hsu
*/
#ifndef __ARCH_ALPHA_TRU64_SYSTEM_HH__
#define __ARCH_ALPHA_TRU64_SYSTEM_HH__
#include "arch/alpha/system.hh"
#include "arch/isa_traits.hh"
#include "params/Tru64AlphaSystem.hh"
#include "sim/system.hh"
class ThreadContext;
class BreakPCEvent;
class BadAddrEvent;
class SkipFuncEvent;
class PrintfEvent;
class DebugPrintfEvent;
class DebugPrintfrEvent;
class DumpMbufEvent;
class AlphaArguments;
class Tru64AlphaSystem : public AlphaSystem
{
private:
#ifdef DEBUG
/** Event to halt the simulator if the kernel calls panic() */
BreakPCEvent *kernelPanicEvent;
#endif
BadAddrEvent *badaddrEvent;
SkipFuncEvent *skipPowerStateEvent;
SkipFuncEvent *skipScavengeBootEvent;
PrintfEvent *printfEvent;
DebugPrintfEvent *debugPrintfEvent;
DebugPrintfrEvent *debugPrintfrEvent;
DumpMbufEvent *dumpMbufEvent;
public:
typedef Tru64AlphaSystemParams Params;
Tru64AlphaSystem(Params *p);
~Tru64AlphaSystem();
static void Printf(AlphaArguments args);
static void DumpMbuf(AlphaArguments args);
};
#endif // __ARCH_ALPHA_TRU64_SYSTEM_HH__

View File

@ -0,0 +1,72 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* 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: Korey Sewell
*/
#include "arch/alpha/tru64/tru64.hh"
// open(2) flags translation table
OpenFlagTransTable AlphaTru64::openFlagTable[] = {
#ifdef _MSC_VER
{ AlphaTru64::TGT_O_RDONLY, _O_RDONLY },
{ AlphaTru64::TGT_O_WRONLY, _O_WRONLY },
{ AlphaTru64::TGT_O_RDWR, _O_RDWR },
{ AlphaTru64::TGT_O_APPEND, _O_APPEND },
{ AlphaTru64::TGT_O_CREAT, _O_CREAT },
{ AlphaTru64::TGT_O_TRUNC, _O_TRUNC },
{ AlphaTru64::TGT_O_EXCL, _O_EXCL },
#ifdef _O_NONBLOCK
{ AlphaTru64::TGT_O_NONBLOCK, _O_NONBLOCK },
#endif
#ifdef _O_NOCTTY
{ AlphaTru64::TGT_O_NOCTTY, _O_NOCTTY },
#endif
#ifdef _O_SYNC
{ AlphaTru64::TGT_O_SYNC, _O_SYNC },
#endif
#else /* !_MSC_VER */
{ AlphaTru64::TGT_O_RDONLY, O_RDONLY },
{ AlphaTru64::TGT_O_WRONLY, O_WRONLY },
{ AlphaTru64::TGT_O_RDWR, O_RDWR },
{ AlphaTru64::TGT_O_APPEND, O_APPEND },
{ AlphaTru64::TGT_O_CREAT, O_CREAT },
{ AlphaTru64::TGT_O_TRUNC, O_TRUNC },
{ AlphaTru64::TGT_O_EXCL, O_EXCL },
{ AlphaTru64::TGT_O_NONBLOCK, O_NONBLOCK },
{ AlphaTru64::TGT_O_NOCTTY, O_NOCTTY },
#ifdef O_SYNC
{ AlphaTru64::TGT_O_SYNC, O_SYNC },
#endif
#endif /* _MSC_VER */
};
const int AlphaTru64::NUM_OPEN_FLAGS =
(sizeof(AlphaTru64::openFlagTable)/sizeof(AlphaTru64::openFlagTable[0]));

View File

@ -0,0 +1,128 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* 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: Korey Sewell
*/
#ifndef __ALPHA_ALPHA_TRU64_TRU64_HH__
#define __ALPHA_ALPHA_TRU64_TRU64_HH__
#include "kern/tru64/tru64.hh"
class AlphaTru64 : public Tru64
{
public:
/// This table maps the target open() flags to the corresponding
/// host open() flags.
static OpenFlagTransTable openFlagTable[];
/// Number of entries in openFlagTable[].
static const int NUM_OPEN_FLAGS;
//@{
/// open(2) flag values.
static const int TGT_O_RDONLY = 00000000; //!< O_RDONLY
static const int TGT_O_WRONLY = 00000001; //!< O_WRONLY
static const int TGT_O_RDWR = 00000002; //!< O_RDWR
static const int TGT_O_NONBLOCK = 00000004; //!< O_NONBLOCK
static const int TGT_O_APPEND = 00000010; //!< O_APPEND
static const int TGT_O_CREAT = 00001000; //!< O_CREAT
static const int TGT_O_TRUNC = 00002000; //!< O_TRUNC
static const int TGT_O_EXCL = 00004000; //!< O_EXCL
static const int TGT_O_NOCTTY = 00010000; //!< O_NOCTTY
static const int TGT_O_SYNC = 00040000; //!< O_SYNC
static const int TGT_O_DRD = 00100000; //!< O_DRD
static const int TGT_O_DIRECTIO = 00200000; //!< O_DIRECTIO
static const int TGT_O_CACHE = 00400000; //!< O_CACHE
static const int TGT_O_DSYNC = 02000000; //!< O_DSYNC
static const int TGT_O_RSYNC = 04000000; //!< O_RSYNC
//@}
/// For mmap().
static const unsigned TGT_MAP_ANONYMOUS = 0x10;
static const unsigned TGT_MAP_FIXED = 0x100;
//@{
/// For getsysinfo().
static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name string
static const unsigned GSI_CPU_INFO = 59; //!< CPU information
static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type
static const unsigned GSI_MAX_CPU = 30; //!< max # CPUs on machine
static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system
static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB
static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz
//@}
//@{
/// For getrusage().
static const int TGT_RUSAGE_THREAD = 1;
static const int TGT_RUSAGE_SELF = 0;
static const int TGT_RUSAGE_CHILDREN = -1;
//@}
//@{
/// For setsysinfo().
static const unsigned SSI_IEEE_FP_CONTROL = 14; //!< ieee_set_fp_control()
//@}
//@{
/// ioctl() command codes.
static const unsigned TIOCGETP_ = 0x40067408;
static const unsigned TIOCSETP_ = 0x80067409;
static const unsigned TIOCSETN_ = 0x8006740a;
static const unsigned TIOCSETC_ = 0x80067411;
static const unsigned TIOCGETC_ = 0x40067412;
static const unsigned FIONREAD_ = 0x4004667f;
static const unsigned TIOCISATTY_ = 0x2000745e;
static const unsigned TIOCGETS_ = 0x402c7413;
static const unsigned TIOCGETA_ = 0x40127417;
static const unsigned TCSETAW_ = 0x80147419;
//@}
//@{
/// For table().
static const int TBL_SYSINFO = 12;
//@}
/// Resource enumeration for getrlimit().
enum rlimit_resources {
TGT_RLIMIT_CPU = 0,
TGT_RLIMIT_FSIZE = 1,
TGT_RLIMIT_DATA = 2,
TGT_RLIMIT_STACK = 3,
TGT_RLIMIT_CORE = 4,
TGT_RLIMIT_RSS = 5,
TGT_RLIMIT_NOFILE = 6,
TGT_RLIMIT_AS = 7,
TGT_RLIMIT_VMEM = 7,
TGT_RLIMIT_NPROC = 8,
TGT_RLIMIT_MEMLOCK = 9,
TGT_RLIMIT_LOCKS = 10
};
};
#endif // __ALPHA_ALPHA_TRU64_TRU64_HH__

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* 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: Nathan Binkert
* Steve Reinhardt
*/
#ifndef __ARCH_ALPHA_TYPES_HH__
#define __ARCH_ALPHA_TYPES_HH__
#include "arch/generic/types.hh"
#include "base/types.hh"
namespace AlphaISA {
typedef uint32_t MachInst;
typedef uint64_t ExtMachInst;
typedef GenericISA::SimplePCState<MachInst> PCState;
typedef uint64_t LargestRead;
enum annotes
{
ANNOTE_NONE = 0,
// An impossible number for instruction annotations
ITOUCH_ANNOTE = 0xffffffff
};
} // namespace AlphaISA
#endif // __ARCH_ALPHA_TYPES_HH__

View File

@ -0,0 +1,106 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* 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: Nathan Binkert
* Ali Saidi
*/
#include "arch/alpha/utility.hh"
#include "arch/alpha/vtophys.hh"
#include "mem/fs_translating_port_proxy.hh"
#include "sim/full_system.hh"
namespace AlphaISA {
uint64_t
getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
{
if (!FullSystem) {
panic("getArgument() is Full system only\n");
M5_DUMMY_RETURN;
}
const int NumArgumentRegs = 6;
if (number < NumArgumentRegs) {
if (fp)
return tc->readFloatRegBits(16 + number);
else
return tc->readIntReg(16 + number);
} else {
Addr sp = tc->readIntReg(StackPointerReg);
FSTranslatingPortProxy &vp = tc->getVirtProxy();
uint64_t arg = vp.read<uint64_t>(sp +
(number-NumArgumentRegs) *
sizeof(uint64_t));
return arg;
}
}
void
copyRegs(ThreadContext *src, ThreadContext *dest)
{
// First loop through the integer registers.
for (int i = 0; i < NumIntRegs; ++i)
dest->setIntReg(i, src->readIntReg(i));
// Then loop through the floating point registers.
for (int i = 0; i < NumFloatRegs; ++i)
dest->setFloatRegBits(i, src->readFloatRegBits(i));
// Copy misc. registers
copyMiscRegs(src, dest);
// Lastly copy PC/NPC
dest->pcState(src->pcState());
}
void
copyMiscRegs(ThreadContext *src, ThreadContext *dest)
{
dest->setMiscRegNoEffect(MISCREG_FPCR,
src->readMiscRegNoEffect(MISCREG_FPCR));
dest->setMiscRegNoEffect(MISCREG_UNIQ,
src->readMiscRegNoEffect(MISCREG_UNIQ));
dest->setMiscRegNoEffect(MISCREG_LOCKFLAG,
src->readMiscRegNoEffect(MISCREG_LOCKFLAG));
dest->setMiscRegNoEffect(MISCREG_LOCKADDR,
src->readMiscRegNoEffect(MISCREG_LOCKADDR));
copyIprs(src, dest);
}
void
skipFunction(ThreadContext *tc)
{
TheISA::PCState newPC = tc->pcState();
newPC.set(tc->readIntReg(ReturnAddressReg));
tc->pcState(newPC);
}
} // namespace AlphaISA

View File

@ -0,0 +1,120 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* 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: Nathan Binkert
* Steve Reinhardt
*/
#ifndef __ARCH_ALPHA_UTILITY_HH__
#define __ARCH_ALPHA_UTILITY_HH__
#include "arch/alpha/isa_traits.hh"
#include "arch/alpha/registers.hh"
#include "arch/alpha/types.hh"
#include "base/misc.hh"
#include "cpu/static_inst.hh"
#include "cpu/thread_context.hh"
#include "arch/alpha/ev5.hh"
namespace AlphaISA {
inline PCState
buildRetPC(const PCState &curPC, const PCState &callPC)
{
PCState retPC = callPC;
retPC.advance();
return retPC;
}
uint64_t getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp);
inline bool
inUserMode(ThreadContext *tc)
{
return (tc->readMiscRegNoEffect(IPR_DTB_CM) & 0x18) != 0;
}
/**
* Function to insure ISA semantics about 0 registers.
* @param tc The thread context.
*/
template <class TC>
void zeroRegisters(TC *tc);
// Alpha IPR register accessors
inline bool PcPAL(Addr addr) { return addr & 0x3; }
inline void startupCPU(ThreadContext *tc, int cpuId) { tc->activate(0); }
////////////////////////////////////////////////////////////////////////
//
// Translation stuff
//
inline Addr PteAddr(Addr a) { return (a & PteMask) << PteShift; }
// User Virtual
inline bool IsUSeg(Addr a) { return USegBase <= a && a <= USegEnd; }
// Kernel Direct Mapped
inline bool IsK0Seg(Addr a) { return K0SegBase <= a && a <= K0SegEnd; }
inline Addr K0Seg2Phys(Addr addr) { return addr & ~K0SegBase; }
// Kernel Virtual
inline bool IsK1Seg(Addr a) { return K1SegBase <= a && a <= K1SegEnd; }
inline Addr
TruncPage(Addr addr)
{ return addr & ~(PageBytes - 1); }
inline Addr
RoundPage(Addr addr)
{ return (addr + PageBytes - 1) & ~(PageBytes - 1); }
void initIPRs(ThreadContext *tc, int cpuId);
void initCPU(ThreadContext *tc, int cpuId);
void copyRegs(ThreadContext *src, ThreadContext *dest);
void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
void skipFunction(ThreadContext *tc);
inline void
advancePC(PCState &pc, const StaticInstPtr inst)
{
pc.advance();
}
inline uint64_t
getExecutingAsid(ThreadContext *tc)
{
return DTB_ASN_ASN(tc->readMiscRegNoEffect(IPR_DTB_ASN));
}
} // namespace AlphaISA
#endif // __ARCH_ALPHA_UTILITY_HH__

View File

@ -0,0 +1,118 @@
/*
* Copyright (c) 2002-2005 The Regents of The University of Michigan
* 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: Nathan Binkert
* Steve Reinhardt
* Ali Saidi
*/
#include <string>
#include "arch/alpha/ev5.hh"
#include "arch/alpha/vtophys.hh"
#include "base/chunk_generator.hh"
#include "base/trace.hh"
#include "cpu/thread_context.hh"
#include "debug/VtoPhys.hh"
#include "mem/port_proxy.hh"
using namespace std;
namespace AlphaISA {
PageTableEntry
kernel_pte_lookup(PortProxy &mem, Addr ptbr, VAddr vaddr)
{
Addr level1_pte = ptbr + vaddr.level1();
PageTableEntry level1 = mem.read<uint64_t>(level1_pte);
if (!level1.valid()) {
DPRINTF(VtoPhys, "level 1 PTE not valid, va = %#\n", vaddr);
return 0;
}
Addr level2_pte = level1.paddr() + vaddr.level2();
PageTableEntry level2 = mem.read<uint64_t>(level2_pte);
if (!level2.valid()) {
DPRINTF(VtoPhys, "level 2 PTE not valid, va = %#x\n", vaddr);
return 0;
}
Addr level3_pte = level2.paddr() + vaddr.level3();
PageTableEntry level3 = mem.read<uint64_t>(level3_pte);
if (!level3.valid()) {
DPRINTF(VtoPhys, "level 3 PTE not valid, va = %#x\n", vaddr);
return 0;
}
return level3;
}
Addr
vtophys(Addr vaddr)
{
Addr paddr = 0;
if (IsUSeg(vaddr))
DPRINTF(VtoPhys, "vtophys: invalid vaddr %#x", vaddr);
else if (IsK0Seg(vaddr))
paddr = K0Seg2Phys(vaddr);
else
panic("vtophys: ptbr is not set on virtual lookup");
DPRINTF(VtoPhys, "vtophys(%#x) -> %#x\n", vaddr, paddr);
return paddr;
}
Addr
vtophys(ThreadContext *tc, Addr addr)
{
VAddr vaddr = addr;
Addr ptbr = tc->readMiscRegNoEffect(IPR_PALtemp20);
Addr paddr = 0;
//@todo Andrew couldn't remember why he commented some of this code
//so I put it back in. Perhaps something to do with gdb debugging?
if (PcPAL(vaddr) && (vaddr < PalMax)) {
paddr = vaddr & ~ULL(1);
} else {
if (IsK0Seg(vaddr)) {
paddr = K0Seg2Phys(vaddr);
} else if (!ptbr) {
paddr = vaddr;
} else {
PageTableEntry pte =
kernel_pte_lookup(tc->getPhysProxy(), ptbr, vaddr);
if (pte.valid())
paddr = pte.paddr() | vaddr.offset();
}
}
DPRINTF(VtoPhys, "vtophys(%#x) -> %#x\n", vaddr, paddr);
return paddr;
}
} // namespace AlphaISA

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2002-2005 The Regents of The University of Michigan
* 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: Nathan Binkert
* Steve Reinhardt
*/
#ifndef __ARCH_ALPHA_VTOPHYS_H__
#define __ARCH_ALPHA_VTOPHYS_H__
#include "arch/alpha/isa_traits.hh"
#include "arch/alpha/pagetable.hh"
#include "arch/alpha/utility.hh"
class ThreadContext;
class PortProxy;
namespace AlphaISA {
PageTableEntry kernel_pte_lookup(PortProxy &mem, Addr ptbr,
VAddr vaddr);
Addr vtophys(Addr vaddr);
Addr vtophys(ThreadContext *tc, Addr vaddr);
} // namespace AlphaISA
#endif // __ARCH_ALPHA_VTOPHYS_H__

View File

@ -0,0 +1,33 @@
# Copyright (c) 2009 ARM Limited
# 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: Ali Saidi
from m5.SimObject import SimObject
class ArmInterrupts(SimObject):
type = 'ArmInterrupts'
cxx_class = 'ArmISA::Interrupts'

View File

@ -0,0 +1,37 @@
# Copyright (c) 2009 The Regents of The University of Michigan
# 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: Gabe Black
from m5.SimObject import SimObject
from m5.params import *
from NativeTrace import NativeTrace
class ArmNativeTrace(NativeTrace):
type = 'ArmNativeTrace'
cxx_class = 'Trace::ArmNativeTrace'
stop_on_pc_error = Param.Bool(True,
"Stop M5 if it and statetrace's pcs are different")

View File

@ -0,0 +1,69 @@
# Copyright (c) 2009 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: Ali Saidi
from m5.params import *
from System import System
class ArmMachineType(Enum):
map = {'RealView_EB' : 827,
'RealView_PBX' : 1901,
'VExpress_ELT' : 2272,
'VExpress_CA9' : 2272,
'VExpress_EMM' : 2272}
class ArmSystem(System):
type = 'ArmSystem'
load_addr_mask = 0xffffffff
# 0x35 Implementor is '5' from "M5"
# 0x0 Variant
# 0xf Architecture from CPUID scheme
# 0xc00 Primary part number ("c" or higher implies ARM v7)
# 0x0 Revision
midr_regval = Param.UInt32(0x350fc000, "MIDR value")
multi_proc = Param.Bool(True, "Multiprocessor system?")
boot_loader = Param.String("", "File that contains the boot loader code if any")
gic_cpu_addr = Param.Addr(0, "Addres of the GIC CPU interface")
flags_addr = Param.Addr(0, "Address of the flags register for MP booting")
class LinuxArmSystem(ArmSystem):
type = 'LinuxArmSystem'
load_addr_mask = 0x0fffffff
machine_type = Param.ArmMachineType('RealView_PBX',
"Machine id from http://www.arm.linux.org.uk/developer/machines/")
atags_addr = Param.Addr(0x100, "Address where default atags structure should be written")
early_kernel_symbols = Param.Bool(False, "enable early kernel symbol tables before MMU")

View File

@ -0,0 +1,58 @@
# -*- mode:python -*-
# Copyright (c) 2009 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: Ali Saidi
from m5.SimObject import SimObject
from m5.params import *
from m5.proxy import *
from MemObject import MemObject
class ArmTableWalker(MemObject):
type = 'ArmTableWalker'
cxx_class = 'ArmISA::TableWalker'
port = MasterPort("Port for TableWalker to do walk the translation with")
sys = Param.System(Parent.any, "system object parameter")
min_backoff = Param.Tick(0, "Minimum backoff delay after failed send")
max_backoff = Param.Tick(100000, "Minimum backoff delay after failed send")
class ArmTLB(SimObject):
type = 'ArmTLB'
cxx_class = 'ArmISA::TLB'
size = Param.Int(64, "TLB size")
walker = Param.ArmTableWalker(ArmTableWalker(), "HW Table walker")

View File

@ -0,0 +1,90 @@
# -*- mode:python -*-
# Copyright (c) 2009 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.
#
# Copyright (c) 2007-2008 The Florida State University
# 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: Stephen Hines
# Ali Saidi
Import('*')
if env['TARGET_ISA'] == 'arm':
# Workaround for bug in SCons version > 0.97d20071212
# Scons bug id: 2006 M5 Bug id: 308
Dir('isa/formats')
Source('decoder.cc')
Source('faults.cc')
Source('insts/macromem.cc')
Source('insts/mem.cc')
Source('insts/misc.cc')
Source('insts/pred_inst.cc')
Source('insts/static_inst.cc')
Source('insts/vfp.cc')
Source('interrupts.cc')
Source('isa.cc')
Source('linux/linux.cc')
Source('linux/process.cc')
Source('linux/system.cc')
Source('miscregs.cc')
Source('nativetrace.cc')
Source('process.cc')
Source('remote_gdb.cc')
Source('stacktrace.cc')
Source('system.cc')
Source('table_walker.cc')
Source('tlb.cc')
Source('utility.cc')
Source('vtophys.cc')
SimObject('ArmInterrupts.py')
SimObject('ArmNativeTrace.py')
SimObject('ArmSystem.py')
SimObject('ArmTLB.py')
DebugFlag('Arm')
DebugFlag('Decoder', "Instructions returned by the predecoder")
DebugFlag('Faults', "Trace Exceptions, interrupts, svc/swi")
DebugFlag('TLBVerbose')
# Add in files generated by the ISA description.
isa_desc_files = env.ISADesc('isa/main.isa')
# Only non-header files need to be compiled.
for f in isa_desc_files:
if not f.path.endswith('.hh'):
Source(f)

View File

@ -0,0 +1,33 @@
# -*- mode:python -*-
# Copyright (c) 2007-2008 The Florida State University
# 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: Stephen Hines
Import('*')
all_isa_list.append('arm')

View File

@ -0,0 +1,124 @@
/*
* Copyright (c) 2012 Google
* 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: Gabe Black
*/
#include "arch/arm/decoder.hh"
#include "arch/arm/isa_traits.hh"
#include "arch/arm/utility.hh"
#include "base/trace.hh"
#include "cpu/thread_context.hh"
#include "debug/Decoder.hh"
namespace ArmISA
{
GenericISA::BasicDecodeCache Decoder::defaultCache;
void
Decoder::process()
{
// emi is typically ready, with some caveats below...
instDone = true;
if (!emi.thumb) {
emi.instBits = data;
emi.sevenAndFour = bits(data, 7) && bits(data, 4);
emi.isMisc = (bits(data, 24, 23) == 0x2 &&
bits(data, 20) == 0);
consumeBytes(4);
DPRINTF(Decoder, "Arm inst: %#x.\n", (uint64_t)emi);
} else {
uint16_t word = (data >> (offset * 8));
if (bigThumb) {
// A 32 bit thumb inst is half collected.
emi.instBits = emi.instBits | word;
bigThumb = false;
consumeBytes(2);
DPRINTF(Decoder, "Second half of 32 bit Thumb: %#x.\n",
emi.instBits);
} else {
uint16_t highBits = word & 0xF800;
if (highBits == 0xE800 || highBits == 0xF000 ||
highBits == 0xF800) {
// The start of a 32 bit thumb inst.
emi.bigThumb = 1;
if (offset == 0) {
// We've got the whole thing.
emi.instBits = (data >> 16) | (data << 16);
DPRINTF(Decoder, "All of 32 bit Thumb: %#x.\n",
emi.instBits);
consumeBytes(4);
} else {
// We only have the first half word.
DPRINTF(Decoder,
"First half of 32 bit Thumb.\n");
emi.instBits = (uint32_t)word << 16;
bigThumb = true;
consumeBytes(2);
// emi not ready yet.
instDone = false;
}
} else {
// A 16 bit thumb inst.
consumeBytes(2);
emi.instBits = word;
// Set the condition code field artificially.
emi.condCode = COND_UC;
DPRINTF(Decoder, "16 bit Thumb: %#x.\n",
emi.instBits);
if (bits(word, 15, 8) == 0xbf &&
bits(word, 3, 0) != 0x0) {
foundIt = true;
itBits = bits(word, 7, 0);
DPRINTF(Decoder,
"IT detected, cond = %#x, mask = %#x\n",
itBits.cond, itBits.mask);
}
}
}
}
}
//Use this to give data to the decoder. This should be used
//when there is control flow.
void
Decoder::moreBytes(const PCState &pc, Addr fetchPC, MachInst inst)
{
data = inst;
offset = (fetchPC >= pc.instAddr()) ? 0 : pc.instAddr() - fetchPC;
emi.thumb = pc.thumb();
FPSCR fpscr = tc->readMiscReg(MISCREG_FPSCR);
emi.fpscrLen = fpscr.len;
emi.fpscrStride = fpscr.stride;
outOfBytes = false;
process();
}
}

View File

@ -0,0 +1,162 @@
/*
* Copyright (c) 2012 Google
* 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: Gabe Black
*/
#ifndef __ARCH_ARM_DECODER_HH__
#define __ARCH_ARM_DECODER_HH__
#include <cassert>
#include "arch/arm/miscregs.hh"
#include "arch/arm/types.hh"
#include "arch/generic/decode_cache.hh"
#include "base/types.hh"
#include "cpu/static_inst.hh"
class ThreadContext;
namespace ArmISA
{
class Decoder
{
protected:
ThreadContext * tc;
//The extended machine instruction being generated
ExtMachInst emi;
MachInst data;
bool bigThumb;
bool instDone;
bool outOfBytes;
int offset;
bool foundIt;
ITSTATE itBits;
public:
void reset()
{
bigThumb = false;
offset = 0;
emi = 0;
instDone = false;
outOfBytes = true;
foundIt = false;
}
Decoder(ThreadContext * _tc) : tc(_tc), data(0)
{
reset();
}
ThreadContext * getTC()
{
return tc;
}
void
setTC(ThreadContext * _tc)
{
tc = _tc;
}
void process();
//Use this to give data to the decoder. This should be used
//when there is control flow.
void moreBytes(const PCState &pc, Addr fetchPC, MachInst inst);
//Use this to give data to the decoder. This should be used
//when instructions are executed in order.
void moreBytes(MachInst machInst)
{
moreBytes(0, 0, machInst);
}
inline void consumeBytes(int numBytes)
{
offset += numBytes;
assert(offset <= sizeof(MachInst));
if (offset == sizeof(MachInst))
outOfBytes = true;
}
bool needMoreBytes() const
{
return outOfBytes;
}
bool instReady() const
{
return instDone;
}
int getInstSize() const
{
return (!emi.thumb || emi.bigThumb) ? 4 : 2;
}
protected:
/// A cache of decoded instruction objects.
static GenericISA::BasicDecodeCache defaultCache;
public:
StaticInstPtr decodeInst(ExtMachInst mach_inst);
/// Decode a machine instruction.
/// @param mach_inst The binary instruction to decode.
/// @retval A pointer to the corresponding StaticInst object.
StaticInstPtr
decode(ExtMachInst mach_inst, Addr addr)
{
return defaultCache.decode(this, mach_inst, addr);
}
StaticInstPtr
decode(ArmISA::PCState &nextPC)
{
if (!instDone)
return NULL;
assert(instDone);
ExtMachInst thisEmi = emi;
nextPC.npc(nextPC.pc() + getInstSize());
if (foundIt)
nextPC.nextItstate(itBits);
thisEmi.itstate = nextPC.itstate();
nextPC.size(getInstSize());
emi = 0;
instDone = false;
foundIt = false;
return decode(thisEmi, nextPC.instAddr());
}
};
} // namespace ArmISA
#endif // __ARCH_ARM_DECODER_HH__

View File

@ -0,0 +1,269 @@
/*
* 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.
*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* Copyright (c) 2007-2008 The Florida State University
* 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: Ali Saidi
* Gabe Black
*/
#include "arch/arm/faults.hh"
#include "base/trace.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
#include "debug/Faults.hh"
#include "sim/full_system.hh"
namespace ArmISA
{
template<> ArmFault::FaultVals ArmFaultVals<Reset>::vals =
{"reset", 0x00, MODE_SVC, 0, 0, true, true};
template<> ArmFault::FaultVals ArmFaultVals<UndefinedInstruction>::vals =
{"Undefined Instruction", 0x04, MODE_UNDEFINED, 4 ,2, false, false} ;
template<> ArmFault::FaultVals ArmFaultVals<SupervisorCall>::vals =
{"Supervisor Call", 0x08, MODE_SVC, 4, 2, false, false};
template<> ArmFault::FaultVals ArmFaultVals<PrefetchAbort>::vals =
{"Prefetch Abort", 0x0C, MODE_ABORT, 4, 4, true, false};
template<> ArmFault::FaultVals ArmFaultVals<DataAbort>::vals =
{"Data Abort", 0x10, MODE_ABORT, 8, 8, true, false};
template<> ArmFault::FaultVals ArmFaultVals<Interrupt>::vals =
{"IRQ", 0x18, MODE_IRQ, 4, 4, true, false};
template<> ArmFault::FaultVals ArmFaultVals<FastInterrupt>::vals =
{"FIQ", 0x1C, MODE_FIQ, 4, 4, true, true};
template<> ArmFault::FaultVals ArmFaultVals<FlushPipe>::vals =
{"Pipe Flush", 0x00, MODE_SVC, 0, 0, true, true}; // some dummy values
template<> ArmFault::FaultVals ArmFaultVals<ArmSev>::vals =
{"ArmSev Flush", 0x00, MODE_SVC, 0, 0, true, true}; // some dummy values
Addr
ArmFault::getVector(ThreadContext *tc)
{
// ARM ARM B1-3
SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR);
// panic if SCTLR.VE because I have no idea what to do with vectored
// interrupts
assert(!sctlr.ve);
if (!sctlr.v)
return offset();
return offset() + HighVecs;
}
void
ArmFault::invoke(ThreadContext *tc, StaticInstPtr inst)
{
// ARM ARM B1.6.3
FaultBase::invoke(tc);
if (!FullSystem)
return;
countStat()++;
SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR);
CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
CPSR saved_cpsr = tc->readMiscReg(MISCREG_CPSR);
saved_cpsr.nz = tc->readIntReg(INTREG_CONDCODES_NZ);
saved_cpsr.c = tc->readIntReg(INTREG_CONDCODES_C);
saved_cpsr.v = tc->readIntReg(INTREG_CONDCODES_V);
saved_cpsr.ge = tc->readIntReg(INTREG_CONDCODES_GE);
Addr curPc M5_VAR_USED = tc->pcState().pc();
ITSTATE it = tc->pcState().itstate();
saved_cpsr.it2 = it.top6;
saved_cpsr.it1 = it.bottom2;
cpsr.mode = nextMode();
cpsr.it1 = cpsr.it2 = 0;
cpsr.j = 0;
cpsr.t = sctlr.te;
cpsr.a = cpsr.a | abortDisable();
cpsr.f = cpsr.f | fiqDisable();
cpsr.i = 1;
cpsr.e = sctlr.ee;
tc->setMiscReg(MISCREG_CPSR, cpsr);
// Make sure mailbox sets to one always
tc->setMiscReg(MISCREG_SEV_MAILBOX, 1);
tc->setIntReg(INTREG_LR, curPc +
(saved_cpsr.t ? thumbPcOffset() : armPcOffset()));
switch (nextMode()) {
case MODE_FIQ:
tc->setMiscReg(MISCREG_SPSR_FIQ, saved_cpsr);
break;
case MODE_IRQ:
tc->setMiscReg(MISCREG_SPSR_IRQ, saved_cpsr);
break;
case MODE_SVC:
tc->setMiscReg(MISCREG_SPSR_SVC, saved_cpsr);
break;
case MODE_UNDEFINED:
tc->setMiscReg(MISCREG_SPSR_UND, saved_cpsr);
break;
case MODE_ABORT:
tc->setMiscReg(MISCREG_SPSR_ABT, saved_cpsr);
break;
default:
panic("unknown Mode\n");
}
Addr newPc = getVector(tc);
DPRINTF(Faults, "Invoking Fault:%s cpsr:%#x PC:%#x lr:%#x newVec: %#x\n",
name(), cpsr, curPc, tc->readIntReg(INTREG_LR), newPc);
PCState pc(newPc);
pc.thumb(cpsr.t);
pc.nextThumb(pc.thumb());
pc.jazelle(cpsr.j);
pc.nextJazelle(pc.jazelle());
tc->pcState(pc);
}
void
Reset::invoke(ThreadContext *tc, StaticInstPtr inst)
{
if (FullSystem) {
tc->getCpuPtr()->clearInterrupts();
tc->clearArchRegs();
}
ArmFault::invoke(tc, inst);
}
void
UndefinedInstruction::invoke(ThreadContext *tc, StaticInstPtr inst)
{
if (FullSystem) {
ArmFault::invoke(tc, inst);
return;
}
// If the mnemonic isn't defined this has to be an unknown instruction.
assert(unknown || mnemonic != NULL);
if (disabled) {
panic("Attempted to execute disabled instruction "
"'%s' (inst 0x%08x)", mnemonic, machInst);
} else if (unknown) {
panic("Attempted to execute unknown instruction (inst 0x%08x)",
machInst);
} else {
panic("Attempted to execute unimplemented instruction "
"'%s' (inst 0x%08x)", mnemonic, machInst);
}
}
void
SupervisorCall::invoke(ThreadContext *tc, StaticInstPtr inst)
{
if (FullSystem) {
ArmFault::invoke(tc, inst);
return;
}
// As of now, there isn't a 32 bit thumb version of this instruction.
assert(!machInst.bigThumb);
uint32_t callNum;
callNum = tc->readIntReg(INTREG_R7);
tc->syscall(callNum);
// Advance the PC since that won't happen automatically.
PCState pc = tc->pcState();
assert(inst);
inst->advancePC(pc);
tc->pcState(pc);
}
template<class T>
void
AbortFault<T>::invoke(ThreadContext *tc, StaticInstPtr inst)
{
ArmFaultVals<T>::invoke(tc, inst);
FSR fsr = 0;
fsr.fsLow = bits(status, 3, 0);
fsr.fsHigh = bits(status, 4);
fsr.domain = domain;
fsr.wnr = (write ? 1 : 0);
fsr.ext = 0;
tc->setMiscReg(T::FsrIndex, fsr);
tc->setMiscReg(T::FarIndex, faultAddr);
DPRINTF(Faults, "Abort Fault fsr=%#x faultAddr=%#x\n", fsr, faultAddr);
}
void
FlushPipe::invoke(ThreadContext *tc, StaticInstPtr inst) {
DPRINTF(Faults, "Invoking FlushPipe Fault\n");
// Set the PC to the next instruction of the faulting instruction.
// Net effect is simply squashing all instructions behind and
// start refetching from the next instruction.
PCState pc = tc->pcState();
assert(inst);
inst->advancePC(pc);
tc->pcState(pc);
}
template void AbortFault<PrefetchAbort>::invoke(ThreadContext *tc,
StaticInstPtr inst);
template void AbortFault<DataAbort>::invoke(ThreadContext *tc,
StaticInstPtr inst);
void
ArmSev::invoke(ThreadContext *tc, StaticInstPtr inst) {
DPRINTF(Faults, "Invoking ArmSev Fault\n");
if (!FullSystem)
return;
// Set sev_mailbox to 1, clear the pending interrupt from remote
// SEV execution and let pipeline continue as pcState is still
// valid.
tc->setMiscReg(MISCREG_SEV_MAILBOX, 1);
tc->getCpuPtr()->clearInterrupt(INT_SEV, 0);
}
// return via SUBS pc, lr, xxx; rfe, movs, ldm
} // namespace ArmISA

View File

@ -0,0 +1,251 @@
/*
* 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.
*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* Copyright (c) 2007-2008 The Florida State University
* 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: Ali Saidi
* Gabe Black
*/
#ifndef __ARM_FAULTS_HH__
#define __ARM_FAULTS_HH__
#include "arch/arm/miscregs.hh"
#include "arch/arm/types.hh"
#include "base/misc.hh"
#include "sim/faults.hh"
#include "sim/full_system.hh"
// The design of the "name" and "vect" functions is in sim/faults.hh
namespace ArmISA
{
typedef const Addr FaultOffset;
class ArmFault : public FaultBase
{
protected:
Addr getVector(ThreadContext *tc);
public:
enum StatusEncoding
{
// Fault Status register encodings
// ARM ARM B3.9.4
AlignmentFault = 0x1,
DebugEvent = 0x2,
AccessFlag0 = 0x3,
InstructionCacheMaintenance = 0x4,
Translation0 = 0x5,
AccessFlag1 = 0x6,
Translation1 = 0x7,
SynchronousExternalAbort0 = 0x8,
Domain0 = 0x9,
SynchronousExternalAbort1 = 0x8,
Domain1 = 0xb,
TranslationTableWalkExtAbt0 = 0xc,
Permission0 = 0xd,
TranslationTableWalkExtAbt1 = 0xe,
Permission1 = 0xf,
AsynchronousExternalAbort = 0x16,
MemoryAccessAsynchronousParityError = 0x18,
MemoryAccessSynchronousParityError = 0x19,
TranslationTableWalkPrtyErr0 = 0x1c,
TranslationTableWalkPrtyErr1 = 0x1e,
// not a real fault. This is a status code
// to allow the translation function to inform
// the memory access function not to proceed
// for a Prefetch that misses in the TLB.
PrefetchTLBMiss = 0x1f,
PrefetchUncacheable = 0x20
};
struct FaultVals
{
const FaultName name;
const FaultOffset offset;
const OperatingMode nextMode;
const uint8_t armPcOffset;
const uint8_t thumbPcOffset;
const bool abortDisable;
const bool fiqDisable;
FaultStat count;
};
void invoke(ThreadContext *tc,
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
virtual FaultStat& countStat() = 0;
virtual FaultOffset offset() = 0;
virtual OperatingMode nextMode() = 0;
virtual uint8_t armPcOffset() = 0;
virtual uint8_t thumbPcOffset() = 0;
virtual bool abortDisable() = 0;
virtual bool fiqDisable() = 0;
};
template<typename T>
class ArmFaultVals : public ArmFault
{
protected:
static FaultVals vals;
public:
FaultName name() const { return vals.name; }
FaultStat & countStat() {return vals.count;}
FaultOffset offset() { return vals.offset; }
OperatingMode nextMode() { return vals.nextMode; }
uint8_t armPcOffset() { return vals.armPcOffset; }
uint8_t thumbPcOffset() { return vals.thumbPcOffset; }
bool abortDisable() { return vals.abortDisable; }
bool fiqDisable() { return vals.fiqDisable; }
};
class Reset : public ArmFaultVals<Reset>
{
public:
void invoke(ThreadContext *tc,
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
};
class UndefinedInstruction : public ArmFaultVals<UndefinedInstruction>
{
protected:
ExtMachInst machInst;
bool unknown;
const char *mnemonic;
bool disabled;
public:
UndefinedInstruction(ExtMachInst _machInst,
bool _unknown,
const char *_mnemonic = NULL,
bool _disabled = false) :
machInst(_machInst), unknown(_unknown),
mnemonic(_mnemonic), disabled(_disabled)
{
}
UndefinedInstruction() :
machInst(0), unknown(false), mnemonic("undefined"), disabled(false)
{}
void invoke(ThreadContext *tc,
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
};
class SupervisorCall : public ArmFaultVals<SupervisorCall>
{
protected:
ExtMachInst machInst;
public:
SupervisorCall(ExtMachInst _machInst) : machInst(_machInst)
{}
SupervisorCall() : machInst(0)
{}
void invoke(ThreadContext *tc,
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
};
template <class T>
class AbortFault : public ArmFaultVals<T>
{
protected:
Addr faultAddr;
bool write;
uint8_t domain;
uint8_t status;
public:
AbortFault(Addr _faultAddr, bool _write,
uint8_t _domain, uint8_t _status) :
faultAddr(_faultAddr), write(_write),
domain(_domain), status(_status)
{}
void invoke(ThreadContext *tc,
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
};
class PrefetchAbort : public AbortFault<PrefetchAbort>
{
public:
static const MiscRegIndex FsrIndex = MISCREG_IFSR;
static const MiscRegIndex FarIndex = MISCREG_IFAR;
PrefetchAbort(Addr _addr, uint8_t _status) :
AbortFault<PrefetchAbort>(_addr, false, 0, _status)
{}
};
class DataAbort : public AbortFault<DataAbort>
{
public:
static const MiscRegIndex FsrIndex = MISCREG_DFSR;
static const MiscRegIndex FarIndex = MISCREG_DFAR;
DataAbort(Addr _addr, uint8_t _domain, bool _write, uint8_t _status) :
AbortFault<DataAbort>(_addr, _write, _domain, _status)
{}
};
class Interrupt : public ArmFaultVals<Interrupt> {};
class FastInterrupt : public ArmFaultVals<FastInterrupt> {};
// A fault that flushes the pipe, excluding the faulting instructions
class FlushPipe : public ArmFaultVals<FlushPipe>
{
public:
FlushPipe() {}
void invoke(ThreadContext *tc,
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
};
// A fault that flushes the pipe, excluding the faulting instructions
class ArmSev : public ArmFaultVals<ArmSev>
{
public:
ArmSev () {}
void invoke(ThreadContext *tc,
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
};
} // namespace ArmISA
#endif // __ARM_FAULTS_HH__

View File

@ -0,0 +1,134 @@
/*
* 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.
*
* Copyright (c) 2007-2008 The Florida State University
* 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: Stephen Hines
*/
#ifndef __ARCH_ARM_INSTS_BRANCH_HH__
#define __ARCH_ARM_INSTS_BRANCH_HH__
#include "arch/arm/insts/pred_inst.hh"
namespace ArmISA
{
// Branch to a target computed with an immediate
class BranchImm : public PredOp
{
protected:
int32_t imm;
public:
BranchImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
int32_t _imm) :
PredOp(mnem, _machInst, __opClass), imm(_imm)
{}
};
// Conditionally Branch to a target computed with an immediate
class BranchImmCond : public BranchImm
{
public:
BranchImmCond(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
int32_t _imm, ConditionCode _condCode) :
BranchImm(mnem, _machInst, __opClass, _imm)
{
// Only update if this isn't part of an IT block
if (!machInst.itstateMask)
condCode = _condCode;
}
};
// Branch to a target computed with a register
class BranchReg : public PredOp
{
protected:
IntRegIndex op1;
public:
BranchReg(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
IntRegIndex _op1) :
PredOp(mnem, _machInst, __opClass), op1(_op1)
{}
};
// Conditionally Branch to a target computed with a register
class BranchRegCond : public BranchReg
{
public:
BranchRegCond(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
IntRegIndex _op1, ConditionCode _condCode) :
BranchReg(mnem, _machInst, __opClass, _op1)
{
// Only update if this isn't part of an IT block
if (!machInst.itstateMask)
condCode = _condCode;
}
};
// Branch to a target computed with two registers
class BranchRegReg : public PredOp
{
protected:
IntRegIndex op1;
IntRegIndex op2;
public:
BranchRegReg(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
IntRegIndex _op1, IntRegIndex _op2) :
PredOp(mnem, _machInst, __opClass), op1(_op1), op2(_op2)
{}
};
// Branch to a target computed with an immediate and a register
class BranchImmReg : public PredOp
{
protected:
int32_t imm;
IntRegIndex op1;
public:
BranchImmReg(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
int32_t _imm, IntRegIndex _op1) :
PredOp(mnem, _machInst, __opClass), imm(_imm), op1(_op1)
{}
};
}
#endif //__ARCH_ARM_INSTS_BRANCH_HH__

View File

@ -0,0 +1,967 @@
/*
* 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.
*
* Copyright (c) 2007-2008 The Florida State University
* 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: Stephen Hines
*/
#include <sstream>
#include "arch/arm/insts/macromem.hh"
#include "arch/arm/generated/decoder.hh"
using namespace std;
using namespace ArmISAInst;
namespace ArmISA
{
MacroMemOp::MacroMemOp(const char *mnem, ExtMachInst machInst,
OpClass __opClass, IntRegIndex rn,
bool index, bool up, bool user, bool writeback,
bool load, uint32_t reglist) :
PredMacroOp(mnem, machInst, __opClass)
{
uint32_t regs = reglist;
uint32_t ones = number_of_ones(reglist);
// Remember that writeback adds a uop or two and the temp register adds one
numMicroops = ones + (writeback ? (load ? 2 : 1) : 0) + 1;
// It's technically legal to do a lot of nothing
if (!ones)
numMicroops = 1;
microOps = new StaticInstPtr[numMicroops];
uint32_t addr = 0;
if (!up)
addr = (ones << 2) - 4;
if (!index)
addr += 4;
StaticInstPtr *uop = microOps;
// Add 0 to Rn and stick it in ureg0.
// This is equivalent to a move.
*uop = new MicroAddiUop(machInst, INTREG_UREG0, rn, 0);
unsigned reg = 0;
unsigned regIdx = 0;
bool force_user = user & !bits(reglist, 15);
bool exception_ret = user & bits(reglist, 15);
for (int i = 0; i < ones; i++) {
// Find the next register.
while (!bits(regs, reg))
reg++;
replaceBits(regs, reg, 0);
regIdx = reg;
if (force_user) {
regIdx = intRegInMode(MODE_USER, regIdx);
}
if (load) {
if (writeback && i == ones - 1) {
// If it's a writeback and this is the last register
// do the load into a temporary register which we'll move
// into the final one later
*++uop = new MicroLdrUop(machInst, INTREG_UREG1, INTREG_UREG0,
up, addr);
} else {
// Otherwise just do it normally
if (reg == INTREG_PC && exception_ret) {
// This must be the exception return form of ldm.
*++uop = new MicroLdrRetUop(machInst, regIdx,
INTREG_UREG0, up, addr);
} else {
*++uop = new MicroLdrUop(machInst, regIdx,
INTREG_UREG0, up, addr);
}
}
} else {
*++uop = new MicroStrUop(machInst, regIdx, INTREG_UREG0, up, addr);
}
if (up)
addr += 4;
else
addr -= 4;
}
if (writeback && ones) {
// put the register update after we're done all loading
if (up)
*++uop = new MicroAddiUop(machInst, rn, rn, ones * 4);
else
*++uop = new MicroSubiUop(machInst, rn, rn, ones * 4);
// If this was a load move the last temporary value into place
// this way we can't take an exception after we update the base
// register.
if (load && reg == INTREG_PC && exception_ret) {
*++uop = new MicroUopRegMovRet(machInst, 0, INTREG_UREG1);
} else if (load) {
*++uop = new MicroUopRegMov(machInst, regIdx, INTREG_UREG1);
if (reg == INTREG_PC) {
(*uop)->setFlag(StaticInst::IsControl);
(*uop)->setFlag(StaticInst::IsCondControl);
(*uop)->setFlag(StaticInst::IsIndirectControl);
// This is created as a RAS POP
if (rn == INTREG_SP)
(*uop)->setFlag(StaticInst::IsReturn);
}
}
}
(*uop)->setLastMicroop();
for (StaticInstPtr *curUop = microOps;
!(*curUop)->isLastMicroop(); curUop++) {
MicroOp * uopPtr = dynamic_cast<MicroOp *>(curUop->get());
assert(uopPtr);
uopPtr->setDelayedCommit();
}
}
VldMultOp::VldMultOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
unsigned elems, RegIndex rn, RegIndex vd, unsigned regs,
unsigned inc, uint32_t size, uint32_t align, RegIndex rm) :
PredMacroOp(mnem, machInst, __opClass)
{
assert(regs > 0 && regs <= 4);
assert(regs % elems == 0);
numMicroops = (regs > 2) ? 2 : 1;
bool wb = (rm != 15);
bool deinterleave = (elems > 1);
if (wb) numMicroops++;
if (deinterleave) numMicroops += (regs / elems);
microOps = new StaticInstPtr[numMicroops];
RegIndex rMid = deinterleave ? NumFloatArchRegs : vd * 2;
uint32_t noAlign = TLB::MustBeOne;
unsigned uopIdx = 0;
switch (regs) {
case 4:
microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>(
size, machInst, rMid, rn, 0, align);
microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>(
size, machInst, rMid + 4, rn, 16, noAlign);
break;
case 3:
microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>(
size, machInst, rMid, rn, 0, align);
microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon8Uop>(
size, machInst, rMid + 4, rn, 16, noAlign);
break;
case 2:
microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon16Uop>(
size, machInst, rMid, rn, 0, align);
break;
case 1:
microOps[uopIdx++] = newNeonMemInst<MicroLdrNeon8Uop>(
size, machInst, rMid, rn, 0, align);
break;
default:
// Unknown number of registers
microOps[uopIdx++] = new Unknown(machInst);
}
if (wb) {
if (rm != 15 && rm != 13) {
microOps[uopIdx++] =
new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL);
} else {
microOps[uopIdx++] =
new MicroAddiUop(machInst, rn, rn, regs * 8);
}
}
if (deinterleave) {
switch (elems) {
case 4:
assert(regs == 4);
microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon8Uop>(
size, machInst, vd * 2, rMid, inc * 2);
break;
case 3:
assert(regs == 3);
microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon6Uop>(
size, machInst, vd * 2, rMid, inc * 2);
break;
case 2:
assert(regs == 4 || regs == 2);
if (regs == 4) {
microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>(
size, machInst, vd * 2, rMid, inc * 2);
microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>(
size, machInst, vd * 2 + 2, rMid + 4, inc * 2);
} else {
microOps[uopIdx++] = newNeonMixInst<MicroDeintNeon4Uop>(
size, machInst, vd * 2, rMid, inc * 2);
}
break;
default:
// Bad number of elements to deinterleave
microOps[uopIdx++] = new Unknown(machInst);
}
}
assert(uopIdx == numMicroops);
for (unsigned i = 0; i < numMicroops - 1; i++) {
MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get());
assert(uopPtr);
uopPtr->setDelayedCommit();
}
microOps[numMicroops - 1]->setLastMicroop();
}
VldSingleOp::VldSingleOp(const char *mnem, ExtMachInst machInst,
OpClass __opClass, bool all, unsigned elems,
RegIndex rn, RegIndex vd, unsigned regs,
unsigned inc, uint32_t size, uint32_t align,
RegIndex rm, unsigned lane) :
PredMacroOp(mnem, machInst, __opClass)
{
assert(regs > 0 && regs <= 4);
assert(regs % elems == 0);
unsigned eBytes = (1 << size);
unsigned loadSize = eBytes * elems;
unsigned loadRegs M5_VAR_USED = (loadSize + sizeof(FloatRegBits) - 1) /
sizeof(FloatRegBits);
assert(loadRegs > 0 && loadRegs <= 4);
numMicroops = 1;
bool wb = (rm != 15);
if (wb) numMicroops++;
numMicroops += (regs / elems);
microOps = new StaticInstPtr[numMicroops];
RegIndex ufp0 = NumFloatArchRegs;
unsigned uopIdx = 0;
switch (loadSize) {
case 1:
microOps[uopIdx++] = new MicroLdrNeon1Uop<uint8_t>(
machInst, ufp0, rn, 0, align);
break;
case 2:
if (eBytes == 2) {
microOps[uopIdx++] = new MicroLdrNeon2Uop<uint16_t>(
machInst, ufp0, rn, 0, align);
} else {
microOps[uopIdx++] = new MicroLdrNeon2Uop<uint8_t>(
machInst, ufp0, rn, 0, align);
}
break;
case 3:
microOps[uopIdx++] = new MicroLdrNeon3Uop<uint8_t>(
machInst, ufp0, rn, 0, align);
break;
case 4:
switch (eBytes) {
case 1:
microOps[uopIdx++] = new MicroLdrNeon4Uop<uint8_t>(
machInst, ufp0, rn, 0, align);
break;
case 2:
microOps[uopIdx++] = new MicroLdrNeon4Uop<uint16_t>(
machInst, ufp0, rn, 0, align);
break;
case 4:
microOps[uopIdx++] = new MicroLdrNeon4Uop<uint32_t>(
machInst, ufp0, rn, 0, align);
break;
}
break;
case 6:
microOps[uopIdx++] = new MicroLdrNeon6Uop<uint16_t>(
machInst, ufp0, rn, 0, align);
break;
case 8:
switch (eBytes) {
case 2:
microOps[uopIdx++] = new MicroLdrNeon8Uop<uint16_t>(
machInst, ufp0, rn, 0, align);
break;
case 4:
microOps[uopIdx++] = new MicroLdrNeon8Uop<uint32_t>(
machInst, ufp0, rn, 0, align);
break;
}
break;
case 12:
microOps[uopIdx++] = new MicroLdrNeon12Uop<uint32_t>(
machInst, ufp0, rn, 0, align);
break;
case 16:
microOps[uopIdx++] = new MicroLdrNeon16Uop<uint32_t>(
machInst, ufp0, rn, 0, align);
break;
default:
// Unrecognized load size
microOps[uopIdx++] = new Unknown(machInst);
}
if (wb) {
if (rm != 15 && rm != 13) {
microOps[uopIdx++] =
new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL);
} else {
microOps[uopIdx++] =
new MicroAddiUop(machInst, rn, rn, loadSize);
}
}
switch (elems) {
case 4:
assert(regs == 4);
switch (size) {
case 0:
if (all) {
microOps[uopIdx++] = new MicroUnpackAllNeon2to8Uop<uint8_t>(
machInst, vd * 2, ufp0, inc * 2);
} else {
microOps[uopIdx++] = new MicroUnpackNeon2to8Uop<uint8_t>(
machInst, vd * 2, ufp0, inc * 2, lane);
}
break;
case 1:
if (all) {
microOps[uopIdx++] = new MicroUnpackAllNeon2to8Uop<uint16_t>(
machInst, vd * 2, ufp0, inc * 2);
} else {
microOps[uopIdx++] = new MicroUnpackNeon2to8Uop<uint16_t>(
machInst, vd * 2, ufp0, inc * 2, lane);
}
break;
case 2:
if (all) {
microOps[uopIdx++] = new MicroUnpackAllNeon4to8Uop<uint32_t>(
machInst, vd * 2, ufp0, inc * 2);
} else {
microOps[uopIdx++] = new MicroUnpackNeon4to8Uop<uint32_t>(
machInst, vd * 2, ufp0, inc * 2, lane);
}
break;
default:
// Bad size
microOps[uopIdx++] = new Unknown(machInst);
break;
}
break;
case 3:
assert(regs == 3);
switch (size) {
case 0:
if (all) {
microOps[uopIdx++] = new MicroUnpackAllNeon2to6Uop<uint8_t>(
machInst, vd * 2, ufp0, inc * 2);
} else {
microOps[uopIdx++] = new MicroUnpackNeon2to6Uop<uint8_t>(
machInst, vd * 2, ufp0, inc * 2, lane);
}
break;
case 1:
if (all) {
microOps[uopIdx++] = new MicroUnpackAllNeon2to6Uop<uint16_t>(
machInst, vd * 2, ufp0, inc * 2);
} else {
microOps[uopIdx++] = new MicroUnpackNeon2to6Uop<uint16_t>(
machInst, vd * 2, ufp0, inc * 2, lane);
}
break;
case 2:
if (all) {
microOps[uopIdx++] = new MicroUnpackAllNeon4to6Uop<uint32_t>(
machInst, vd * 2, ufp0, inc * 2);
} else {
microOps[uopIdx++] = new MicroUnpackNeon4to6Uop<uint32_t>(
machInst, vd * 2, ufp0, inc * 2, lane);
}
break;
default:
// Bad size
microOps[uopIdx++] = new Unknown(machInst);
break;
}
break;
case 2:
assert(regs == 2);
assert(loadRegs <= 2);
switch (size) {
case 0:
if (all) {
microOps[uopIdx++] = new MicroUnpackAllNeon2to4Uop<uint8_t>(
machInst, vd * 2, ufp0, inc * 2);
} else {
microOps[uopIdx++] = new MicroUnpackNeon2to4Uop<uint8_t>(
machInst, vd * 2, ufp0, inc * 2, lane);
}
break;
case 1:
if (all) {
microOps[uopIdx++] = new MicroUnpackAllNeon2to4Uop<uint16_t>(
machInst, vd * 2, ufp0, inc * 2);
} else {
microOps[uopIdx++] = new MicroUnpackNeon2to4Uop<uint16_t>(
machInst, vd * 2, ufp0, inc * 2, lane);
}
break;
case 2:
if (all) {
microOps[uopIdx++] = new MicroUnpackAllNeon2to4Uop<uint32_t>(
machInst, vd * 2, ufp0, inc * 2);
} else {
microOps[uopIdx++] = new MicroUnpackNeon2to4Uop<uint32_t>(
machInst, vd * 2, ufp0, inc * 2, lane);
}
break;
default:
// Bad size
microOps[uopIdx++] = new Unknown(machInst);
break;
}
break;
case 1:
assert(regs == 1 || (all && regs == 2));
assert(loadRegs <= 2);
for (unsigned offset = 0; offset < regs; offset++) {
switch (size) {
case 0:
if (all) {
microOps[uopIdx++] =
new MicroUnpackAllNeon2to2Uop<uint8_t>(
machInst, (vd + offset) * 2, ufp0, inc * 2);
} else {
microOps[uopIdx++] =
new MicroUnpackNeon2to2Uop<uint8_t>(
machInst, (vd + offset) * 2, ufp0, inc * 2, lane);
}
break;
case 1:
if (all) {
microOps[uopIdx++] =
new MicroUnpackAllNeon2to2Uop<uint16_t>(
machInst, (vd + offset) * 2, ufp0, inc * 2);
} else {
microOps[uopIdx++] =
new MicroUnpackNeon2to2Uop<uint16_t>(
machInst, (vd + offset) * 2, ufp0, inc * 2, lane);
}
break;
case 2:
if (all) {
microOps[uopIdx++] =
new MicroUnpackAllNeon2to2Uop<uint32_t>(
machInst, (vd + offset) * 2, ufp0, inc * 2);
} else {
microOps[uopIdx++] =
new MicroUnpackNeon2to2Uop<uint32_t>(
machInst, (vd + offset) * 2, ufp0, inc * 2, lane);
}
break;
default:
// Bad size
microOps[uopIdx++] = new Unknown(machInst);
break;
}
}
break;
default:
// Bad number of elements to unpack
microOps[uopIdx++] = new Unknown(machInst);
}
assert(uopIdx == numMicroops);
for (unsigned i = 0; i < numMicroops - 1; i++) {
MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get());
assert(uopPtr);
uopPtr->setDelayedCommit();
}
microOps[numMicroops - 1]->setLastMicroop();
}
VstMultOp::VstMultOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
unsigned elems, RegIndex rn, RegIndex vd, unsigned regs,
unsigned inc, uint32_t size, uint32_t align, RegIndex rm) :
PredMacroOp(mnem, machInst, __opClass)
{
assert(regs > 0 && regs <= 4);
assert(regs % elems == 0);
numMicroops = (regs > 2) ? 2 : 1;
bool wb = (rm != 15);
bool interleave = (elems > 1);
if (wb) numMicroops++;
if (interleave) numMicroops += (regs / elems);
microOps = new StaticInstPtr[numMicroops];
uint32_t noAlign = TLB::MustBeOne;
RegIndex rMid = interleave ? NumFloatArchRegs : vd * 2;
unsigned uopIdx = 0;
if (interleave) {
switch (elems) {
case 4:
assert(regs == 4);
microOps[uopIdx++] = newNeonMixInst<MicroInterNeon8Uop>(
size, machInst, rMid, vd * 2, inc * 2);
break;
case 3:
assert(regs == 3);
microOps[uopIdx++] = newNeonMixInst<MicroInterNeon6Uop>(
size, machInst, rMid, vd * 2, inc * 2);
break;
case 2:
assert(regs == 4 || regs == 2);
if (regs == 4) {
microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>(
size, machInst, rMid, vd * 2, inc * 2);
microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>(
size, machInst, rMid + 4, vd * 2 + 2, inc * 2);
} else {
microOps[uopIdx++] = newNeonMixInst<MicroInterNeon4Uop>(
size, machInst, rMid, vd * 2, inc * 2);
}
break;
default:
// Bad number of elements to interleave
microOps[uopIdx++] = new Unknown(machInst);
}
}
switch (regs) {
case 4:
microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>(
size, machInst, rMid, rn, 0, align);
microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>(
size, machInst, rMid + 4, rn, 16, noAlign);
break;
case 3:
microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>(
size, machInst, rMid, rn, 0, align);
microOps[uopIdx++] = newNeonMemInst<MicroStrNeon8Uop>(
size, machInst, rMid + 4, rn, 16, noAlign);
break;
case 2:
microOps[uopIdx++] = newNeonMemInst<MicroStrNeon16Uop>(
size, machInst, rMid, rn, 0, align);
break;
case 1:
microOps[uopIdx++] = newNeonMemInst<MicroStrNeon8Uop>(
size, machInst, rMid, rn, 0, align);
break;
default:
// Unknown number of registers
microOps[uopIdx++] = new Unknown(machInst);
}
if (wb) {
if (rm != 15 && rm != 13) {
microOps[uopIdx++] =
new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL);
} else {
microOps[uopIdx++] =
new MicroAddiUop(machInst, rn, rn, regs * 8);
}
}
assert(uopIdx == numMicroops);
for (unsigned i = 0; i < numMicroops - 1; i++) {
MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get());
assert(uopPtr);
uopPtr->setDelayedCommit();
}
microOps[numMicroops - 1]->setLastMicroop();
}
VstSingleOp::VstSingleOp(const char *mnem, ExtMachInst machInst,
OpClass __opClass, bool all, unsigned elems,
RegIndex rn, RegIndex vd, unsigned regs,
unsigned inc, uint32_t size, uint32_t align,
RegIndex rm, unsigned lane) :
PredMacroOp(mnem, machInst, __opClass)
{
assert(!all);
assert(regs > 0 && regs <= 4);
assert(regs % elems == 0);
unsigned eBytes = (1 << size);
unsigned storeSize = eBytes * elems;
unsigned storeRegs M5_VAR_USED = (storeSize + sizeof(FloatRegBits) - 1) /
sizeof(FloatRegBits);
assert(storeRegs > 0 && storeRegs <= 4);
numMicroops = 1;
bool wb = (rm != 15);
if (wb) numMicroops++;
numMicroops += (regs / elems);
microOps = new StaticInstPtr[numMicroops];
RegIndex ufp0 = NumFloatArchRegs;
unsigned uopIdx = 0;
switch (elems) {
case 4:
assert(regs == 4);
switch (size) {
case 0:
microOps[uopIdx++] = new MicroPackNeon8to2Uop<uint8_t>(
machInst, ufp0, vd * 2, inc * 2, lane);
break;
case 1:
microOps[uopIdx++] = new MicroPackNeon8to2Uop<uint16_t>(
machInst, ufp0, vd * 2, inc * 2, lane);
break;
case 2:
microOps[uopIdx++] = new MicroPackNeon8to4Uop<uint32_t>(
machInst, ufp0, vd * 2, inc * 2, lane);
break;
default:
// Bad size
microOps[uopIdx++] = new Unknown(machInst);
break;
}
break;
case 3:
assert(regs == 3);
switch (size) {
case 0:
microOps[uopIdx++] = new MicroPackNeon6to2Uop<uint8_t>(
machInst, ufp0, vd * 2, inc * 2, lane);
break;
case 1:
microOps[uopIdx++] = new MicroPackNeon6to2Uop<uint16_t>(
machInst, ufp0, vd * 2, inc * 2, lane);
break;
case 2:
microOps[uopIdx++] = new MicroPackNeon6to4Uop<uint32_t>(
machInst, ufp0, vd * 2, inc * 2, lane);
break;
default:
// Bad size
microOps[uopIdx++] = new Unknown(machInst);
break;
}
break;
case 2:
assert(regs == 2);
assert(storeRegs <= 2);
switch (size) {
case 0:
microOps[uopIdx++] = new MicroPackNeon4to2Uop<uint8_t>(
machInst, ufp0, vd * 2, inc * 2, lane);
break;
case 1:
microOps[uopIdx++] = new MicroPackNeon4to2Uop<uint16_t>(
machInst, ufp0, vd * 2, inc * 2, lane);
break;
case 2:
microOps[uopIdx++] = new MicroPackNeon4to2Uop<uint32_t>(
machInst, ufp0, vd * 2, inc * 2, lane);
break;
default:
// Bad size
microOps[uopIdx++] = new Unknown(machInst);
break;
}
break;
case 1:
assert(regs == 1 || (all && regs == 2));
assert(storeRegs <= 2);
for (unsigned offset = 0; offset < regs; offset++) {
switch (size) {
case 0:
microOps[uopIdx++] = new MicroPackNeon2to2Uop<uint8_t>(
machInst, ufp0, (vd + offset) * 2, inc * 2, lane);
break;
case 1:
microOps[uopIdx++] = new MicroPackNeon2to2Uop<uint16_t>(
machInst, ufp0, (vd + offset) * 2, inc * 2, lane);
break;
case 2:
microOps[uopIdx++] = new MicroPackNeon2to2Uop<uint32_t>(
machInst, ufp0, (vd + offset) * 2, inc * 2, lane);
break;
default:
// Bad size
microOps[uopIdx++] = new Unknown(machInst);
break;
}
}
break;
default:
// Bad number of elements to unpack
microOps[uopIdx++] = new Unknown(machInst);
}
switch (storeSize) {
case 1:
microOps[uopIdx++] = new MicroStrNeon1Uop<uint8_t>(
machInst, ufp0, rn, 0, align);
break;
case 2:
if (eBytes == 2) {
microOps[uopIdx++] = new MicroStrNeon2Uop<uint16_t>(
machInst, ufp0, rn, 0, align);
} else {
microOps[uopIdx++] = new MicroStrNeon2Uop<uint8_t>(
machInst, ufp0, rn, 0, align);
}
break;
case 3:
microOps[uopIdx++] = new MicroStrNeon3Uop<uint8_t>(
machInst, ufp0, rn, 0, align);
break;
case 4:
switch (eBytes) {
case 1:
microOps[uopIdx++] = new MicroStrNeon4Uop<uint8_t>(
machInst, ufp0, rn, 0, align);
break;
case 2:
microOps[uopIdx++] = new MicroStrNeon4Uop<uint16_t>(
machInst, ufp0, rn, 0, align);
break;
case 4:
microOps[uopIdx++] = new MicroStrNeon4Uop<uint32_t>(
machInst, ufp0, rn, 0, align);
break;
}
break;
case 6:
microOps[uopIdx++] = new MicroStrNeon6Uop<uint16_t>(
machInst, ufp0, rn, 0, align);
break;
case 8:
switch (eBytes) {
case 2:
microOps[uopIdx++] = new MicroStrNeon8Uop<uint16_t>(
machInst, ufp0, rn, 0, align);
break;
case 4:
microOps[uopIdx++] = new MicroStrNeon8Uop<uint32_t>(
machInst, ufp0, rn, 0, align);
break;
}
break;
case 12:
microOps[uopIdx++] = new MicroStrNeon12Uop<uint32_t>(
machInst, ufp0, rn, 0, align);
break;
case 16:
microOps[uopIdx++] = new MicroStrNeon16Uop<uint32_t>(
machInst, ufp0, rn, 0, align);
break;
default:
// Bad store size
microOps[uopIdx++] = new Unknown(machInst);
}
if (wb) {
if (rm != 15 && rm != 13) {
microOps[uopIdx++] =
new MicroAddUop(machInst, rn, rn, rm, 0, ArmISA::LSL);
} else {
microOps[uopIdx++] =
new MicroAddiUop(machInst, rn, rn, storeSize);
}
}
assert(uopIdx == numMicroops);
for (unsigned i = 0; i < numMicroops - 1; i++) {
MicroOp * uopPtr = dynamic_cast<MicroOp *>(microOps[i].get());
assert(uopPtr);
uopPtr->setDelayedCommit();
}
microOps[numMicroops - 1]->setLastMicroop();
}
MacroVFPMemOp::MacroVFPMemOp(const char *mnem, ExtMachInst machInst,
OpClass __opClass, IntRegIndex rn,
RegIndex vd, bool single, bool up,
bool writeback, bool load, uint32_t offset) :
PredMacroOp(mnem, machInst, __opClass)
{
int i = 0;
// The lowest order bit selects fldmx (set) or fldmd (clear). These seem
// to be functionally identical except that fldmx is deprecated. For now
// we'll assume they're otherwise interchangable.
int count = (single ? offset : (offset / 2));
if (count == 0 || count > NumFloatArchRegs)
warn_once("Bad offset field for VFP load/store multiple.\n");
if (count == 0) {
// Force there to be at least one microop so the macroop makes sense.
writeback = true;
}
if (count > NumFloatArchRegs)
count = NumFloatArchRegs;
numMicroops = count * (single ? 1 : 2) + (writeback ? 1 : 0);
microOps = new StaticInstPtr[numMicroops];
int64_t addr = 0;
if (!up)
addr = 4 * offset;
bool tempUp = up;
for (int j = 0; j < count; j++) {
if (load) {
if (single) {
microOps[i++] = new MicroLdrFpUop(machInst, vd++, rn,
tempUp, addr);
} else {
microOps[i++] = new MicroLdrDBFpUop(machInst, vd++, rn,
tempUp, addr);
microOps[i++] = new MicroLdrDTFpUop(machInst, vd++, rn, tempUp,
addr + (up ? 4 : -4));
}
} else {
if (single) {
microOps[i++] = new MicroStrFpUop(machInst, vd++, rn,
tempUp, addr);
} else {
microOps[i++] = new MicroStrDBFpUop(machInst, vd++, rn,
tempUp, addr);
microOps[i++] = new MicroStrDTFpUop(machInst, vd++, rn, tempUp,
addr + (up ? 4 : -4));
}
}
if (!tempUp) {
addr -= (single ? 4 : 8);
// The microops don't handle negative displacement, so turn if we
// hit zero, flip polarity and start adding.
if (addr <= 0) {
tempUp = true;
addr = -addr;
}
} else {
addr += (single ? 4 : 8);
}
}
if (writeback) {
if (up) {
microOps[i++] =
new MicroAddiUop(machInst, rn, rn, 4 * offset);
} else {
microOps[i++] =
new MicroSubiUop(machInst, rn, rn, 4 * offset);
}
}
assert(numMicroops == i);
microOps[numMicroops - 1]->setLastMicroop();
for (StaticInstPtr *curUop = microOps;
!(*curUop)->isLastMicroop(); curUop++) {
MicroOp * uopPtr = dynamic_cast<MicroOp *>(curUop->get());
assert(uopPtr);
uopPtr->setDelayedCommit();
}
}
std::string
MicroIntImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
printMnemonic(ss);
printReg(ss, ura);
ss << ", ";
printReg(ss, urb);
ss << ", ";
ccprintf(ss, "#%d", imm);
return ss.str();
}
std::string
MicroSetPCCPSR::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
printMnemonic(ss);
ss << "[PC,CPSR]";
return ss.str();
}
std::string
MicroIntMov::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
printMnemonic(ss);
printReg(ss, ura);
ss << ", ";
printReg(ss, urb);
return ss.str();
}
std::string
MicroIntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
printMnemonic(ss);
printReg(ss, ura);
ss << ", ";
printReg(ss, urb);
ss << ", ";
printReg(ss, urc);
return ss.str();
}
std::string
MicroMemOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
printMnemonic(ss);
printReg(ss, ura);
ss << ", [";
printReg(ss, urb);
ss << ", ";
ccprintf(ss, "#%d", imm);
ss << "]";
return ss.str();
}
}

View File

@ -0,0 +1,316 @@
/*
* 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.
*
* Copyright (c) 2007-2008 The Florida State University
* 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: Stephen Hines
*/
#ifndef __ARCH_ARM_MACROMEM_HH__
#define __ARCH_ARM_MACROMEM_HH__
#include "arch/arm/insts/pred_inst.hh"
#include "arch/arm/tlb.hh"
namespace ArmISA
{
static inline unsigned int
number_of_ones(int32_t val)
{
uint32_t ones = 0;
for (int i = 0; i < 32; i++ )
{
if ( val & (1<<i) )
ones++;
}
return ones;
}
/**
* Base class for Memory microops
*/
class MicroOp : public PredOp
{
protected:
MicroOp(const char *mnem, ExtMachInst machInst, OpClass __opClass)
: PredOp(mnem, machInst, __opClass)
{
}
public:
void
advancePC(PCState &pcState) const
{
if (flags[IsLastMicroop]) {
pcState.uEnd();
} else if (flags[IsMicroop]) {
pcState.uAdvance();
} else {
pcState.advance();
}
}
};
/**
* Microops for Neon loads/stores
*/
class MicroNeonMemOp : public MicroOp
{
protected:
RegIndex dest, ura;
uint32_t imm;
unsigned memAccessFlags;
MicroNeonMemOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
RegIndex _dest, RegIndex _ura, uint32_t _imm)
: MicroOp(mnem, machInst, __opClass),
dest(_dest), ura(_ura), imm(_imm),
memAccessFlags(TLB::MustBeOne)
{
}
};
/**
* Microops for Neon load/store (de)interleaving
*/
class MicroNeonMixOp : public MicroOp
{
protected:
RegIndex dest, op1;
uint32_t step;
MicroNeonMixOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
RegIndex _dest, RegIndex _op1, uint32_t _step)
: MicroOp(mnem, machInst, __opClass),
dest(_dest), op1(_op1), step(_step)
{
}
};
class MicroNeonMixLaneOp : public MicroNeonMixOp
{
protected:
unsigned lane;
MicroNeonMixLaneOp(const char *mnem, ExtMachInst machInst,
OpClass __opClass, RegIndex _dest, RegIndex _op1,
uint32_t _step, unsigned _lane)
: MicroNeonMixOp(mnem, machInst, __opClass, _dest, _op1, _step),
lane(_lane)
{
}
};
/**
* Microops of the form
* PC = IntRegA
* CPSR = IntRegB
*/
class MicroSetPCCPSR : public MicroOp
{
protected:
IntRegIndex ura, urb, urc;
MicroSetPCCPSR(const char *mnem, ExtMachInst machInst, OpClass __opClass,
IntRegIndex _ura, IntRegIndex _urb, IntRegIndex _urc)
: MicroOp(mnem, machInst, __opClass),
ura(_ura), urb(_urb), urc(_urc)
{
}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
/**
* Microops of the form IntRegA = IntRegB
*/
class MicroIntMov : public MicroOp
{
protected:
RegIndex ura, urb;
MicroIntMov(const char *mnem, ExtMachInst machInst, OpClass __opClass,
RegIndex _ura, RegIndex _urb)
: MicroOp(mnem, machInst, __opClass),
ura(_ura), urb(_urb)
{
}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
/**
* Microops of the form IntRegA = IntRegB op Imm
*/
class MicroIntImmOp : public MicroOp
{
protected:
RegIndex ura, urb;
uint32_t imm;
MicroIntImmOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
RegIndex _ura, RegIndex _urb, uint32_t _imm)
: MicroOp(mnem, machInst, __opClass),
ura(_ura), urb(_urb), imm(_imm)
{
}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
/**
* Microops of the form IntRegA = IntRegB op IntRegC
*/
class MicroIntOp : public MicroOp
{
protected:
RegIndex ura, urb, urc;
MicroIntOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
RegIndex _ura, RegIndex _urb, RegIndex _urc)
: MicroOp(mnem, machInst, __opClass),
ura(_ura), urb(_urb), urc(_urc)
{
}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
/**
* Microops of the form IntRegA = IntRegB op shifted IntRegC
*/
class MicroIntRegOp : public MicroOp
{
protected:
RegIndex ura, urb, urc;
int32_t shiftAmt;
ArmShiftType shiftType;
MicroIntRegOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
RegIndex _ura, RegIndex _urb, RegIndex _urc,
int32_t _shiftAmt, ArmShiftType _shiftType)
: MicroOp(mnem, machInst, __opClass),
ura(_ura), urb(_urb), urc(_urc),
shiftAmt(_shiftAmt), shiftType(_shiftType)
{
}
};
/**
* Memory microops which use IntReg + Imm addressing
*/
class MicroMemOp : public MicroIntImmOp
{
protected:
bool up;
unsigned memAccessFlags;
MicroMemOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
RegIndex _ura, RegIndex _urb, bool _up, uint8_t _imm)
: MicroIntImmOp(mnem, machInst, __opClass, _ura, _urb, _imm),
up(_up), memAccessFlags(TLB::MustBeOne | TLB::AlignWord)
{
}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
/**
* Base class for microcoded integer memory instructions.
*/
class MacroMemOp : public PredMacroOp
{
protected:
MacroMemOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
IntRegIndex rn, bool index, bool up, bool user,
bool writeback, bool load, uint32_t reglist);
};
/**
* Base classes for microcoded integer memory instructions.
*/
class VldMultOp : public PredMacroOp
{
protected:
VldMultOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
unsigned elems, RegIndex rn, RegIndex vd, unsigned regs,
unsigned inc, uint32_t size, uint32_t align, RegIndex rm);
};
class VldSingleOp : public PredMacroOp
{
protected:
VldSingleOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
bool all, unsigned elems, RegIndex rn, RegIndex vd,
unsigned regs, unsigned inc, uint32_t size,
uint32_t align, RegIndex rm, unsigned lane);
};
/**
* Base class for microcoded integer memory instructions.
*/
class VstMultOp : public PredMacroOp
{
protected:
VstMultOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
unsigned width, RegIndex rn, RegIndex vd, unsigned regs,
unsigned inc, uint32_t size, uint32_t align, RegIndex rm);
};
class VstSingleOp : public PredMacroOp
{
protected:
VstSingleOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
bool all, unsigned elems, RegIndex rn, RegIndex vd,
unsigned regs, unsigned inc, uint32_t size,
uint32_t align, RegIndex rm, unsigned lane);
};
/**
* Base class for microcoded floating point memory instructions.
*/
class MacroVFPMemOp : public PredMacroOp
{
protected:
MacroVFPMemOp(const char *mnem, ExtMachInst machInst, OpClass __opClass,
IntRegIndex rn, RegIndex vd, bool single, bool up,
bool writeback, bool load, uint32_t offset);
};
}
#endif //__ARCH_ARM_INSTS_MACROMEM_HH__

View File

@ -0,0 +1,194 @@
/*
* 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.
*
* Copyright (c) 2007-2008 The Florida State University
* 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: Stephen Hines
*/
#include "arch/arm/insts/mem.hh"
#include "base/loader/symtab.hh"
using namespace std;
namespace ArmISA
{
void
MemoryReg::printOffset(std::ostream &os) const
{
if (!add)
os << "-";
printReg(os, index);
if (shiftType != LSL || shiftAmt != 0) {
switch (shiftType) {
case LSL:
ccprintf(os, " LSL #%d", shiftAmt);
break;
case LSR:
ccprintf(os, " LSR #%d", (shiftAmt == 0) ? 32 : shiftAmt);
break;
case ASR:
ccprintf(os, " ASR #%d", (shiftAmt == 0) ? 32 : shiftAmt);
break;
case ROR:
if (shiftAmt == 0) {
ccprintf(os, " RRX");
} else {
ccprintf(os, " ROR #%d", shiftAmt);
}
break;
}
}
}
string
Swap::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
stringstream ss;
printMnemonic(ss);
printReg(ss, dest);
ss << ", ";
printReg(ss, op1);
ss << ", [";
printReg(ss, base);
ss << "]";
return ss.str();
}
string
RfeOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
stringstream ss;
switch (mode) {
case DecrementAfter:
printMnemonic(ss, "da");
break;
case DecrementBefore:
printMnemonic(ss, "db");
break;
case IncrementAfter:
printMnemonic(ss, "ia");
break;
case IncrementBefore:
printMnemonic(ss, "ib");
break;
}
printReg(ss, base);
if (wb) {
ss << "!";
}
return ss.str();
}
string
SrsOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
stringstream ss;
switch (mode) {
case DecrementAfter:
printMnemonic(ss, "da");
break;
case DecrementBefore:
printMnemonic(ss, "db");
break;
case IncrementAfter:
printMnemonic(ss, "ia");
break;
case IncrementBefore:
printMnemonic(ss, "ib");
break;
}
printReg(ss, INTREG_SP);
if (wb) {
ss << "!";
}
ss << ", #";
switch (regMode) {
case MODE_USER:
ss << "user";
break;
case MODE_FIQ:
ss << "fiq";
break;
case MODE_IRQ:
ss << "irq";
break;
case MODE_SVC:
ss << "supervisor";
break;
case MODE_MON:
ss << "monitor";
break;
case MODE_ABORT:
ss << "abort";
break;
case MODE_UNDEFINED:
ss << "undefined";
break;
case MODE_SYSTEM:
ss << "system";
break;
default:
ss << "unrecognized";
break;
}
return ss.str();
}
void
Memory::printInst(std::ostream &os, AddrMode addrMode) const
{
printMnemonic(os);
printDest(os);
os << ", [";
printReg(os, base);
if (addrMode != AddrMd_PostIndex) {
os << ", ";
printOffset(os);
os << "]";
if (addrMode == AddrMd_PreIndex) {
os << "!";
}
} else {
os << "] ";
printOffset(os);
}
}
}

View File

@ -0,0 +1,499 @@
/*
* 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.
*
* Copyright (c) 2007-2008 The Florida State University
* 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: Stephen Hines
*/
#ifndef __ARCH_ARM_MEM_HH__
#define __ARCH_ARM_MEM_HH__
#include "arch/arm/insts/pred_inst.hh"
namespace ArmISA
{
class Swap : public PredOp
{
protected:
IntRegIndex dest;
IntRegIndex op1;
IntRegIndex base;
Swap(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _base)
: PredOp(mnem, _machInst, __opClass),
dest(_dest), op1(_op1), base(_base)
{}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
class MightBeMicro : public PredOp
{
protected:
MightBeMicro(const char *mnem, ExtMachInst _machInst, OpClass __opClass)
: PredOp(mnem, _machInst, __opClass)
{}
void
advancePC(PCState &pcState) const
{
if (flags[IsLastMicroop]) {
pcState.uEnd();
} else if (flags[IsMicroop]) {
pcState.uAdvance();
} else {
pcState.advance();
}
}
};
// The address is a base register plus an immediate.
class RfeOp : public MightBeMicro
{
public:
enum AddrMode {
DecrementAfter,
DecrementBefore,
IncrementAfter,
IncrementBefore
};
protected:
IntRegIndex base;
AddrMode mode;
bool wb;
IntRegIndex ura, urb, urc;
static const unsigned numMicroops = 3;
StaticInstPtr *uops;
RfeOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
IntRegIndex _base, AddrMode _mode, bool _wb)
: MightBeMicro(mnem, _machInst, __opClass),
base(_base), mode(_mode), wb(_wb),
ura(INTREG_UREG0), urb(INTREG_UREG1),
urc(INTREG_UREG2),
uops(NULL)
{}
virtual
~RfeOp()
{
delete [] uops;
}
StaticInstPtr
fetchMicroop(MicroPC microPC) const
{
assert(uops != NULL && microPC < numMicroops);
return uops[microPC];
}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
// The address is a base register plus an immediate.
class SrsOp : public MightBeMicro
{
public:
enum AddrMode {
DecrementAfter,
DecrementBefore,
IncrementAfter,
IncrementBefore
};
protected:
uint32_t regMode;
AddrMode mode;
bool wb;
static const unsigned numMicroops = 2;
StaticInstPtr *uops;
SrsOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
uint32_t _regMode, AddrMode _mode, bool _wb)
: MightBeMicro(mnem, _machInst, __opClass),
regMode(_regMode), mode(_mode), wb(_wb), uops(NULL)
{}
virtual
~SrsOp()
{
delete [] uops;
}
StaticInstPtr
fetchMicroop(MicroPC microPC) const
{
assert(uops != NULL && microPC < numMicroops);
return uops[microPC];
}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
class Memory : public MightBeMicro
{
public:
enum AddrMode {
AddrMd_Offset,
AddrMd_PreIndex,
AddrMd_PostIndex
};
protected:
IntRegIndex dest;
IntRegIndex base;
bool add;
static const unsigned numMicroops = 3;
StaticInstPtr *uops;
Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
IntRegIndex _dest, IntRegIndex _base, bool _add)
: MightBeMicro(mnem, _machInst, __opClass),
dest(_dest), base(_base), add(_add), uops(NULL)
{}
virtual
~Memory()
{
delete [] uops;
}
StaticInstPtr
fetchMicroop(MicroPC microPC) const
{
assert(uops != NULL && microPC < numMicroops);
return uops[microPC];
}
virtual void
printOffset(std::ostream &os) const
{}
virtual void
printDest(std::ostream &os) const
{
printReg(os, dest);
}
void printInst(std::ostream &os, AddrMode addrMode) const;
};
// The address is a base register plus an immediate.
class MemoryImm : public Memory
{
protected:
int32_t imm;
MemoryImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
IntRegIndex _dest, IntRegIndex _base, bool _add, int32_t _imm)
: Memory(mnem, _machInst, __opClass, _dest, _base, _add), imm(_imm)
{}
void
printOffset(std::ostream &os) const
{
int32_t pImm = imm;
if (!add)
pImm = -pImm;
ccprintf(os, "#%d", pImm);
}
};
class MemoryExImm : public MemoryImm
{
protected:
IntRegIndex result;
MemoryExImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
IntRegIndex _result, IntRegIndex _dest, IntRegIndex _base,
bool _add, int32_t _imm)
: MemoryImm(mnem, _machInst, __opClass, _dest, _base, _add, _imm),
result(_result)
{}
void
printDest(std::ostream &os) const
{
printReg(os, result);
os << ", ";
MemoryImm::printDest(os);
}
};
// The address is a base register plus an immediate.
class MemoryDImm : public MemoryImm
{
protected:
IntRegIndex dest2;
MemoryDImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
IntRegIndex _dest, IntRegIndex _dest2,
IntRegIndex _base, bool _add, int32_t _imm)
: MemoryImm(mnem, _machInst, __opClass, _dest, _base, _add, _imm),
dest2(_dest2)
{}
void
printDest(std::ostream &os) const
{
MemoryImm::printDest(os);
os << ", ";
printReg(os, dest2);
}
};
class MemoryExDImm : public MemoryDImm
{
protected:
IntRegIndex result;
MemoryExDImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
IntRegIndex _result, IntRegIndex _dest, IntRegIndex _dest2,
IntRegIndex _base, bool _add, int32_t _imm)
: MemoryDImm(mnem, _machInst, __opClass, _dest, _dest2,
_base, _add, _imm), result(_result)
{}
void
printDest(std::ostream &os) const
{
printReg(os, result);
os << ", ";
MemoryDImm::printDest(os);
}
};
// The address is a shifted register plus an immediate
class MemoryReg : public Memory
{
protected:
int32_t shiftAmt;
ArmShiftType shiftType;
IntRegIndex index;
MemoryReg(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
IntRegIndex _dest, IntRegIndex _base, bool _add,
int32_t _shiftAmt, ArmShiftType _shiftType,
IntRegIndex _index)
: Memory(mnem, _machInst, __opClass, _dest, _base, _add),
shiftAmt(_shiftAmt), shiftType(_shiftType), index(_index)
{}
void printOffset(std::ostream &os) const;
};
class MemoryDReg : public MemoryReg
{
protected:
IntRegIndex dest2;
MemoryDReg(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
IntRegIndex _dest, IntRegIndex _dest2,
IntRegIndex _base, bool _add,
int32_t _shiftAmt, ArmShiftType _shiftType,
IntRegIndex _index)
: MemoryReg(mnem, _machInst, __opClass, _dest, _base, _add,
_shiftAmt, _shiftType, _index),
dest2(_dest2)
{}
void
printDest(std::ostream &os) const
{
MemoryReg::printDest(os);
os << ", ";
printReg(os, dest2);
}
};
template<class Base>
class MemoryOffset : public Base
{
protected:
MemoryOffset(const char *mnem, ExtMachInst _machInst,
OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
bool _add, int32_t _imm)
: Base(mnem, _machInst, __opClass, _dest, _base, _add, _imm)
{}
MemoryOffset(const char *mnem, ExtMachInst _machInst,
OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
bool _add, int32_t _shiftAmt, ArmShiftType _shiftType,
IntRegIndex _index)
: Base(mnem, _machInst, __opClass, _dest, _base, _add,
_shiftAmt, _shiftType, _index)
{}
MemoryOffset(const char *mnem, ExtMachInst _machInst,
OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
IntRegIndex _base, bool _add, int32_t _imm)
: Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add, _imm)
{}
MemoryOffset(const char *mnem, ExtMachInst _machInst,
OpClass __opClass, IntRegIndex _result,
IntRegIndex _dest, IntRegIndex _dest2,
IntRegIndex _base, bool _add, int32_t _imm)
: Base(mnem, _machInst, __opClass, _result,
_dest, _dest2, _base, _add, _imm)
{}
MemoryOffset(const char *mnem, ExtMachInst _machInst,
OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
IntRegIndex _base, bool _add,
int32_t _shiftAmt, ArmShiftType _shiftType,
IntRegIndex _index)
: Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add,
_shiftAmt, _shiftType, _index)
{}
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
this->printInst(ss, Memory::AddrMd_Offset);
return ss.str();
}
};
template<class Base>
class MemoryPreIndex : public Base
{
protected:
MemoryPreIndex(const char *mnem, ExtMachInst _machInst,
OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
bool _add, int32_t _imm)
: Base(mnem, _machInst, __opClass, _dest, _base, _add, _imm)
{}
MemoryPreIndex(const char *mnem, ExtMachInst _machInst,
OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
bool _add, int32_t _shiftAmt, ArmShiftType _shiftType,
IntRegIndex _index)
: Base(mnem, _machInst, __opClass, _dest, _base, _add,
_shiftAmt, _shiftType, _index)
{}
MemoryPreIndex(const char *mnem, ExtMachInst _machInst,
OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
IntRegIndex _base, bool _add, int32_t _imm)
: Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add, _imm)
{}
MemoryPreIndex(const char *mnem, ExtMachInst _machInst,
OpClass __opClass, IntRegIndex _result,
IntRegIndex _dest, IntRegIndex _dest2,
IntRegIndex _base, bool _add, int32_t _imm)
: Base(mnem, _machInst, __opClass, _result,
_dest, _dest2, _base, _add, _imm)
{}
MemoryPreIndex(const char *mnem, ExtMachInst _machInst,
OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
IntRegIndex _base, bool _add,
int32_t _shiftAmt, ArmShiftType _shiftType,
IntRegIndex _index)
: Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add,
_shiftAmt, _shiftType, _index)
{}
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
this->printInst(ss, Memory::AddrMd_PreIndex);
return ss.str();
}
};
template<class Base>
class MemoryPostIndex : public Base
{
protected:
MemoryPostIndex(const char *mnem, ExtMachInst _machInst,
OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
bool _add, int32_t _imm)
: Base(mnem, _machInst, __opClass, _dest, _base, _add, _imm)
{}
MemoryPostIndex(const char *mnem, ExtMachInst _machInst,
OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
bool _add, int32_t _shiftAmt, ArmShiftType _shiftType,
IntRegIndex _index)
: Base(mnem, _machInst, __opClass, _dest, _base, _add,
_shiftAmt, _shiftType, _index)
{}
MemoryPostIndex(const char *mnem, ExtMachInst _machInst,
OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
IntRegIndex _base, bool _add, int32_t _imm)
: Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add, _imm)
{}
MemoryPostIndex(const char *mnem, ExtMachInst _machInst,
OpClass __opClass, IntRegIndex _result,
IntRegIndex _dest, IntRegIndex _dest2,
IntRegIndex _base, bool _add, int32_t _imm)
: Base(mnem, _machInst, __opClass, _result,
_dest, _dest2, _base, _add, _imm)
{}
MemoryPostIndex(const char *mnem, ExtMachInst _machInst,
OpClass __opClass, IntRegIndex _dest, IntRegIndex _dest2,
IntRegIndex _base, bool _add,
int32_t _shiftAmt, ArmShiftType _shiftType,
IntRegIndex _index)
: Base(mnem, _machInst, __opClass, _dest, _dest2, _base, _add,
_shiftAmt, _shiftType, _index)
{}
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
this->printInst(ss, Memory::AddrMd_PostIndex);
return ss.str();
}
};
}
#endif //__ARCH_ARM_INSTS_MEM_HH__

View File

@ -0,0 +1,269 @@
/*
* 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
*/
#include "arch/arm/insts/misc.hh"
std::string
MrsOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
printMnemonic(ss);
printReg(ss, dest);
ss << ", ";
bool foundPsr = false;
for (unsigned i = 0; i < numSrcRegs(); i++) {
int idx = srcRegIdx(i);
if (idx < Ctrl_Base_DepTag) {
continue;
}
idx -= Ctrl_Base_DepTag;
if (idx == MISCREG_CPSR) {
ss << "cpsr";
foundPsr = true;
break;
}
if (idx == MISCREG_SPSR) {
ss << "spsr";
foundPsr = true;
break;
}
}
if (!foundPsr) {
ss << "????";
}
return ss.str();
}
void
MsrBase::printMsrBase(std::ostream &os) const
{
printMnemonic(os);
bool apsr = false;
bool foundPsr = false;
for (unsigned i = 0; i < numDestRegs(); i++) {
int idx = destRegIdx(i);
if (idx < Ctrl_Base_DepTag) {
continue;
}
idx -= Ctrl_Base_DepTag;
if (idx == MISCREG_CPSR) {
os << "cpsr_";
foundPsr = true;
break;
}
if (idx == MISCREG_SPSR) {
if (bits(byteMask, 1, 0)) {
os << "spsr_";
} else {
os << "apsr_";
apsr = true;
}
foundPsr = true;
break;
}
}
if (!foundPsr) {
os << "????";
return;
}
if (bits(byteMask, 3)) {
if (apsr) {
os << "nzcvq";
} else {
os << "f";
}
}
if (bits(byteMask, 2)) {
if (apsr) {
os << "g";
} else {
os << "s";
}
}
if (bits(byteMask, 1)) {
os << "x";
}
if (bits(byteMask, 0)) {
os << "c";
}
}
std::string
MsrImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
printMsrBase(ss);
ccprintf(ss, ", #%#x", imm);
return ss.str();
}
std::string
MsrRegOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
printMsrBase(ss);
ss << ", ";
printReg(ss, op1);
return ss.str();
}
std::string
ImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
printMnemonic(ss);
ccprintf(ss, "#%d", imm);
return ss.str();
}
std::string
RegImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
printMnemonic(ss);
printReg(ss, dest);
ccprintf(ss, ", #%d", imm);
return ss.str();
}
std::string
RegRegOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
printMnemonic(ss);
printReg(ss, dest);
ss << ", ";
printReg(ss, op1);
return ss.str();
}
std::string
RegRegRegImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
printMnemonic(ss);
printReg(ss, dest);
ss << ", ";
printReg(ss, op1);
ss << ", ";
printReg(ss, op2);
ccprintf(ss, ", #%d", imm);
return ss.str();
}
std::string
RegRegRegRegOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
printMnemonic(ss);
printReg(ss, dest);
ss << ", ";
printReg(ss, op1);
ss << ", ";
printReg(ss, op2);
ss << ", ";
printReg(ss, op3);
return ss.str();
}
std::string
RegRegRegOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
printMnemonic(ss);
printReg(ss, dest);
ss << ", ";
printReg(ss, op1);
ss << ", ";
printReg(ss, op2);
return ss.str();
}
std::string
RegRegImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
printMnemonic(ss);
printReg(ss, dest);
ss << ", ";
printReg(ss, op1);
ccprintf(ss, ", #%d", imm);
return ss.str();
}
std::string
RegRegImmImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
printMnemonic(ss);
printReg(ss, dest);
ss << ", ";
printReg(ss, op1);
ccprintf(ss, ", #%d, #%d", imm1, imm2);
return ss.str();
}
std::string
RegImmRegOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
printMnemonic(ss);
printReg(ss, dest);
ccprintf(ss, ", #%d, ", imm);
printReg(ss, op1);
return ss.str();
}
std::string
RegImmRegShiftOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
printMnemonic(ss);
printReg(ss, dest);
ccprintf(ss, ", #%d, ", imm);
printShiftOperand(ss, op1, true, shiftAmt, INTREG_ZERO, shiftType);
printReg(ss, op1);
return ss.str();
}
std::string
UnknownOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
return csprintf("%-10s (inst %#08x)", "unknown", machInst);
}

View File

@ -0,0 +1,272 @@
/*
* 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
*/
#ifndef __ARCH_ARM_INSTS_MISC_HH__
#define __ARCH_ARM_INSTS_MISC_HH__
#include "arch/arm/insts/pred_inst.hh"
class MrsOp : public PredOp
{
protected:
IntRegIndex dest;
MrsOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
IntRegIndex _dest) :
PredOp(mnem, _machInst, __opClass), dest(_dest)
{}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
class MsrBase : public PredOp
{
protected:
uint8_t byteMask;
MsrBase(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
uint8_t _byteMask) :
PredOp(mnem, _machInst, __opClass), byteMask(_byteMask)
{}
void printMsrBase(std::ostream &os) const;
};
class MsrImmOp : public MsrBase
{
protected:
uint32_t imm;
MsrImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
uint32_t _imm, uint8_t _byteMask) :
MsrBase(mnem, _machInst, __opClass, _byteMask), imm(_imm)
{}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
class MsrRegOp : public MsrBase
{
protected:
IntRegIndex op1;
MsrRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
IntRegIndex _op1, uint8_t _byteMask) :
MsrBase(mnem, _machInst, __opClass, _byteMask), op1(_op1)
{}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
class ImmOp : public PredOp
{
protected:
uint64_t imm;
ImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
uint64_t _imm) :
PredOp(mnem, _machInst, __opClass), imm(_imm)
{}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
class RegImmOp : public PredOp
{
protected:
IntRegIndex dest;
uint64_t imm;
RegImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
IntRegIndex _dest, uint64_t _imm) :
PredOp(mnem, _machInst, __opClass), dest(_dest), imm(_imm)
{}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
class RegRegOp : public PredOp
{
protected:
IntRegIndex dest;
IntRegIndex op1;
RegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
IntRegIndex _dest, IntRegIndex _op1) :
PredOp(mnem, _machInst, __opClass), dest(_dest), op1(_op1)
{}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
class RegImmRegOp : public PredOp
{
protected:
IntRegIndex dest;
uint64_t imm;
IntRegIndex op1;
RegImmRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
IntRegIndex _dest, uint64_t _imm, IntRegIndex _op1) :
PredOp(mnem, _machInst, __opClass),
dest(_dest), imm(_imm), op1(_op1)
{}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
class RegRegRegImmOp : public PredOp
{
protected:
IntRegIndex dest;
IntRegIndex op1;
IntRegIndex op2;
uint64_t imm;
RegRegRegImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2,
uint64_t _imm) :
PredOp(mnem, _machInst, __opClass),
dest(_dest), op1(_op1), op2(_op2), imm(_imm)
{}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
class RegRegRegRegOp : public PredOp
{
protected:
IntRegIndex dest;
IntRegIndex op1;
IntRegIndex op2;
IntRegIndex op3;
RegRegRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
IntRegIndex _dest, IntRegIndex _op1,
IntRegIndex _op2, IntRegIndex _op3) :
PredOp(mnem, _machInst, __opClass),
dest(_dest), op1(_op1), op2(_op2), op3(_op3)
{}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
class RegRegRegOp : public PredOp
{
protected:
IntRegIndex dest;
IntRegIndex op1;
IntRegIndex op2;
RegRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2) :
PredOp(mnem, _machInst, __opClass),
dest(_dest), op1(_op1), op2(_op2)
{}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
class RegRegImmOp : public PredOp
{
protected:
IntRegIndex dest;
IntRegIndex op1;
uint64_t imm;
RegRegImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
IntRegIndex _dest, IntRegIndex _op1,
uint64_t _imm) :
PredOp(mnem, _machInst, __opClass),
dest(_dest), op1(_op1), imm(_imm)
{}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
class RegRegImmImmOp : public PredOp
{
protected:
IntRegIndex dest;
IntRegIndex op1;
uint64_t imm1;
uint64_t imm2;
RegRegImmImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
IntRegIndex _dest, IntRegIndex _op1,
uint64_t _imm1, uint64_t _imm2) :
PredOp(mnem, _machInst, __opClass),
dest(_dest), op1(_op1), imm1(_imm1), imm2(_imm2)
{}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
class RegImmRegShiftOp : public PredOp
{
protected:
IntRegIndex dest;
uint64_t imm;
IntRegIndex op1;
int32_t shiftAmt;
ArmShiftType shiftType;
RegImmRegShiftOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
IntRegIndex _dest, uint64_t _imm, IntRegIndex _op1,
int32_t _shiftAmt, ArmShiftType _shiftType) :
PredOp(mnem, _machInst, __opClass),
dest(_dest), imm(_imm), op1(_op1),
shiftAmt(_shiftAmt), shiftType(_shiftType)
{}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
class UnknownOp : public PredOp
{
protected:
UnknownOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
PredOp(mnem, _machInst, __opClass)
{}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
#endif

View File

@ -0,0 +1,79 @@
/*
* 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
*/
#ifndef __ARCH_ARM_INSTS_MULT_HH__
#define __ARCH_ARM_INSTS_MULT_HH__
#include "arch/arm/insts/static_inst.hh"
#include "base/trace.hh"
namespace ArmISA
{
/**
* Base class for multipy instructions using three registers.
*/
class Mult3 : public PredOp
{
protected:
IntRegIndex reg0, reg1, reg2;
Mult3(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
IntRegIndex _reg0, IntRegIndex _reg1, IntRegIndex _reg2) :
PredOp(mnem, _machInst, __opClass),
reg0(_reg0), reg1(_reg1), reg2(_reg2)
{}
};
/**
* Base class for multipy instructions using four registers.
*/
class Mult4 : public Mult3
{
protected:
IntRegIndex reg3;
Mult4(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
IntRegIndex _reg0, IntRegIndex _reg1,
IntRegIndex _reg2, IntRegIndex _reg3) :
Mult3(mnem, _machInst, __opClass, _reg0, _reg1, _reg2), reg3(_reg3)
{}
};
}
#endif //__ARCH_ARM_INSTS_MULT_HH__

View File

@ -0,0 +1,114 @@
/*
* 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.
*
* Copyright (c) 2007-2008 The Florida State University
* 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: Stephen Hines
*/
#include "arch/arm/insts/pred_inst.hh"
namespace ArmISA
{
std::string
PredIntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
unsigned rotate = machInst.rotate * 2;
uint32_t imm = machInst.imm;
imm = (imm << (32 - rotate)) | (imm >> rotate);
printDataInst(ss, false, machInst.opcode4 == 0, machInst.sField,
(IntRegIndex)(uint32_t)machInst.rd,
(IntRegIndex)(uint32_t)machInst.rn,
(IntRegIndex)(uint32_t)machInst.rm,
(IntRegIndex)(uint32_t)machInst.rs,
machInst.shiftSize, (ArmShiftType)(uint32_t)machInst.shift,
imm);
return ss.str();
}
std::string
PredImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
printDataInst(ss, true, machInst.opcode4 == 0, machInst.sField,
(IntRegIndex)(uint32_t)machInst.rd,
(IntRegIndex)(uint32_t)machInst.rn,
(IntRegIndex)(uint32_t)machInst.rm,
(IntRegIndex)(uint32_t)machInst.rs,
machInst.shiftSize, (ArmShiftType)(uint32_t)machInst.shift,
imm);
return ss.str();
}
std::string
DataImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
printDataInst(ss, true, false, /*XXX not really s*/ false, dest, op1,
INTREG_ZERO, INTREG_ZERO, 0, LSL, imm);
return ss.str();
}
std::string
DataRegOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
printDataInst(ss, false, true, /*XXX not really s*/ false, dest, op1,
op2, INTREG_ZERO, shiftAmt, shiftType, 0);
return ss.str();
}
std::string
DataRegRegOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
printDataInst(ss, false, false, /*XXX not really s*/ false, dest, op1,
op2, shift, 0, shiftType, 0);
return ss.str();
}
std::string
PredMacroOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
ccprintf(ss, "%-10s ", mnemonic);
return ss.str();
}
}

View File

@ -0,0 +1,349 @@
/*
* 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.
*
* Copyright (c) 2007-2008 The Florida State University
* 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: Stephen Hines
*/
#ifndef __ARCH_ARM_INSTS_PREDINST_HH__
#define __ARCH_ARM_INSTS_PREDINST_HH__
#include "arch/arm/insts/static_inst.hh"
#include "base/trace.hh"
namespace ArmISA
{
static inline uint32_t
rotate_imm(uint32_t immValue, int rotateValue)
{
return ((immValue >> (rotateValue & 31)) |
(immValue << (32 - (rotateValue & 31))));
}
static inline uint32_t
modified_imm(uint8_t ctrlImm, uint8_t dataImm)
{
uint32_t bigData = dataImm;
uint32_t bigCtrl = ctrlImm;
if (bigCtrl < 4) {
switch (bigCtrl) {
case 0:
return bigData;
case 1:
return bigData | (bigData << 16);
case 2:
return (bigData << 8) | (bigData << 24);
case 3:
return (bigData << 0) | (bigData << 8) |
(bigData << 16) | (bigData << 24);
}
}
bigCtrl = (bigCtrl << 1) | ((bigData >> 7) & 0x1);
bigData |= (1 << 7);
return bigData << (32 - bigCtrl);
}
static inline uint64_t
simd_modified_imm(bool op, uint8_t cmode, uint8_t data, bool &immValid)
{
uint64_t bigData = data;
immValid = true;
switch (cmode) {
case 0x0:
case 0x1:
bigData = (bigData << 0) | (bigData << 32);
break;
case 0x2:
case 0x3:
bigData = (bigData << 8) | (bigData << 40);
break;
case 0x4:
case 0x5:
bigData = (bigData << 16) | (bigData << 48);
break;
case 0x6:
case 0x7:
bigData = (bigData << 24) | (bigData << 56);
break;
case 0x8:
case 0x9:
bigData = (bigData << 0) | (bigData << 16) |
(bigData << 32) | (bigData << 48);
break;
case 0xa:
case 0xb:
bigData = (bigData << 8) | (bigData << 24) |
(bigData << 40) | (bigData << 56);
break;
case 0xc:
bigData = (0xffULL << 0) | (bigData << 8) |
(0xffULL << 32) | (bigData << 40);
break;
case 0xd:
bigData = (0xffffULL << 0) | (bigData << 16) |
(0xffffULL << 32) | (bigData << 48);
break;
case 0xe:
if (op) {
bigData = 0;
for (int i = 7; i >= 0; i--) {
if (bits(data, i)) {
bigData |= (ULL(0xFF) << (i * 8));
}
}
} else {
bigData = (bigData << 0) | (bigData << 8) |
(bigData << 16) | (bigData << 24) |
(bigData << 32) | (bigData << 40) |
(bigData << 48) | (bigData << 56);
}
break;
case 0xf:
if (!op) {
uint64_t bVal = bits(bigData, 6) ? (0x1F) : (0x20);
bigData = (bits(bigData, 5, 0) << 19) |
(bVal << 25) | (bits(bigData, 7) << 31);
bigData |= (bigData << 32);
break;
}
// Fall through, immediate encoding is invalid.
default:
immValid = false;
break;
}
return bigData;
}
static inline uint64_t
vfp_modified_imm(uint8_t data, bool wide)
{
uint64_t bigData = data;
uint64_t repData;
if (wide) {
repData = bits(data, 6) ? 0xFF : 0;
bigData = (bits(bigData, 5, 0) << 48) |
(repData << 54) | (bits(~bigData, 6) << 62) |
(bits(bigData, 7) << 63);
} else {
repData = bits(data, 6) ? 0x1F : 0;
bigData = (bits(bigData, 5, 0) << 19) |
(repData << 25) | (bits(~bigData, 6) << 30) |
(bits(bigData, 7) << 31);
}
return bigData;
}
/**
* Base class for predicated integer operations.
*/
class PredOp : public ArmStaticInst
{
protected:
ConditionCode condCode;
/// Constructor
PredOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
ArmStaticInst(mnem, _machInst, __opClass),
condCode(machInst.itstateMask ?
(ConditionCode)(uint8_t)machInst.itstateCond :
(ConditionCode)(unsigned)machInst.condCode)
{
}
};
/**
* Base class for predicated immediate operations.
*/
class PredImmOp : public PredOp
{
protected:
uint32_t imm;
uint32_t rotated_imm;
uint32_t rotated_carry;
uint32_t rotate;
/// Constructor
PredImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
PredOp(mnem, _machInst, __opClass),
imm(machInst.imm), rotated_imm(0), rotated_carry(0),
rotate(machInst.rotate << 1)
{
rotated_imm = rotate_imm(imm, rotate);
if (rotate != 0)
rotated_carry = bits(rotated_imm, 31);
}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
/**
* Base class for predicated integer operations.
*/
class PredIntOp : public PredOp
{
protected:
uint32_t shift_size;
uint32_t shift;
/// Constructor
PredIntOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
PredOp(mnem, _machInst, __opClass),
shift_size(machInst.shiftSize), shift(machInst.shift)
{
}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
class DataImmOp : public PredOp
{
protected:
IntRegIndex dest, op1;
uint32_t imm;
// Whether the carry flag should be modified if that's an option for
// this instruction.
bool rotC;
DataImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
IntRegIndex _dest, IntRegIndex _op1, uint32_t _imm, bool _rotC) :
PredOp(mnem, _machInst, __opClass),
dest(_dest), op1(_op1), imm(_imm), rotC(_rotC)
{}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
class DataRegOp : public PredOp
{
protected:
IntRegIndex dest, op1, op2;
int32_t shiftAmt;
ArmShiftType shiftType;
DataRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2,
int32_t _shiftAmt, ArmShiftType _shiftType) :
PredOp(mnem, _machInst, __opClass),
dest(_dest), op1(_op1), op2(_op2),
shiftAmt(_shiftAmt), shiftType(_shiftType)
{}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
class DataRegRegOp : public PredOp
{
protected:
IntRegIndex dest, op1, op2, shift;
ArmShiftType shiftType;
DataRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2,
IntRegIndex _shift, ArmShiftType _shiftType) :
PredOp(mnem, _machInst, __opClass),
dest(_dest), op1(_op1), op2(_op2), shift(_shift),
shiftType(_shiftType)
{}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
/**
* Base class for predicated macro-operations.
*/
class PredMacroOp : public PredOp
{
protected:
uint32_t numMicroops;
StaticInstPtr * microOps;
/// Constructor
PredMacroOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
PredOp(mnem, _machInst, __opClass),
numMicroops(0)
{
// We rely on the subclasses of this object to handle the
// initialization of the micro-operations, since they are
// all of variable length
flags[IsMacroop] = true;
}
~PredMacroOp()
{
if (numMicroops)
delete [] microOps;
}
StaticInstPtr
fetchMicroop(MicroPC microPC) const
{
assert(microPC < numMicroops);
return microOps[microPC];
}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
/**
* Base class for predicated micro-operations.
*/
class PredMicroop : public PredOp
{
/// Constructor
PredMicroop(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
PredOp(mnem, _machInst, __opClass)
{
flags[IsMicroop] = true;
}
void
advancePC(PCState &pcState) const
{
if (flags[IsLastMicroop])
pcState.uEnd();
else
pcState.uAdvance();
}
};
}
#endif //__ARCH_ARM_INSTS_PREDINST_HH__

Some files were not shown because too many files have changed in this diff Show More