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

View File

@ -0,0 +1,68 @@
# -*- 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'] == 'sparc':
Source('asi.cc')
Source('decoder.cc')
Source('faults.cc')
Source('interrupts.cc')
Source('isa.cc')
Source('linux/linux.cc')
Source('linux/process.cc')
Source('linux/syscalls.cc')
Source('nativetrace.cc')
Source('pagetable.cc')
Source('process.cc')
Source('remote_gdb.cc')
Source('solaris/process.cc')
Source('solaris/solaris.cc')
Source('system.cc')
Source('tlb.cc')
Source('ua2005.cc')
Source('utility.cc')
Source('vtophys.cc')
SimObject('SparcInterrupts.py')
SimObject('SparcNativeTrace.py')
SimObject('SparcSystem.py')
SimObject('SparcTLB.py')
DebugFlag('Sparc', "Generic SPARC ISA stuff")
DebugFlag('RegisterWindows', "Register window manipulation")
# 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) 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: Nathan Binkert
Import('*')
all_isa_list.append('sparc')

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 SparcInterrupts(SimObject):
type = 'SparcInterrupts'
cxx_class = 'SparcISA::Interrupts'

View File

@ -0,0 +1,35 @@
# 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 SparcNativeTrace(NativeTrace):
type = 'SparcNativeTrace'
cxx_class = 'Trace::SparcNativeTrace'

View File

@ -0,0 +1,74 @@
# 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 SimpleMemory import SimpleMemory
from System import System
class SparcSystem(System):
type = 'SparcSystem'
_rom_base = 0xfff0000000
_nvram_base = 0x1f11000000
_hypervisor_desc_base = 0x1f12080000
_partition_desc_base = 0x1f12000000
# ROM for OBP/Reset/Hypervisor
rom = Param.SimpleMemory(
SimpleMemory(range=AddrRange(_rom_base, size='8MB')),
"Memory to hold the ROM data")
# nvram
nvram = Param.SimpleMemory(
SimpleMemory(range=AddrRange(_nvram_base, size='8kB')),
"Memory to hold the nvram data")
# hypervisor description
hypervisor_desc = Param.SimpleMemory(
SimpleMemory(range=AddrRange(_hypervisor_desc_base, size='8kB')),
"Memory to hold the hypervisor description")
# partition description
partition_desc = Param.SimpleMemory(
SimpleMemory(range=AddrRange(_partition_desc_base, size='8kB')),
"Memory to hold the partition description")
reset_addr = Param.Addr(_rom_base, "Address to load ROM at")
hypervisor_addr = Param.Addr(Addr('64kB') + _rom_base,
"Address to load hypervisor at")
openboot_addr = Param.Addr(Addr('512kB') + _rom_base,
"Address to load openboot at")
nvram_addr = Param.Addr(_nvram_base, "Address to put the nvram")
hypervisor_desc_addr = Param.Addr(_hypervisor_desc_base,
"Address for the hypervisor description")
partition_desc_addr = Param.Addr(_partition_desc_base,
"Address for the partition description")
reset_bin = Param.String("file that contains the reset code")
hypervisor_bin = Param.String("file that contains the hypervisor code")
openboot_bin = Param.String("file that contains the openboot code")
nvram_bin = Param.String("file that contains the contents of nvram")
hypervisor_desc_bin = Param.String("file that contains the hypervisor description")
partition_desc_bin = Param.String("file that contains the partition description")
load_addr_mask = 0xffffffffff

View File

@ -0,0 +1,37 @@
# 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: Ali Saidi
from m5.SimObject import SimObject
from m5.params import *
from BaseTLB import BaseTLB
class SparcTLB(BaseTLB):
type = 'SparcTLB'
cxx_class = 'SparcISA::TLB'
size = Param.Int(64, "TLB size")

View File

@ -0,0 +1,318 @@
/*
* 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: Gabe Black
* Ali Saidi
*/
#include "arch/sparc/asi.hh"
namespace SparcISA
{
bool
asiIsBlock(ASI asi)
{
return asi == ASI_BLK_AIUP ||
asi == ASI_BLK_AIUS ||
asi == ASI_BLK_AIUP_L ||
asi == ASI_BLK_AIUS_L ||
asi == ASI_BLK_P ||
asi == ASI_BLK_S ||
asi == ASI_BLK_PL ||
asi == ASI_BLK_SL;
}
bool
asiIsPrimary(ASI asi)
{
return asi == ASI_AIUP ||
asi == ASI_BLK_AIUP ||
asi == ASI_AIUP_L ||
asi == ASI_BLK_AIUP_L ||
asi == ASI_LDTX_AIUP ||
asi == ASI_LDTX_AIUP_L ||
asi == ASI_P ||
asi == ASI_PNF ||
asi == ASI_PL ||
asi == ASI_PNFL ||
asi == ASI_PST8_P ||
asi == ASI_PST16_P ||
asi == ASI_PST32_P ||
asi == ASI_PST8_PL ||
asi == ASI_PST16_PL ||
asi == ASI_PST32_PL ||
asi == ASI_FL8_P ||
asi == ASI_FL16_P ||
asi == ASI_FL8_PL ||
asi == ASI_FL16_PL ||
asi == ASI_LDTX_P ||
asi == ASI_LDTX_PL ||
asi == ASI_BLK_P ||
asi == ASI_BLK_PL;
}
bool
asiIsSecondary(ASI asi)
{
return asi == ASI_AIUS ||
asi == ASI_BLK_AIUS ||
asi == ASI_AIUS_L ||
asi == ASI_BLK_AIUS_L ||
asi == ASI_LDTX_AIUS ||
asi == ASI_LDTX_AIUS_L ||
asi == ASI_S ||
asi == ASI_SNF ||
asi == ASI_SL ||
asi == ASI_SNFL ||
asi == ASI_PST8_S ||
asi == ASI_PST16_S ||
asi == ASI_PST32_S ||
asi == ASI_PST8_SL ||
asi == ASI_PST16_SL ||
asi == ASI_PST32_SL ||
asi == ASI_FL8_S ||
asi == ASI_FL16_S ||
asi == ASI_FL8_SL ||
asi == ASI_FL16_SL ||
asi == ASI_LDTX_S ||
asi == ASI_LDTX_SL ||
asi == ASI_BLK_S ||
asi == ASI_BLK_SL;
}
bool
asiIsNucleus(ASI asi)
{
return asi == ASI_N ||
asi == ASI_NL ||
asi == ASI_LDTX_N ||
asi == ASI_LDTX_NL;
}
bool
asiIsAsIfUser(ASI asi)
{
return asi == ASI_AIUP ||
asi == ASI_AIUS ||
asi == ASI_BLK_AIUP ||
asi == ASI_BLK_AIUS ||
asi == ASI_AIUP_L ||
asi == ASI_AIUS_L ||
asi == ASI_BLK_AIUP_L ||
asi == ASI_BLK_AIUS_L ||
asi == ASI_LDTX_AIUP ||
asi == ASI_LDTX_AIUS ||
asi == ASI_LDTX_AIUP_L ||
asi == ASI_LDTX_AIUS_L;
}
bool
asiIsIO(ASI asi)
{
return asi == ASI_REAL_IO ||
asi == ASI_REAL_IO_L;
}
bool
asiIsReal(ASI asi)
{
return asi == ASI_REAL ||
asi == ASI_REAL_IO ||
asi == ASI_REAL_L ||
asi == ASI_REAL_IO_L ||
asi == ASI_LDTX_REAL ||
asi == ASI_LDTX_REAL_L;
}
bool
asiIsLittle(ASI asi)
{
return asi == ASI_NL ||
asi == ASI_AIUP_L ||
asi == ASI_AIUS_L ||
asi == ASI_REAL_L ||
asi == ASI_REAL_IO_L ||
asi == ASI_BLK_AIUP_L ||
asi == ASI_BLK_AIUS_L ||
asi == ASI_LDTX_AIUP_L ||
asi == ASI_LDTX_AIUS_L ||
asi == ASI_LDTX_REAL_L ||
asi == ASI_LDTX_NL ||
asi == ASI_PL ||
asi == ASI_SL ||
asi == ASI_PNFL ||
asi == ASI_SNFL ||
asi == ASI_PST8_PL ||
asi == ASI_PST8_SL ||
asi == ASI_PST16_PL ||
asi == ASI_PST16_SL ||
asi == ASI_PST32_PL ||
asi == ASI_PST32_SL ||
asi == ASI_FL8_PL ||
asi == ASI_FL8_SL ||
asi == ASI_FL16_PL ||
asi == ASI_FL16_SL ||
asi == ASI_LDTX_PL ||
asi == ASI_LDTX_SL ||
asi == ASI_BLK_PL ||
asi == ASI_BLK_SL ||
asi == ASI_LTX_L;
}
bool
asiIsTwin(ASI asi)
{
return (asi >= ASI_LDTX_AIUP &&
asi <= ASI_LDTX_N &&
asi != ASI_QUEUE) ||
(asi >= ASI_LDTX_AIUP_L &&
asi <= ASI_LDTX_NL &&
asi != 0x2D) ||
asi == ASI_LDTX_P ||
asi == ASI_LDTX_S ||
asi == ASI_LDTX_PL ||
asi == ASI_LDTX_SL;
}
bool
asiIsPartialStore(ASI asi)
{
return asi == ASI_PST8_P ||
asi == ASI_PST8_S ||
asi == ASI_PST16_P ||
asi == ASI_PST16_S ||
asi == ASI_PST32_P ||
asi == ASI_PST32_S ||
asi == ASI_PST8_PL ||
asi == ASI_PST8_SL ||
asi == ASI_PST16_PL ||
asi == ASI_PST16_SL ||
asi == ASI_PST32_PL ||
asi == ASI_PST32_SL;
}
bool
asiIsFloatingLoad(ASI asi)
{
return asi == ASI_FL8_P ||
asi == ASI_FL8_S ||
asi == ASI_FL16_P ||
asi == ASI_FL16_S ||
asi == ASI_FL8_PL ||
asi == ASI_FL8_SL ||
asi == ASI_FL16_PL ||
asi == ASI_FL16_SL;
}
bool
asiIsNoFault(ASI asi)
{
return asi == ASI_PNF ||
asi == ASI_SNF ||
asi == ASI_PNFL ||
asi == ASI_SNFL;
}
bool
asiIsScratchPad(ASI asi)
{
return asi == ASI_SCRATCHPAD ||
asi == ASI_HYP_SCRATCHPAD;
}
bool
asiIsCmt(ASI asi)
{
return asi == ASI_CMT_PER_STRAND ||
asi == ASI_CMT_SHARED;
}
bool
asiIsQueue(ASI asi)
{
return asi == ASI_QUEUE;
}
bool
asiIsInterrupt(ASI asi)
{
return asi == ASI_SWVR_INTR_RECEIVE ||
asi == ASI_SWVR_UDB_INTR_W ||
asi == ASI_SWVR_UDB_INTR_R ;
}
bool
asiIsMmu(ASI asi)
{
return asi == ASI_MMU ||
asi == ASI_LSU_CONTROL_REG ||
(asi >= ASI_DMMU_CTXT_ZERO_TSB_BASE_PS0 &&
asi <= ASI_IMMU_CTXT_ZERO_CONFIG) ||
(asi >= ASI_DMMU_CTXT_NONZERO_TSB_BASE_PS0 &&
asi <= ASI_IMMU_CTXT_NONZERO_CONFIG) ||
(asi >= ASI_IMMU &&
asi <= ASI_IMMU_TSB_PS1_PTR_REG) ||
(asi >= ASI_ITLB_DATA_IN_REG &&
asi <= ASI_TLB_INVALIDATE_ALL);
}
bool
asiIsUnPriv(ASI asi)
{
return asi >= 0x80;
}
bool
asiIsPriv(ASI asi)
{
return asi <= 0x2f;
}
bool
asiIsHPriv(ASI asi)
{
return asi >= 0x30 && asi <= 0x7f;
}
bool
asiIsReg(ASI asi)
{
return asiIsMmu(asi) || asiIsScratchPad(asi) ||
asiIsSparcError(asi) || asiIsInterrupt(asi)
|| asiIsCmt(asi);
}
bool
asiIsSparcError(ASI asi)
{
return asi == ASI_SPARC_ERROR_EN_REG ||
asi == ASI_SPARC_ERROR_STATUS_REG;
}
}

View File

@ -0,0 +1,277 @@
/*
* 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: Gabe Black
* Ali Saidi
*/
#ifndef __ARCH_SPARC_ASI_HH__
#define __ARCH_SPARC_ASI_HH__
namespace SparcISA
{
enum ASI {
ASI_IMPLICIT = 0x00,
/* Priveleged ASIs */
// 0x00-0x03 implementation dependent
ASI_NUCLEUS = 0x4,
ASI_N = 0x4,
// 0x05-0x0B implementation dependent
ASI_NL = 0xC,
ASI_NUCLEUS_LITTLE = ASI_NL,
// 0x0D-0x0F implementation dependent
ASI_AIUP = 0x10,
ASI_AS_IF_USER_PRIMARY = ASI_AIUP,
ASI_AIUS = 0x11,
ASI_AS_IF_USER_SECONDARY = ASI_AIUS,
// 0x12-0x13 implementation dependent
ASI_REAL = 0x14,
ASI_REAL_IO = 0x15,
ASI_BLK_AIUP = 0x16,
ASI_BLOCK_AS_IF_USER_PRIMARY = ASI_BLK_AIUP,
ASI_BLK_AIUS = 0x17,
ASI_BLOCK_AS_IF_USER_SECONDARY = ASI_BLK_AIUS,
ASI_AIUP_L = 0x18,
ASI_AS_IF_USER_PRIMARY_LITTLE = ASI_AIUP_L,
ASI_AIUS_L = 0x19,
ASI_AS_IF_USER_SECONDARY_LITTLE = ASI_AIUS_L,
// 0x1A-0x1B implementation dependent
ASI_REAL_L = 0x1C,
ASI_REAL_LITTLE = ASI_REAL_L,
ASI_REAL_IO_L = 0x1D,
ASI_REAL_IO_LITTLE = ASI_REAL_IO_L,
ASI_BLK_AIUP_L = 0x1E,
ASI_BLOCK_AS_IF_USER_PRIMARY_LITTLE = ASI_BLK_AIUP_L,
ASI_BLK_AIUS_L = 0x1F,
ASI_BLOCK_AS_IF_USER_SECONDARY_LITTLE = ASI_BLK_AIUS_L,
ASI_SCRATCHPAD = 0x20,
ASI_MMU = 0x21,
ASI_LDTX_AIUP = 0x22,
ASI_LD_TWINX_AS_IF_USER_PRIMARY = ASI_LDTX_AIUP,
ASI_LDTX_AIUS = 0x23,
ASI_LD_TWINX_AS_IF_USER_SECONDARY = ASI_LDTX_AIUS,
ASI_QUAD_LDD = 0x24,
ASI_QUEUE = 0x25,
ASI_QUAD_LDD_REAL = 0x26,
ASI_LDTX_REAL = ASI_QUAD_LDD_REAL,
ASI_LDTX_N = 0x27,
ASI_LD_TWINX_NUCLEUS = ASI_LDTX_N,
ASI_ST_BLKINIT_NUCLEUS = ASI_LDTX_N,
ASI_STBI_N = ASI_LDTX_N,
// 0x28-0x29 implementation dependent
ASI_LDTX_AIUP_L = 0x2A,
ASI_TWINX_AS_IF_USER_PRIMARY_LITTLE = ASI_LDTX_AIUP_L,
ASI_ST_BLKINIT_AS_IF_USER_PRIMARY_LITTLE = ASI_LDTX_AIUP_L,
ASI_STBI_AIUP_L = ASI_LDTX_AIUP_L,
ASI_LDTX_AIUS_L = 0x2B,
ASI_LD_TWINX_AS_IF_USER_SECONDARY_LITTLE = ASI_LDTX_AIUS_L,
ASI_ST_BLKINIT_AS_IF_USER_SECONDARY_LITTLE = ASI_LDTX_AIUS_L,
ASI_STBI_AIUS_L = ASI_LDTX_AIUS_L,
ASI_LTX_L = 0x2C,
ASI_TWINX_LITTLE = ASI_LTX_L,
// 0x2D implementation dependent
ASI_LDTX_REAL_L = 0x2E,
ASI_LD_TWINX_REAL_LITTLE = ASI_LDTX_REAL_L,
ASI_LDTX_NL = 0x2F,
ASI_LD_TWINX_NUCLEUS_LITTLE = ASI_LDTX_NL,
// 0x20 implementation dependent
ASI_DMMU_CTXT_ZERO_TSB_BASE_PS0 = 0x31,
ASI_DMMU_CTXT_ZERO_TSB_BASE_PS1 = 0x32,
ASI_DMMU_CTXT_ZERO_CONFIG = 0x33,
// 0x34 implementation dependent
ASI_IMMU_CTXT_ZERO_TSB_BASE_PS0 = 0x35,
ASI_IMMU_CTXT_ZERO_TSB_BASE_PS1 = 0x36,
ASI_IMMU_CTXT_ZERO_CONFIG = 0x37,
// 0x38 implementation dependent
ASI_DMMU_CTXT_NONZERO_TSB_BASE_PS0 = 0x39,
ASI_DMMU_CTXT_NONZERO_TSB_BASE_PS1 = 0x3A,
ASI_DMMU_CTXT_NONZERO_CONFIG = 0x3B,
// 0x3C implementation dependent
ASI_IMMU_CTXT_NONZERO_TSB_BASE_PS0 = 0x3D,
ASI_IMMU_CTXT_NONZERO_TSB_BASE_PS1 = 0x3E,
ASI_IMMU_CTXT_NONZERO_CONFIG = 0x3F,
ASI_STREAM_MA = 0x40,
ASI_CMT_SHARED = 0x41,
// 0x41 implementation dependent
ASI_SPARC_BIST_CONTROL = 0x42,
ASI_INST_MASK_REG = 0x42,
ASI_LSU_DIAG_REG = 0x42,
// 0x43 implementation dependent
ASI_STM_CTL_REG = 0x44,
ASI_LSU_CONTROL_REG = 0x45,
ASI_DCACHE_DATA = 0x46,
ASI_DCACHE_TAG = 0x47,
ASI_INTR_DISPATCH_STATUS = 0x48,
ASI_INTR_RECEIVE = 0x49,
ASI_UPA_CONFIG_REGISTER = 0x4A,
ASI_SPARC_ERROR_EN_REG = 0x4B,
ASI_SPARC_ERROR_STATUS_REG = 0x4C,
ASI_SPARC_ERROR_ADDRESS_REG = 0x4D,
ASI_ECACHE_TAG_DATA = 0x4E,
ASI_HYP_SCRATCHPAD = 0x4F,
ASI_IMMU = 0x50,
ASI_IMMU_TSB_PS0_PTR_REG = 0x51,
ASI_IMMU_TSB_PS1_PTR_REG = 0x52,
// 0x53 implementation dependent
ASI_ITLB_DATA_IN_REG = 0x54,
ASI_ITLB_DATA_ACCESS_REG = 0x55,
ASI_ITLB_TAG_READ_REG = 0x56,
ASI_IMMU_DEMAP = 0x57,
ASI_DMMU = 0x58,
ASI_DMMU_TSB_PS0_PTR_REG = 0x59,
ASI_DMMU_TSB_PS1_PTR_REG = 0x5A,
ASI_DMMU_TSB_DIRECT_PTR_REG = 0x5B,
ASI_DTLB_DATA_IN_REG = 0x5C,
ASI_DTLB_DATA_ACCESS_REG = 0x5D,
ASI_DTLB_TAG_READ_REG = 0x5E,
ASI_DMMU_DEMAP = 0x5F,
ASI_TLB_INVALIDATE_ALL = 0x60,
// 0x61-0x62 implementation dependent
ASI_CMT_PER_STRAND = 0x63,
// 0x64-0x65 implementation dependent
ASI_ICACHE_INSTR = 0x66,
ASI_ICACHE_TAG = 0x67,
// 0x68-0x71 implementation dependent
ASI_SWVR_INTR_RECEIVE = 0x72,
ASI_SWVR_UDB_INTR_W = 0x73,
ASI_SWVR_UDB_INTR_R = 0x74,
// 0x74-0x7F reserved
/* Unpriveleged ASIs */
ASI_P = 0x80,
ASI_PRIMARY = ASI_P,
ASI_S = 0x81,
ASI_SECONDARY = ASI_S,
ASI_PNF = 0x82,
ASI_PRIMARY_NO_FAULT = ASI_PNF,
ASI_SNF = 0x83,
ASI_SECONDARY_NO_FAULT = ASI_SNF,
// 0x84-0x87 reserved
ASI_PL = 0x88,
ASI_PRIMARY_LITTLE = ASI_PL,
ASI_SL = 0x89,
ASI_SECONDARY_LITTLE = ASI_SL,
ASI_PNFL = 0x8A,
ASI_PRIMARY_NO_FAULT_LITTLE = ASI_PNFL,
ASI_SNFL = 0x8B,
ASI_SECONDARY_NO_FAULT_LITTLE = ASI_SNFL,
// 0x8C-0xBF reserved
ASI_PST8_P = 0xC0,
ASI_PST8_PRIMARY = ASI_PST8_P,
ASI_PST8_S = 0xC1,
ASI_PST8_SECONDARY = ASI_PST8_S,
ASI_PST16_P = 0xC2,
ASI_PST16_PRIMARY = ASI_PST16_P,
ASI_PST16_S = 0xC3,
ASI_PST16_SECONDARY = ASI_PST16_S,
ASI_PST32_P = 0xC4,
ASI_PST32_PRIMARY = ASI_PST32_P,
ASI_PST32_S = 0xC5,
ASI_PST32_SECONDARY = ASI_PST32_S,
// 0xC6-0xC7 implementation dependent
ASI_PST8_PL = 0xC8,
ASI_PST8_PRIMARY_LITTLE = ASI_PST8_PL,
ASI_PST8_SL = 0xC9,
ASI_PST8_SECONDARY_LITTLE = ASI_PST8_SL,
ASI_PST16_PL = 0xCA,
ASI_PST16_PRIMARY_LITTLE = ASI_PST16_PL,
ASI_PST16_SL = 0xCB,
ASI_PST16_SECONDARY_LITTLE = ASI_PST16_SL,
ASI_PST32_PL = 0xCC,
ASI_PST32_PRIMARY_LITTLE = ASI_PST32_PL,
ASI_PST32_SL = 0xCD,
ASI_PST32_SECONDARY_LITTLE = ASI_PST32_SL,
// 0xCE-0xCF implementation dependent
ASI_FL8_P = 0xD0,
ASI_FL8_PRIMARY = ASI_FL8_P,
ASI_FL8_S = 0xD1,
ASI_FL8_SECONDARY = ASI_FL8_S,
ASI_FL16_P = 0xD2,
ASI_FL16_PRIMARY = ASI_FL16_P,
ASI_FL16_S = 0xD3,
ASI_FL16_SECONDARY = ASI_FL16_S,
// 0xD4-0xD7 implementation dependent
ASI_FL8_PL = 0xD8,
ASI_FL8_PRIMARY_LITTLE = ASI_FL8_PL,
ASI_FL8_SL = 0xD9,
ASI_FL8_SECONDARY_LITTLE = ASI_FL8_SL,
ASI_FL16_PL = 0xDA,
ASI_FL16_PRIMARY_LITTLE = ASI_FL16_PL,
ASI_FL16_SL = 0xDB,
ASI_FL16_SECONDARY_LITTLE = ASI_FL16_SL,
// 0xDC-0xDF implementation dependent
// 0xE0-0xE1 reserved
ASI_LDTX_P = 0xE2,
ASI_LD_TWINX_PRIMARY = ASI_LDTX_P,
ASI_LDTX_S = 0xE3,
ASI_LD_TWINX_SECONDARY = ASI_LDTX_S,
// 0xE4-0xE9 implementation dependent
ASI_LDTX_PL = 0xEA,
ASI_LD_TWINX_PRIMARY_LITTLE = ASI_LDTX_PL,
ASI_LDTX_SL = 0xEB,
ASI_LD_TWINX_SECONDARY_LITTLE = ASI_LDTX_SL,
// 0xEC-0xEF implementation dependent
ASI_BLK_P = 0xF0,
ASI_BLOCK_PRIMARY = ASI_BLK_P,
ASI_BLK_S = 0xF1,
ASI_BLOCK_SECONDARY = ASI_BLK_S,
// 0xF2-0xF7 implementation dependent
ASI_BLK_PL = 0xF8,
ASI_BLOCK_PRIMARY_LITTLE = ASI_BLK_PL,
ASI_BLK_SL = 0xF9,
ASI_BLOCK_SECONDARY_LITTLE = ASI_BLK_SL,
// 0xFA-0xFF implementation dependent
MAX_ASI = 0xFF
};
// Functions that classify an asi
bool asiIsBlock(ASI);
bool asiIsPrimary(ASI);
bool asiIsSecondary(ASI);
bool asiIsNucleus(ASI);
bool asiIsAsIfUser(ASI);
bool asiIsIO(ASI);
bool asiIsReal(ASI);
bool asiIsLittle(ASI);
bool asiIsTwin(ASI);
bool asiIsPartialStore(ASI);
bool asiIsFloatingLoad(ASI);
bool asiIsNoFault(ASI);
bool asiIsScratchPad(ASI);
bool asiIsCmt(ASI);
bool asiIsQueue(ASI);
bool asiIsDtlb(ASI);
bool asiIsMmu(ASI);
bool asiIsUnPriv(ASI);
bool asiIsPriv(ASI);
bool asiIsHPriv(ASI);
bool asiIsReg(ASI);
bool asiIsInterrupt(ASI);
bool asiIsSparcError(ASI);
};
#endif // __ARCH_SPARC_ASI_HH__

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/sparc/decoder.hh"
namespace SparcISA
{
GenericISA::BasicDecodeCache Decoder::defaultCache;
}

View File

@ -0,0 +1,138 @@
/*
* 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_SPARC_DECODER_HH__
#define __ARCH_SPARC_DECODER_HH__
#include "arch/generic/decode_cache.hh"
#include "arch/sparc/registers.hh"
#include "arch/types.hh"
#include "cpu/static_inst.hh"
#include "cpu/thread_context.hh"
class ThreadContext;
namespace SparcISA
{
class Decoder
{
protected:
ThreadContext * tc;
// The extended machine instruction being generated
ExtMachInst emi;
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)
{
emi = inst;
// The I bit, bit 13, is used to figure out where the ASI
// should come from. Use that in the ExtMachInst. This is
// slightly redundant, but it removes the need to put a condition
// into all the execute functions
if (inst & (1 << 13)) {
emi |= (static_cast<ExtMachInst>(
tc->readMiscRegNoEffect(MISCREG_ASI))
<< (sizeof(MachInst) * 8));
} else {
emi |= (static_cast<ExtMachInst>(bits(inst, 12, 5))
<< (sizeof(MachInst) * 8));
}
instDone = true;
}
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(SparcISA::PCState &nextPC)
{
if (!instDone)
return NULL;
instDone = false;
return decode(emi, nextPC.instAddr());
}
};
} // namespace SparcISA
#endif // __ARCH_SPARC_DECODER_HH__

View File

@ -0,0 +1,727 @@
/*
* 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 <algorithm>
#include "arch/sparc/faults.hh"
#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/process.hh"
#include "arch/sparc/types.hh"
#include "base/bitfield.hh"
#include "base/trace.hh"
#include "sim/full_system.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
#include "mem/page_table.hh"
#include "sim/process.hh"
#include "sim/full_system.hh"
using namespace std;
namespace SparcISA
{
template<> SparcFaultBase::FaultVals
SparcFault<PowerOnReset>::vals =
{"power_on_reset", 0x001, 0, {H, H, H}};
template<> SparcFaultBase::FaultVals
SparcFault<WatchDogReset>::vals =
{"watch_dog_reset", 0x002, 120, {H, H, H}};
template<> SparcFaultBase::FaultVals
SparcFault<ExternallyInitiatedReset>::vals =
{"externally_initiated_reset", 0x003, 110, {H, H, H}};
template<> SparcFaultBase::FaultVals
SparcFault<SoftwareInitiatedReset>::vals =
{"software_initiated_reset", 0x004, 130, {SH, SH, H}};
template<> SparcFaultBase::FaultVals
SparcFault<REDStateException>::vals =
{"RED_state_exception", 0x005, 1, {H, H, H}};
template<> SparcFaultBase::FaultVals
SparcFault<StoreError>::vals =
{"store_error", 0x007, 201, {H, H, H}};
template<> SparcFaultBase::FaultVals
SparcFault<InstructionAccessException>::vals =
{"instruction_access_exception", 0x008, 300, {H, H, H}};
//XXX This trap is apparently dropped from ua2005
/*template<> SparcFaultBase::FaultVals
SparcFault<InstructionAccessMMUMiss>::vals =
{"inst_mmu", 0x009, 2, {H, H, H}};*/
template<> SparcFaultBase::FaultVals
SparcFault<InstructionAccessError>::vals =
{"instruction_access_error", 0x00A, 400, {H, H, H}};
template<> SparcFaultBase::FaultVals
SparcFault<IllegalInstruction>::vals =
{"illegal_instruction", 0x010, 620, {H, H, H}};
template<> SparcFaultBase::FaultVals
SparcFault<PrivilegedOpcode>::vals =
{"privileged_opcode", 0x011, 700, {P, SH, SH}};
//XXX This trap is apparently dropped from ua2005
/*template<> SparcFaultBase::FaultVals
SparcFault<UnimplementedLDD>::vals =
{"unimp_ldd", 0x012, 6, {H, H, H}};*/
//XXX This trap is apparently dropped from ua2005
/*template<> SparcFaultBase::FaultVals
SparcFault<UnimplementedSTD>::vals =
{"unimp_std", 0x013, 6, {H, H, H}};*/
template<> SparcFaultBase::FaultVals
SparcFault<FpDisabled>::vals =
{"fp_disabled", 0x020, 800, {P, P, H}};
template<> SparcFaultBase::FaultVals
SparcFault<FpExceptionIEEE754>::vals =
{"fp_exception_ieee_754", 0x021, 1110, {P, P, H}};
template<> SparcFaultBase::FaultVals
SparcFault<FpExceptionOther>::vals =
{"fp_exception_other", 0x022, 1110, {P, P, H}};
template<> SparcFaultBase::FaultVals
SparcFault<TagOverflow>::vals =
{"tag_overflow", 0x023, 1400, {P, P, H}};
template<> SparcFaultBase::FaultVals
SparcFault<CleanWindow>::vals =
{"clean_window", 0x024, 1010, {P, P, H}};
template<> SparcFaultBase::FaultVals
SparcFault<DivisionByZero>::vals =
{"division_by_zero", 0x028, 1500, {P, P, H}};
template<> SparcFaultBase::FaultVals
SparcFault<InternalProcessorError>::vals =
{"internal_processor_error", 0x029, 4, {H, H, H}};
template<> SparcFaultBase::FaultVals
SparcFault<InstructionInvalidTSBEntry>::vals =
{"instruction_invalid_tsb_entry", 0x02A, 210, {H, H, SH}};
template<> SparcFaultBase::FaultVals
SparcFault<DataInvalidTSBEntry>::vals =
{"data_invalid_tsb_entry", 0x02B, 1203, {H, H, H}};
template<> SparcFaultBase::FaultVals
SparcFault<DataAccessException>::vals =
{"data_access_exception", 0x030, 1201, {H, H, H}};
//XXX This trap is apparently dropped from ua2005
/*template<> SparcFaultBase::FaultVals
SparcFault<DataAccessMMUMiss>::vals =
{"data_mmu", 0x031, 12, {H, H, H}};*/
template<> SparcFaultBase::FaultVals
SparcFault<DataAccessError>::vals =
{"data_access_error", 0x032, 1210, {H, H, H}};
template<> SparcFaultBase::FaultVals
SparcFault<DataAccessProtection>::vals =
{"data_access_protection", 0x033, 1207, {H, H, H}};
template<> SparcFaultBase::FaultVals
SparcFault<MemAddressNotAligned>::vals =
{"mem_address_not_aligned", 0x034, 1020, {H, H, H}};
template<> SparcFaultBase::FaultVals
SparcFault<LDDFMemAddressNotAligned>::vals =
{"LDDF_mem_address_not_aligned", 0x035, 1010, {H, H, H}};
template<> SparcFaultBase::FaultVals
SparcFault<STDFMemAddressNotAligned>::vals =
{"STDF_mem_address_not_aligned", 0x036, 1010, {H, H, H}};
template<> SparcFaultBase::FaultVals
SparcFault<PrivilegedAction>::vals =
{"privileged_action", 0x037, 1110, {H, H, SH}};
template<> SparcFaultBase::FaultVals
SparcFault<LDQFMemAddressNotAligned>::vals =
{"LDQF_mem_address_not_aligned", 0x038, 1010, {H, H, H}};
template<> SparcFaultBase::FaultVals
SparcFault<STQFMemAddressNotAligned>::vals =
{"STQF_mem_address_not_aligned", 0x039, 1010, {H, H, H}};
template<> SparcFaultBase::FaultVals
SparcFault<InstructionRealTranslationMiss>::vals =
{"instruction_real_translation_miss", 0x03E, 208, {H, H, SH}};
template<> SparcFaultBase::FaultVals
SparcFault<DataRealTranslationMiss>::vals =
{"data_real_translation_miss", 0x03F, 1203, {H, H, H}};
//XXX This trap is apparently dropped from ua2005
/*template<> SparcFaultBase::FaultVals
SparcFault<AsyncDataError>::vals =
{"async_data", 0x040, 2, {H, H, H}};*/
template<> SparcFaultBase::FaultVals
SparcFault<InterruptLevelN>::vals =
{"interrupt_level_n", 0x040, 0, {P, P, SH}};
template<> SparcFaultBase::FaultVals
SparcFault<HstickMatch>::vals =
{"hstick_match", 0x05E, 1601, {H, H, H}};
template<> SparcFaultBase::FaultVals
SparcFault<TrapLevelZero>::vals =
{"trap_level_zero", 0x05F, 202, {H, H, SH}};
template<> SparcFaultBase::FaultVals
SparcFault<InterruptVector>::vals =
{"interrupt_vector", 0x060, 2630, {H, H, H}};
template<> SparcFaultBase::FaultVals
SparcFault<PAWatchpoint>::vals =
{"PA_watchpoint", 0x061, 1209, {H, H, H}};
template<> SparcFaultBase::FaultVals
SparcFault<VAWatchpoint>::vals =
{"VA_watchpoint", 0x062, 1120, {P, P, SH}};
template<> SparcFaultBase::FaultVals
SparcFault<FastInstructionAccessMMUMiss>::vals =
{"fast_instruction_access_MMU_miss", 0x064, 208, {H, H, SH}};
template<> SparcFaultBase::FaultVals
SparcFault<FastDataAccessMMUMiss>::vals =
{"fast_data_access_MMU_miss", 0x068, 1203, {H, H, H}};
template<> SparcFaultBase::FaultVals
SparcFault<FastDataAccessProtection>::vals =
{"fast_data_access_protection", 0x06C, 1207, {H, H, H}};
template<> SparcFaultBase::FaultVals
SparcFault<InstructionBreakpoint>::vals =
{"instruction_break", 0x076, 610, {H, H, H}};
template<> SparcFaultBase::FaultVals
SparcFault<CpuMondo>::vals =
{"cpu_mondo", 0x07C, 1608, {P, P, SH}};
template<> SparcFaultBase::FaultVals
SparcFault<DevMondo>::vals =
{"dev_mondo", 0x07D, 1611, {P, P, SH}};
template<> SparcFaultBase::FaultVals
SparcFault<ResumableError>::vals =
{"resume_error", 0x07E, 3330, {P, P, SH}};
template<> SparcFaultBase::FaultVals
SparcFault<SpillNNormal>::vals =
{"spill_n_normal", 0x080, 900, {P, P, H}};
template<> SparcFaultBase::FaultVals
SparcFault<SpillNOther>::vals =
{"spill_n_other", 0x0A0, 900, {P, P, H}};
template<> SparcFaultBase::FaultVals
SparcFault<FillNNormal>::vals =
{"fill_n_normal", 0x0C0, 900, {P, P, H}};
template<> SparcFaultBase::FaultVals
SparcFault<FillNOther>::vals =
{"fill_n_other", 0x0E0, 900, {P, P, H}};
template<> SparcFaultBase::FaultVals
SparcFault<TrapInstruction>::vals =
{"trap_instruction", 0x100, 1602, {P, P, H}};
/**
* This causes the thread context to enter RED state. This causes the side
* effects which go with entering RED state because of a trap.
*/
void
enterREDState(ThreadContext *tc)
{
//@todo Disable the mmu?
//@todo Disable watchpoints?
HPSTATE hpstate= tc->readMiscRegNoEffect(MISCREG_HPSTATE);
hpstate.red = 1;
hpstate.hpriv = 1;
tc->setMiscReg(MISCREG_HPSTATE, hpstate);
// PSTATE.priv is set to 1 here. The manual says it should be 0, but
// Legion sets it to 1.
PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
pstate.priv = 1;
tc->setMiscReg(MISCREG_PSTATE, pstate);
}
/**
* This sets everything up for a RED state trap except for actually jumping to
* the handler.
*/
void
doREDFault(ThreadContext *tc, TrapType tt)
{
MiscReg TL = tc->readMiscRegNoEffect(MISCREG_TL);
MiscReg TSTATE = tc->readMiscRegNoEffect(MISCREG_TSTATE);
PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2);
MiscReg ASI = tc->readMiscRegNoEffect(MISCREG_ASI);
MiscReg CWP = tc->readMiscRegNoEffect(MISCREG_CWP);
MiscReg CANSAVE = tc->readMiscRegNoEffect(NumIntArchRegs + 3);
MiscReg GL = tc->readMiscRegNoEffect(MISCREG_GL);
PCState pc = tc->pcState();
TL++;
Addr pcMask = pstate.am ? mask(32) : mask(64);
// set TSTATE.gl to gl
replaceBits(TSTATE, 42, 40, GL);
// set TSTATE.ccr to ccr
replaceBits(TSTATE, 39, 32, CCR);
// set TSTATE.asi to asi
replaceBits(TSTATE, 31, 24, ASI);
// set TSTATE.pstate to pstate
replaceBits(TSTATE, 20, 8, pstate);
// set TSTATE.cwp to cwp
replaceBits(TSTATE, 4, 0, CWP);
// Write back TSTATE
tc->setMiscRegNoEffect(MISCREG_TSTATE, TSTATE);
// set TPC to PC
tc->setMiscRegNoEffect(MISCREG_TPC, pc.pc() & pcMask);
// set TNPC to NPC
tc->setMiscRegNoEffect(MISCREG_TNPC, pc.npc() & pcMask);
// set HTSTATE.hpstate to hpstate
tc->setMiscRegNoEffect(MISCREG_HTSTATE, hpstate);
// TT = trap type;
tc->setMiscRegNoEffect(MISCREG_TT, tt);
// Update GL
tc->setMiscReg(MISCREG_GL, min<int>(GL+1, MaxGL));
bool priv = pstate.priv; // just save the priv bit
pstate = 0;
pstate.priv = priv;
pstate.pef = 1;
tc->setMiscRegNoEffect(MISCREG_PSTATE, pstate);
hpstate.red = 1;
hpstate.hpriv = 1;
hpstate.ibe = 0;
hpstate.tlz = 0;
tc->setMiscRegNoEffect(MISCREG_HPSTATE, hpstate);
bool changedCWP = true;
if (tt == 0x24)
CWP++;
else if (0x80 <= tt && tt <= 0xbf)
CWP += (CANSAVE + 2);
else if (0xc0 <= tt && tt <= 0xff)
CWP--;
else
changedCWP = false;
if (changedCWP) {
CWP = (CWP + NWindows) % NWindows;
tc->setMiscReg(MISCREG_CWP, CWP);
}
}
/**
* This sets everything up for a normal trap except for actually jumping to
* the handler.
*/
void
doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
{
MiscReg TL = tc->readMiscRegNoEffect(MISCREG_TL);
MiscReg TSTATE = tc->readMiscRegNoEffect(MISCREG_TSTATE);
PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2);
MiscReg ASI = tc->readMiscRegNoEffect(MISCREG_ASI);
MiscReg CWP = tc->readMiscRegNoEffect(MISCREG_CWP);
MiscReg CANSAVE = tc->readIntReg(NumIntArchRegs + 3);
MiscReg GL = tc->readMiscRegNoEffect(MISCREG_GL);
PCState pc = tc->pcState();
// Increment the trap level
TL++;
tc->setMiscRegNoEffect(MISCREG_TL, TL);
Addr pcMask = pstate.am ? mask(32) : mask(64);
// Save off state
// set TSTATE.gl to gl
replaceBits(TSTATE, 42, 40, GL);
// set TSTATE.ccr to ccr
replaceBits(TSTATE, 39, 32, CCR);
// set TSTATE.asi to asi
replaceBits(TSTATE, 31, 24, ASI);
// set TSTATE.pstate to pstate
replaceBits(TSTATE, 20, 8, pstate);
// set TSTATE.cwp to cwp
replaceBits(TSTATE, 4, 0, CWP);
// Write back TSTATE
tc->setMiscRegNoEffect(MISCREG_TSTATE, TSTATE);
// set TPC to PC
tc->setMiscRegNoEffect(MISCREG_TPC, pc.pc() & pcMask);
// set TNPC to NPC
tc->setMiscRegNoEffect(MISCREG_TNPC, pc.npc() & pcMask);
// set HTSTATE.hpstate to hpstate
tc->setMiscRegNoEffect(MISCREG_HTSTATE, hpstate);
// TT = trap type;
tc->setMiscRegNoEffect(MISCREG_TT, tt);
// Update the global register level
if (!gotoHpriv)
tc->setMiscReg(MISCREG_GL, min<int>(GL + 1, MaxPGL));
else
tc->setMiscReg(MISCREG_GL, min<int>(GL + 1, MaxGL));
// pstate.mm is unchanged
pstate.pef = 1; // PSTATE.pef = whether or not an fpu is present
pstate.am = 0;
pstate.ie = 0;
// pstate.tle is unchanged
// pstate.tct = 0
if (gotoHpriv) {
pstate.cle = 0;
// The manual says PSTATE.priv should be 0, but Legion leaves it alone
hpstate.red = 0;
hpstate.hpriv = 1;
hpstate.ibe = 0;
// hpstate.tlz is unchanged
tc->setMiscRegNoEffect(MISCREG_HPSTATE, hpstate);
} else { // we are going to priv
pstate.priv = 1;
pstate.cle = pstate.tle;
}
tc->setMiscRegNoEffect(MISCREG_PSTATE, pstate);
bool changedCWP = true;
if (tt == 0x24)
CWP++;
else if (0x80 <= tt && tt <= 0xbf)
CWP += (CANSAVE + 2);
else if (0xc0 <= tt && tt <= 0xff)
CWP--;
else
changedCWP = false;
if (changedCWP) {
CWP = (CWP + NWindows) % NWindows;
tc->setMiscReg(MISCREG_CWP, CWP);
}
}
void
getREDVector(MiscReg TT, Addr &PC, Addr &NPC)
{
//XXX The following constant might belong in a header file.
const Addr RSTVAddr = 0xFFF0000000ULL;
PC = RSTVAddr | ((TT << 5) & 0xFF);
NPC = PC + sizeof(MachInst);
}
void
getHyperVector(ThreadContext * tc, Addr &PC, Addr &NPC, MiscReg TT)
{
Addr HTBA = tc->readMiscRegNoEffect(MISCREG_HTBA);
PC = (HTBA & ~mask(14)) | ((TT << 5) & mask(14));
NPC = PC + sizeof(MachInst);
}
void
getPrivVector(ThreadContext *tc, Addr &PC, Addr &NPC, MiscReg TT, MiscReg TL)
{
Addr TBA = tc->readMiscRegNoEffect(MISCREG_TBA);
PC = (TBA & ~mask(15)) |
(TL > 1 ? (1 << 14) : 0) |
((TT << 5) & mask(14));
NPC = PC + sizeof(MachInst);
}
void
SparcFaultBase::invoke(ThreadContext * tc, StaticInstPtr inst)
{
FaultBase::invoke(tc);
if (!FullSystem)
return;
countStat()++;
// We can refer to this to see what the trap level -was-, but something
// in the middle could change it in the regfile out from under us.
MiscReg tl = tc->readMiscRegNoEffect(MISCREG_TL);
MiscReg tt = tc->readMiscRegNoEffect(MISCREG_TT);
PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
Addr PC, NPC;
PrivilegeLevel current;
if (hpstate.hpriv)
current = Hyperprivileged;
else if (pstate.priv)
current = Privileged;
else
current = User;
PrivilegeLevel level = getNextLevel(current);
if (hpstate.red || (tl == MaxTL - 1)) {
getREDVector(5, PC, NPC);
doREDFault(tc, tt);
// This changes the hpstate and pstate, so we need to make sure we
// save the old version on the trap stack in doREDFault.
enterREDState(tc);
} else if (tl == MaxTL) {
panic("Should go to error state here.. crap\n");
// Do error_state somehow?
// Probably inject a WDR fault using the interrupt mechanism.
// What should the PC and NPC be set to?
} else if (tl > MaxPTL && level == Privileged) {
// guest_watchdog fault
doNormalFault(tc, trapType(), true);
getHyperVector(tc, PC, NPC, 2);
} else if (level == Hyperprivileged ||
(level == Privileged && trapType() >= 384)) {
doNormalFault(tc, trapType(), true);
getHyperVector(tc, PC, NPC, trapType());
} else {
doNormalFault(tc, trapType(), false);
getPrivVector(tc, PC, NPC, trapType(), tl + 1);
}
PCState pc;
pc.pc(PC);
pc.npc(NPC);
pc.nnpc(NPC + sizeof(MachInst));
pc.upc(0);
pc.nupc(1);
tc->pcState(pc);
}
void
PowerOnReset::invoke(ThreadContext *tc, StaticInstPtr inst)
{
// For SPARC, when a system is first started, there is a power
// on reset Trap which sets the processor into the following state.
// Bits that aren't set aren't defined on startup.
tc->setMiscRegNoEffect(MISCREG_TL, MaxTL);
tc->setMiscRegNoEffect(MISCREG_TT, trapType());
tc->setMiscReg(MISCREG_GL, MaxGL);
PSTATE pstate = 0;
pstate.pef = 1;
pstate.priv = 1;
tc->setMiscRegNoEffect(MISCREG_PSTATE, pstate);
// Turn on red and hpriv, set everything else to 0
HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
hpstate.red = 1;
hpstate.hpriv = 1;
hpstate.ibe = 0;
hpstate.tlz = 0;
tc->setMiscRegNoEffect(MISCREG_HPSTATE, hpstate);
// The tick register is unreadable by nonprivileged software
tc->setMiscRegNoEffect(MISCREG_TICK, 1ULL << 63);
// Enter RED state. We do this last so that the actual state preserved in
// the trap stack is the state from before this fault.
enterREDState(tc);
Addr PC, NPC;
getREDVector(trapType(), PC, NPC);
PCState pc;
pc.pc(PC);
pc.npc(NPC);
pc.nnpc(NPC + sizeof(MachInst));
pc.upc(0);
pc.nupc(1);
tc->pcState(pc);
// These registers are specified as "undefined" after a POR, and they
// should have reasonable values after the miscregfile is reset
/*
// Clear all the soft interrupt bits
softint = 0;
// disable timer compare interrupts, reset tick_cmpr
tc->setMiscRegNoEffect(MISCREG_
tick_cmprFields.int_dis = 1;
tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
stickFields.npt = 1; // The TICK register is unreadable by by !priv
stick_cmprFields.int_dis = 1; // disable timer compare interrupts
stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
tt[tl] = _trapType;
hintp = 0; // no interrupts pending
hstick_cmprFields.int_dis = 1; // disable timer compare interrupts
hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
*/
}
void
FastInstructionAccessMMUMiss::invoke(ThreadContext *tc, StaticInstPtr inst)
{
if (FullSystem) {
SparcFaultBase::invoke(tc, inst);
return;
}
Process *p = tc->getProcessPtr();
TlbEntry entry;
bool success = p->pTable->lookup(vaddr, entry);
if (!success) {
panic("Tried to execute unmapped address %#x.\n", vaddr);
} else {
Addr alignedVaddr = p->pTable->pageAlign(vaddr);
tc->getITBPtr()->insert(alignedVaddr, 0 /*partition id*/,
p->M5_pid /*context id*/, false, entry.pte);
}
}
void
FastDataAccessMMUMiss::invoke(ThreadContext *tc, StaticInstPtr inst)
{
if (FullSystem) {
SparcFaultBase::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", vaddr);
} else {
Addr alignedVaddr = p->pTable->pageAlign(vaddr);
tc->getDTBPtr()->insert(alignedVaddr, 0 /*partition id*/,
p->M5_pid /*context id*/, false, entry.pte);
}
}
void
SpillNNormal::invoke(ThreadContext *tc, StaticInstPtr inst)
{
if (FullSystem) {
SparcFaultBase::invoke(tc, inst);
return;
}
doNormalFault(tc, trapType(), false);
Process *p = tc->getProcessPtr();
//XXX This will only work in faults from a SparcLiveProcess
SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p);
assert(lp);
// Then adjust the PC and NPC
tc->pcState(lp->readSpillStart());
}
void
FillNNormal::invoke(ThreadContext *tc, StaticInstPtr inst)
{
if (FullSystem) {
SparcFaultBase::invoke(tc, inst);
return;
}
doNormalFault(tc, trapType(), false);
Process *p = tc->getProcessPtr();
//XXX This will only work in faults from a SparcLiveProcess
SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p);
assert(lp);
// Then adjust the PC and NPC
tc->pcState(lp->readFillStart());
}
void
TrapInstruction::invoke(ThreadContext *tc, StaticInstPtr inst)
{
if (FullSystem) {
SparcFaultBase::invoke(tc, inst);
return;
}
// In SE, this mechanism is how the process requests a service from
// the operating system. We'll get the process object from the thread
// context and let it service the request.
Process *p = tc->getProcessPtr();
SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p);
assert(lp);
lp->handleTrap(_n, tc);
// We need to explicitly advance the pc, since that's not done for us
// on a faulting instruction
PCState pc = tc->pcState();
pc.advance();
tc->pcState(pc);
}
} // namespace SparcISA

View File

@ -0,0 +1,281 @@
/*
* 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 __SPARC_FAULTS_HH__
#define __SPARC_FAULTS_HH__
#include "cpu/static_inst.hh"
#include "sim/faults.hh"
// The design of the "name" and "vect" functions is in sim/faults.hh
namespace SparcISA
{
typedef uint32_t TrapType;
typedef uint32_t FaultPriority;
class ITB;
class SparcFaultBase : public FaultBase
{
public:
enum PrivilegeLevel
{
U, User = U,
P, Privileged = P,
H, Hyperprivileged = H,
NumLevels,
SH = -1,
ShouldntHappen = SH
};
struct FaultVals
{
const FaultName name;
const TrapType trapType;
const FaultPriority priority;
const PrivilegeLevel nextPrivilegeLevel[NumLevels];
FaultStat count;
};
void invoke(ThreadContext * tc,
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
virtual TrapType trapType() = 0;
virtual FaultPriority priority() = 0;
virtual FaultStat & countStat() = 0;
virtual PrivilegeLevel getNextLevel(PrivilegeLevel current) = 0;
};
template<typename T>
class SparcFault : public SparcFaultBase
{
protected:
static FaultVals vals;
public:
FaultName name() const { return vals.name; }
TrapType trapType() { return vals.trapType; }
FaultPriority priority() { return vals.priority; }
FaultStat & countStat() { return vals.count; }
PrivilegeLevel
getNextLevel(PrivilegeLevel current)
{
return vals.nextPrivilegeLevel[current];
}
};
class PowerOnReset : public SparcFault<PowerOnReset>
{
void invoke(ThreadContext * tc,
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
};
class WatchDogReset : public SparcFault<WatchDogReset> {};
class ExternallyInitiatedReset : public SparcFault<ExternallyInitiatedReset> {};
class SoftwareInitiatedReset : public SparcFault<SoftwareInitiatedReset> {};
class REDStateException : public SparcFault<REDStateException> {};
class StoreError : public SparcFault<StoreError> {};
class InstructionAccessException : public SparcFault<InstructionAccessException> {};
// class InstructionAccessMMUMiss : public SparcFault<InstructionAccessMMUMiss> {};
class InstructionAccessError : public SparcFault<InstructionAccessError> {};
class IllegalInstruction : public SparcFault<IllegalInstruction> {};
class PrivilegedOpcode : public SparcFault<PrivilegedOpcode> {};
// class UnimplementedLDD : public SparcFault<UnimplementedLDD> {};
// class UnimplementedSTD : public SparcFault<UnimplementedSTD> {};
class FpDisabled : public SparcFault<FpDisabled> {};
class FpExceptionIEEE754 : public SparcFault<FpExceptionIEEE754> {};
class FpExceptionOther : public SparcFault<FpExceptionOther> {};
class TagOverflow : public SparcFault<TagOverflow> {};
class CleanWindow : public SparcFault<CleanWindow> {};
class DivisionByZero : public SparcFault<DivisionByZero> {};
class InternalProcessorError :
public SparcFault<InternalProcessorError> {};
class InstructionInvalidTSBEntry :
public SparcFault<InstructionInvalidTSBEntry> {};
class DataInvalidTSBEntry : public SparcFault<DataInvalidTSBEntry> {};
class DataAccessException : public SparcFault<DataAccessException> {};
// class DataAccessMMUMiss : public SparcFault<DataAccessMMUMiss> {};
class DataAccessError : public SparcFault<DataAccessError> {};
class DataAccessProtection : public SparcFault<DataAccessProtection> {};
class MemAddressNotAligned :
public SparcFault<MemAddressNotAligned> {};
class LDDFMemAddressNotAligned : public SparcFault<LDDFMemAddressNotAligned> {};
class STDFMemAddressNotAligned : public SparcFault<STDFMemAddressNotAligned> {};
class PrivilegedAction : public SparcFault<PrivilegedAction> {};
class LDQFMemAddressNotAligned : public SparcFault<LDQFMemAddressNotAligned> {};
class STQFMemAddressNotAligned : public SparcFault<STQFMemAddressNotAligned> {};
class InstructionRealTranslationMiss :
public SparcFault<InstructionRealTranslationMiss> {};
class DataRealTranslationMiss : public SparcFault<DataRealTranslationMiss> {};
// class AsyncDataError : public SparcFault<AsyncDataError> {};
template <class T>
class EnumeratedFault : public SparcFault<T>
{
protected:
uint32_t _n;
public:
EnumeratedFault(uint32_t n) : SparcFault<T>(), _n(n) {}
TrapType trapType() { return SparcFault<T>::trapType() + _n; }
};
class InterruptLevelN : public EnumeratedFault<InterruptLevelN>
{
public:
InterruptLevelN(uint32_t n) : EnumeratedFault<InterruptLevelN>(n) {;}
FaultPriority priority() { return 3200 - _n*100; }
};
class HstickMatch : public SparcFault<HstickMatch> {};
class TrapLevelZero : public SparcFault<TrapLevelZero> {};
class InterruptVector : public SparcFault<InterruptVector> {};
class PAWatchpoint : public SparcFault<PAWatchpoint> {};
class VAWatchpoint : public SparcFault<VAWatchpoint> {};
class FastInstructionAccessMMUMiss :
public SparcFault<FastInstructionAccessMMUMiss>
{
protected:
Addr vaddr;
public:
FastInstructionAccessMMUMiss(Addr addr) : vaddr(addr)
{}
FastInstructionAccessMMUMiss() : vaddr(0)
{}
void invoke(ThreadContext * tc,
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
};
class FastDataAccessMMUMiss : public SparcFault<FastDataAccessMMUMiss>
{
protected:
Addr vaddr;
public:
FastDataAccessMMUMiss(Addr addr) : vaddr(addr)
{}
FastDataAccessMMUMiss() : vaddr(0)
{}
void invoke(ThreadContext * tc,
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
};
class FastDataAccessProtection : public SparcFault<FastDataAccessProtection> {};
class InstructionBreakpoint : public SparcFault<InstructionBreakpoint> {};
class CpuMondo : public SparcFault<CpuMondo> {};
class DevMondo : public SparcFault<DevMondo> {};
class ResumableError : public SparcFault<ResumableError> {};
class SpillNNormal : public EnumeratedFault<SpillNNormal>
{
public:
SpillNNormal(uint32_t n) : EnumeratedFault<SpillNNormal>(n) {;}
// These need to be handled specially to enable spill traps in SE
void invoke(ThreadContext * tc,
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
};
class SpillNOther : public EnumeratedFault<SpillNOther>
{
public:
SpillNOther(uint32_t n) : EnumeratedFault<SpillNOther>(n)
{}
};
class FillNNormal : public EnumeratedFault<FillNNormal>
{
public:
FillNNormal(uint32_t n) : EnumeratedFault<FillNNormal>(n)
{}
// These need to be handled specially to enable fill traps in SE
void invoke(ThreadContext * tc,
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
};
class FillNOther : public EnumeratedFault<FillNOther>
{
public:
FillNOther(uint32_t n) : EnumeratedFault<FillNOther>(n)
{}
};
class TrapInstruction : public EnumeratedFault<TrapInstruction>
{
public:
TrapInstruction(uint32_t n) : EnumeratedFault<TrapInstruction>(n)
{}
// In SE, trap instructions are requesting services from the OS.
void invoke(ThreadContext * tc,
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
};
} // namespace SparcISA
#endif // __SPARC_FAULTS_HH__

View File

@ -0,0 +1,190 @@
/*
* 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
*/
#ifndef __ARCH_SPARC_HANDLERS_HH__
#define __ARCH_SPARC_HANDLERS_HH__
#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/types.hh"
#include "sim/byteswap.hh"
namespace SparcISA {
// We only use 19 instructions for the trap handlers, but there would be
// space for 32 in a real SPARC trap table.
const int numFillInsts = 32;
const int numSpillInsts = 32;
const MachInst fillHandler64[numFillInsts] =
{
htog(0x87802016), // wr %g0, ASI_AIUP, %asi
htog(0xe0dba7ff), // ldxa [%sp + BIAS + (0*8)] %asi, %l0
htog(0xe2dba807), // ldxa [%sp + BIAS + (1*8)] %asi, %l1
htog(0xe4dba80f), // ldxa [%sp + BIAS + (2*8)] %asi, %l2
htog(0xe6dba817), // ldxa [%sp + BIAS + (3*8)] %asi, %l3
htog(0xe8dba81f), // ldxa [%sp + BIAS + (4*8)] %asi, %l4
htog(0xeadba827), // ldxa [%sp + BIAS + (5*8)] %asi, %l5
htog(0xecdba82f), // ldxa [%sp + BIAS + (6*8)] %asi, %l6
htog(0xeedba837), // ldxa [%sp + BIAS + (7*8)] %asi, %l7
htog(0xf0dba83f), // ldxa [%sp + BIAS + (8*8)] %asi, %i0
htog(0xf2dba847), // ldxa [%sp + BIAS + (9*8)] %asi, %i1
htog(0xf4dba84f), // ldxa [%sp + BIAS + (10*8)] %asi, %i2
htog(0xf6dba857), // ldxa [%sp + BIAS + (11*8)] %asi, %i3
htog(0xf8dba85f), // ldxa [%sp + BIAS + (12*8)] %asi, %i4
htog(0xfadba867), // ldxa [%sp + BIAS + (13*8)] %asi, %i5
htog(0xfcdba86f), // ldxa [%sp + BIAS + (14*8)] %asi, %i6
htog(0xfedba877), // ldxa [%sp + BIAS + (15*8)] %asi, %i7
htog(0x83880000), // restored
htog(0x83F00000), // retry
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000) // illtrap
};
const MachInst fillHandler32[numFillInsts] =
{
htog(0x87802016), // wr %g0, ASI_AIUP, %asi
htog(0xe083a000), // lduwa [%sp + (0*4)] %asi, %l0
htog(0xe283a004), // lduwa [%sp + (1*4)] %asi, %l1
htog(0xe483a008), // lduwa [%sp + (2*4)] %asi, %l2
htog(0xe683a00c), // lduwa [%sp + (3*4)] %asi, %l3
htog(0xe883a010), // lduwa [%sp + (4*4)] %asi, %l4
htog(0xea83a014), // lduwa [%sp + (5*4)] %asi, %l5
htog(0xec83a018), // lduwa [%sp + (6*4)] %asi, %l6
htog(0xee83a01c), // lduwa [%sp + (7*4)] %asi, %l7
htog(0xf083a020), // lduwa [%sp + (8*4)] %asi, %i0
htog(0xf283a024), // lduwa [%sp + (9*4)] %asi, %i1
htog(0xf483a028), // lduwa [%sp + (10*4)] %asi, %i2
htog(0xf683a02c), // lduwa [%sp + (11*4)] %asi, %i3
htog(0xf883a030), // lduwa [%sp + (12*4)] %asi, %i4
htog(0xfa83a034), // lduwa [%sp + (13*4)] %asi, %i5
htog(0xfc83a038), // lduwa [%sp + (14*4)] %asi, %i6
htog(0xfe83a03c), // lduwa [%sp + (15*4)] %asi, %i7
htog(0x83880000), // restored
htog(0x83F00000), // retry
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000) // illtrap
};
const MachInst spillHandler64[numSpillInsts] =
{
htog(0x87802016), // wr %g0, ASI_AIUP, %asi
htog(0xe0f3a7ff), // stxa %l0, [%sp + BIAS + (0*8)] %asi
htog(0xe2f3a807), // stxa %l1, [%sp + BIAS + (1*8)] %asi
htog(0xe4f3a80f), // stxa %l2, [%sp + BIAS + (2*8)] %asi
htog(0xe6f3a817), // stxa %l3, [%sp + BIAS + (3*8)] %asi
htog(0xe8f3a81f), // stxa %l4, [%sp + BIAS + (4*8)] %asi
htog(0xeaf3a827), // stxa %l5, [%sp + BIAS + (5*8)] %asi
htog(0xecf3a82f), // stxa %l6, [%sp + BIAS + (6*8)] %asi
htog(0xeef3a837), // stxa %l7, [%sp + BIAS + (7*8)] %asi
htog(0xf0f3a83f), // stxa %i0, [%sp + BIAS + (8*8)] %asi
htog(0xf2f3a847), // stxa %i1, [%sp + BIAS + (9*8)] %asi
htog(0xf4f3a84f), // stxa %i2, [%sp + BIAS + (10*8)] %asi
htog(0xf6f3a857), // stxa %i3, [%sp + BIAS + (11*8)] %asi
htog(0xf8f3a85f), // stxa %i4, [%sp + BIAS + (12*8)] %asi
htog(0xfaf3a867), // stxa %i5, [%sp + BIAS + (13*8)] %asi
htog(0xfcf3a86f), // stxa %i6, [%sp + BIAS + (14*8)] %asi
htog(0xfef3a877), // stxa %i7, [%sp + BIAS + (15*8)] %asi
htog(0x81880000), // saved
htog(0x83F00000), // retry
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000) // illtrap
};
const MachInst spillHandler32[numSpillInsts] =
{
htog(0x87802016), // wr %g0, ASI_AIUP, %asi
htog(0xe0a3a000), // stwa %l0, [%sp + (0*4)] %asi
htog(0xe2a3a004), // stwa %l1, [%sp + (1*4)] %asi
htog(0xe4a3a008), // stwa %l2, [%sp + (2*4)] %asi
htog(0xe6a3a00c), // stwa %l3, [%sp + (3*4)] %asi
htog(0xe8a3a010), // stwa %l4, [%sp + (4*4)] %asi
htog(0xeaa3a014), // stwa %l5, [%sp + (5*4)] %asi
htog(0xeca3a018), // stwa %l6, [%sp + (6*4)] %asi
htog(0xeea3a01c), // stwa %l7, [%sp + (7*4)] %asi
htog(0xf0a3a020), // stwa %i0, [%sp + (8*4)] %asi
htog(0xf2a3a024), // stwa %i1, [%sp + (9*4)] %asi
htog(0xf4a3a028), // stwa %i2, [%sp + (10*4)] %asi
htog(0xf6a3a02c), // stwa %i3, [%sp + (11*4)] %asi
htog(0xf8a3a030), // stwa %i4, [%sp + (12*4)] %asi
htog(0xfaa3a034), // stwa %i5, [%sp + (13*4)] %asi
htog(0xfca3a038), // stwa %i6, [%sp + (14*4)] %asi
htog(0xfea3a03c), // stwa %i7, [%sp + (15*4)] %asi
htog(0x81880000), // saved
htog(0x83F00000), // retry
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000), // illtrap
htog(0x00000000) // illtrap
};
} // namespace SparcISA
#endif // __ARCH_SPARC_HANDLERS_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/sparc/interrupts.hh"
SparcISA::Interrupts *
SparcInterruptsParams::create()
{
return new SparcISA::Interrupts(this);
}

View File

@ -0,0 +1,209 @@
/*
* 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
* Lisa Hsu
*/
#ifndef __ARCH_SPARC_INTERRUPT_HH__
#define __ARCH_SPARC_INTERRUPT_HH__
#include "arch/sparc/faults.hh"
#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/registers.hh"
#include "cpu/thread_context.hh"
#include "debug/Interrupt.hh"
#include "params/SparcInterrupts.hh"
#include "sim/sim_object.hh"
namespace SparcISA
{
class Interrupts : public SimObject
{
private:
BaseCPU * cpu;
uint64_t interrupts[NumInterruptTypes];
uint64_t intStatus;
public:
void
setCPU(BaseCPU * _cpu)
{
cpu = _cpu;
}
typedef SparcInterruptsParams Params;
const Params *
params() const
{
return dynamic_cast<const Params *>(_params);
}
Interrupts(Params * p) : SimObject(p), cpu(NULL)
{
clearAll();
}
int
InterruptLevel(uint64_t softint)
{
if (softint & 0x10000 || softint & 0x1)
return 14;
int level = 15;
while (level > 0 && !(1 << level & softint))
level--;
if (1 << level & softint)
return level;
return 0;
}
void
post(int int_num, int index)
{
DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
assert(int_num >= 0 && int_num < NumInterruptTypes);
assert(index >= 0 && index < 64);
interrupts[int_num] |= ULL(1) << index;
intStatus |= ULL(1) << int_num;
}
void
clear(int int_num, int index)
{
DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
assert(int_num >= 0 && int_num < NumInterruptTypes);
assert(index >= 0 && index < 64);
interrupts[int_num] &= ~(ULL(1) << index);
if (!interrupts[int_num])
intStatus &= ~(ULL(1) << int_num);
}
void
clearAll()
{
for (int i = 0; i < NumInterruptTypes; ++i) {
interrupts[i] = 0;
}
intStatus = 0;
}
bool
checkInterrupts(ThreadContext *tc) const
{
return intStatus;
}
Fault
getInterrupt(ThreadContext *tc)
{
HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
// THESE ARE IN ORDER OF PRIORITY
// since there are early returns, and the highest
// priority interrupts should get serviced,
// it is v. important that new interrupts are inserted
// in the right order of processing
if (hpstate.hpriv) {
if (pstate.ie) {
if (interrupts[IT_HINTP]) {
// This will be cleaned by a HINTP write
return new HstickMatch;
}
if (interrupts[IT_INT_VEC]) {
// this will be cleared by an ASI read (or write)
return new InterruptVector;
}
}
} else {
if (interrupts[IT_TRAP_LEVEL_ZERO]) {
// this is cleared by deasserting HPSTATE::tlz
return new TrapLevelZero;
}
// HStick matches always happen in priv mode (ie doesn't matter)
if (interrupts[IT_HINTP]) {
return new HstickMatch;
}
if (interrupts[IT_INT_VEC]) {
// this will be cleared by an ASI read (or write)
return new InterruptVector;
}
if (pstate.ie) {
if (interrupts[IT_CPU_MONDO]) {
return new CpuMondo;
}
if (interrupts[IT_DEV_MONDO]) {
return new DevMondo;
}
if (interrupts[IT_SOFT_INT]) {
int level = InterruptLevel(interrupts[IT_SOFT_INT]);
return new InterruptLevelN(level);
}
if (interrupts[IT_RES_ERROR]) {
return new ResumableError;
}
} // !hpriv && pstate.ie
} // !hpriv
return NoFault;
}
void
updateIntrInfo(ThreadContext *tc)
{}
uint64_t
get_vec(int int_num)
{
assert(int_num >= 0 && int_num < NumInterruptTypes);
return interrupts[int_num];
}
void
serialize(std::ostream &os)
{
SERIALIZE_ARRAY(interrupts,NumInterruptTypes);
SERIALIZE_SCALAR(intStatus);
}
void
unserialize(Checkpoint *cp, const std::string &section)
{
UNSERIALIZE_ARRAY(interrupts,NumInterruptTypes);
UNSERIALIZE_SCALAR(intStatus);
}
};
} // namespace SPARC_ISA
#endif // __ARCH_SPARC_INTERRUPT_HH__

View File

@ -0,0 +1,778 @@
/*
* 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 "arch/sparc/asi.hh"
#include "arch/sparc/isa.hh"
#include "base/bitfield.hh"
#include "base/trace.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
#include "debug/MiscRegs.hh"
#include "debug/Timer.hh"
namespace SparcISA
{
static PSTATE
buildPstateMask()
{
PSTATE mask = 0;
mask.ie = 1;
mask.priv = 1;
mask.am = 1;
mask.pef = 1;
mask.mm = 3;
mask.tle = 1;
mask.cle = 1;
mask.pid1 = 1;
return mask;
}
static const PSTATE PstateMask = buildPstateMask();
void
ISA::reloadRegMap()
{
installGlobals(gl, CurrentGlobalsOffset);
installWindow(cwp, CurrentWindowOffset);
// Microcode registers.
for (int i = 0; i < NumMicroIntRegs; i++)
intRegMap[MicroIntOffset + i] = i + TotalGlobals + NWindows * 16;
installGlobals(gl, NextGlobalsOffset);
installWindow(cwp - 1, NextWindowOffset);
installGlobals(gl, PreviousGlobalsOffset);
installWindow(cwp + 1, PreviousWindowOffset);
}
void
ISA::installWindow(int cwp, int offset)
{
assert(offset >= 0 && offset + NumWindowedRegs <= NumIntRegs);
RegIndex *mapChunk = intRegMap + offset;
for (int i = 0; i < NumWindowedRegs; i++)
mapChunk[i] = TotalGlobals +
((i - cwp * RegsPerWindow + TotalWindowed) % (TotalWindowed));
}
void
ISA::installGlobals(int gl, int offset)
{
assert(offset >= 0 && offset + NumGlobalRegs <= NumIntRegs);
RegIndex *mapChunk = intRegMap + offset;
mapChunk[0] = 0;
for (int i = 1; i < NumGlobalRegs; i++)
mapChunk[i] = i + gl * NumGlobalRegs;
}
void
ISA::clear()
{
cwp = 0;
gl = 0;
reloadRegMap();
// y = 0;
// ccr = 0;
asi = 0;
tick = ULL(1) << 63;
fprs = 0;
gsr = 0;
softint = 0;
tick_cmpr = 0;
stick = 0;
stick_cmpr = 0;
memset(tpc, 0, sizeof(tpc));
memset(tnpc, 0, sizeof(tnpc));
memset(tstate, 0, sizeof(tstate));
memset(tt, 0, sizeof(tt));
tba = 0;
pstate = 0;
tl = 0;
pil = 0;
// cansave = 0;
// canrestore = 0;
// cleanwin = 0;
// otherwin = 0;
// wstate = 0;
// In a T1, bit 11 is apparently always 1
hpstate = 0;
hpstate.id = 1;
memset(htstate, 0, sizeof(htstate));
hintp = 0;
htba = 0;
hstick_cmpr = 0;
// This is set this way in Legion for some reason
strandStatusReg = 0x50000;
fsr = 0;
priContext = 0;
secContext = 0;
partId = 0;
lsuCtrlReg = 0;
memset(scratchPad, 0, sizeof(scratchPad));
cpu_mondo_head = 0;
cpu_mondo_tail = 0;
dev_mondo_head = 0;
dev_mondo_tail = 0;
res_error_head = 0;
res_error_tail = 0;
nres_error_head = 0;
nres_error_tail = 0;
// If one of these events is active, it's not obvious to me how to get
// rid of it cleanly. For now we'll just assert that they're not.
if (tickCompare != NULL && sTickCompare != NULL && hSTickCompare != NULL)
panic("Tick comparison event active when clearing the ISA object.\n");
}
MiscReg
ISA::readMiscRegNoEffect(int miscReg)
{
// The three miscRegs are moved up from the switch statement
// due to more frequent calls.
if (miscReg == MISCREG_GL)
return gl;
if (miscReg == MISCREG_CWP)
return cwp;
if (miscReg == MISCREG_TLB_DATA) {
/* Package up all the data for the tlb:
* 6666555555555544444444443333333333222222222211111111110000000000
* 3210987654321098765432109876543210987654321098765432109876543210
* secContext | priContext | |tl|partid| |||||^hpriv
* ||||^red
* |||^priv
* ||^am
* |^lsuim
* ^lsudm
*/
return (uint64_t)hpstate.hpriv |
(uint64_t)hpstate.red << 1 |
(uint64_t)pstate.priv << 2 |
(uint64_t)pstate.am << 3 |
bits((uint64_t)lsuCtrlReg,3,2) << 4 |
bits((uint64_t)partId,7,0) << 8 |
bits((uint64_t)tl,2,0) << 16 |
(uint64_t)priContext << 32 |
(uint64_t)secContext << 48;
}
switch (miscReg) {
// case MISCREG_TLB_DATA:
// [original contents see above]
// case MISCREG_Y:
// return y;
// case MISCREG_CCR:
// return ccr;
case MISCREG_ASI:
return asi;
case MISCREG_FPRS:
return fprs;
case MISCREG_TICK:
return tick;
case MISCREG_PCR:
panic("PCR not implemented\n");
case MISCREG_PIC:
panic("PIC not implemented\n");
case MISCREG_GSR:
return gsr;
case MISCREG_SOFTINT:
return softint;
case MISCREG_TICK_CMPR:
return tick_cmpr;
case MISCREG_STICK:
return stick;
case MISCREG_STICK_CMPR:
return stick_cmpr;
/** Privilged Registers */
case MISCREG_TPC:
return tpc[tl-1];
case MISCREG_TNPC:
return tnpc[tl-1];
case MISCREG_TSTATE:
return tstate[tl-1];
case MISCREG_TT:
return tt[tl-1];
case MISCREG_PRIVTICK:
panic("Priviliged access to tick registers not implemented\n");
case MISCREG_TBA:
return tba;
case MISCREG_PSTATE:
return (MiscReg)pstate;
case MISCREG_TL:
return tl;
case MISCREG_PIL:
return pil;
// CWP, GL moved
// case MISCREG_CWP:
// return cwp;
// case MISCREG_CANSAVE:
// return cansave;
// case MISCREG_CANRESTORE:
// return canrestore;
// case MISCREG_CLEANWIN:
// return cleanwin;
// case MISCREG_OTHERWIN:
// return otherwin;
// case MISCREG_WSTATE:
// return wstate;
// case MISCREG_GL:
// return gl;
/** Hyper privileged registers */
case MISCREG_HPSTATE:
return (MiscReg)hpstate;
case MISCREG_HTSTATE:
return htstate[tl-1];
case MISCREG_HINTP:
return hintp;
case MISCREG_HTBA:
return htba;
case MISCREG_STRAND_STS_REG:
return strandStatusReg;
case MISCREG_HSTICK_CMPR:
return hstick_cmpr;
/** Floating Point Status Register */
case MISCREG_FSR:
DPRINTF(MiscRegs, "FSR read as: %#x\n", fsr);
return fsr;
case MISCREG_MMU_P_CONTEXT:
return priContext;
case MISCREG_MMU_S_CONTEXT:
return secContext;
case MISCREG_MMU_PART_ID:
return partId;
case MISCREG_MMU_LSU_CTRL:
return lsuCtrlReg;
case MISCREG_SCRATCHPAD_R0:
return scratchPad[0];
case MISCREG_SCRATCHPAD_R1:
return scratchPad[1];
case MISCREG_SCRATCHPAD_R2:
return scratchPad[2];
case MISCREG_SCRATCHPAD_R3:
return scratchPad[3];
case MISCREG_SCRATCHPAD_R4:
return scratchPad[4];
case MISCREG_SCRATCHPAD_R5:
return scratchPad[5];
case MISCREG_SCRATCHPAD_R6:
return scratchPad[6];
case MISCREG_SCRATCHPAD_R7:
return scratchPad[7];
case MISCREG_QUEUE_CPU_MONDO_HEAD:
return cpu_mondo_head;
case MISCREG_QUEUE_CPU_MONDO_TAIL:
return cpu_mondo_tail;
case MISCREG_QUEUE_DEV_MONDO_HEAD:
return dev_mondo_head;
case MISCREG_QUEUE_DEV_MONDO_TAIL:
return dev_mondo_tail;
case MISCREG_QUEUE_RES_ERROR_HEAD:
return res_error_head;
case MISCREG_QUEUE_RES_ERROR_TAIL:
return res_error_tail;
case MISCREG_QUEUE_NRES_ERROR_HEAD:
return nres_error_head;
case MISCREG_QUEUE_NRES_ERROR_TAIL:
return nres_error_tail;
default:
panic("Miscellaneous register %d not implemented\n", miscReg);
}
}
MiscReg
ISA::readMiscReg(int miscReg, ThreadContext * tc)
{
switch (miscReg) {
// tick and stick are aliased to each other in niagra
// well store the tick data in stick and the interrupt bit in tick
case MISCREG_STICK:
case MISCREG_TICK:
case MISCREG_PRIVTICK:
// I'm not sure why legion ignores the lowest two bits, but we'll go
// with it
// change from curCycle() to instCount() until we're done with legion
DPRINTF(Timer, "Instruction Count when TICK read: %#X stick=%#X\n",
tc->getCpuPtr()->instCount(), stick);
return mbits(tc->getCpuPtr()->instCount() + (int64_t)stick,62,2) |
mbits(tick,63,63);
case MISCREG_FPRS:
// in legion if fp is enabled du and dl are set
return fprs | 0x3;
case MISCREG_PCR:
case MISCREG_PIC:
panic("Performance Instrumentation not impl\n");
case MISCREG_SOFTINT_CLR:
case MISCREG_SOFTINT_SET:
panic("Can read from softint clr/set\n");
case MISCREG_SOFTINT:
case MISCREG_TICK_CMPR:
case MISCREG_STICK_CMPR:
case MISCREG_HINTP:
case MISCREG_HTSTATE:
case MISCREG_HTBA:
case MISCREG_HVER:
case MISCREG_STRAND_STS_REG:
case MISCREG_HSTICK_CMPR:
case MISCREG_QUEUE_CPU_MONDO_HEAD:
case MISCREG_QUEUE_CPU_MONDO_TAIL:
case MISCREG_QUEUE_DEV_MONDO_HEAD:
case MISCREG_QUEUE_DEV_MONDO_TAIL:
case MISCREG_QUEUE_RES_ERROR_HEAD:
case MISCREG_QUEUE_RES_ERROR_TAIL:
case MISCREG_QUEUE_NRES_ERROR_HEAD:
case MISCREG_QUEUE_NRES_ERROR_TAIL:
case MISCREG_HPSTATE:
return readFSReg(miscReg, tc);
}
return readMiscRegNoEffect(miscReg);
}
void
ISA::setMiscRegNoEffect(int miscReg, MiscReg val)
{
switch (miscReg) {
// case MISCREG_Y:
// y = val;
// break;
// case MISCREG_CCR:
// ccr = val;
// break;
case MISCREG_ASI:
asi = val;
break;
case MISCREG_FPRS:
fprs = val;
break;
case MISCREG_TICK:
tick = val;
break;
case MISCREG_PCR:
panic("PCR not implemented\n");
case MISCREG_PIC:
panic("PIC not implemented\n");
case MISCREG_GSR:
gsr = val;
break;
case MISCREG_SOFTINT:
softint = val;
break;
case MISCREG_TICK_CMPR:
tick_cmpr = val;
break;
case MISCREG_STICK:
stick = val;
break;
case MISCREG_STICK_CMPR:
stick_cmpr = val;
break;
/** Privilged Registers */
case MISCREG_TPC:
tpc[tl-1] = val;
break;
case MISCREG_TNPC:
tnpc[tl-1] = val;
break;
case MISCREG_TSTATE:
tstate[tl-1] = val;
break;
case MISCREG_TT:
tt[tl-1] = val;
break;
case MISCREG_PRIVTICK:
panic("Priviliged access to tick regesiters not implemented\n");
case MISCREG_TBA:
// clear lower 7 bits on writes.
tba = val & ULL(~0x7FFF);
break;
case MISCREG_PSTATE:
pstate = (val & PstateMask);
break;
case MISCREG_TL:
tl = val;
break;
case MISCREG_PIL:
pil = val;
break;
case MISCREG_CWP:
cwp = val;
break;
// case MISCREG_CANSAVE:
// cansave = val;
// break;
// case MISCREG_CANRESTORE:
// canrestore = val;
// break;
// case MISCREG_CLEANWIN:
// cleanwin = val;
// break;
// case MISCREG_OTHERWIN:
// otherwin = val;
// break;
// case MISCREG_WSTATE:
// wstate = val;
// break;
case MISCREG_GL:
gl = val;
break;
/** Hyper privileged registers */
case MISCREG_HPSTATE:
hpstate = val;
break;
case MISCREG_HTSTATE:
htstate[tl-1] = val;
break;
case MISCREG_HINTP:
hintp = val;
case MISCREG_HTBA:
htba = val;
break;
case MISCREG_STRAND_STS_REG:
strandStatusReg = val;
break;
case MISCREG_HSTICK_CMPR:
hstick_cmpr = val;
break;
/** Floating Point Status Register */
case MISCREG_FSR:
fsr = val;
DPRINTF(MiscRegs, "FSR written with: %#x\n", fsr);
break;
case MISCREG_MMU_P_CONTEXT:
priContext = val;
break;
case MISCREG_MMU_S_CONTEXT:
secContext = val;
break;
case MISCREG_MMU_PART_ID:
partId = val;
break;
case MISCREG_MMU_LSU_CTRL:
lsuCtrlReg = val;
break;
case MISCREG_SCRATCHPAD_R0:
scratchPad[0] = val;
break;
case MISCREG_SCRATCHPAD_R1:
scratchPad[1] = val;
break;
case MISCREG_SCRATCHPAD_R2:
scratchPad[2] = val;
break;
case MISCREG_SCRATCHPAD_R3:
scratchPad[3] = val;
break;
case MISCREG_SCRATCHPAD_R4:
scratchPad[4] = val;
break;
case MISCREG_SCRATCHPAD_R5:
scratchPad[5] = val;
break;
case MISCREG_SCRATCHPAD_R6:
scratchPad[6] = val;
break;
case MISCREG_SCRATCHPAD_R7:
scratchPad[7] = val;
break;
case MISCREG_QUEUE_CPU_MONDO_HEAD:
cpu_mondo_head = val;
break;
case MISCREG_QUEUE_CPU_MONDO_TAIL:
cpu_mondo_tail = val;
break;
case MISCREG_QUEUE_DEV_MONDO_HEAD:
dev_mondo_head = val;
break;
case MISCREG_QUEUE_DEV_MONDO_TAIL:
dev_mondo_tail = val;
break;
case MISCREG_QUEUE_RES_ERROR_HEAD:
res_error_head = val;
break;
case MISCREG_QUEUE_RES_ERROR_TAIL:
res_error_tail = val;
break;
case MISCREG_QUEUE_NRES_ERROR_HEAD:
nres_error_head = val;
break;
case MISCREG_QUEUE_NRES_ERROR_TAIL:
nres_error_tail = val;
break;
default:
panic("Miscellaneous register %d not implemented\n", miscReg);
}
}
void
ISA::setMiscReg(int miscReg, MiscReg val, ThreadContext * tc)
{
MiscReg new_val = val;
switch (miscReg) {
case MISCREG_STICK:
case MISCREG_TICK:
// stick and tick are same thing on niagra
// use stick for offset and tick for holding intrrupt bit
stick = mbits(val,62,0) - tc->getCpuPtr()->instCount();
tick = mbits(val,63,63);
DPRINTF(Timer, "Writing TICK=%#X\n", val);
break;
case MISCREG_FPRS:
// Configure the fpu based on the fprs
break;
case MISCREG_PCR:
// Set up performance counting based on pcr value
break;
case MISCREG_PSTATE:
pstate = val & PstateMask;
return;
case MISCREG_TL:
{
tl = val;
if (hpstate.tlz && tl == 0 && !hpstate.hpriv)
tc->getCpuPtr()->postInterrupt(IT_TRAP_LEVEL_ZERO, 0);
else
tc->getCpuPtr()->clearInterrupt(IT_TRAP_LEVEL_ZERO, 0);
return;
}
case MISCREG_CWP:
new_val = val >= NWindows ? NWindows - 1 : val;
if (val >= NWindows)
new_val = NWindows - 1;
installWindow(new_val, CurrentWindowOffset);
installWindow(new_val - 1, NextWindowOffset);
installWindow(new_val + 1, PreviousWindowOffset);
break;
case MISCREG_GL:
installGlobals(val, CurrentGlobalsOffset);
installGlobals(val, NextGlobalsOffset);
installGlobals(val, PreviousGlobalsOffset);
break;
case MISCREG_PIL:
case MISCREG_SOFTINT:
case MISCREG_SOFTINT_SET:
case MISCREG_SOFTINT_CLR:
case MISCREG_TICK_CMPR:
case MISCREG_STICK_CMPR:
case MISCREG_HINTP:
case MISCREG_HTSTATE:
case MISCREG_HTBA:
case MISCREG_HVER:
case MISCREG_STRAND_STS_REG:
case MISCREG_HSTICK_CMPR:
case MISCREG_QUEUE_CPU_MONDO_HEAD:
case MISCREG_QUEUE_CPU_MONDO_TAIL:
case MISCREG_QUEUE_DEV_MONDO_HEAD:
case MISCREG_QUEUE_DEV_MONDO_TAIL:
case MISCREG_QUEUE_RES_ERROR_HEAD:
case MISCREG_QUEUE_RES_ERROR_TAIL:
case MISCREG_QUEUE_NRES_ERROR_HEAD:
case MISCREG_QUEUE_NRES_ERROR_TAIL:
case MISCREG_HPSTATE:
setFSReg(miscReg, val, tc);
return;
}
setMiscRegNoEffect(miscReg, new_val);
}
void
ISA::serialize(EventManager *em, std::ostream &os)
{
SERIALIZE_SCALAR(asi);
SERIALIZE_SCALAR(tick);
SERIALIZE_SCALAR(fprs);
SERIALIZE_SCALAR(gsr);
SERIALIZE_SCALAR(softint);
SERIALIZE_SCALAR(tick_cmpr);
SERIALIZE_SCALAR(stick);
SERIALIZE_SCALAR(stick_cmpr);
SERIALIZE_ARRAY(tpc,MaxTL);
SERIALIZE_ARRAY(tnpc,MaxTL);
SERIALIZE_ARRAY(tstate,MaxTL);
SERIALIZE_ARRAY(tt,MaxTL);
SERIALIZE_SCALAR(tba);
SERIALIZE_SCALAR((uint16_t)pstate);
SERIALIZE_SCALAR(tl);
SERIALIZE_SCALAR(pil);
SERIALIZE_SCALAR(cwp);
SERIALIZE_SCALAR(gl);
SERIALIZE_SCALAR((uint64_t)hpstate);
SERIALIZE_ARRAY(htstate,MaxTL);
SERIALIZE_SCALAR(hintp);
SERIALIZE_SCALAR(htba);
SERIALIZE_SCALAR(hstick_cmpr);
SERIALIZE_SCALAR(strandStatusReg);
SERIALIZE_SCALAR(fsr);
SERIALIZE_SCALAR(priContext);
SERIALIZE_SCALAR(secContext);
SERIALIZE_SCALAR(partId);
SERIALIZE_SCALAR(lsuCtrlReg);
SERIALIZE_ARRAY(scratchPad,8);
SERIALIZE_SCALAR(cpu_mondo_head);
SERIALIZE_SCALAR(cpu_mondo_tail);
SERIALIZE_SCALAR(dev_mondo_head);
SERIALIZE_SCALAR(dev_mondo_tail);
SERIALIZE_SCALAR(res_error_head);
SERIALIZE_SCALAR(res_error_tail);
SERIALIZE_SCALAR(nres_error_head);
SERIALIZE_SCALAR(nres_error_tail);
Tick tick_cmp = 0, stick_cmp = 0, hstick_cmp = 0;
ThreadContext *tc = NULL;
BaseCPU *cpu = NULL;
int tc_num = 0;
bool tick_intr_sched = true;
if (tickCompare)
tc = tickCompare->getTC();
else if (sTickCompare)
tc = sTickCompare->getTC();
else if (hSTickCompare)
tc = hSTickCompare->getTC();
else
tick_intr_sched = false;
SERIALIZE_SCALAR(tick_intr_sched);
if (tc) {
cpu = tc->getCpuPtr();
tc_num = cpu->findContext(tc);
if (tickCompare && tickCompare->scheduled())
tick_cmp = tickCompare->when();
if (sTickCompare && sTickCompare->scheduled())
stick_cmp = sTickCompare->when();
if (hSTickCompare && hSTickCompare->scheduled())
hstick_cmp = hSTickCompare->when();
SERIALIZE_OBJPTR(cpu);
SERIALIZE_SCALAR(tc_num);
SERIALIZE_SCALAR(tick_cmp);
SERIALIZE_SCALAR(stick_cmp);
SERIALIZE_SCALAR(hstick_cmp);
}
}
void
ISA::unserialize(EventManager *em, Checkpoint *cp, const std::string &section)
{
UNSERIALIZE_SCALAR(asi);
UNSERIALIZE_SCALAR(tick);
UNSERIALIZE_SCALAR(fprs);
UNSERIALIZE_SCALAR(gsr);
UNSERIALIZE_SCALAR(softint);
UNSERIALIZE_SCALAR(tick_cmpr);
UNSERIALIZE_SCALAR(stick);
UNSERIALIZE_SCALAR(stick_cmpr);
UNSERIALIZE_ARRAY(tpc,MaxTL);
UNSERIALIZE_ARRAY(tnpc,MaxTL);
UNSERIALIZE_ARRAY(tstate,MaxTL);
UNSERIALIZE_ARRAY(tt,MaxTL);
UNSERIALIZE_SCALAR(tba);
{
uint16_t pstate;
UNSERIALIZE_SCALAR(pstate);
this->pstate = pstate;
}
UNSERIALIZE_SCALAR(tl);
UNSERIALIZE_SCALAR(pil);
UNSERIALIZE_SCALAR(cwp);
UNSERIALIZE_SCALAR(gl);
reloadRegMap();
{
uint64_t hpstate;
UNSERIALIZE_SCALAR(hpstate);
this->hpstate = hpstate;
}
UNSERIALIZE_ARRAY(htstate,MaxTL);
UNSERIALIZE_SCALAR(hintp);
UNSERIALIZE_SCALAR(htba);
UNSERIALIZE_SCALAR(hstick_cmpr);
UNSERIALIZE_SCALAR(strandStatusReg);
UNSERIALIZE_SCALAR(fsr);
UNSERIALIZE_SCALAR(priContext);
UNSERIALIZE_SCALAR(secContext);
UNSERIALIZE_SCALAR(partId);
UNSERIALIZE_SCALAR(lsuCtrlReg);
UNSERIALIZE_ARRAY(scratchPad,8);
UNSERIALIZE_SCALAR(cpu_mondo_head);
UNSERIALIZE_SCALAR(cpu_mondo_tail);
UNSERIALIZE_SCALAR(dev_mondo_head);
UNSERIALIZE_SCALAR(dev_mondo_tail);
UNSERIALIZE_SCALAR(res_error_head);
UNSERIALIZE_SCALAR(res_error_tail);
UNSERIALIZE_SCALAR(nres_error_head);
UNSERIALIZE_SCALAR(nres_error_tail);
Tick tick_cmp = 0, stick_cmp = 0, hstick_cmp = 0;
ThreadContext *tc = NULL;
BaseCPU *cpu = NULL;
int tc_num;
bool tick_intr_sched;
UNSERIALIZE_SCALAR(tick_intr_sched);
if (tick_intr_sched) {
UNSERIALIZE_OBJPTR(cpu);
if (cpu) {
UNSERIALIZE_SCALAR(tc_num);
UNSERIALIZE_SCALAR(tick_cmp);
UNSERIALIZE_SCALAR(stick_cmp);
UNSERIALIZE_SCALAR(hstick_cmp);
tc = cpu->getContext(tc_num);
if (tick_cmp) {
tickCompare = new TickCompareEvent(this, tc);
em->schedule(tickCompare, tick_cmp);
}
if (stick_cmp) {
sTickCompare = new STickCompareEvent(this, tc);
em->schedule(sTickCompare, stick_cmp);
}
if (hstick_cmp) {
hSTickCompare = new HSTickCompareEvent(this, tc);
em->schedule(hSTickCompare, hstick_cmp);
}
}
}
}
}

View File

@ -0,0 +1,214 @@
/*
* 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_SPARC_ISA_HH__
#define __ARCH_SPARC_ISA_HH__
#include <ostream>
#include <string>
#include "arch/sparc/registers.hh"
#include "arch/sparc/types.hh"
#include "cpu/cpuevent.hh"
class Checkpoint;
class EventManager;
class ThreadContext;
namespace SparcISA
{
class ISA
{
private:
/* ASR Registers */
// uint64_t y; // Y (used in obsolete multiplication)
// uint8_t ccr; // Condition Code Register
uint8_t asi; // Address Space Identifier
uint64_t tick; // Hardware clock-tick counter
uint8_t fprs; // Floating-Point Register State
uint64_t gsr; // General Status Register
uint64_t softint;
uint64_t tick_cmpr; // Hardware tick compare registers
uint64_t stick; // Hardware clock-tick counter
uint64_t stick_cmpr; // Hardware tick compare registers
/* Privileged Registers */
uint64_t tpc[MaxTL]; // Trap Program Counter (value from
// previous trap level)
uint64_t tnpc[MaxTL]; // Trap Next Program Counter (value from
// previous trap level)
uint64_t tstate[MaxTL]; // Trap State
uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured
// on the previous level)
uint64_t tba; // Trap Base Address
PSTATE pstate; // Process State Register
uint8_t tl; // Trap Level
uint8_t pil; // Process Interrupt Register
uint8_t cwp; // Current Window Pointer
// uint8_t cansave; // Savable windows
// uint8_t canrestore; // Restorable windows
// uint8_t cleanwin; // Clean windows
// uint8_t otherwin; // Other windows
// uint8_t wstate; // Window State
uint8_t gl; // Global level register
/** Hyperprivileged Registers */
HPSTATE hpstate; // Hyperprivileged State Register
uint64_t htstate[MaxTL];// Hyperprivileged Trap State Register
uint64_t hintp;
uint64_t htba; // Hyperprivileged Trap Base Address register
uint64_t hstick_cmpr; // Hardware tick compare registers
uint64_t strandStatusReg;// Per strand status register
/** Floating point misc registers. */
uint64_t fsr; // Floating-Point State Register
/** MMU Internal Registers */
uint16_t priContext;
uint16_t secContext;
uint16_t partId;
uint64_t lsuCtrlReg;
uint64_t scratchPad[8];
uint64_t cpu_mondo_head;
uint64_t cpu_mondo_tail;
uint64_t dev_mondo_head;
uint64_t dev_mondo_tail;
uint64_t res_error_head;
uint64_t res_error_tail;
uint64_t nres_error_head;
uint64_t nres_error_tail;
// These need to check the int_dis field and if 0 then
// set appropriate bit in softint and checkinterrutps on the cpu
void setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc);
MiscReg readFSReg(int miscReg, ThreadContext * tc);
// Update interrupt state on softint or pil change
void checkSoftInt(ThreadContext *tc);
/** Process a tick compare event and generate an interrupt on the cpu if
* appropriate. */
void processTickCompare(ThreadContext *tc);
void processSTickCompare(ThreadContext *tc);
void processHSTickCompare(ThreadContext *tc);
typedef CpuEventWrapper<ISA,
&ISA::processTickCompare> TickCompareEvent;
TickCompareEvent *tickCompare;
typedef CpuEventWrapper<ISA,
&ISA::processSTickCompare> STickCompareEvent;
STickCompareEvent *sTickCompare;
typedef CpuEventWrapper<ISA,
&ISA::processHSTickCompare> HSTickCompareEvent;
HSTickCompareEvent *hSTickCompare;
static const int NumGlobalRegs = 8;
static const int NumWindowedRegs = 24;
static const int WindowOverlap = 8;
static const int TotalGlobals = (MaxGL + 1) * NumGlobalRegs;
static const int RegsPerWindow = NumWindowedRegs - WindowOverlap;
static const int TotalWindowed = NWindows * RegsPerWindow;
enum InstIntRegOffsets {
CurrentGlobalsOffset = 0,
CurrentWindowOffset = CurrentGlobalsOffset + NumGlobalRegs,
MicroIntOffset = CurrentWindowOffset + NumWindowedRegs,
NextGlobalsOffset = MicroIntOffset + NumMicroIntRegs,
NextWindowOffset = NextGlobalsOffset + NumGlobalRegs,
PreviousGlobalsOffset = NextWindowOffset + NumWindowedRegs,
PreviousWindowOffset = PreviousGlobalsOffset + NumGlobalRegs,
TotalInstIntRegs = PreviousWindowOffset + NumWindowedRegs
};
RegIndex intRegMap[TotalInstIntRegs];
void installWindow(int cwp, int offset);
void installGlobals(int gl, int offset);
void reloadRegMap();
public:
void clear();
void serialize(EventManager *em, std::ostream & os);
void unserialize(EventManager *em, Checkpoint *cp,
const std::string & section);
protected:
bool isHyperPriv() { return hpstate.hpriv; }
bool isPriv() { return hpstate.hpriv || pstate.priv; }
bool isNonPriv() { return !isPriv(); }
public:
MiscReg readMiscRegNoEffect(int miscReg);
MiscReg readMiscReg(int miscReg, ThreadContext *tc);
void setMiscRegNoEffect(int miscReg, const MiscReg val);
void setMiscReg(int miscReg, const MiscReg val,
ThreadContext *tc);
int
flattenIntIndex(int reg)
{
assert(reg < TotalInstIntRegs);
RegIndex flatIndex = intRegMap[reg];
assert(flatIndex < NumIntRegs);
return flatIndex;
}
int
flattenFloatIndex(int reg)
{
return reg;
}
ISA()
{
tickCompare = NULL;
sTickCompare = NULL;
hSTickCompare = NULL;
clear();
}
};
}
#endif

View File

@ -0,0 +1,582 @@
// 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: Ali Saidi
// Gabe Black
// Steve Reinhardt
////////////////////////////////////////////////////////////////////
//
// Base class for sparc instructions, and some support functions
//
output header {{
union CondCodes
{
struct
{
uint8_t c:1;
uint8_t v:1;
uint8_t z:1;
uint8_t n:1;
};
uint32_t bits;
};
enum CondTest
{
Always=0x8,
Never=0x0,
NotEqual=0x9,
Equal=0x1,
Greater=0xA,
LessOrEqual=0x2,
GreaterOrEqual=0xB,
Less=0x3,
GreaterUnsigned=0xC,
LessOrEqualUnsigned=0x4,
CarryClear=0xD,
CarrySet=0x5,
Positive=0xE,
Negative=0x6,
OverflowClear=0xF,
OverflowSet=0x7
};
enum FpCondTest
{
FAlways=0x8,
FNever=0x0,
FUnordered=0x7,
FGreater=0x6,
FUnorderedOrGreater=0x5,
FLess=0x4,
FUnorderedOrLess=0x3,
FLessOrGreater=0x2,
FNotEqual=0x1,
FEqual=0x9,
FUnorderedOrEqual=0xA,
FGreaterOrEqual=0xB,
FUnorderedOrGreaterOrEqual=0xC,
FLessOrEqual=0xD,
FUnorderedOrLessOrEqual=0xE,
FOrdered=0xF
};
extern const char *CondTestAbbrev[];
/**
* Base class for all SPARC static instructions.
*/
class SparcStaticInst : public StaticInst
{
protected:
// Constructor.
SparcStaticInst(const char *mnem,
ExtMachInst _machInst, OpClass __opClass)
: StaticInst(mnem, _machInst, __opClass)
{
}
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const;
void printReg(std::ostream &os, int reg) const;
void printSrcReg(std::ostream &os, int reg) const;
void printDestReg(std::ostream &os, int reg) const;
void printRegArray(std::ostream &os,
const RegIndex indexArray[], int num) const;
void advancePC(SparcISA::PCState &pcState) const;
};
bool passesFpCondition(uint32_t fcc, uint32_t condition);
bool passesCondition(uint32_t codes, uint32_t condition);
inline int64_t
sign_ext(uint64_t data, int origWidth)
{
int shiftAmount = 64 - origWidth;
return (((int64_t)data) << shiftAmount) >> shiftAmount;
}
}};
output decoder {{
const char *CondTestAbbrev[] =
{
"nev", // Never
"e", // Equal
"le", // Less or Equal
"l", // Less
"leu", // Less or Equal Unsigned
"c", // Carry set
"n", // Negative
"o", // Overflow set
"a", // Always
"ne", // Not Equal
"g", // Greater
"ge", // Greater or Equal
"gu", // Greater Unsigned
"cc", // Carry clear
"p", // Positive
"oc" // Overflow Clear
};
}};
def template ROrImmDecode {{
{
return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst))
: (SparcStaticInst *)(new %(class_name)s(machInst)));
}
}};
output header {{
union DoubleSingle
{
double d;
uint64_t ui;
uint32_t s[2];
DoubleSingle(double _d) : d(_d)
{}
DoubleSingle(uint64_t _ui) : ui(_ui)
{}
DoubleSingle(uint32_t _s0, uint32_t _s1)
{
s[0] = _s0;
s[1] = _s1;
}
};
}};
let {{
def filterDoubles(code):
assignRE = re.compile(r'\s*=(?!=)', re.MULTILINE)
for opName in ("Frd", "Frs1", "Frs2", "Frd_N"):
next_pos = 0
operandsREString = (r'''
(?<!\w) # neg. lookbehind assertion: prevent partial matches
((%s)(?:_([^\W_]+))?) # match: operand with optional '.' then suffix
(?!\w) # neg. lookahead assertion: prevent partial matches
''' % opName)
operandsRE = re.compile(operandsREString, re.MULTILINE|re.VERBOSE)
is_src = False
is_dest = False
extension = None
foundOne = False
while 1:
match = operandsRE.search(code, next_pos)
if not match:
break
foundOne = True
op = match.groups()
(op_full, op_base, op_ext) = op
is_dest_local = (assignRE.match(code, match.end()) != None)
is_dest = is_dest or is_dest_local
is_src = is_src or not is_dest_local
if extension and extension != op_ext:
raise Exception, "Inconsistent extensions in double filter."
extension = op_ext
next_pos = match.end()
if foundOne:
# Get rid of any unwanted extension
code = operandsRE.sub(op_base, code)
is_int = False
member = "d"
if extension in ("sb", "ub", "shw", "uhw", "sw", "uw", "sdw", "udw"):
is_int = True
member = "ui"
if is_src:
code = ("%s = DoubleSingle(%s_high, %s_low).%s;" % \
(opName, opName, opName, member)) + code
if is_dest:
code += '''
%s_low = DoubleSingle(%s).s[1];
%s_high = DoubleSingle(%s).s[0];''' % \
(opName, opName, opName, opName)
if is_int:
code = ("uint64_t %s;" % opName) + code
else:
code = ("double %s;" % opName) + code
return code
}};
let {{
def splitOutImm(code):
matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)(?P<typeQual>_[^\W_]+)?')
rOrImmMatch = matcher.search(code)
if (rOrImmMatch == None):
return (False, code, '', '', '')
rString = rOrImmMatch.group("rNum")
if (rOrImmMatch.group("typeQual") != None):
rString += rOrImmMatch.group("typeQual")
iString = rOrImmMatch.group("iNum")
orig_code = code
code = matcher.sub('Rs' + rString, orig_code)
imm_code = matcher.sub('imm', orig_code)
return (True, code, imm_code, rString, iString)
}};
output decoder {{
inline void printMnemonic(std::ostream &os, const char * mnemonic)
{
ccprintf(os, "\t%s ", mnemonic);
}
void SparcStaticInst::printRegArray(std::ostream &os,
const RegIndex indexArray[], int num) const
{
if (num <= 0)
return;
printReg(os, indexArray[0]);
for (int x = 1; x < num; x++) {
os << ", ";
printReg(os, indexArray[x]);
}
}
void
SparcStaticInst::advancePC(SparcISA::PCState &pcState) const
{
pcState.advance();
}
void
SparcStaticInst::printSrcReg(std::ostream &os, int reg) const
{
if (_numSrcRegs > reg)
printReg(os, _srcRegIdx[reg]);
}
void
SparcStaticInst::printDestReg(std::ostream &os, int reg) const
{
if (_numDestRegs > reg)
printReg(os, _destRegIdx[reg]);
}
void
SparcStaticInst::printReg(std::ostream &os, int reg) const
{
const int MaxGlobal = 8;
const int MaxOutput = 16;
const int MaxLocal = 24;
const int MaxInput = 32;
const int MaxMicroReg = 40;
if (reg < FP_Base_DepTag) {
// If we used a register from the next or previous window,
// take out the offset.
while (reg >= MaxMicroReg)
reg -= MaxMicroReg;
if (reg == FramePointerReg)
ccprintf(os, "%%fp");
else if (reg == StackPointerReg)
ccprintf(os, "%%sp");
else if (reg < MaxGlobal)
ccprintf(os, "%%g%d", reg);
else if (reg < MaxOutput)
ccprintf(os, "%%o%d", reg - MaxGlobal);
else if (reg < MaxLocal)
ccprintf(os, "%%l%d", reg - MaxOutput);
else if (reg < MaxInput)
ccprintf(os, "%%i%d", reg - MaxLocal);
else if (reg < MaxMicroReg)
ccprintf(os, "%%u%d", reg - MaxInput);
// The fake int regs that are really control regs
else {
switch (reg - MaxMicroReg) {
case 1:
ccprintf(os, "%%y");
break;
case 2:
ccprintf(os, "%%ccr");
break;
case 3:
ccprintf(os, "%%cansave");
break;
case 4:
ccprintf(os, "%%canrestore");
break;
case 5:
ccprintf(os, "%%cleanwin");
break;
case 6:
ccprintf(os, "%%otherwin");
break;
case 7:
ccprintf(os, "%%wstate");
break;
}
}
} else if (reg < Ctrl_Base_DepTag) {
ccprintf(os, "%%f%d", reg - FP_Base_DepTag);
} else {
switch (reg - Ctrl_Base_DepTag) {
case MISCREG_ASI:
ccprintf(os, "%%asi");
break;
case MISCREG_FPRS:
ccprintf(os, "%%fprs");
break;
case MISCREG_PCR:
ccprintf(os, "%%pcr");
break;
case MISCREG_PIC:
ccprintf(os, "%%pic");
break;
case MISCREG_GSR:
ccprintf(os, "%%gsr");
break;
case MISCREG_SOFTINT:
ccprintf(os, "%%softint");
break;
case MISCREG_SOFTINT_SET:
ccprintf(os, "%%softint_set");
break;
case MISCREG_SOFTINT_CLR:
ccprintf(os, "%%softint_clr");
break;
case MISCREG_TICK_CMPR:
ccprintf(os, "%%tick_cmpr");
break;
case MISCREG_STICK:
ccprintf(os, "%%stick");
break;
case MISCREG_STICK_CMPR:
ccprintf(os, "%%stick_cmpr");
break;
case MISCREG_TPC:
ccprintf(os, "%%tpc");
break;
case MISCREG_TNPC:
ccprintf(os, "%%tnpc");
break;
case MISCREG_TSTATE:
ccprintf(os, "%%tstate");
break;
case MISCREG_TT:
ccprintf(os, "%%tt");
break;
case MISCREG_TICK:
ccprintf(os, "%%tick");
break;
case MISCREG_TBA:
ccprintf(os, "%%tba");
break;
case MISCREG_PSTATE:
ccprintf(os, "%%pstate");
break;
case MISCREG_TL:
ccprintf(os, "%%tl");
break;
case MISCREG_PIL:
ccprintf(os, "%%pil");
break;
case MISCREG_CWP:
ccprintf(os, "%%cwp");
break;
case MISCREG_GL:
ccprintf(os, "%%gl");
break;
case MISCREG_HPSTATE:
ccprintf(os, "%%hpstate");
break;
case MISCREG_HTSTATE:
ccprintf(os, "%%htstate");
break;
case MISCREG_HINTP:
ccprintf(os, "%%hintp");
break;
case MISCREG_HTBA:
ccprintf(os, "%%htba");
break;
case MISCREG_HSTICK_CMPR:
ccprintf(os, "%%hstick_cmpr");
break;
case MISCREG_HVER:
ccprintf(os, "%%hver");
break;
case MISCREG_STRAND_STS_REG:
ccprintf(os, "%%strand_sts_reg");
break;
case MISCREG_FSR:
ccprintf(os, "%%fsr");
break;
default:
ccprintf(os, "%%ctrl%d", reg - Ctrl_Base_DepTag);
}
}
}
std::string
SparcStaticInst::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
std::stringstream ss;
printMnemonic(ss, 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();
}
bool
passesFpCondition(uint32_t fcc, uint32_t condition)
{
bool u = (fcc == 3);
bool g = (fcc == 2);
bool l = (fcc == 1);
bool e = (fcc == 0);
switch (condition) {
case FAlways:
return 1;
case FNever:
return 0;
case FUnordered:
return u;
case FGreater:
return g;
case FUnorderedOrGreater:
return u || g;
case FLess:
return l;
case FUnorderedOrLess:
return u || l;
case FLessOrGreater:
return l || g;
case FNotEqual:
return l || g || u;
case FEqual:
return e;
case FUnorderedOrEqual:
return u || e;
case FGreaterOrEqual:
return g || e;
case FUnorderedOrGreaterOrEqual:
return u || g || e;
case FLessOrEqual:
return l || e;
case FUnorderedOrLessOrEqual:
return u || l || e;
case FOrdered:
return e || l || g;
}
panic("Tried testing condition nonexistant "
"condition code %d", condition);
}
bool
passesCondition(uint32_t codes, uint32_t condition)
{
CondCodes condCodes;
condCodes.bits = 0;
condCodes.c = codes & 0x1 ? 1 : 0;
condCodes.v = codes & 0x2 ? 1 : 0;
condCodes.z = codes & 0x4 ? 1 : 0;
condCodes.n = codes & 0x8 ? 1 : 0;
switch (condition) {
case Always:
return true;
case Never:
return false;
case NotEqual:
return !condCodes.z;
case Equal:
return condCodes.z;
case Greater:
return !(condCodes.z | (condCodes.n ^ condCodes.v));
case LessOrEqual:
return condCodes.z | (condCodes.n ^ condCodes.v);
case GreaterOrEqual:
return !(condCodes.n ^ condCodes.v);
case Less:
return (condCodes.n ^ condCodes.v);
case GreaterUnsigned:
return !(condCodes.c | condCodes.z);
case LessOrEqualUnsigned:
return (condCodes.c | condCodes.z);
case CarryClear:
return !condCodes.c;
case CarrySet:
return condCodes.c;
case Positive:
return !condCodes.n;
case Negative:
return condCodes.n;
case OverflowClear:
return !condCodes.v;
case OverflowSet:
return condCodes.v;
}
panic("Tried testing condition nonexistant "
"condition code %d", condition);
}
}};
output exec {{
/// Check "FP enabled" machine status bit. Called when executing any FP
/// instruction.
/// @retval Full-system mode: NoFault if FP is enabled, FpDisabled
/// if not. Non-full-system mode: always returns NoFault.
static inline Fault
checkFpEnableFault(%(CPU_exec_context)s *xc)
{
if (FullSystem) {
PSTATE pstate = xc->readMiscReg(MISCREG_PSTATE);
if (pstate.pef && xc->readMiscReg(MISCREG_FPRS) & 0x4) {
return NoFault;
} else {
return new FpDisabled;
}
} else {
return NoFault;
}
}
}};

View File

@ -0,0 +1,83 @@
// 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: Ali Saidi
// Gabe Black
// Steve Reinhardt
////////////////////////////////////////////////////////////////////
//
// Bitfield definitions.
//
// Bitfields are shared liberally between instruction formats, so they are
// simply defined alphabetically
def bitfield A <29>;
def bitfield BPCC <21:20>; // for BPcc & FBPcc
def bitfield FCMPCC <26:25>; // for FCMP & FCMPEa
def bitfield FMOVCC <13:11>; // for FMOVcc
def bitfield CC <12:11>; // for MOVcc & Tcc
def bitfield MOVCC3 <18>; // also for MOVcc
def bitfield CMASK <6:4>;
def bitfield COND2 <28:25>;
def bitfield COND4 <17:14>;
def bitfield D16HI <21:20>;
def bitfield D16LO <13:0>;
def bitfield DISP19 <18:0>;
def bitfield DISP22 <21:0>;
def bitfield DISP30 <29:0>;
def bitfield FCN <29:25>;
def bitfield I <13>;
def bitfield IMM_ASI <12:5>;
def bitfield IMM22 <21:0>;
def bitfield M5FUNC <15:7>;
def bitfield MMASK <3:0>;
def bitfield OP <31:30>;
def bitfield OP2 <24:22>;
def bitfield OP3 <24:19>;
def bitfield OPF <13:5>;
def bitfield OPF_CC <13:11>;
def bitfield OPF_LOW5 <9:5>;
def bitfield OPF_LOW6 <10:5>;
def bitfield P <19>;
def bitfield RCOND2 <27:25>;
def bitfield RCOND3 <12:10>;
def bitfield RCOND4 <12:10>;
def bitfield RD <29:25>;
def bitfield RS1 <18:14>;
def bitfield RS2 <4:0>;
def bitfield SHCNT32 <4:0>;
def bitfield SHCNT64 <5:0>;
def bitfield SIMM10 <9:0>;
def bitfield SIMM11 <10:0>;
def bitfield SIMM13 <12:0>;
def bitfield SW_TRAP <7:0>;
def bitfield X <12>;
// Extended bitfields which aren't part of the actual instruction.
def bitfield EXT_ASI <39:32>;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,196 @@
// 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: Ali Saidi
// Gabe Black
// Steve Reinhardt
// Declarations for execute() methods.
def template BasicExecDeclare {{
Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const;
}};
def template DoFpOpDeclare {{
Fault doFpOp(%(CPU_exec_context)s *, Trace::InstRecord *)
const M5_NO_INLINE;
}};
// Definitions of execute methods that panic.
def template BasicExecPanic {{
Fault
execute(%(CPU_exec_context)s *, Trace::InstRecord *) const
{
panic("Execute method called when it shouldn't!");
M5_DUMMY_RETURN
}
}};
// 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 declaration template.
def template FpBasicDeclare {{
/**
* Static instruction class for "%(mnemonic)s".
*/
class %(class_name)s : public %(base_class)s
{
public:
// Constructor.
%(class_name)s(ExtMachInst machInst);
%(BasicExecDeclare)s
%(DoFpOpDeclare)s
};
}};
// Basic instruction class declaration template.
def template BasicDeclareWithMnemonic {{
/**
* Static instruction class for "%(mnemonic)s".
*/
class %(class_name)s : public %(base_class)s
{
public:
// Constructor.
%(class_name)s(const char * mnemonic, 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 constructor template.
def template BasicConstructorWithMnemonic {{
inline %(class_name)s::%(class_name)s(const char * mnemonic,
ExtMachInst machInst)
: %(base_class)s(mnemonic, 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;
}
}};
def template DoFpOpExecute {{
Fault
%(class_name)s::doFpOp(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
%(op_decl)s;
%(op_rd)s;
%(fp_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) {{
code = filterDoubles(code)
iop = InstObjParams(name, Name, 'SparcStaticInst', code, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};
def format FpBasic(code, *flags) {{
exec_code = """
Fsr |= bits(Fsr, 4, 0) << 5;
Fsr = insertBits(Fsr, 4, 0, 0);
int newrnd = M5_FE_TONEAREST;
switch (Fsr<31:30>) {
case 0: newrnd = M5_FE_TONEAREST; break;
case 1: newrnd = M5_FE_TOWARDZERO; break;
case 2: newrnd = M5_FE_UPWARD; break;
case 3: newrnd = M5_FE_DOWNWARD; break;
}
int oldrnd = m5_fegetround();
m5_fesetround(newrnd);
__asm__ __volatile__("" ::: "memory");
fault = doFpOp(xc, traceData);
__asm__ __volatile__("" ::: "memory");
m5_fesetround(oldrnd);
return fault;
"""
fp_code = filterDoubles(code)
iop = InstObjParams(name, Name, 'SparcStaticInst',
{ "code" : exec_code, "fp_code" : fp_code }, flags)
header_output = FpBasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
exec_output += DoFpOpExecute.subst(iop)
}};

View File

@ -0,0 +1,347 @@
// 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
// Steve Reinhardt
////////////////////////////////////////////////////////////////////
//
// Branch instructions
//
output header {{
/**
* Base class for branch operations.
*/
class Branch : public SparcStaticInst
{
protected:
// Constructor
Branch(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
SparcStaticInst(mnem, _machInst, __opClass)
{
}
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const;
};
/**
* Base class for branch operations with an immediate displacement.
*/
class BranchDisp : public Branch
{
protected:
// Constructor
BranchDisp(const char *mnem, ExtMachInst _machInst,
OpClass __opClass) :
Branch(mnem, _machInst, __opClass)
{
}
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const;
int32_t disp;
};
/**
* Base class for branches with n bit displacements.
*/
template<int bits>
class BranchNBits : public BranchDisp
{
protected:
// Constructor
BranchNBits(const char *mnem, ExtMachInst _machInst,
OpClass __opClass) :
BranchDisp(mnem, _machInst, __opClass)
{
disp = sext<bits + 2>((_machInst & mask(bits)) << 2);
}
};
/**
* Base class for 16bit split displacements.
*/
class BranchSplit : public BranchDisp
{
protected:
// Constructor
BranchSplit(const char *mnem, ExtMachInst _machInst,
OpClass __opClass) :
BranchDisp(mnem, _machInst, __opClass)
{
disp = sext<18>((D16HI << 16) | (D16LO << 2));
}
};
/**
* Base class for branches that use an immediate and a register to
* compute their displacements.
*/
class BranchImm13 : public Branch
{
protected:
// Constructor
BranchImm13(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
Branch(mnem, _machInst, __opClass), imm(sext<13>(SIMM13))
{
}
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const;
int32_t imm;
};
}};
output decoder {{
template class BranchNBits<19>;
template class BranchNBits<22>;
template class BranchNBits<30>;
std::string
Branch::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream response;
printMnemonic(response, mnemonic);
printRegArray(response, _srcRegIdx, _numSrcRegs);
if (_numDestRegs && _numSrcRegs)
response << ", ";
printDestReg(response, 0);
return response.str();
}
std::string
BranchImm13::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
std::stringstream response;
printMnemonic(response, mnemonic);
printRegArray(response, _srcRegIdx, _numSrcRegs);
if (_numSrcRegs > 0)
response << ", ";
ccprintf(response, "0x%x", imm);
if (_numDestRegs > 0)
response << ", ";
printDestReg(response, 0);
return response.str();
}
std::string
BranchDisp::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
std::stringstream response;
std::string symbol;
Addr symbolAddr;
Addr target = disp + pc;
printMnemonic(response, mnemonic);
ccprintf(response, "0x%x", target);
if (symtab &&
symtab->findNearestSymbol(target, symbol, symbolAddr)) {
ccprintf(response, " <%s", symbol);
if (symbolAddr != target)
ccprintf(response, "+%d>", target - symbolAddr);
else
ccprintf(response, ">");
}
return response.str();
}
}};
def template JumpExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
// Attempt to execute the instruction
Fault fault = NoFault;
%(op_decl)s;
%(op_rd)s;
%(code)s;
if (fault == NoFault) {
// Write the resulting state to the execution context
%(op_wb)s;
}
return fault;
}
}};
def template BranchExecute {{
Fault
%(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
// Attempt to execute the instruction
Fault fault = NoFault;
%(op_decl)s;
%(op_rd)s;
if (%(cond)s) {
%(code)s;
} else {
%(fail)s;
}
if (fault == NoFault) {
// Write the resulting state to the execution context
%(op_wb)s;
}
return fault;
}
}};
def template BranchDecode {{
if (A)
return new %(class_name)sAnnul("%(mnemonic)s,a", machInst);
else
return new %(class_name)s("%(mnemonic)s", machInst);
}};
// Primary format for branch instructions:
def format Branch(code, *opt_flags) {{
code = 'NNPC = NNPC;\n' + code
(usesImm, code, immCode,
rString, iString) = splitOutImm(code)
iop = InstObjParams(name, Name, 'Branch', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
exec_output = JumpExecute.subst(iop)
if usesImm:
imm_iop = InstObjParams(name, Name + 'Imm', 'BranchImm' + iString,
immCode, opt_flags)
header_output += BasicDeclare.subst(imm_iop)
decoder_output += BasicConstructor.subst(imm_iop)
exec_output += JumpExecute.subst(imm_iop)
decode_block = ROrImmDecode.subst(iop)
else:
decode_block = BasicDecode.subst(iop)
}};
let {{
def doBranch(name, Name, base, cond,
code, annul_code, fail, annul_fail, opt_flags):
#@todo: add flags and branchTarget() for DirectCntrl branches
# the o3 model can take advantage of this annotation if
# done correctly
iop = InstObjParams(name, Name, base,
{"code": code,
"fail": fail,
"cond": cond
},
opt_flags)
header_output = BasicDeclareWithMnemonic.subst(iop)
decoder_output = BasicConstructorWithMnemonic.subst(iop)
exec_output = BranchExecute.subst(iop)
if annul_code == "None":
decode_block = BasicDecodeWithMnemonic.subst(iop)
else:
decode_block = BranchDecode.subst(iop)
if annul_code != "None":
iop = InstObjParams(name + ',a', Name + 'Annul', base,
{"code": annul_code,
"fail": annul_fail,
"cond": cond
},
opt_flags)
header_output += BasicDeclareWithMnemonic.subst(iop)
decoder_output += BasicConstructorWithMnemonic.subst(iop)
exec_output += BranchExecute.subst(iop)
return (header_output, decoder_output, exec_output, decode_block)
def doCondBranch(name, Name, base, cond, code, opt_flags):
opt_flags += ('IsCondControl', )
return doBranch(name, Name, base, cond, code, code,
'NNPC = NNPC; NPC = NPC;\n',
'NNPC = NPC + 8; NPC = NPC + 4;\n',
opt_flags)
def doUncondBranch(name, Name, base, code, annul_code, opt_flags):
opt_flags += ('IsUncondControl', )
return doBranch(name, Name, base, "true", code, annul_code,
";", ";", opt_flags)
default_branch_code = 'NNPC = PC + disp;\n'
}};
// Format for branch instructions with n bit displacements:
def format BranchN(bits, code=default_branch_code,
test=None, annul_code=None, *opt_flags) {{
if code == "default_branch_code":
code = default_branch_code
if test != "None":
(header_output,
decoder_output,
exec_output,
decode_block) = doCondBranch(name, Name,
"BranchNBits<%d>" % bits, test, code, opt_flags)
else:
(header_output,
decoder_output,
exec_output,
decode_block) = doUncondBranch(name, Name,
"BranchNBits<%d>" % bits, code, annul_code, opt_flags)
}};
// Format for branch instructions with split displacements:
def format BranchSplit(code=default_branch_code,
test=None, annul_code=None, *opt_flags) {{
if code == "default_branch_code":
code = default_branch_code
if test != "None":
(header_output,
decoder_output,
exec_output,
decode_block) = doCondBranch(name, Name,
"BranchSplit", test, code, opt_flags)
else:
(header_output,
decoder_output,
exec_output,
decode_block) = doUncondBranch(name, Name,
"BranchSplit", code, annul_code, opt_flags)
}};

View File

@ -0,0 +1,59 @@
// 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: Gabe Black
// Include the basic format
// Templates from this format are used later
##include "basic.isa"
// Include base classes for microcoding instructions
##include "micro.isa"
// Include the noop format
##include "nop.isa"
// Include the integerOp and integerOpCc format
##include "integerop.isa"
// Include the memory formats
##include "mem/mem.isa"
// Include the trap format
##include "trap.isa"
// Include the unimplemented format
##include "unimp.isa"
// Include the "unknown" format
##include "unknown.isa"
// Include the priveleged mode format
##include "priv.isa"
// Include the branch format
##include "branch.isa"

View File

@ -0,0 +1,370 @@
// 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: Ali Saidi
// Gabe Black
// Steve Reinhardt
////////////////////////////////////////////////////////////////////
//
// Integer operate instructions
//
output header {{
/**
* Base class for integer operations.
*/
class IntOp : public SparcStaticInst
{
protected:
// Constructor
IntOp(const char *mnem, ExtMachInst _machInst,
OpClass __opClass) :
SparcStaticInst(mnem, _machInst, __opClass)
{
}
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const;
virtual bool printPseudoOps(std::ostream &os, Addr pc,
const SymbolTable *symtab) const;
};
/**
* Base class for immediate integer operations.
*/
class IntOpImm : public IntOp
{
protected:
// Constructor
IntOpImm(const char *mnem, ExtMachInst _machInst,
OpClass __opClass) :
IntOp(mnem, _machInst, __opClass)
{
}
int64_t imm;
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const;
virtual bool printPseudoOps(std::ostream &os, Addr pc,
const SymbolTable *symtab) const;
};
/**
* Base class for 10 bit immediate integer operations.
*/
class IntOpImm10 : public IntOpImm
{
protected:
// Constructor
IntOpImm10(const char *mnem, ExtMachInst _machInst,
OpClass __opClass) :
IntOpImm(mnem, _machInst, __opClass)
{
imm = sext<10>(SIMM10);
}
};
/**
* Base class for 11 bit immediate integer operations.
*/
class IntOpImm11 : public IntOpImm
{
protected:
// Constructor
IntOpImm11(const char *mnem, ExtMachInst _machInst,
OpClass __opClass) :
IntOpImm(mnem, _machInst, __opClass)
{
imm = sext<11>(SIMM11);
}
};
/**
* Base class for 13 bit immediate integer operations.
*/
class IntOpImm13 : public IntOpImm
{
protected:
// Constructor
IntOpImm13(const char *mnem, ExtMachInst _machInst,
OpClass __opClass) :
IntOpImm(mnem, _machInst, __opClass)
{
imm = sext<13>(SIMM13);
}
};
/**
* Base class for sethi.
*/
class SetHi : public IntOpImm
{
protected:
// Constructor
SetHi(const char *mnem, ExtMachInst _machInst,
OpClass __opClass) :
IntOpImm(mnem, _machInst, __opClass)
{
imm = (IMM22 & 0x3FFFFF) << 10;
}
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const;
};
}};
def template SetHiDecode {{
{
if (RD == 0 && IMM22 == 0)
return (SparcStaticInst *)(new Nop("nop", machInst, No_OpClass));
else
return (SparcStaticInst *)(new %(class_name)s(machInst));
}
}};
output decoder {{
bool
IntOp::printPseudoOps(std::ostream &os, Addr pc,
const SymbolTable *symbab) const
{
if (!std::strcmp(mnemonic, "or") && _srcRegIdx[0] == 0) {
printMnemonic(os, "mov");
printSrcReg(os, 1);
ccprintf(os, ", ");
printDestReg(os, 0);
return true;
}
return false;
}
bool
IntOpImm::printPseudoOps(std::ostream &os, Addr pc,
const SymbolTable *symbab) const
{
if (!std::strcmp(mnemonic, "or")) {
if (_numSrcRegs > 0 && _srcRegIdx[0] == 0) {
if (imm == 0) {
printMnemonic(os, "clr");
} else {
printMnemonic(os, "mov");
ccprintf(os, " 0x%x, ", imm);
}
printDestReg(os, 0);
return true;
} else if (imm == 0) {
printMnemonic(os, "mov");
printSrcReg(os, 0);
ccprintf(os, ", ");
printDestReg(os, 0);
return true;
}
}
return false;
}
std::string
IntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream response;
if (printPseudoOps(response, pc, symtab))
return response.str();
printMnemonic(response, mnemonic);
printRegArray(response, _srcRegIdx, _numSrcRegs);
if (_numDestRegs && _numSrcRegs)
response << ", ";
printDestReg(response, 0);
return response.str();
}
std::string
IntOpImm::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
std::stringstream response;
if (printPseudoOps(response, pc, symtab))
return response.str();
printMnemonic(response, mnemonic);
printRegArray(response, _srcRegIdx, _numSrcRegs);
if (_numSrcRegs > 0)
response << ", ";
ccprintf(response, "0x%x", imm);
if (_numDestRegs > 0)
response << ", ";
printDestReg(response, 0);
return response.str();
}
std::string
SetHi::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream response;
printMnemonic(response, mnemonic);
ccprintf(response, "%%hi(0x%x), ", imm);
printDestReg(response, 0);
return response.str();
}
}};
def template IntOpExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
%(op_decl)s;
%(op_rd)s;
%(code)s;
// Write the resulting state to the execution context
if (fault == NoFault) {
%(cc_code)s;
%(op_wb)s;
}
return fault;
}
}};
let {{
def doIntFormat(code, ccCode, name, Name, opt_flags):
(usesImm, code, immCode,
rString, iString) = splitOutImm(code)
iop = InstObjParams(name, Name, 'IntOp',
{"code": code, "cc_code": ccCode},
opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
exec_output = IntOpExecute.subst(iop)
if usesImm:
imm_iop = InstObjParams(name, Name + 'Imm', 'IntOpImm' + iString,
{"code": immCode, "cc_code": ccCode}, opt_flags)
header_output += BasicDeclare.subst(imm_iop)
decoder_output += BasicConstructor.subst(imm_iop)
exec_output += IntOpExecute.subst(imm_iop)
decode_block = ROrImmDecode.subst(iop)
else:
decode_block = BasicDecode.subst(iop)
return (header_output, decoder_output, exec_output, decode_block)
calcCcCode = '''
uint16_t _ic, _iv, _iz, _in, _xc, _xv, _xz, _xn;
_in = (Rd >> 31) & 1;
_iz = ((Rd & 0xFFFFFFFF) == 0);
_xn = (Rd >> 63) & 1;
_xz = (Rd == 0);
_iv = %(iv)s & 1;
_ic = %(ic)s & 1;
_xv = %(xv)s & 1;
_xc = %(xc)s & 1;
Ccr = _ic << 0 | _iv << 1 | _iz << 2 | _in << 3 |
_xc << 4 | _xv << 5 | _xz << 6 | _xn << 7;
DPRINTF(Sparc, "in = %%d\\n", _in);
DPRINTF(Sparc, "iz = %%d\\n", _iz);
DPRINTF(Sparc, "xn = %%d\\n", _xn);
DPRINTF(Sparc, "xz = %%d\\n", _xz);
DPRINTF(Sparc, "iv = %%d\\n", _iv);
DPRINTF(Sparc, "ic = %%d\\n", _ic);
DPRINTF(Sparc, "xv = %%d\\n", _xv);
DPRINTF(Sparc, "xc = %%d\\n", _xc);
'''
default_ic = "findCarry(32, res, op1, op2)"
default_iv = "findOverflow(32, res, op1, op2)"
default_xc = "findCarry(64, res, op1, op2)"
default_xv = "findOverflow(64, res, op1, op2)"
default_sub_ic = "!findCarry(32, res, op1, ~op2)"
default_sub_iv = "findOverflow(32, res, op1, ~op2)"
default_sub_xc = "!findCarry(64, res, op1, ~op2)"
default_sub_xv = "findOverflow(64, res, op1, ~op2)"
}};
// Primary format for integer operate instructions:
def format IntOp(code, *opt_flags) {{
ccCode = ''
(header_output,
decoder_output,
exec_output,
decode_block) = doIntFormat(code, ccCode,
name, Name, opt_flags)
}};
// Primary format for integer operate instructions:
def format IntOpCc(code, ic=default_ic, iv=default_iv,
xc=default_xc, xv=default_xv,
sub=False, *opt_flags) {{
if sub == "False":
(def_ic, def_iv, def_xc, def_xv) = \
(default_ic, default_iv, default_xc, default_xv)
else:
(def_ic, def_iv, def_xc, def_xv) = \
(default_sub_ic, default_sub_iv, default_sub_xc, default_sub_xv)
if ic == "default_ic":
ic = def_ic
if iv == "default_iv":
iv = def_iv
if xc == "default_xc":
xc = def_xc
if xv == "default_xv":
xv = def_xv
ccCode = calcCcCode % vars()
(header_output,
decoder_output,
exec_output,
decode_block) = doIntFormat(code, ccCode,
name, Name, opt_flags)
}};
// Primary format for integer operate instructions:
def format IntOpCcRes(code, ic=0, iv=0, xc=0, xv=0, *opt_flags) {{
ccCode = calcCcCode % {"ic" : ic, "iv" : iv, "xc" : xc, "xv" : xv}
(header_output,
decoder_output,
exec_output,
decode_block) = doIntFormat(code, ccCode,
name, Name, opt_flags)
}};
def format SetHi(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'SetHi',
{"code": code, "cc_code": ''}, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
exec_output = IntOpExecute.subst(iop)
decode_block = SetHiDecode.subst(iop)
}};

View File

@ -0,0 +1,135 @@
// -*- mode:c++ -*-
// 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: Ali Saidi
// Gabe Black
////////////////////////////////////////////////////////////////////
//
// Mem instructions
//
def template MemDeclare {{
/**
* 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
};
}};
let {{
def doMemFormat(code, execute, faultCode, name, Name, asi, opt_flags, postacc_code = ''):
addrCalcReg = 'EA = Rs1 + Rs2;'
addrCalcImm = 'EA = Rs1 + imm;'
iop = InstObjParams(name, Name, 'Mem',
{"code": code, "postacc_code" : postacc_code,
"fault_check": faultCode, "ea_code": addrCalcReg,
"EA_trunc": TruncateEA}, opt_flags)
iop_imm = InstObjParams(name, Name + "Imm", 'MemImm',
{"code": code, "postacc_code" : postacc_code,
"fault_check": faultCode, "ea_code": addrCalcImm,
"EA_trunc": TruncateEA}, opt_flags)
header_output = MemDeclare.subst(iop) + MemDeclare.subst(iop_imm)
decoder_output = BasicConstructor.subst(iop) + BasicConstructor.subst(iop_imm)
decode_block = ROrImmDecode.subst(iop)
exec_output = doDualSplitExecute(code, postacc_code, addrCalcReg,
addrCalcImm, execute, faultCode, name, name + "Imm",
Name, Name + "Imm", asi, opt_flags)
exec_output += EACompExecute.subst(iop);
exec_output += EACompExecute.subst(iop_imm);
return (header_output, decoder_output, exec_output, decode_block)
}};
def format LoadAlt(code, *opt_flags) {{
code = filterDoubles(code)
(header_output,
decoder_output,
exec_output,
decode_block) = doMemFormat(code, LoadFuncs,
AlternateASIPrivFaultCheck, name, Name, "EXT_ASI", opt_flags)
}};
def format StoreAlt(code, *opt_flags) {{
code = filterDoubles(code)
(header_output,
decoder_output,
exec_output,
decode_block) = doMemFormat(code, StoreFuncs,
AlternateASIPrivFaultCheck, name, Name, "EXT_ASI", opt_flags)
}};
def format Load(code, *opt_flags) {{
code = filterDoubles(code)
(header_output,
decoder_output,
exec_output,
decode_block) = doMemFormat(code,
LoadFuncs, '', name, Name, 0, opt_flags)
}};
def format Store(code, *opt_flags) {{
code = filterDoubles(code)
(header_output,
decoder_output,
exec_output,
decode_block) = doMemFormat(code,
StoreFuncs, '', name, Name, 0, opt_flags)
}};
def format StoreFsr(code, *opt_flags) {{
code = filterDoubles(code)
(header_output,
decoder_output,
exec_output,
decode_block) = doMemFormat(code,
StoreFuncs, '', name, Name, 0, opt_flags,
'Fsr = insertBits(Fsr,16,14,0);')
}};
def format TwinLoad(code, *opt_flags) {{
(header_output,
decoder_output,
exec_output,
decode_block) = doMemFormat(code, LoadFuncs,
AlternateASIPrivFaultCheck + TwinAlignmentFaultCheck,
name, Name, "EXT_ASI", opt_flags)
}};

View File

@ -0,0 +1,341 @@
// 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: Ali Saidi
// Gabe Black
////////////////////////////////////////////////////////////////////
//
// Block Memory instructions
//
output header {{
class BlockMem : public SparcMacroInst
{
protected:
// Constructor
// We make the assumption that all block memory operations
// Will take 8 instructions to execute
BlockMem(const char *mnem, ExtMachInst _machInst) :
SparcMacroInst(mnem, _machInst, No_OpClass, 8)
{}
};
class BlockMemImm : public BlockMem
{
protected:
// Constructor
BlockMemImm(const char *mnem, ExtMachInst _machInst) :
BlockMem(mnem, _machInst)
{}
};
class BlockMemMicro : public SparcMicroInst
{
protected:
// Constructor
BlockMemMicro(const char *mnem, ExtMachInst _machInst,
OpClass __opClass, int8_t _offset) :
SparcMicroInst(mnem, _machInst, __opClass),
offset(_offset)
{}
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const;
const int8_t offset;
};
class BlockMemImmMicro : public BlockMemMicro
{
protected:
// Constructor
BlockMemImmMicro(const char *mnem, ExtMachInst _machInst,
OpClass __opClass, int8_t _offset) :
BlockMemMicro(mnem, _machInst, __opClass, _offset),
imm(sext<13>(SIMM13))
{}
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const;
const int32_t imm;
};
}};
output decoder {{
std::string BlockMemMicro::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
std::stringstream response;
bool load = flags[IsLoad];
bool save = flags[IsStore];
printMnemonic(response, mnemonic);
if (save) {
printReg(response, _srcRegIdx[0]);
ccprintf(response, ", ");
}
ccprintf(response, "[ ");
printReg(response, _srcRegIdx[!save ? 0 : 1]);
ccprintf(response, " + ");
printReg(response, _srcRegIdx[!save ? 1 : 2]);
ccprintf(response, " ]");
if (load) {
ccprintf(response, ", ");
printReg(response, _destRegIdx[0]);
}
return response.str();
}
std::string BlockMemImmMicro::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
std::stringstream response;
bool load = flags[IsLoad];
bool save = flags[IsStore];
printMnemonic(response, mnemonic);
if (save) {
printReg(response, _srcRegIdx[1]);
ccprintf(response, ", ");
}
ccprintf(response, "[ ");
printReg(response, _srcRegIdx[0]);
if (imm >= 0)
ccprintf(response, " + 0x%x ]", imm);
else
ccprintf(response, " + -0x%x ]", -imm);
if (load) {
ccprintf(response, ", ");
printReg(response, _destRegIdx[0]);
}
return response.str();
}
}};
def template BlockMemDeclare {{
/**
* Static instruction class for a block memory operation
*/
class %(class_name)s : public %(base_class)s
{
public:
// Constructor
%(class_name)s(ExtMachInst machInst);
protected:
class %(class_name)s_0 : public %(base_class)sMicro
{
public:
// Constructor
%(class_name)s_0(ExtMachInst machInst);
%(BasicExecDeclare)s
%(InitiateAccDeclare)s
%(CompleteAccDeclare)s
};
class %(class_name)s_1 : public %(base_class)sMicro
{
public:
// Constructor
%(class_name)s_1(ExtMachInst machInst);
%(BasicExecDeclare)s
%(InitiateAccDeclare)s
%(CompleteAccDeclare)s
};
class %(class_name)s_2 : public %(base_class)sMicro
{
public:
// Constructor
%(class_name)s_2(ExtMachInst machInst);
%(BasicExecDeclare)s
%(InitiateAccDeclare)s
%(CompleteAccDeclare)s
};
class %(class_name)s_3 : public %(base_class)sMicro
{
public:
// Constructor
%(class_name)s_3(ExtMachInst machInst);
%(BasicExecDeclare)s
%(InitiateAccDeclare)s
%(CompleteAccDeclare)s
};
class %(class_name)s_4 : public %(base_class)sMicro
{
public:
// Constructor
%(class_name)s_4(ExtMachInst machInst);
%(BasicExecDeclare)s
%(InitiateAccDeclare)s
%(CompleteAccDeclare)s
};
class %(class_name)s_5 : public %(base_class)sMicro
{
public:
// Constructor
%(class_name)s_5(ExtMachInst machInst);
%(BasicExecDeclare)s
%(InitiateAccDeclare)s
%(CompleteAccDeclare)s
};
class %(class_name)s_6 : public %(base_class)sMicro
{
public:
// Constructor
%(class_name)s_6(ExtMachInst machInst);
%(BasicExecDeclare)s
%(InitiateAccDeclare)s
%(CompleteAccDeclare)s
};
class %(class_name)s_7 : public %(base_class)sMicro
{
public:
// Constructor
%(class_name)s_7(ExtMachInst machInst);
%(BasicExecDeclare)s
%(InitiateAccDeclare)s
%(CompleteAccDeclare)s
};
};
}};
// Basic instruction class constructor template.
def template BlockMemConstructor {{
inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
: %(base_class)s("%(mnemonic)s", machInst)
{
%(constructor)s;
microops[0] = new %(class_name)s_0(machInst);
microops[1] = new %(class_name)s_1(machInst);
microops[2] = new %(class_name)s_2(machInst);
microops[3] = new %(class_name)s_3(machInst);
microops[4] = new %(class_name)s_4(machInst);
microops[5] = new %(class_name)s_5(machInst);
microops[6] = new %(class_name)s_6(machInst);
microops[7] = new %(class_name)s_7(machInst);
}
}};
def template BlockMemMicroConstructor {{
inline %(class_name)s::
%(class_name)s_%(micro_pc)s::
%(class_name)s_%(micro_pc)s(ExtMachInst machInst) :
%(base_class)sMicro("%(mnemonic)s[%(micro_pc)s]",
machInst, %(op_class)s, %(micro_pc)s * 8)
{
%(constructor)s;
%(set_flags)s;
}
}};
let {{
def doBlockMemFormat(code, faultCode, execute, name, Name, opt_flags):
# XXX Need to take care of pstate.hpriv as well. The lower ASIs
# are split into ones that are available in priv and hpriv, and
# those that are only available in hpriv
addrCalcReg = 'EA = Rs1 + Rs2 + offset;'
addrCalcImm = 'EA = Rs1 + imm + offset;'
iop = InstObjParams(name, Name, 'BlockMem', code, opt_flags)
iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', code, opt_flags)
header_output = BlockMemDeclare.subst(iop) + BlockMemDeclare.subst(iop_imm)
decoder_output = BlockMemConstructor.subst(iop) + BlockMemConstructor.subst(iop_imm)
decode_block = ROrImmDecode.subst(iop)
matcher = re.compile(r'Frd_N')
exec_output = ''
for microPc in range(8):
flag_code = ''
if (microPc == 7):
flag_code = "flags[IsLastMicroop] = true;"
elif (microPc == 0):
flag_code = "flags[IsDelayedCommit] = true; flags[IsFirstMicroop] = true;"
else:
flag_code = "flags[IsDelayedCommit] = true;"
pcedCode = matcher.sub("Frd_%d" % microPc, code)
iop = InstObjParams(name, Name, 'BlockMem',
{"code": pcedCode, "ea_code": addrCalcReg,
"fault_check": faultCode, "micro_pc": microPc,
"set_flags": flag_code, "EA_trunc" : TruncateEA},
opt_flags)
iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm',
{"code": pcedCode, "ea_code": addrCalcImm,
"fault_check": faultCode, "micro_pc": microPc,
"set_flags": flag_code, "EA_trunc" : TruncateEA},
opt_flags)
decoder_output += BlockMemMicroConstructor.subst(iop)
decoder_output += BlockMemMicroConstructor.subst(iop_imm)
exec_output += doDualSplitExecute(
pcedCode, '', addrCalcReg, addrCalcImm, execute, faultCode,
makeMicroName(name, microPc),
makeMicroName(name + "Imm", microPc),
makeMicroName(Name, microPc),
makeMicroName(Name + "Imm", microPc),
"EXT_ASI", opt_flags);
faultCode = ''
return (header_output, decoder_output, exec_output, decode_block)
}};
def format BlockLoad(code, *opt_flags) {{
code = filterDoubles(code)
# We need to make sure to check the highest priority fault last.
# That way, if other faults have been detected, they'll be overwritten
# rather than the other way around.
faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck
(header_output,
decoder_output,
exec_output,
decode_block) = doBlockMemFormat(code, faultCode,
LoadFuncs, name, Name, opt_flags)
}};
def format BlockStore(code, *opt_flags) {{
code = filterDoubles(code)
# We need to make sure to check the highest priority fault last.
# That way, if other faults have been detected, they'll be overwritten
# rather than the other way around.
faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck
(header_output,
decoder_output,
exec_output,
decode_block) = doBlockMemFormat(code, faultCode,
StoreFuncs, name, Name, opt_flags)
}};

View File

@ -0,0 +1,45 @@
// 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: Ali Saidi
// Gabe Black
////////////////////////////////////////////////////////////////////
//
// Mem formats
//
// Include mem utility templates and functions
##include "util.isa"
// Include the basic memory format
##include "basicmem.isa"
// Include the block memory format
##include "blockmem.isa"
// Include the load/store and cas memory format
##include "swap.isa"

View File

@ -0,0 +1,183 @@
// 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: Gabe Black
// Ali Saidi
// This template provides the execute functions for a swap
def template SwapExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
// This is to support the conditional store in cas instructions.
// It should be optomized out in all the others
bool storeCond = true;
Addr EA;
%(fp_enable_check)s;
%(op_decl)s;
uint64_t mem_data = 0;
%(op_rd)s;
%(ea_code)s;
DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
%(fault_check)s;
if (fault == NoFault) {
%(code)s;
}
if (storeCond && fault == NoFault) {
%(EA_trunc)s
fault = writeMemAtomic(xc, traceData, Mem, EA,
%(asi_val)s, &mem_data);
}
if (fault == NoFault) {
// Handle the swapping
%(postacc_code)s;
}
if (fault == NoFault) {
// Write the resulting state to the execution context
%(op_wb)s;
}
return fault;
}
}};
def template SwapInitiateAcc {{
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
Trace::InstRecord * traceData) const
{
Fault fault = NoFault;
Addr EA;
%(fp_enable_check)s;
uint64_t mem_data = 0;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
%(fault_check)s;
if (fault == NoFault) {
%(code)s;
}
if (fault == NoFault) {
%(EA_trunc)s
fault = writeMemTiming(xc, traceData, Mem, EA, %(asi_val)s,
&mem_data);
}
return fault;
}
}};
def template SwapCompleteAcc {{
Fault %(class_name)s::completeAcc(PacketPtr pkt, %(CPU_exec_context)s * xc,
Trace::InstRecord * traceData) const
{
Fault fault = NoFault;
%(op_decl)s;
getMem(pkt, Mem, traceData);
uint64_t mem_data = Mem;
if (fault == NoFault) {
// Handle the swapping
%(postacc_code)s;
}
if (fault == NoFault) {
// Write the resulting state to the execution context
%(op_wb)s;
}
return fault;
}
}};
let {{
SwapFuncs = [SwapExecute, SwapInitiateAcc, SwapCompleteAcc]
}};
def format Swap(code, postacc_code, mem_flags, *opt_flags) {{
mem_flags = makeList(mem_flags)
mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
flags = string.join(mem_flags, '|')
(header_output,
decoder_output,
exec_output,
decode_block) = doMemFormat(code, SwapFuncs, '', name, Name, flags,
["IsStoreConditional"], postacc_code)
}};
def format SwapAlt(code, postacc_code, mem_flags, *opt_flags) {{
mem_flags = makeList(mem_flags)
mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
mem_flags.append("EXT_ASI")
flags = string.join(mem_flags, '|')
(header_output,
decoder_output,
exec_output,
decode_block) = doMemFormat(code, SwapFuncs, AlternateASIPrivFaultCheck,
name, Name, flags, ["IsStoreConditional"], postacc_code)
}};
let {{
def doCasFormat(code, execute, faultCode, name, Name, mem_flags, opt_flags, postacc_code = ''):
addrCalcReg = 'EA = Rs1;'
iop = InstObjParams(name, Name, 'Mem',
{"code": code, "postacc_code" : postacc_code,
"fault_check": faultCode, "ea_code": addrCalcReg,
"EA_trunc" : TruncateEA}, opt_flags)
header_output = MemDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
microParams = {"code": code, "postacc_code" : postacc_code,
"ea_code" : addrCalcReg, "fault_check" : faultCode,
"EA_trunc" : TruncateEA}
exec_output = doSplitExecute(execute, name, Name, mem_flags,
["IsStoreConditional"], microParams);
return (header_output, decoder_output, exec_output + EACompExecute.subst(iop), decode_block)
}};
def format CasAlt(code, postacc_code, mem_flags, *opt_flags) {{
mem_flags = makeList(mem_flags)
mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
mem_flags.append("EXT_ASI")
flags = string.join(mem_flags, '|')
(header_output,
decoder_output,
exec_output,
decode_block) = doCasFormat(code, SwapFuncs, AlternateASIPrivFaultCheck,
name, Name, flags, ["IsStoreConditional"], postacc_code)
}};

View File

@ -0,0 +1,366 @@
// 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: Ali Saidi
// Gabe Black
// Steve Reinhardt
////////////////////////////////////////////////////////////////////
//
// Mem utility templates and functions
//
output header {{
/**
* Base class for memory operations.
*/
class Mem : public SparcStaticInst
{
protected:
// Constructor
Mem(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
SparcStaticInst(mnem, _machInst, __opClass)
{
}
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const;
};
/**
* Class for memory operations which use an immediate offset.
*/
class MemImm : public Mem
{
protected:
// Constructor
MemImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
Mem(mnem, _machInst, __opClass), imm(sext<13>(SIMM13))
{}
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const;
const int32_t imm;
};
}};
output decoder {{
std::string Mem::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
std::stringstream response;
bool load = flags[IsLoad];
bool store = flags[IsStore];
printMnemonic(response, mnemonic);
if (store) {
printReg(response, _srcRegIdx[0]);
ccprintf(response, ", ");
}
ccprintf(response, "[");
if (_srcRegIdx[!store ? 0 : 1] != 0) {
printSrcReg(response, !store ? 0 : 1);
ccprintf(response, " + ");
}
printSrcReg(response, !store ? 1 : 2);
ccprintf(response, "]");
if (load) {
ccprintf(response, ", ");
printReg(response, _destRegIdx[0]);
}
return response.str();
}
std::string MemImm::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
std::stringstream response;
bool load = flags[IsLoad];
bool save = flags[IsStore];
printMnemonic(response, mnemonic);
if (save) {
printReg(response, _srcRegIdx[0]);
ccprintf(response, ", ");
}
ccprintf(response, "[");
if (_srcRegIdx[!save ? 0 : 1] != 0) {
printReg(response, _srcRegIdx[!save ? 0 : 1]);
ccprintf(response, " + ");
}
if (imm >= 0)
ccprintf(response, "0x%x]", imm);
else
ccprintf(response, "-0x%x]", -imm);
if (load) {
ccprintf(response, ", ");
printReg(response, _destRegIdx[0]);
}
return response.str();
}
}};
// This template provides the execute functions for a load
def template LoadExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
Addr EA;
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
%(fault_check)s;
if (fault == NoFault) {
%(EA_trunc)s
fault = readMemAtomic(xc, traceData, EA, Mem, %(asi_val)s);
}
if (fault == NoFault) {
%(code)s;
}
if (fault == NoFault) {
// Write the resulting state to the execution context
%(op_wb)s;
}
return fault;
}
}};
def template LoadInitiateAcc {{
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
Trace::InstRecord * traceData) const
{
Fault fault = NoFault;
Addr EA;
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
%(fault_check)s;
if (fault == NoFault) {
%(EA_trunc)s
fault = readMemTiming(xc, traceData, EA, Mem, %(asi_val)s);
}
return fault;
}
}};
def template LoadCompleteAcc {{
Fault %(class_name)s::completeAcc(PacketPtr pkt, %(CPU_exec_context)s * xc,
Trace::InstRecord * traceData) const
{
Fault fault = NoFault;
%(op_decl)s;
%(op_rd)s;
getMem(pkt, Mem, traceData);
%(code)s;
if (fault == NoFault) {
%(op_wb)s;
}
return fault;
}
}};
// This template provides the execute functions for a store
def template StoreExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
// This is to support the conditional store in cas instructions.
// It should be optomized out in all the others
bool storeCond = true;
Addr EA;
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
%(fault_check)s;
if (fault == NoFault) {
%(code)s;
}
if (storeCond && fault == NoFault) {
%(EA_trunc)s
fault = writeMemAtomic(xc, traceData, Mem, EA, %(asi_val)s, 0);
}
if (fault == NoFault) {
// Write the resulting state to the execution context
%(op_wb)s;
}
return fault;
}
}};
def template StoreInitiateAcc {{
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
Trace::InstRecord * traceData) const
{
Fault fault = NoFault;
bool storeCond = true;
Addr EA;
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
%(fault_check)s;
if (fault == NoFault) {
%(code)s;
}
if (storeCond && fault == NoFault) {
%(EA_trunc)s
fault = writeMemTiming(xc, traceData, Mem, EA, %(asi_val)s, 0);
}
return fault;
}
}};
def template StoreCompleteAcc {{
Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc,
Trace::InstRecord * traceData) const
{
return NoFault;
}
}};
def template EACompExecute {{
Fault
%(class_name)s::eaComp(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = NoFault;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
%(fault_check)s;
// NOTE: Trace Data is written using execute or completeAcc templates
if (fault == NoFault) {
%(EA_trunc)s
xc->setEA(EA);
}
return fault;
}
}};
def template EACompDeclare {{
Fault eaComp(%(CPU_exec_context)s *, Trace::InstRecord *) const;
}};
// This delcares the initiateAcc function in memory operations
def template InitiateAccDeclare {{
Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
}};
// This declares the completeAcc function in memory operations
def template CompleteAccDeclare {{
Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
}};
// Here are some code snippets which check for various fault conditions
let {{
LoadFuncs = [LoadExecute, LoadInitiateAcc, LoadCompleteAcc]
StoreFuncs = [StoreExecute, StoreInitiateAcc, StoreCompleteAcc]
# The LSB can be zero, since it's really the MSB in doubles and quads
# and we're dealing with doubles
BlockAlignmentFaultCheck = '''
if (RD & 0xe)
fault = new IllegalInstruction;
else if (EA & 0x3f)
fault = new MemAddressNotAligned;
'''
TwinAlignmentFaultCheck = '''
if (RD & 0x1)
fault = new IllegalInstruction;
else if (EA & 0xf)
fault = new MemAddressNotAligned;
'''
# XXX Need to take care of pstate.hpriv as well. The lower ASIs
# are split into ones that are available in priv and hpriv, and
# those that are only available in hpriv
AlternateASIPrivFaultCheck = '''
if ((!Pstate.priv && !Hpstate.hpriv &&
!asiIsUnPriv((ASI)EXT_ASI)) ||
(!Hpstate.hpriv && asiIsHPriv((ASI)EXT_ASI)))
fault = new PrivilegedAction;
else if (asiIsAsIfUser((ASI)EXT_ASI) && !Pstate.priv)
fault = new PrivilegedAction;
'''
TruncateEA = '''
if (!FullSystem)
EA = Pstate.am ? EA<31:0> : EA;
'''
}};
// A simple function to generate the name of the macro op of a certain
// instruction at a certain micropc
let {{
def makeMicroName(name, microPc):
return name + "::" + name + "_" + str(microPc)
}};
// This function properly generates the execute functions for one of the
// templates above. This is needed because in one case, ea computation,
// fault checks and the actual code all occur in the same function,
// and in the other they're distributed across two. Also note that for
// execute functions, the name of the base class doesn't matter.
let {{
def doSplitExecute(execute, name, Name, asi, opt_flags, microParam):
microParam["asi_val"] = asi;
iop = InstObjParams(name, Name, '', microParam, opt_flags)
(execf, initf, compf) = execute
return execf.subst(iop) + initf.subst(iop) + compf.subst(iop)
def doDualSplitExecute(code, postacc_code, eaRegCode, eaImmCode, execute,
faultCode, nameReg, nameImm, NameReg, NameImm, asi, opt_flags):
executeCode = ''
for (eaCode, name, Name) in (
(eaRegCode, nameReg, NameReg),
(eaImmCode, nameImm, NameImm)):
microParams = {"code": code, "postacc_code" : postacc_code,
"ea_code": eaCode, "fault_check": faultCode,
"EA_trunc" : TruncateEA}
executeCode += doSplitExecute(execute, name, Name,
asi, opt_flags, microParams)
return executeCode
}};

View File

@ -0,0 +1,145 @@
// 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
// This delcares the initiateAcc function in memory operations
def template MacroInitiateAcc {{
Fault
initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const
{
panic("Tried to execute a macroop directly!\n");
return NoFault;
}
}};
def template MacroCompleteAcc {{
Fault
completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const
{
panic("Tried to execute a macroop directly!\n");
return NoFault;
}
}};
// This template provides the execute functions for a store
def template MacroExecute {{
Fault
execute(%(CPU_exec_context)s *, Trace::InstRecord *) const
{
panic("Tried to execute a macroop directly!\n");
return NoFault;
}
}};
output header {{
class SparcMacroInst : public SparcStaticInst
{
protected:
const uint32_t numMicroops;
// Constructor.
SparcMacroInst(const char *mnem, ExtMachInst _machInst,
OpClass __opClass, uint32_t _numMicroops)
: SparcStaticInst(mnem, _machInst, __opClass),
numMicroops(_numMicroops)
{
assert(numMicroops);
microops = new StaticInstPtr[numMicroops];
flags[IsMacroop] = true;
}
~SparcMacroInst()
{
delete [] microops;
}
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const;
StaticInstPtr * microops;
StaticInstPtr
fetchMicroop(MicroPC upc) const
{
assert(upc < numMicroops);
return microops[upc];
}
%(MacroExecute)s
%(MacroInitiateAcc)s
%(MacroCompleteAcc)s
};
class SparcMicroInst : public SparcStaticInst
{
protected:
// Constructor.
SparcMicroInst(const char *mnem,
ExtMachInst _machInst, OpClass __opClass)
: SparcStaticInst(mnem, _machInst, __opClass)
{
flags[IsMicroop] = true;
}
void
advancePC(SparcISA::PCState &pcState) const
{
if (flags[IsLastMicroop])
pcState.uEnd();
else
pcState.uAdvance();
}
};
class SparcDelayedMicroInst : public SparcMicroInst
{
protected:
// Constructor.
SparcDelayedMicroInst(const char *mnem,
ExtMachInst _machInst, OpClass __opClass)
: SparcMicroInst(mnem, _machInst, __opClass)
{
flags[IsDelayedCommit] = true;
}
};
}};
output decoder {{
std::string
SparcMacroInst::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
std::stringstream response;
printMnemonic(response, mnemonic);
return response.str();
}
}};

View File

@ -0,0 +1,97 @@
// 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
// Steve Reinhardt
////////////////////////////////////////////////////////////////////
//
// Nop instruction
//
// Per-cpu-model nop execute method.
def template NopExec {{
Fault execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
{
// Nothing to see here, move along
return NoFault;
}
}};
output header {{
/**
* Nop class.
*/
class Nop : public SparcStaticInst
{
public:
// Constructor
Nop(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
SparcStaticInst(mnem, _machInst, __opClass)
{
flags[IsNop] = true;
}
// All Nop instructions do the same thing, so this can be
// defined here. Nops can be defined directly, so there
// needs to be a default implementation. Interpolate via
// template so i gets expanded to a set of
// cpu-model-specific functions.
%(NopExec)s
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const;
};
}};
output decoder {{
std::string Nop::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
std::stringstream response;
printMnemonic(response, mnemonic);
return response.str();
}
}};
def template NopExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
// Nothing to see here, move along
return NoFault;
}
}};
// Primary format for integer operate instructions:
def format Nop(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'Nop', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = NopExecute.subst(iop)
}};

View File

@ -0,0 +1,301 @@
// 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: Ali Saidi
// Gabe Black
// Steve Reinhardt
////////////////////////////////////////////////////////////////////
//
// Privilege mode instructions
//
output header {{
/**
* Base class for privelege mode operations.
*/
class Priv : public SparcStaticInst
{
protected:
// Constructor
Priv(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
SparcStaticInst(mnem, _machInst, __opClass)
{
}
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const;
};
// This class is for instructions that explicitly read control
// registers. It provides a special generateDisassembly function.
class RdPriv : public Priv
{
protected:
// Constructor
RdPriv(const char *mnem, ExtMachInst _machInst,
OpClass __opClass, char const * _regName) :
Priv(mnem, _machInst, __opClass), regName(_regName)
{
}
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const;
char const * regName;
};
// This class is for instructions that explicitly write control
// registers. It provides a special generateDisassembly function.
class WrPriv : public Priv
{
protected:
// Constructor
WrPriv(const char *mnem, ExtMachInst _machInst,
OpClass __opClass, char const * _regName) :
Priv(mnem, _machInst, __opClass), regName(_regName)
{
}
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const;
char const * regName;
};
/**
* Base class for privelege mode operations with immediates.
*/
class PrivImm : public Priv
{
protected:
// Constructor
PrivImm(const char *mnem, ExtMachInst _machInst,
OpClass __opClass) :
Priv(mnem, _machInst, __opClass), imm(SIMM13)
{
}
int32_t imm;
};
// This class is for instructions that explicitly write control
// registers. It provides a special generateDisassembly function.
class WrPrivImm : public PrivImm
{
protected:
// Constructor
WrPrivImm(const char *mnem, ExtMachInst _machInst,
OpClass __opClass, char const * _regName) :
PrivImm(mnem, _machInst, __opClass), regName(_regName)
{
}
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const;
char const * regName;
};
}};
output decoder {{
std::string
Priv::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream response;
printMnemonic(response, mnemonic);
return response.str();
}
std::string
RdPriv::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream response;
printMnemonic(response, mnemonic);
ccprintf(response, " %%%s, ", regName);
printDestReg(response, 0);
return response.str();
}
std::string
WrPriv::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream response;
printMnemonic(response, mnemonic);
ccprintf(response, " ");
// If the first reg is %g0, don't print it.
// This improves readability
if (_srcRegIdx[0] != 0) {
printSrcReg(response, 0);
ccprintf(response, ", ");
}
printSrcReg(response, 1);
ccprintf(response, ", %%%s", regName);
return response.str();
}
std::string WrPrivImm::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
std::stringstream response;
printMnemonic(response, mnemonic);
ccprintf(response, " ");
// If the first reg is %g0, don't print it.
// This improves readability
if (_srcRegIdx[0] != 0) {
printSrcReg(response, 0);
ccprintf(response, ", ");
}
ccprintf(response, "0x%x, %%%s", imm, regName);
return response.str();
}
}};
def template ControlRegConstructor {{
inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
: %(base_class)s("%(mnemonic)s", machInst,
%(op_class)s, "%(reg_name)s")
{
%(constructor)s;
}
}};
def template PrivExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
%(op_decl)s;
%(op_rd)s;
// If the processor isn't in privileged mode, fault out right away
if (%(check)s)
return new PrivilegedAction;
if (%(tlCheck)s)
return new IllegalInstruction;
Fault fault = NoFault;
%(code)s;
%(op_wb)s;
return fault;
}
}};
let {{
def doPrivFormat(code, checkCode, name, Name, tlCheck, opt_flags):
(usesImm, code, immCode,
rString, iString) = splitOutImm(code)
#If these are rd, rdpr, rdhpr, wr, wrpr, or wrhpr instructions,
#cut any other info out of the mnemonic. Also pick a different
#base class.
regBase = 'Priv'
regName = ''
for mnem in ["rdhpr", "rdpr", "rd"]:
if name.startswith(mnem):
regName = name[len(mnem):]
name = mnem
regBase = 'RdPriv'
break
for mnem in ["wrhpr", "wrpr", "wr"]:
if name.startswith(mnem):
regName = name[len(mnem):]
name = mnem
regBase = 'WrPriv'
break
iop = InstObjParams(name, Name, regBase,
{"code": code, "check": checkCode,
"tlCheck": tlCheck, "reg_name": regName},
opt_flags)
header_output = BasicDeclare.subst(iop)
if regName == '':
decoder_output = BasicConstructor.subst(iop)
else:
decoder_output = ControlRegConstructor.subst(iop)
exec_output = PrivExecute.subst(iop)
if usesImm:
imm_iop = InstObjParams(name, Name + 'Imm', regBase + 'Imm',
{"code": immCode, "check": checkCode,
"tlCheck": tlCheck, "reg_name": regName},
opt_flags)
header_output += BasicDeclare.subst(imm_iop)
if regName == '':
decoder_output += BasicConstructor.subst(imm_iop)
else:
decoder_output += ControlRegConstructor.subst(imm_iop)
exec_output += PrivExecute.subst(imm_iop)
decode_block = ROrImmDecode.subst(iop)
else:
decode_block = BasicDecode.subst(iop)
return (header_output, decoder_output, exec_output, decode_block)
}};
def format Priv(code, extraCond=true, checkTl=false, *opt_flags) {{
checkCode = "(%s) && !(Pstate.priv || Hpstate.hpriv)" % extraCond
if checkTl != "false":
tlCheck = "Tl == 0"
else:
tlCheck = "false"
(header_output, decoder_output,
exec_output, decode_block) = doPrivFormat(code,
checkCode, name, Name, tlCheck, opt_flags)
}};
def format NoPriv(code, checkTl=false, *opt_flags) {{
#Instructions which use this format don't really check for
#any particular mode, but the disassembly is performed
#using the control registers actual name
checkCode = "false"
if checkTl != "false":
tlCheck = "Tl == 0"
else:
tlCheck = "false"
(header_output, decoder_output,
exec_output, decode_block) = doPrivFormat(code,
checkCode, name, Name, tlCheck, opt_flags)
}};
def format HPriv(code, checkTl=false, *opt_flags) {{
checkCode = "!Hpstate.hpriv"
if checkTl != "false":
tlCheck = "Tl == 0"
else:
tlCheck = "false"
(header_output, decoder_output,
exec_output, decode_block) = doPrivFormat(code,
checkCode, name, Name, tlCheck, opt_flags)
}};

View File

@ -0,0 +1,136 @@
// 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
// Steve Reinhardt
////////////////////////////////////////////////////////////////////
//
// Trap instructions
//
output header {{
/**
* Base class for trap instructions,
* or instructions that always fault.
*/
class Trap : public SparcStaticInst
{
protected:
// Constructor
Trap(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
SparcStaticInst(mnem, _machInst, __opClass), trapNum(SW_TRAP)
{
}
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const;
int trapNum;
};
}};
output decoder {{
std::string
Trap::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream response;
printMnemonic(response, mnemonic);
ccprintf(response, " ");
printReg(response, _srcRegIdx[0]);
ccprintf(response, ", 0x%x", trapNum);
ccprintf(response, ", or ");
printReg(response, _srcRegIdx[1]);
return response.str();
}
}};
def template TrapExecute {{
Fault
%(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
%(op_decl)s;
%(op_rd)s;
%(code)s
return fault;
}
}};
def template FpUnimplExecute {{
Fault
%(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
%(op_decl)s;
%(op_rd)s;
%(code)s
%(op_wb)s;
return fault;
}
}};
def format Trap(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'Trap', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = TrapExecute.subst(iop)
}};
output header {{
class FpUnimpl : public SparcStaticInst
{
protected:
FpUnimpl(const char *mnem,
ExtMachInst _machInst, OpClass __opClass)
: SparcStaticInst(mnem, _machInst, __opClass)
{
}
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
return mnemonic;
}
};
}};
def format FpUnimpl(*flags) {{
fpunimpl_code = '''
Fsr = insertBits(Fsr, 16, 14, 3);
fault = new FpExceptionOther;
'''
iop = InstObjParams(name, Name, 'FpUnimpl', fpunimpl_code, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = FpUnimplExecute.subst(iop)
}};

View File

@ -0,0 +1,143 @@
// -*- 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 SparcStaticInst
{
public:
/// Constructor
FailUnimplemented(const char *_mnemonic, ExtMachInst _machInst)
: SparcStaticInst(_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 SparcStaticInst
{
private:
/// Have we warned on this instruction yet?
mutable bool warned;
public:
/// Constructor
WarnUnimplemented(const char *_mnemonic, ExtMachInst _machInst)
: SparcStaticInst(_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
{
return csprintf("%-10s (unimplemented)", mnemonic);
}
}};
output exec {{
Fault
FailUnimplemented::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
panic("attempt to execute unimplemented instruction '%s' "
"(inst 0x%08x)", mnemonic, machInst);
return NoFault;
}
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)
}};

View File

@ -0,0 +1,75 @@
// 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: Gabe Black
// Steve Reinhardt
////////////////////////////////////////////////////////////////////
//
// Unknown instructions
//
output header {{
/**
* Class for Unknown/Illegal instructions
*/
class Unknown : public SparcStaticInst
{
public:
// Constructor
Unknown(ExtMachInst _machInst) :
SparcStaticInst("unknown", _machInst, No_OpClass)
{
}
%(BasicExecDeclare)s
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const;
};
}};
output decoder {{
std::string Unknown::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
return "Unknown instruction";
}
}};
output exec {{
Fault Unknown::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
return new IllegalInstruction;
}
}};
def format Unknown() {{
decode_block = 'return new Unknown(machInst);\n'
}};

View File

@ -0,0 +1,85 @@
// 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: Ali Saidi
// Gabe Black
// Steve Reinhardt
////////////////////////////////////////////////////////////////////
//
// Output include file directives.
//
output header {{
#include <cstring>
#include <iostream>
#include <sstream>
#include "arch/sparc/faults.hh"
#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/registers.hh"
#include "base/condcodes.hh"
#include "base/misc.hh"
#include "cpu/static_inst.hh"
#include "mem/packet.hh"
#include "mem/request.hh" // some constructors use MemReq flags
}};
output decoder {{
#include <algorithm>
#include "arch/sparc/decoder.hh"
#include "base/loader/symtab.hh"
#include "base/cprintf.hh"
#include "base/fenv.hh"
#include "cpu/thread_context.hh" // for Jump::branchTarget()
#include "mem/packet.hh"
using namespace SparcISA;
}};
output exec {{
#include "base/fenv.hh"
#include <cmath>
#include <limits>
#include "arch/generic/memhelpers.hh"
#include "arch/sparc/asi.hh"
#include "base/bigint.hh"
#include "cpu/base.hh"
#include "cpu/exetrace.hh"
#include "debug/Sparc.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 SparcISA;
using namespace std;
}};

View File

@ -0,0 +1,61 @@
// -*- 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: Gabe Black
////////////////////////////////////////////////////////////////////
//
// SPARC ISA description file.
//
////////////////////////////////////////////////////////////////////
// Include the C++ include directives
##include "includes.isa"
////////////////////////////////////////////////////////////////////
//
// Namespace statement. Everything below this line will be in the
// SparcISAInst namespace.
//
namespace SparcISA;
// Include the bitfield definitions
##include "bitfields.isa"
// Include the operand_types and operand definitions
##include "operands.isa"
// Include the base class for sparc instructions, and some support code
##include "base.isa"
// Include the definitions for the instruction formats
##include "formats/formats.isa"
// Include the decoder definition
##include "decoder.isa"

View File

@ -0,0 +1,201 @@
// 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: Ali Saidi
// Gabe Black
// Steve Reinhardt
def operand_types {{
'sb' : 'int8_t',
'ub' : 'uint8_t',
'shw' : 'int16_t',
'uhw' : 'uint16_t',
'sw' : 'int32_t',
'uw' : 'uint32_t',
'sdw' : 'int64_t',
'udw' : 'uint64_t',
'tudw' : 'Twin64_t',
'tuw' : 'Twin32_t',
'sf' : 'float',
'df' : 'double',
'pstate' : 'PSTATE',
'hpstate' : 'HPSTATE'
}};
output header {{
// A function to "decompress" double and quad floating point
// register numbers stuffed into 5 bit fields. These have their
// MSB put in the LSB position but are otherwise normal.
static inline unsigned int
dfpr(unsigned int regNum)
{
return (regNum & (~1)) | ((regNum & 1) << 5);
}
static inline unsigned int
dfprl(unsigned int regNum)
{
return dfpr(regNum) & (~0x1);
}
static inline unsigned int
dfprh(unsigned int regNum)
{
return dfpr(regNum) | 0x1;
}
}};
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'.
'Rd': ('IntReg', 'udw', 'RD', 'IsInteger', 1),
# The Rd from the previous window
'Rd_prev': ('IntReg', 'udw', 'RD + NumIntArchRegs + NumMicroIntRegs', 'IsInteger', 2),
# The Rd from the next window
'Rd_next': ('IntReg', 'udw', 'RD + 2 * NumIntArchRegs + NumMicroIntRegs', 'IsInteger', 3),
# For microcoded twin load instructions, RdTwin appears in the "code"
# for the instruction is replaced by RdLow or RdHigh by the format
# before it's processed by the iop.
# The low (even) register of a two register pair
'RdLow': ('IntReg', 'udw', 'RD & (~1)', 'IsInteger', 4),
# The high (odd) register of a two register pair
'RdHigh': ('IntReg', 'udw', 'RD | 1', 'IsInteger', 5),
'Rs1': ('IntReg', 'udw', 'RS1', 'IsInteger', 6),
'Rs2': ('IntReg', 'udw', 'RS2', 'IsInteger', 7),
# A microcode register. Right now, this is the only one.
'uReg0': ('IntReg', 'udw', 'NumIntArchRegs', 'IsInteger', 8),
# Because double and quad precision register numbers are decoded
# differently, they get different operands. The single precision versions
# have an s post pended to their name.
'Frds': ('FloatReg', 'sf', 'RD', 'IsFloating', 10),
#'Frd': ('FloatReg', 'df', 'dfpr(RD)', 'IsFloating', 10),
'Frd_low': ('FloatReg', 'uw', 'dfprl(RD)', 'IsFloating', 10),
'Frd_high': ('FloatReg', 'uw', 'dfprh(RD)', 'IsFloating', 10),
# Each Frd_N refers to the Nth double precision register from Frd.
# Note that this adds twice N to the register number.
#'Frd_0': ('FloatReg', 'df', 'dfpr(RD)', 'IsFloating', 10),
'Frd_0_low': ('FloatReg', 'uw', 'dfprl(RD)', 'IsFloating', 10),
'Frd_0_high': ('FloatReg', 'uw', 'dfprh(RD)', 'IsFloating', 10),
#'Frd_1': ('FloatReg', 'df', 'dfpr(RD) + 2', 'IsFloating', 10),
'Frd_1_low': ('FloatReg', 'uw', 'dfprl(RD) + 2', 'IsFloating', 10),
'Frd_1_high': ('FloatReg', 'uw', 'dfprh(RD) + 2', 'IsFloating', 10),
#'Frd_2': ('FloatReg', 'df', 'dfpr(RD) + 4', 'IsFloating', 10),
'Frd_2_low': ('FloatReg', 'uw', 'dfprl(RD) + 4', 'IsFloating', 10),
'Frd_2_high': ('FloatReg', 'uw', 'dfprh(RD) + 4', 'IsFloating', 10),
#'Frd_3': ('FloatReg', 'df', 'dfpr(RD) + 6', 'IsFloating', 10),
'Frd_3_low': ('FloatReg', 'uw', 'dfprl(RD) + 6', 'IsFloating', 10),
'Frd_3_high': ('FloatReg', 'uw', 'dfprh(RD) + 6', 'IsFloating', 10),
#'Frd_4': ('FloatReg', 'df', 'dfpr(RD) + 8', 'IsFloating', 10),
'Frd_4_low': ('FloatReg', 'uw', 'dfprl(RD) + 8', 'IsFloating', 10),
'Frd_4_high': ('FloatReg', 'uw', 'dfprh(RD) + 8', 'IsFloating', 10),
#'Frd_5': ('FloatReg', 'df', 'dfpr(RD) + 10', 'IsFloating', 10),
'Frd_5_low': ('FloatReg', 'uw', 'dfprl(RD) + 10', 'IsFloating', 10),
'Frd_5_high': ('FloatReg', 'uw', 'dfprh(RD) + 10', 'IsFloating', 10),
#'Frd_6': ('FloatReg', 'df', 'dfpr(RD) + 12', 'IsFloating', 10),
'Frd_6_low': ('FloatReg', 'uw', 'dfprl(RD) + 12', 'IsFloating', 10),
'Frd_6_high': ('FloatReg', 'uw', 'dfprh(RD) + 12', 'IsFloating', 10),
#'Frd_7': ('FloatReg', 'df', 'dfpr(RD) + 14', 'IsFloating', 10),
'Frd_7_low': ('FloatReg', 'uw', 'dfprl(RD) + 14', 'IsFloating', 10),
'Frd_7_high': ('FloatReg', 'uw', 'dfprh(RD) + 14', 'IsFloating', 10),
'Frs1s': ('FloatReg', 'sf', 'RS1', 'IsFloating', 11),
#'Frs1': ('FloatReg', 'df', 'dfpr(RS1)', 'IsFloating', 11),
'Frs1_low': ('FloatReg', 'uw', 'dfprl(RS1)', 'IsFloating', 11),
'Frs1_high': ('FloatReg', 'uw', 'dfprh(RS1)', 'IsFloating', 11),
'Frs2s': ('FloatReg', 'sf', 'RS2', 'IsFloating', 12),
#'Frs2': ('FloatReg', 'df', 'dfpr(RS2)', 'IsFloating', 12),
'Frs2_low': ('FloatReg', 'uw', 'dfprl(RS2)', 'IsFloating', 12),
'Frs2_high': ('FloatReg', 'uw', 'dfprh(RS2)', 'IsFloating', 12),
'PC': ('PCState', 'udw', 'pc', (None, None, 'IsControl'), 30),
'NPC': ('PCState', 'udw', 'npc', (None, None, 'IsControl'), 30),
'NNPC': ('PCState', 'udw', 'nnpc', (None, None, 'IsControl'), 30),
# Registers which are used explicitly in instructions
'R0': ('IntReg', 'udw', '0', None, 6),
'R1': ('IntReg', 'udw', '1', None, 7),
'R15': ('IntReg', 'udw', '15', 'IsInteger', 8),
'R16': ('IntReg', 'udw', '16', None, 9),
'O0': ('IntReg', 'udw', '8', 'IsInteger', 10),
'O1': ('IntReg', 'udw', '9', 'IsInteger', 11),
'O2': ('IntReg', 'udw', '10', 'IsInteger', 12),
'O3': ('IntReg', 'udw', '11', 'IsInteger', 13),
'O4': ('IntReg', 'udw', '12', 'IsInteger', 14),
'O5': ('IntReg', 'udw', '13', 'IsInteger', 15),
# Control registers
# 'Y': ('ControlReg', 'udw', 'MISCREG_Y', None, 40),
# 'Ccr': ('ControlReg', 'udw', 'MISCREG_CCR', None, 41),
'Y': ('IntReg', 'udw', 'NumIntArchRegs + 1', None, 40),
'Ccr': ('IntReg', 'udw', 'NumIntArchRegs + 2', None, 41),
'Asi': ('ControlReg', 'udw', 'MISCREG_ASI', None, 42),
'Fprs': ('ControlReg', 'udw', 'MISCREG_FPRS', None, 43),
'Pcr': ('ControlReg', 'udw', 'MISCREG_PCR', None, 44),
'Pic': ('ControlReg', 'udw', 'MISCREG_PIC', None, 45),
# 'Gsr': ('ControlReg', 'udw', 'MISCREG_GSR', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 46),
'Gsr': ('IntReg', 'udw', 'NumIntArchRegs + 8', None, 46),
'Softint': ('ControlReg', 'udw', 'MISCREG_SOFTINT', None, 47),
'SoftintSet': ('ControlReg', 'udw', 'MISCREG_SOFTINT_SET', None, 48),
'SoftintClr': ('ControlReg', 'udw', 'MISCREG_SOFTINT_CLR', None, 49),
'TickCmpr': ('ControlReg', 'udw', 'MISCREG_TICK_CMPR', None, 50),
'Stick': ('ControlReg', 'udw', 'MISCREG_STICK', None, 51),
'StickCmpr': ('ControlReg', 'udw', 'MISCREG_STICK_CMPR', None, 52),
'Tpc': ('ControlReg', 'udw', 'MISCREG_TPC', None, 53),
'Tnpc': ('ControlReg', 'udw', 'MISCREG_TNPC', None, 54),
'Tstate': ('ControlReg', 'udw', 'MISCREG_TSTATE', None, 55),
'Tt': ('ControlReg', 'udw', 'MISCREG_TT', None, 56),
'Tick': ('ControlReg', 'udw', 'MISCREG_TICK', None, 57),
'Tba': ('ControlReg', 'udw', 'MISCREG_TBA', None, 58),
'Pstate': ('ControlReg', 'pstate', 'MISCREG_PSTATE', None, 59),
'Tl': ('ControlReg', 'udw', 'MISCREG_TL', None, 60),
'Pil': ('ControlReg', 'udw', 'MISCREG_PIL', None, 61),
'Cwp': ('ControlReg', 'udw', 'MISCREG_CWP', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 62),
# 'Cansave': ('ControlReg', 'udw', 'MISCREG_CANSAVE', None, 63),
# 'Canrestore': ('ControlReg', 'udw', 'MISCREG_CANRESTORE', None, 64),
# 'Cleanwin': ('ControlReg', 'udw', 'MISCREG_CLEANWIN', None, 65),
# 'Otherwin': ('ControlReg', 'udw', 'MISCREG_OTHERWIN', None, 66),
# 'Wstate': ('ControlReg', 'udw', 'MISCREG_WSTATE', None, 67),
'Cansave': ('IntReg', 'udw', 'NumIntArchRegs + 3', None, 63),
'Canrestore': ('IntReg', 'udw', 'NumIntArchRegs + 4', None, 64),
'Cleanwin': ('IntReg', 'udw', 'NumIntArchRegs + 5', None, 65),
'Otherwin': ('IntReg', 'udw', 'NumIntArchRegs + 6', None, 66),
'Wstate': ('IntReg', 'udw', 'NumIntArchRegs + 7', None, 67),
'Gl': ('ControlReg', 'udw', 'MISCREG_GL', None, 68),
'Hpstate': ('ControlReg', 'hpstate', 'MISCREG_HPSTATE', None, 69),
'Htstate': ('ControlReg', 'udw', 'MISCREG_HTSTATE', None, 70),
'Hintp': ('ControlReg', 'udw', 'MISCREG_HINTP', None, 71),
'Htba': ('ControlReg', 'udw', 'MISCREG_HTBA', None, 72),
'HstickCmpr': ('ControlReg', 'udw', 'MISCREG_HSTICK_CMPR', None, 73),
'Hver': ('ControlReg', 'udw', 'MISCREG_HVER', None, 74),
'StrandStsReg': ('ControlReg', 'udw', 'MISCREG_STRAND_STS_REG', None, 75),
'Fsr': ('ControlReg', 'udw', 'MISCREG_FSR', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 80),
# Mem gets a large number so it's always last
'Mem': ('Mem', 'udw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 100)
}};

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: Gabe Black
* Ali Saidi
*/
#ifndef __ARCH_SPARC_ISA_TRAITS_HH__
#define __ARCH_SPARC_ISA_TRAITS_HH__
#include "arch/sparc/sparc_traits.hh"
#include "arch/sparc/types.hh"
#include "base/types.hh"
#include "cpu/static_inst_fwd.hh"
namespace BigEndianGuest {}
namespace SparcISA
{
const int MachineBytes = 8;
// This makes sure the big endian versions of certain functions are used.
using namespace BigEndianGuest;
// SPARC has a delay slot
#define ISA_HAS_DELAY_SLOT 1
// SPARC NOP (sethi %(hi(0), g0)
const MachInst NoopMachInst = 0x01000000;
// 8K. This value is implmentation specific; and should probably
// be somewhere else.
const int LogVMPageSize = 13;
const int VMPageSize = (1 << LogVMPageSize);
// real address virtual mapping
// sort of like alpha super page, but less frequently used
const Addr SegKPMEnd = ULL(0xfffffffc00000000);
const Addr SegKPMBase = ULL(0xfffffac000000000);
// Why does both the previous set of constants and this one exist?
const int PageShift = 13;
const int PageBytes = 1ULL << PageShift;
const int BranchPredAddrShiftAmt = 2;
StaticInstPtr decodeInst(ExtMachInst);
/////////// TLB Stuff ////////////
const Addr StartVAddrHole = ULL(0x0000800000000000);
const Addr EndVAddrHole = ULL(0xFFFF7FFFFFFFFFFF);
const Addr VAddrAMask = ULL(0xFFFFFFFF);
const Addr PAddrImplMask = ULL(0x000000FFFFFFFFFF);
const Addr BytesInPageMask = ULL(0x1FFF);
enum InterruptTypes
{
IT_TRAP_LEVEL_ZERO,
IT_HINTP,
IT_INT_VEC,
IT_CPU_MONDO,
IT_DEV_MONDO,
IT_RES_ERROR,
IT_SOFT_INT,
NumInterruptTypes
};
// Memory accesses cannot be unaligned
const bool HasUnalignedMemAcc = false;
}
#endif // __ARCH_SPARC_ISA_TRAITS_HH__

View File

@ -0,0 +1,57 @@
/*
* 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
*/
#ifndef __ARCH_SPARC_KERNEL_STATS_HH__
#define __ARCH_SPARC_KERNEL_STATS_HH__
#include <map>
#include <stack>
#include <string>
#include <vector>
#include "kern/kernel_stats.hh"
namespace SparcISA {
namespace Kernel {
enum cpu_mode { hypervisor, kernel, user, idle, cpu_mode_num };
extern const char *modestr[];
class Statistics : public ::Kernel::Statistics
{
public:
Statistics(System *system) : ::Kernel::Statistics(system)
{}
};
} // namespace AlphaISA::Kernel
} // namespace AlphaISA
#endif // __ARCH_SPARC_KERNEL_STATS_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: Gabe Black
*/
#include <fcntl.h>
#include "arch/sparc/linux/linux.hh"
// open(2) flags translation table
OpenFlagTransTable SparcLinux::openFlagTable[] = {
#ifdef _MSC_VER
{ SparcLinux::TGT_O_RDONLY, _O_RDONLY },
{ SparcLinux::TGT_O_WRONLY, _O_WRONLY },
{ SparcLinux::TGT_O_RDWR, _O_RDWR },
{ SparcLinux::TGT_O_APPEND, _O_APPEND },
{ SparcLinux::TGT_O_CREAT, _O_CREAT },
{ SparcLinux::TGT_O_TRUNC, _O_TRUNC },
{ SparcLinux::TGT_O_EXCL, _O_EXCL },
#ifdef _O_NONBLOCK
{ SparcLinux::TGT_O_NONBLOCK, _O_NONBLOCK },
#endif
#ifdef _O_NOCTTY
{ SparcLinux::TGT_O_NOCTTY, _O_NOCTTY },
#endif
#ifdef _O_SYNC
{ SparcLinux::TGT_O_SYNC, _O_SYNC },
#endif
#else /* !_MSC_VER */
{ SparcLinux::TGT_O_RDONLY, O_RDONLY },
{ SparcLinux::TGT_O_WRONLY, O_WRONLY },
{ SparcLinux::TGT_O_RDWR, O_RDWR },
{ SparcLinux::TGT_O_APPEND, O_APPEND },
{ SparcLinux::TGT_O_CREAT, O_CREAT },
{ SparcLinux::TGT_O_TRUNC, O_TRUNC },
{ SparcLinux::TGT_O_EXCL, O_EXCL },
{ SparcLinux::TGT_O_NONBLOCK, O_NONBLOCK },
{ SparcLinux::TGT_O_NOCTTY, O_NOCTTY },
#ifdef O_SYNC
{ SparcLinux::TGT_O_SYNC, O_SYNC },
#endif
#endif /* _MSC_VER */
};
const int SparcLinux::NUM_OPEN_FLAGS =
(sizeof(SparcLinux::openFlagTable)/sizeof(SparcLinux::openFlagTable[0]));

View File

@ -0,0 +1,143 @@
/*
* 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_SPARC_LINUX_LINUX_HH__
#define __ARCH_SPARC_LINUX_LINUX_HH__
#include "kern/linux/linux.hh"
class SparcLinux : public Linux
{
public:
typedef struct {
uint32_t st_dev;
char __pad1[4];
uint64_t st_ino;
uint32_t st_mode;
uint16_t st_nlink;
uint32_t st_uid;
uint32_t st_gid;
uint32_t st_rdev;
char __pad2[4];
int64_t st_size;
int64_t st_atimeX;
int64_t st_mtimeX;
int64_t st_ctimeX;
int64_t st_blksize;
int64_t st_blocks;
uint64_t __unused4[2];
} tgt_stat;
static OpenFlagTransTable openFlagTable[];
static const int TGT_O_RDONLY = 0x00000000; //!< O_RDONLY
static const int TGT_O_WRONLY = 0x00000001; //!< O_WRONLY
static const int TGT_O_RDWR = 0x00000002; //!< O_RDWR
static const int TGT_O_NONBLOCK = 0x00004000; //!< O_NONBLOCK
static const int TGT_O_APPEND = 0x00000008; //!< O_APPEND
static const int TGT_O_CREAT = 0x00000200; //!< O_CREAT
static const int TGT_O_TRUNC = 0x00000400; //!< O_TRUNC
static const int TGT_O_EXCL = 0x00000800; //!< O_EXCL
static const int TGT_O_NOCTTY = 0x00008000; //!< O_NOCTTY
static const int TGT_O_SYNC = 0x00002000; //!< O_SYNC
// static const int TGT_O_DRD = 0x00010000; //!< O_DRD
// static const int TGT_O_DIRECTIO = 0x00020000; //!< O_DIRECTIO
// static const int TGT_O_CACHE = 0x00002000; //!< O_CACHE
// static const int TGT_O_DSYNC = 0x00008000; //!< O_DSYNC
// static const int TGT_O_RSYNC = 0x00040000; //!< O_RSYNC
static const int NUM_OPEN_FLAGS;
static const unsigned TGT_MAP_ANONYMOUS = 0x20;
static const unsigned TGT_MAP_FIXED = 0x10;
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;
};
class Sparc32Linux : public SparcLinux
{
public:
typedef struct {
uint64_t st_dev;
uint64_t st_ino;
uint32_t st_mode;
uint32_t st_nlink;
uint32_t st_uid;
uint32_t st_gid;
uint64_t st_rdev;
uint8_t __pad3[8];
int64_t st_size;
int32_t st_blksize;
uint8_t __pad4[8];
int64_t st_blocks;
uint64_t st_atimeX;
uint64_t st_atime_nsec;
uint64_t st_mtimeX;
uint64_t st_mtime_nsec;
uint64_t st_ctimeX;
uint64_t st_ctime_nsec;
uint32_t __unused4;
uint32_t __unused5;
} tgt_stat64;
typedef struct {
int32_t uptime; /* Seconds since boot */
uint32_t loads[3]; /* 1, 5, and 15 minute load averages */
uint32_t totalram; /* Total usable main memory size */
uint32_t freeram; /* Available memory size */
uint32_t sharedram; /* Amount of shared memory */
uint32_t bufferram; /* Memory used by buffers */
uint32_t totalswap; /* Total swap space size */
uint32_t freeswap; /* swap space still available */
uint16_t procs; /* Number of current processes */
uint32_t totalhigh; /* Total high memory size */
uint32_t freehigh; /* Available high memory size */
uint32_t mem_unit; /* Memory unit size in bytes */
} tgt_sysinfo;
};
#endif

View File

@ -0,0 +1,92 @@
/*
* 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
* Ali Saidi
*/
#include "arch/sparc/linux/process.hh"
#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/registers.hh"
#include "base/trace.hh"
#include "cpu/thread_context.hh"
#include "kern/linux/linux.hh"
#include "sim/process.hh"
#include "sim/syscall_emul.hh"
using namespace std;
using namespace SparcISA;
SyscallDesc*
SparcLinuxProcess::getDesc(int callnum)
{
if (callnum < 0 || callnum >= Num_Syscall_Descs)
return NULL;
return &syscallDescs[callnum];
}
SyscallDesc*
SparcLinuxProcess::getDesc32(int callnum)
{
if (callnum < 0 || callnum >= Num_Syscall32_Descs)
return NULL;
return &syscall32Descs[callnum];
}
Sparc32LinuxProcess::Sparc32LinuxProcess(LiveProcessParams * params,
ObjectFile *objFile)
: Sparc32LiveProcess(params, objFile)
{}
void Sparc32LinuxProcess::handleTrap(int trapNum, ThreadContext *tc)
{
switch (trapNum) {
case 0x10: //Linux 32 bit syscall trap
tc->syscall(tc->readIntReg(1));
break;
default:
SparcLiveProcess::handleTrap(trapNum, tc);
}
}
Sparc64LinuxProcess::Sparc64LinuxProcess(LiveProcessParams * params,
ObjectFile *objFile)
: Sparc64LiveProcess(params, objFile)
{}
void Sparc64LinuxProcess::handleTrap(int trapNum, ThreadContext *tc)
{
switch (trapNum) {
// case 0x10: // Linux 32 bit syscall trap
case 0x6d: // Linux 64 bit syscall trap
tc->syscall(tc->readIntReg(1));
break;
default:
SparcLiveProcess::handleTrap(trapNum, tc);
}
}

View File

@ -0,0 +1,96 @@
/*
* 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 __SPARC_LINUX_PROCESS_HH__
#define __SPARC_LINUX_PROCESS_HH__
#include "arch/sparc/linux/linux.hh"
#include "arch/sparc/process.hh"
#include "sim/process.hh"
namespace SparcISA {
// This contains all of the common elements of a SPARC Linux process which
// are not shared by other operating systems. The rest come from the common
// SPARC process class.
class SparcLinuxProcess
{
public:
/// Array of syscall descriptors, indexed by call number.
static SyscallDesc syscallDescs[];
/// Array of 32 bit compatibility syscall descriptors,
/// indexed by call number.
static SyscallDesc syscall32Descs[];
SyscallDesc* getDesc(int callnum);
SyscallDesc* getDesc32(int callnum);
static const int Num_Syscall_Descs;
static const int Num_Syscall32_Descs;
};
/// A process with emulated SPARC/Linux syscalls.
class Sparc32LinuxProcess : public SparcLinuxProcess, public Sparc32LiveProcess
{
public:
/// Constructor.
Sparc32LinuxProcess(LiveProcessParams * params, ObjectFile *objFile);
SyscallDesc*
getDesc(int callnum)
{
return SparcLinuxProcess::getDesc32(callnum);
}
void handleTrap(int trapNum, ThreadContext *tc);
};
/// A process with emulated 32 bit SPARC/Linux syscalls.
class Sparc64LinuxProcess : public SparcLinuxProcess, public Sparc64LiveProcess
{
public:
/// Constructor.
Sparc64LinuxProcess(LiveProcessParams * params, ObjectFile *objFile);
SyscallDesc*
getDesc(int callnum)
{
return SparcLinuxProcess::getDesc(callnum);
}
void handleTrap(int trapNum, ThreadContext *tc);
};
SyscallReturn getresuidFunc(SyscallDesc *desc, int num,
LiveProcess *p, ThreadContext *tc);
} // namespace SparcISA
#endif // __SPARC_LINUX_PROCESS_HH__

View File

@ -0,0 +1,685 @@
/*
* 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 "arch/sparc/linux/process.hh"
#include "sim/syscall_emul.hh"
class LiveProcess;
class ThreadContext;
namespace SparcISA {
/// 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.12-9-sparc64");
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
strcpy(name->machine, "sparc");
name.copyOut(tc->getMemProxy());
return 0;
}
SyscallReturn
getresuidFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
{
const IntReg id = htog(100);
int index = 0;
Addr ruid = p->getSyscallArg(tc, index);
Addr euid = p->getSyscallArg(tc, index);
Addr suid = p->getSyscallArg(tc, index);
// Handle the EFAULT case
// Set the ruid
if (ruid) {
BufferArg ruidBuff(ruid, sizeof(IntReg));
memcpy(ruidBuff.bufferPtr(), &id, sizeof(IntReg));
ruidBuff.copyOut(tc->getMemProxy());
}
// Set the euid
if (euid) {
BufferArg euidBuff(euid, sizeof(IntReg));
memcpy(euidBuff.bufferPtr(), &id, sizeof(IntReg));
euidBuff.copyOut(tc->getMemProxy());
}
// Set the suid
if (suid) {
BufferArg suidBuff(suid, sizeof(IntReg));
memcpy(suidBuff.bufferPtr(), &id, sizeof(IntReg));
suidBuff.copyOut(tc->getMemProxy());
}
return 0;
}
SyscallDesc SparcLinuxProcess::syscall32Descs[] = {
/* 0 */ SyscallDesc("restart_syscall", unimplementedFunc),
/* 1 */ SyscallDesc("exit", exitFunc), // 32 bit
/* 2 */ SyscallDesc("fork", unimplementedFunc),
/* 3 */ SyscallDesc("read", readFunc),
/* 4 */ SyscallDesc("write", writeFunc),
/* 5 */ SyscallDesc("open", openFunc<Sparc32Linux>), // 32 bit
/* 6 */ SyscallDesc("close", closeFunc),
/* 7 */ SyscallDesc("wait4", unimplementedFunc), // 32 bit
/* 8 */ SyscallDesc("creat", unimplementedFunc), // 32 bit
/* 9 */ SyscallDesc("link", unimplementedFunc),
/* 10 */ SyscallDesc("unlink", unlinkFunc),
/* 11 */ SyscallDesc("execv", unimplementedFunc),
/* 12 */ SyscallDesc("chdir", unimplementedFunc),
/* 13 */ SyscallDesc("chown", chownFunc), // 32 bit
/* 14 */ SyscallDesc("mknod", unimplementedFunc),
/* 15 */ SyscallDesc("chmod", unimplementedFunc),
/* 16 */ SyscallDesc("lchown", unimplementedFunc), // 32 bit
/* 17 */ SyscallDesc("brk", brkFunc),
/* 18 */ SyscallDesc("perfctr", unimplementedFunc), // 32 bit
/* 19 */ SyscallDesc("lseek", lseekFunc), // 32 bit
/* 20 */ SyscallDesc("getpid", getpidFunc),
/* 21 */ SyscallDesc("capget", unimplementedFunc),
/* 22 */ SyscallDesc("capset", unimplementedFunc),
/* 23 */ SyscallDesc("setuid", setuidFunc), // 32 bit
/* 24 */ SyscallDesc("getuid", getuidFunc), // 32 bit
/* 25 */ SyscallDesc("time", unimplementedFunc),
/* 26 */ SyscallDesc("ptrace", unimplementedFunc),
/* 27 */ SyscallDesc("alarm", unimplementedFunc),
/* 28 */ SyscallDesc("sigaltstack", unimplementedFunc), // 32 bit
/* 29 */ SyscallDesc("pause", unimplementedFunc), // 32 bit
/* 30 */ SyscallDesc("utime", unimplementedFunc),
/* 31 */ SyscallDesc("lchown32", unimplementedFunc),
/* 32 */ SyscallDesc("fchown32", unimplementedFunc),
/* 33 */ SyscallDesc("access", unimplementedFunc), // 32 bit
/* 34 */ SyscallDesc("nice", unimplementedFunc), // 32 bit
/* 35 */ SyscallDesc("chown32", unimplementedFunc),
/* 36 */ SyscallDesc("sync", unimplementedFunc),
/* 37 */ SyscallDesc("kill", unimplementedFunc), // 32 bit
/* 38 */ SyscallDesc("stat", unimplementedFunc),
/* 39 */ SyscallDesc("sendfile", unimplementedFunc), // 32 bit
/* 40 */ SyscallDesc("lstat", unimplementedFunc),
/* 41 */ SyscallDesc("dup", unimplementedFunc),
/* 42 */ SyscallDesc("pipe", pipePseudoFunc),
/* 43 */ SyscallDesc("times", ignoreFunc),
/* 44 */ SyscallDesc("getuid32", unimplementedFunc),
/* 45 */ SyscallDesc("umount2", unimplementedFunc), // 32 bit
/* 46 */ SyscallDesc("setgid", unimplementedFunc), // 32 bit
/* 47 */ SyscallDesc("getgid", getgidFunc), // 32 bit
/* 48 */ SyscallDesc("signal", unimplementedFunc), // 32 bit
/* 49 */ SyscallDesc("geteuid", geteuidFunc), // 32 bit
/* 50 */ SyscallDesc("getegid", getegidFunc), // 32 bit
/* 51 */ SyscallDesc("acct", unimplementedFunc),
/* 52 */ SyscallDesc("memory_ordering", unimplementedFunc),
/* 53 */ SyscallDesc("getgid32", unimplementedFunc),
/* 54 */ SyscallDesc("ioctl", unimplementedFunc),
/* 55 */ SyscallDesc("reboot", unimplementedFunc), // 32 bit
/* 56 */ SyscallDesc("mmap2", unimplementedFunc), // 32 bit
/* 57 */ SyscallDesc("symlink", unimplementedFunc),
/* 58 */ SyscallDesc("readlink", readlinkFunc), // 32 bit
/* 59 */ SyscallDesc("execve", unimplementedFunc), // 32 bit
/* 60 */ SyscallDesc("umask", unimplementedFunc), // 32 bit
/* 61 */ SyscallDesc("chroot", unimplementedFunc),
/* 62 */ SyscallDesc("fstat", unimplementedFunc),
/* 63 */ SyscallDesc("fstat64", fstat64Func<Sparc32Linux>),
/* 64 */ SyscallDesc("getpagesize", unimplementedFunc),
/* 65 */ SyscallDesc("msync", unimplementedFunc), // 32 bit
/* 66 */ SyscallDesc("vfork", unimplementedFunc),
/* 67 */ SyscallDesc("pread64", unimplementedFunc), // 32 bit
/* 68 */ SyscallDesc("pwrite64", unimplementedFunc), // 32 bit
/* 69 */ SyscallDesc("geteuid32", unimplementedFunc),
/* 70 */ SyscallDesc("getegid32", unimplementedFunc),
/* 71 */ SyscallDesc("mmap", mmapFunc<Sparc32Linux>),
/* 72 */ SyscallDesc("setreuid32", unimplementedFunc),
/* 73 */ SyscallDesc("munmap", munmapFunc),
/* 74 */ SyscallDesc("mprotect", ignoreFunc),
/* 75 */ SyscallDesc("madvise", unimplementedFunc),
/* 76 */ SyscallDesc("vhangup", unimplementedFunc),
/* 77 */ SyscallDesc("truncate64", unimplementedFunc), // 32 bit
/* 78 */ SyscallDesc("mincore", unimplementedFunc),
/* 79 */ SyscallDesc("getgroups", unimplementedFunc), // 32 bit
/* 80 */ SyscallDesc("setgroups", unimplementedFunc), // 32 bit
/* 81 */ SyscallDesc("getpgrp", unimplementedFunc),
/* 82 */ SyscallDesc("setgroups32", unimplementedFunc), // 32 bit
/* 83 */ SyscallDesc("setitimer", unimplementedFunc), // 32 bit
/* 84 */ SyscallDesc("ftruncate64", unimplementedFunc), // 32 bit
/* 85 */ SyscallDesc("swapon", unimplementedFunc), // 32 bit
/* 86 */ SyscallDesc("getitimer", unimplementedFunc), // 32 bit
/* 87 */ SyscallDesc("setuid32", unimplementedFunc),
/* 88 */ SyscallDesc("sethostname", unimplementedFunc), // 32 bit
/* 89 */ SyscallDesc("setgid32", unimplementedFunc),
/* 90 */ SyscallDesc("dup2", unimplementedFunc),
/* 91 */ SyscallDesc("setfsuid32", unimplementedFunc),
/* 92 */ SyscallDesc("fcntl", unimplementedFunc),
/* 93 */ SyscallDesc("select", unimplementedFunc), // 32 bit
/* 94 */ SyscallDesc("setfsgid32", unimplementedFunc),
/* 95 */ SyscallDesc("fsync", unimplementedFunc),
/* 96 */ SyscallDesc("setpriority", unimplementedFunc), // 32 bit
/* 97 */ SyscallDesc("socket", unimplementedFunc),
/* 98 */ SyscallDesc("connect", unimplementedFunc),
/* 99 */ SyscallDesc("accept", unimplementedFunc),
/* 100 */ SyscallDesc("getpriority", unimplementedFunc), // 32 bit
/* 101 */ SyscallDesc("rt_sigreturn", unimplementedFunc), // 32 bit
/* 102 */ SyscallDesc("rt_sigaction", ignoreFunc), // 32 bit
/* 103 */ SyscallDesc("rt_sigprocmask", ignoreFunc), // 32 bit
/* 104 */ SyscallDesc("rt_sigpending", unimplementedFunc), // 32 bit
/* 105 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc),
/* 106 */ SyscallDesc("rt_sigqueueinfo", unimplementedFunc), // 32 bit
/* 107 */ SyscallDesc("rt_sigsuspend", unimplementedFunc),
/* 108 */ SyscallDesc("setresuid32", unimplementedFunc),
/* 109 */ SyscallDesc("getresuid32", getresuidFunc),
/* 110 */ SyscallDesc("setresgid32", ignoreFunc),
/* 111 */ SyscallDesc("getresgid32", unimplementedFunc),
/* 112 */ SyscallDesc("setregid32", unimplementedFunc),
/* 113 */ SyscallDesc("revcmsg", unimplementedFunc),
/* 114 */ SyscallDesc("sendmsg", unimplementedFunc),
/* 115 */ SyscallDesc("getgroups32", unimplementedFunc), // 32 bit
/* 116 */ SyscallDesc("gettimeofday", gettimeofdayFunc<Sparc32Linux>), // 32 bit
/* 117 */ SyscallDesc("getrusage", unimplementedFunc), // 32 bit
/* 118 */ SyscallDesc("getsockopt", unimplementedFunc),
/* 119 */ SyscallDesc("getcwd", getcwdFunc),
/* 120 */ SyscallDesc("readv", unimplementedFunc),
/* 121 */ SyscallDesc("writev", unimplementedFunc),
/* 122 */ SyscallDesc("settimeofday", unimplementedFunc), // 32 bit
/* 123 */ SyscallDesc("fchown", unimplementedFunc), // 32 bit
/* 124 */ SyscallDesc("fchmod", unimplementedFunc),
/* 125 */ SyscallDesc("recvfrom", unimplementedFunc),
/* 126 */ SyscallDesc("setreuid", unimplementedFunc), // 32 bit
/* 127 */ SyscallDesc("setregid", unimplementedFunc), // 32 bit
/* 128 */ SyscallDesc("rename", renameFunc),
/* 129 */ SyscallDesc("truncate", unimplementedFunc),
/* 130 */ SyscallDesc("ftruncate", unimplementedFunc),
/* 131 */ SyscallDesc("flock", unimplementedFunc),
/* 132 */ SyscallDesc("lstat64", unimplementedFunc),
/* 133 */ SyscallDesc("sendto", unimplementedFunc),
/* 134 */ SyscallDesc("shutdown", unimplementedFunc),
/* 135 */ SyscallDesc("socketpair", unimplementedFunc),
/* 136 */ SyscallDesc("mkdir", mkdirFunc), // 32 bit
/* 137 */ SyscallDesc("rmdir", unimplementedFunc),
/* 138 */ SyscallDesc("utimes", unimplementedFunc), // 32 bit
/* 139 */ SyscallDesc("stat64", unimplementedFunc),
/* 140 */ SyscallDesc("sendfile64", unimplementedFunc), // 32 bit
/* 141 */ SyscallDesc("getpeername", unimplementedFunc),
/* 142 */ SyscallDesc("futex", unimplementedFunc), // 32 bit
/* 143 */ SyscallDesc("gettid", unimplementedFunc),
/* 144 */ SyscallDesc("getrlimit", unimplementedFunc),
/* 145 */ SyscallDesc("setrlimit", unimplementedFunc),
/* 146 */ SyscallDesc("pivot_root", unimplementedFunc),
/* 147 */ SyscallDesc("prctl", unimplementedFunc), // 32 bit
/* 148 */ SyscallDesc("pciconfig_read", unimplementedFunc),
/* 149 */ SyscallDesc("pciconfig_write", unimplementedFunc),
/* 150 */ SyscallDesc("getsockname", unimplementedFunc),
/* 151 */ SyscallDesc("inotify_init", unimplementedFunc),
/* 152 */ SyscallDesc("inotify_add_watch", unimplementedFunc),
/* 153 */ SyscallDesc("poll", unimplementedFunc),
/* 154 */ SyscallDesc("getdents64", unimplementedFunc),
/* 155 */ SyscallDesc("fcntl64", unimplementedFunc),
/* 156 */ SyscallDesc("inotify_rm_watch", unimplementedFunc),
/* 157 */ SyscallDesc("statfs", unimplementedFunc),
/* 158 */ SyscallDesc("fstatfs", unimplementedFunc),
/* 159 */ SyscallDesc("umount", unimplementedFunc),
/* 160 */ SyscallDesc("sched_setaffinity", unimplementedFunc),
/* 161 */ SyscallDesc("sched_getaffinity", unimplementedFunc),
/* 162 */ SyscallDesc("getdomainname", unimplementedFunc), // 32 bit
/* 163 */ SyscallDesc("setdomainname", unimplementedFunc), // 32 bit
/* 164 */ SyscallDesc("ni_syscall", unimplementedFunc),
/* 165 */ SyscallDesc("quotactl", unimplementedFunc),
/* 166 */ SyscallDesc("set_tid_address", unimplementedFunc),
/* 167 */ SyscallDesc("mount", unimplementedFunc),
/* 168 */ SyscallDesc("ustat", unimplementedFunc),
/* 169 */ SyscallDesc("setxattr", unimplementedFunc), // 32 bit
/* 170 */ SyscallDesc("lsetxattr", unimplementedFunc), // 32 bit
/* 171 */ SyscallDesc("fsetxattr", unimplementedFunc), // 32 bit
/* 172 */ SyscallDesc("getxattr", unimplementedFunc),
/* 173 */ SyscallDesc("lgetxattr", unimplementedFunc),
/* 174 */ SyscallDesc("getdents", unimplementedFunc),
/* 175 */ SyscallDesc("setsid", unimplementedFunc),
/* 176 */ SyscallDesc("fchdir", unimplementedFunc),
/* 177 */ SyscallDesc("fgetxattr", unimplementedFunc), // 32 bit
/* 178 */ SyscallDesc("listxattr", unimplementedFunc),
/* 179 */ SyscallDesc("llistxattr", unimplementedFunc),
/* 180 */ SyscallDesc("flistxattr", unimplementedFunc), // 32 bit
/* 181 */ SyscallDesc("removexattr", unimplementedFunc),
/* 182 */ SyscallDesc("lremovexattr", unimplementedFunc),
/* 183 */ SyscallDesc("sigpending", unimplementedFunc),
/* 184 */ SyscallDesc("query_module", unimplementedFunc),
/* 185 */ SyscallDesc("setpgid", unimplementedFunc), // 32 bit
/* 186 */ SyscallDesc("fremovexattr", unimplementedFunc), // 32 bit
/* 187 */ SyscallDesc("tkill", unimplementedFunc), // 32 bit
/* 188 */ SyscallDesc("exit_group", exitGroupFunc), // 32 bit
/* 189 */ SyscallDesc("uname", unameFunc),
/* 190 */ SyscallDesc("init_module", unimplementedFunc), // 32 bit
/* 191 */ SyscallDesc("personality", unimplementedFunc),
/* 192 */ SyscallDesc("remap_file_pages", unimplementedFunc),
/* 193 */ SyscallDesc("epoll_create", unimplementedFunc), // 32 bit
/* 194 */ SyscallDesc("epoll_ctl", unimplementedFunc), // 32 bit
/* 195 */ SyscallDesc("epoll_wait", unimplementedFunc), // 32 bit
/* 196 */ SyscallDesc("ioprio_set", unimplementedFunc), // 32 bit
/* 197 */ SyscallDesc("getppid", getppidFunc),
/* 198 */ SyscallDesc("sigaction", unimplementedFunc), // 32 bit
/* 199 */ SyscallDesc("sgetmask", unimplementedFunc),
/* 200 */ SyscallDesc("ssetmask", unimplementedFunc),
/* 201 */ SyscallDesc("sigsuspend", unimplementedFunc),
/* 202 */ SyscallDesc("oldlstat", unimplementedFunc),
/* 203 */ SyscallDesc("uselib", unimplementedFunc),
/* 204 */ SyscallDesc("readdir", unimplementedFunc),
/* 205 */ SyscallDesc("readahead", unimplementedFunc), // 32 bit
/* 206 */ SyscallDesc("socketcall", unimplementedFunc), // 32 bit
/* 207 */ SyscallDesc("syslog", unimplementedFunc), // 32 bit
/* 208 */ SyscallDesc("lookup_dcookie", unimplementedFunc), // 32 bit
/* 209 */ SyscallDesc("fadvise64", unimplementedFunc), // 32 bit
/* 210 */ SyscallDesc("fadvise64_64", unimplementedFunc), // 32 bit
/* 211 */ SyscallDesc("tgkill", unimplementedFunc), // 32 bit
/* 212 */ SyscallDesc("waitpid", unimplementedFunc), // 32 bit
/* 213 */ SyscallDesc("swapoff", unimplementedFunc),
/* 214 */ SyscallDesc("sysinfo", sysinfoFunc<Sparc32Linux>), // 32 bit
/* 215 */ SyscallDesc("ipc", unimplementedFunc), // 32 bit
/* 216 */ SyscallDesc("sigreturn", unimplementedFunc), // 32 bit
/* 217 */ SyscallDesc("clone", cloneFunc),
/* 218 */ SyscallDesc("ioprio_get", unimplementedFunc), // 32 bit
/* 219 */ SyscallDesc("adjtimex", unimplementedFunc), // 32 bit
/* 220 */ SyscallDesc("sigprocmask", unimplementedFunc), // 32 bit
/* 221 */ SyscallDesc("create_module", unimplementedFunc),
/* 222 */ SyscallDesc("delete_module", unimplementedFunc), // 32 bit
/* 223 */ SyscallDesc("get_kernel_syms", unimplementedFunc),
/* 224 */ SyscallDesc("getpgid", unimplementedFunc), // 32 bit
/* 225 */ SyscallDesc("bdflush", unimplementedFunc), // 32 bit
/* 226 */ SyscallDesc("sysfs", unimplementedFunc), // 32 bit
/* 227 */ SyscallDesc("afs_syscall", unimplementedFunc),
/* 228 */ SyscallDesc("setfsuid", unimplementedFunc), // 32 bit
/* 229 */ SyscallDesc("setfsgid", unimplementedFunc), // 32 bit
/* 230 */ SyscallDesc("_newselect", unimplementedFunc), // 32 bit
/* 231 */ SyscallDesc("time", ignoreFunc),
/* 232 */ SyscallDesc("oldstat", unimplementedFunc),
/* 233 */ SyscallDesc("stime", unimplementedFunc),
/* 234 */ SyscallDesc("statfs64", unimplementedFunc),
/* 235 */ SyscallDesc("fstatfs64", unimplementedFunc),
/* 236 */ SyscallDesc("_llseek", _llseekFunc),
/* 237 */ SyscallDesc("mlock", unimplementedFunc),
/* 238 */ SyscallDesc("munlock", unimplementedFunc),
/* 239 */ SyscallDesc("mlockall", unimplementedFunc), // 32 bit
/* 240 */ SyscallDesc("munlockall", unimplementedFunc),
/* 241 */ SyscallDesc("sched_setparam", unimplementedFunc), // 32 bit
/* 242 */ SyscallDesc("sched_getparam", unimplementedFunc), // 32 bit
/* 243 */ SyscallDesc("sched_setscheduler", unimplementedFunc), // 32 bit
/* 244 */ SyscallDesc("sched_getscheduler", unimplementedFunc), // 32 bit
/* 245 */ SyscallDesc("sched_yield", unimplementedFunc),
/* 246 */ SyscallDesc("sched_get_priority_max", unimplementedFunc), // 32 bit
/* 247 */ SyscallDesc("sched_get_priority_min", unimplementedFunc), // 32 bit
/* 248 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc), // 32 bit
/* 249 */ SyscallDesc("nanosleep", unimplementedFunc),
/* 250 */ SyscallDesc("mremap", mremapFunc<Sparc32Linux>), // 32 bit
/* 251 */ SyscallDesc("_sysctl", unimplementedFunc), // 32 bit
/* 252 */ SyscallDesc("getsid", unimplementedFunc), // 32 bit
/* 253 */ SyscallDesc("fdatasync", unimplementedFunc),
/* 254 */ SyscallDesc("nfsservctl", unimplementedFunc), // 32 bit
/* 255 */ SyscallDesc("aplib", unimplementedFunc),
/* 256 */ SyscallDesc("clock_settime", unimplementedFunc),
/* 257 */ SyscallDesc("clock_gettime", unimplementedFunc),
/* 258 */ SyscallDesc("clock_getres", unimplementedFunc),
/* 259 */ SyscallDesc("clock_nanosleep", unimplementedFunc), // 32 bit
/* 260 */ SyscallDesc("sched_getaffinity", unimplementedFunc),
/* 261 */ SyscallDesc("sched_setaffinity", unimplementedFunc),
/* 262 */ SyscallDesc("timer_settime", unimplementedFunc), // 32 bit
/* 263 */ SyscallDesc("timer_gettime", unimplementedFunc),
/* 264 */ SyscallDesc("timer_getoverrun", unimplementedFunc),
/* 265 */ SyscallDesc("timer_delete", unimplementedFunc),
/* 266 */ SyscallDesc("timer_create", unimplementedFunc),
/* 267 */ SyscallDesc("vserver", unimplementedFunc),
/* 268 */ SyscallDesc("io_setup", unimplementedFunc),
/* 269 */ SyscallDesc("io_destroy", unimplementedFunc),
/* 270 */ SyscallDesc("io_submit", unimplementedFunc), // 32 bit
/* 271 */ SyscallDesc("io_cancel", unimplementedFunc),
/* 272 */ SyscallDesc("io_getevents", unimplementedFunc),
/* 273 */ SyscallDesc("mq_open", unimplementedFunc), // 32 bit
/* 274 */ SyscallDesc("mq_unlink", unimplementedFunc),
/* 275 */ SyscallDesc("mq_timedsend", unimplementedFunc),
/* 276 */ SyscallDesc("mq_timedreceive", unimplementedFunc),
/* 277 */ SyscallDesc("mq_notify", unimplementedFunc),
/* 278 */ SyscallDesc("mq_getsetattr", unimplementedFunc),
/* 279 */ SyscallDesc("waitid", unimplementedFunc),
/* 280 */ SyscallDesc("sys_setaltroot", unimplementedFunc),
/* 281 */ SyscallDesc("add_key", unimplementedFunc),
/* 282 */ SyscallDesc("request_key", unimplementedFunc),
/* 283 */ SyscallDesc("keyctl", unimplementedFunc),
/* 284 */ SyscallDesc("openat", unimplementedFunc),
/* 285 */ SyscallDesc("mkdirat", unimplementedFunc),
/* 286 */ SyscallDesc("mknodat", unimplementedFunc),
/* 287 */ SyscallDesc("fchownat", unimplementedFunc),
/* 288 */ SyscallDesc("futimesat", unimplementedFunc),
/* 289 */ SyscallDesc("fstatat64", unimplementedFunc),
/* 290 */ SyscallDesc("unlinkat", unimplementedFunc),
/* 291 */ SyscallDesc("renameat", unimplementedFunc),
/* 292 */ SyscallDesc("linkat", unimplementedFunc),
/* 293 */ SyscallDesc("symlinkat", unimplementedFunc),
/* 294 */ SyscallDesc("readlinkat", unimplementedFunc),
/* 295 */ SyscallDesc("fchmodat", unimplementedFunc),
/* 296 */ SyscallDesc("faccessat", unimplementedFunc),
/* 297 */ SyscallDesc("pselect6", unimplementedFunc),
/* 298 */ SyscallDesc("ppoll", unimplementedFunc),
/* 299 */ SyscallDesc("unshare", unimplementedFunc)
};
const int SparcLinuxProcess::Num_Syscall32_Descs =
sizeof(SparcLinuxProcess::syscall32Descs) / sizeof(SyscallDesc);
SyscallDesc SparcLinuxProcess::syscallDescs[] = {
/* 0 */ SyscallDesc("restart_syscall", unimplementedFunc),
/* 1 */ SyscallDesc("exit", exitFunc),
/* 2 */ SyscallDesc("fork", unimplementedFunc),
/* 3 */ SyscallDesc("read", readFunc),
/* 4 */ SyscallDesc("write", writeFunc),
/* 5 */ SyscallDesc("open", openFunc<SparcLinux>),
/* 6 */ SyscallDesc("close", closeFunc),
/* 7 */ SyscallDesc("wait4", unimplementedFunc),
/* 8 */ SyscallDesc("creat", unimplementedFunc),
/* 9 */ SyscallDesc("link", unimplementedFunc),
/* 10 */ SyscallDesc("unlink", unlinkFunc),
/* 11 */ SyscallDesc("execv", unimplementedFunc),
/* 12 */ SyscallDesc("chdir", unimplementedFunc),
/* 13 */ SyscallDesc("chown", chownFunc),
/* 14 */ SyscallDesc("mknod", unimplementedFunc),
/* 15 */ SyscallDesc("chmod", chmodFunc<Linux>),
/* 16 */ SyscallDesc("lchown", unimplementedFunc),
/* 17 */ SyscallDesc("brk", brkFunc),
/* 18 */ SyscallDesc("perfctr", unimplementedFunc),
/* 19 */ SyscallDesc("lseek", lseekFunc),
/* 20 */ SyscallDesc("getpid", getpidFunc),
/* 21 */ SyscallDesc("capget", unimplementedFunc),
/* 22 */ SyscallDesc("capset", unimplementedFunc),
/* 23 */ SyscallDesc("setuid", setuidFunc),
/* 24 */ SyscallDesc("getuid", getuidFunc),
/* 25 */ SyscallDesc("time", unimplementedFunc),
/* 26 */ SyscallDesc("ptrace", unimplementedFunc),
/* 27 */ SyscallDesc("alarm", unimplementedFunc),
/* 28 */ SyscallDesc("sigaltstack", unimplementedFunc),
/* 29 */ SyscallDesc("pause", unimplementedFunc),
/* 30 */ SyscallDesc("utime", unimplementedFunc),
/* 31 */ SyscallDesc("lchown32", unimplementedFunc),
/* 32 */ SyscallDesc("fchown32", unimplementedFunc),
/* 33 */ SyscallDesc("access", unimplementedFunc),
/* 34 */ SyscallDesc("nice", unimplementedFunc),
/* 35 */ SyscallDesc("chown32", unimplementedFunc),
/* 36 */ SyscallDesc("sync", unimplementedFunc),
/* 37 */ SyscallDesc("kill", unimplementedFunc),
/* 38 */ SyscallDesc("stat", unimplementedFunc),
/* 39 */ SyscallDesc("sendfile", unimplementedFunc),
/* 40 */ SyscallDesc("lstat", unimplementedFunc),
/* 41 */ SyscallDesc("dup", unimplementedFunc),
/* 42 */ SyscallDesc("pipe", pipePseudoFunc),
/* 43 */ SyscallDesc("times", ignoreFunc),
/* 44 */ SyscallDesc("getuid32", unimplementedFunc),
/* 45 */ SyscallDesc("umount2", unimplementedFunc),
/* 46 */ SyscallDesc("setgid", unimplementedFunc),
/* 47 */ SyscallDesc("getgid", getgidFunc),
/* 48 */ SyscallDesc("signal", unimplementedFunc),
/* 49 */ SyscallDesc("geteuid", geteuidFunc),
/* 50 */ SyscallDesc("getegid", getegidFunc),
/* 51 */ SyscallDesc("acct", unimplementedFunc),
/* 52 */ SyscallDesc("memory_ordering", unimplementedFunc),
/* 53 */ SyscallDesc("getgid32", unimplementedFunc),
/* 54 */ SyscallDesc("ioctl", unimplementedFunc),
/* 55 */ SyscallDesc("reboot", unimplementedFunc),
/* 56 */ SyscallDesc("mmap2", unimplementedFunc),
/* 57 */ SyscallDesc("symlink", unimplementedFunc),
/* 58 */ SyscallDesc("readlink", readlinkFunc),
/* 59 */ SyscallDesc("execve", unimplementedFunc),
/* 60 */ SyscallDesc("umask", unimplementedFunc),
/* 61 */ SyscallDesc("chroot", unimplementedFunc),
/* 62 */ SyscallDesc("fstat", fstatFunc<SparcLinux>),
/* 63 */ SyscallDesc("fstat64", unimplementedFunc),
/* 64 */ SyscallDesc("getpagesize", unimplementedFunc),
/* 65 */ SyscallDesc("msync", unimplementedFunc),
/* 66 */ SyscallDesc("vfork", unimplementedFunc),
/* 67 */ SyscallDesc("pread64", unimplementedFunc),
/* 68 */ SyscallDesc("pwrite64", unimplementedFunc),
/* 69 */ SyscallDesc("geteuid32", unimplementedFunc),
/* 70 */ SyscallDesc("getegid32", unimplementedFunc),
/* 71 */ SyscallDesc("mmap", mmapFunc<SparcLinux>),
/* 72 */ SyscallDesc("setreuid32", unimplementedFunc),
/* 73 */ SyscallDesc("munmap", munmapFunc),
/* 74 */ SyscallDesc("mprotect", ignoreFunc),
/* 75 */ SyscallDesc("madvise", unimplementedFunc),
/* 76 */ SyscallDesc("vhangup", unimplementedFunc),
/* 77 */ SyscallDesc("truncate64", unimplementedFunc),
/* 78 */ SyscallDesc("mincore", unimplementedFunc),
/* 79 */ SyscallDesc("getgroups", unimplementedFunc),
/* 80 */ SyscallDesc("setgroups", unimplementedFunc),
/* 81 */ SyscallDesc("getpgrp", unimplementedFunc),
/* 82 */ SyscallDesc("setgroups32", unimplementedFunc),
/* 83 */ SyscallDesc("setitimer", unimplementedFunc),
/* 84 */ SyscallDesc("ftruncate64", unimplementedFunc),
/* 85 */ SyscallDesc("swapon", unimplementedFunc),
/* 86 */ SyscallDesc("getitimer", unimplementedFunc),
/* 87 */ SyscallDesc("setuid32", unimplementedFunc),
/* 88 */ SyscallDesc("sethostname", unimplementedFunc),
/* 89 */ SyscallDesc("setgid32", unimplementedFunc),
/* 90 */ SyscallDesc("dup2", unimplementedFunc),
/* 91 */ SyscallDesc("setfsuid32", unimplementedFunc),
/* 92 */ SyscallDesc("fcntl", unimplementedFunc),
/* 93 */ SyscallDesc("select", unimplementedFunc),
/* 94 */ SyscallDesc("setfsgid32", 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("rt_sigreturn", unimplementedFunc),
/* 102 */ SyscallDesc("rt_sigaction", ignoreFunc),
/* 103 */ SyscallDesc("rt_sigprocmask", ignoreFunc),
/* 104 */ SyscallDesc("rt_sigpending", unimplementedFunc),
/* 105 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc),
/* 106 */ SyscallDesc("rt_sigqueueinfo", unimplementedFunc),
/* 107 */ SyscallDesc("rt_sigsuspend", unimplementedFunc),
/* 108 */ SyscallDesc("setresuid", unimplementedFunc),
/* 109 */ SyscallDesc("getresuid", getresuidFunc),
/* 110 */ SyscallDesc("setresgid", ignoreFunc),
/* 111 */ SyscallDesc("getresgid", unimplementedFunc),
/* 112 */ SyscallDesc("setregid32", unimplementedFunc),
/* 113 */ SyscallDesc("recvmsg", unimplementedFunc),
/* 114 */ SyscallDesc("sendmsg", unimplementedFunc),
/* 115 */ SyscallDesc("getgroups32", unimplementedFunc),
/* 116 */ SyscallDesc("gettimeofday", gettimeofdayFunc<SparcLinux>),
/* 117 */ SyscallDesc("getrusage", unimplementedFunc),
/* 118 */ SyscallDesc("getsockopt", unimplementedFunc),
/* 119 */ SyscallDesc("getcwd", unimplementedFunc),
/* 120 */ SyscallDesc("readv", unimplementedFunc),
/* 121 */ SyscallDesc("writev", unimplementedFunc),
/* 122 */ SyscallDesc("settimeofday", unimplementedFunc),
/* 123 */ SyscallDesc("fchown", unimplementedFunc),
/* 124 */ SyscallDesc("fchmod", unimplementedFunc),
/* 125 */ SyscallDesc("recvfrom", unimplementedFunc),
/* 126 */ SyscallDesc("setreuid", unimplementedFunc),
/* 127 */ SyscallDesc("setregid", unimplementedFunc),
/* 128 */ SyscallDesc("rename", renameFunc),
/* 129 */ SyscallDesc("truncate", unimplementedFunc),
/* 130 */ SyscallDesc("ftruncate", unimplementedFunc),
/* 131 */ SyscallDesc("flock", unimplementedFunc),
/* 132 */ SyscallDesc("lstat64", 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("stat64", unimplementedFunc),
/* 140 */ SyscallDesc("sendfile64", unimplementedFunc),
/* 141 */ SyscallDesc("getpeername", unimplementedFunc),
/* 142 */ SyscallDesc("futex", unimplementedFunc),
/* 143 */ SyscallDesc("gettid", unimplementedFunc),
/* 144 */ SyscallDesc("getrlimit", unimplementedFunc),
/* 145 */ SyscallDesc("setrlimit", unimplementedFunc),
/* 146 */ SyscallDesc("pivot_root", unimplementedFunc),
/* 147 */ SyscallDesc("prctl", unimplementedFunc),
/* 148 */ SyscallDesc("pciconfig_read", unimplementedFunc),
/* 149 */ SyscallDesc("pciconfig_write", unimplementedFunc),
/* 150 */ SyscallDesc("getsockname", unimplementedFunc),
/* 151 */ SyscallDesc("inotify_init", unimplementedFunc),
/* 152 */ SyscallDesc("inotify_add_watch", unimplementedFunc),
/* 153 */ SyscallDesc("poll", unimplementedFunc),
/* 154 */ SyscallDesc("getdents64", unimplementedFunc),
/* 155 */ SyscallDesc("fcntl64", unimplementedFunc),
/* 156 */ SyscallDesc("inotify_rm_watch", unimplementedFunc),
/* 157 */ SyscallDesc("statfs", unimplementedFunc),
/* 158 */ SyscallDesc("fstatfs", unimplementedFunc),
/* 159 */ SyscallDesc("umount", unimplementedFunc),
/* 160 */ SyscallDesc("sched_set_affinity", unimplementedFunc),
/* 161 */ SyscallDesc("sched_get_affinity", unimplementedFunc),
/* 162 */ SyscallDesc("getdomainname", unimplementedFunc),
/* 163 */ SyscallDesc("setdomainname", unimplementedFunc),
/* 164 */ SyscallDesc("utrap_install", unimplementedFunc),
/* 165 */ SyscallDesc("quotactl", unimplementedFunc),
/* 166 */ SyscallDesc("set_tid_address", unimplementedFunc),
/* 167 */ SyscallDesc("mount", unimplementedFunc),
/* 168 */ SyscallDesc("ustat", unimplementedFunc),
/* 169 */ SyscallDesc("setxattr", unimplementedFunc),
/* 170 */ SyscallDesc("lsetxattr", unimplementedFunc),
/* 171 */ SyscallDesc("fsetxattr", unimplementedFunc),
/* 172 */ SyscallDesc("getxattr", unimplementedFunc),
/* 173 */ SyscallDesc("lgetxattr", unimplementedFunc),
/* 174 */ SyscallDesc("getdents", unimplementedFunc),
/* 175 */ SyscallDesc("setsid", unimplementedFunc),
/* 176 */ SyscallDesc("fchdir", unimplementedFunc),
/* 177 */ SyscallDesc("fgetxattr", unimplementedFunc),
/* 178 */ SyscallDesc("listxattr", unimplementedFunc),
/* 179 */ SyscallDesc("llistxattr", unimplementedFunc),
/* 180 */ SyscallDesc("flistxattr", unimplementedFunc),
/* 181 */ SyscallDesc("removexattr", unimplementedFunc),
/* 182 */ SyscallDesc("lremovexattr", unimplementedFunc),
/* 183 */ SyscallDesc("sigpending", unimplementedFunc),
/* 184 */ SyscallDesc("query_module", unimplementedFunc),
/* 185 */ SyscallDesc("setpgid", unimplementedFunc),
/* 186 */ SyscallDesc("fremovexattr", unimplementedFunc),
/* 187 */ SyscallDesc("tkill", unimplementedFunc),
/* 188 */ SyscallDesc("exit_group", exitGroupFunc),
/* 189 */ SyscallDesc("uname", unameFunc),
/* 190 */ SyscallDesc("init_module", unimplementedFunc),
/* 191 */ SyscallDesc("personality", unimplementedFunc),
/* 192 */ SyscallDesc("remap_file_pages", unimplementedFunc),
/* 193 */ SyscallDesc("epoll_create", unimplementedFunc),
/* 194 */ SyscallDesc("epoll_ctl", unimplementedFunc),
/* 195 */ SyscallDesc("epoll_wait", unimplementedFunc),
/* 196 */ SyscallDesc("ioprio_set", unimplementedFunc),
/* 197 */ SyscallDesc("getppid", getppidFunc),
/* 198 */ SyscallDesc("sigaction", ignoreFunc),
/* 199 */ SyscallDesc("sgetmask", unimplementedFunc),
/* 200 */ SyscallDesc("ssetmask", unimplementedFunc),
/* 201 */ SyscallDesc("sigsuspend", unimplementedFunc),
/* 202 */ SyscallDesc("oldlstat", unimplementedFunc),
/* 203 */ SyscallDesc("uselib", unimplementedFunc),
/* 204 */ SyscallDesc("readdir", unimplementedFunc),
/* 205 */ SyscallDesc("readahead", unimplementedFunc),
/* 206 */ SyscallDesc("socketcall", unimplementedFunc),
/* 207 */ SyscallDesc("syslog", unimplementedFunc),
/* 208 */ SyscallDesc("lookup_dcookie", unimplementedFunc),
/* 209 */ SyscallDesc("fadvise64", unimplementedFunc),
/* 210 */ SyscallDesc("fadvise64_64", unimplementedFunc),
/* 211 */ SyscallDesc("tgkill", unimplementedFunc),
/* 212 */ SyscallDesc("waitpid", unimplementedFunc),
/* 213 */ SyscallDesc("swapoff", unimplementedFunc),
/* 214 */ SyscallDesc("sysinfo", sysinfoFunc<SparcLinux>),
/* 215 */ SyscallDesc("ipc", unimplementedFunc),
/* 216 */ SyscallDesc("sigreturn", unimplementedFunc),
/* 217 */ SyscallDesc("clone", cloneFunc),
/* 218 */ SyscallDesc("ioprio_get", unimplementedFunc),
/* 219 */ SyscallDesc("adjtimex", unimplementedFunc),
/* 220 */ SyscallDesc("sigprocmask", unimplementedFunc),
/* 221 */ SyscallDesc("create_module", unimplementedFunc),
/* 222 */ SyscallDesc("delete_module", unimplementedFunc),
/* 223 */ SyscallDesc("get_kernel_syms", unimplementedFunc),
/* 224 */ SyscallDesc("getpgid", unimplementedFunc),
/* 225 */ SyscallDesc("bdflush", unimplementedFunc),
/* 226 */ SyscallDesc("sysfs", unimplementedFunc),
/* 227 */ SyscallDesc("afs_syscall", unimplementedFunc),
/* 228 */ SyscallDesc("setfsuid", unimplementedFunc),
/* 229 */ SyscallDesc("setfsgid", unimplementedFunc),
/* 230 */ SyscallDesc("_newselect", unimplementedFunc),
/* 231 */ SyscallDesc("time", ignoreFunc),
/* 232 */ SyscallDesc("oldstat", unimplementedFunc),
/* 233 */ SyscallDesc("stime", unimplementedFunc),
/* 234 */ SyscallDesc("statfs64", unimplementedFunc),
/* 235 */ SyscallDesc("fstatfs64", unimplementedFunc),
/* 236 */ SyscallDesc("_llseek", _llseekFunc),
/* 237 */ SyscallDesc("mlock", unimplementedFunc),
/* 238 */ SyscallDesc("munlock", unimplementedFunc),
/* 239 */ SyscallDesc("mlockall", unimplementedFunc),
/* 240 */ SyscallDesc("munlockall", unimplementedFunc),
/* 241 */ SyscallDesc("sched_setparam", unimplementedFunc),
/* 242 */ SyscallDesc("sched_getparam", unimplementedFunc),
/* 243 */ SyscallDesc("sched_setscheduler", unimplementedFunc),
/* 244 */ SyscallDesc("sched_getscheduler", unimplementedFunc),
/* 245 */ SyscallDesc("sched_yield", unimplementedFunc),
/* 246 */ SyscallDesc("sched_get_priority_max", unimplementedFunc),
/* 247 */ SyscallDesc("sched_get_priority_min", unimplementedFunc),
/* 248 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc),
/* 249 */ SyscallDesc("nanosleep", unimplementedFunc),
/* 250 */ SyscallDesc("mremap", mremapFunc<SparcLinux>),
/* 251 */ SyscallDesc("_sysctl", unimplementedFunc),
/* 252 */ SyscallDesc("getsid", unimplementedFunc),
/* 253 */ SyscallDesc("fdatasync", unimplementedFunc),
/* 254 */ SyscallDesc("nfsservctl", unimplementedFunc),
/* 255 */ SyscallDesc("aplib", unimplementedFunc),
/* 256 */ SyscallDesc("clock_settime", unimplementedFunc),
/* 257 */ SyscallDesc("clock_gettime", unimplementedFunc),
/* 258 */ SyscallDesc("clock_getres", unimplementedFunc),
/* 259 */ SyscallDesc("clock_nanosleep", unimplementedFunc),
/* 260 */ SyscallDesc("sched_getaffinity", unimplementedFunc),
/* 261 */ SyscallDesc("sched_setaffinity", unimplementedFunc),
/* 262 */ SyscallDesc("timer_settime", unimplementedFunc),
/* 263 */ SyscallDesc("timer_gettime", unimplementedFunc),
/* 264 */ SyscallDesc("timer_getoverrun", unimplementedFunc),
/* 265 */ SyscallDesc("timer_delete", unimplementedFunc),
/* 266 */ SyscallDesc("timer_create", unimplementedFunc),
/* 267 */ SyscallDesc("vserver", unimplementedFunc),
/* 268 */ SyscallDesc("io_setup", unimplementedFunc),
/* 269 */ SyscallDesc("io_destroy", unimplementedFunc),
/* 270 */ SyscallDesc("io_submit", unimplementedFunc),
/* 271 */ SyscallDesc("io_cancel", unimplementedFunc),
/* 272 */ SyscallDesc("io_getevents", unimplementedFunc),
/* 273 */ SyscallDesc("mq_open", unimplementedFunc),
/* 274 */ SyscallDesc("mq_unlink", unimplementedFunc),
/* 275 */ SyscallDesc("mq_timedsend", unimplementedFunc),
/* 276 */ SyscallDesc("mq_timedreceive", unimplementedFunc),
/* 277 */ SyscallDesc("mq_notify", unimplementedFunc),
/* 278 */ SyscallDesc("mq_getsetattr", unimplementedFunc),
/* 279 */ SyscallDesc("waitid", unimplementedFunc),
/* 280 */ SyscallDesc("sys_setaltroot", unimplementedFunc),
/* 281 */ SyscallDesc("add_key", unimplementedFunc),
/* 282 */ SyscallDesc("request_key", unimplementedFunc),
/* 283 */ SyscallDesc("keyctl", unimplementedFunc)
};
const int SparcLinuxProcess::Num_Syscall_Descs =
sizeof(SparcLinuxProcess::syscallDescs) / sizeof(SyscallDesc);
} // namespace SparcISA

View File

@ -0,0 +1,61 @@
/*
* 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_SPARC_LOCKED_MEM_HH__
#define __ARCH_SPARC_LOCKED_MEM_HH__
/**
* @file
*
* ISA-specific helper functions for locked memory accesses.
*/
#include "mem/request.hh"
namespace SparcISA
{
template <class XC>
inline void
handleLockedRead(XC *xc, Request *req)
{
}
template <class XC>
inline bool
handleLockedWrite(XC *xc, Request *req)
{
return true;
}
} // namespace SparcISA
#endif

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_SPARC_MICROCODE_ROM_HH__
#define __ARCH_SPARC_MICROCODE_ROM_HH__
#include "sim/microcode_rom.hh"
namespace SparcISA
{
using ::MicrocodeRom;
}
#endif // __ARCH_SPARC_MICROCODE_ROM_HH__

View File

@ -0,0 +1,163 @@
/*
* 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
* Ali Saidi
*/
#ifndef __ARCH_SPARC_MISCREGS_HH__
#define __ARCH_SPARC_MISCREGS_HH__
#include "base/bitunion.hh"
#include "base/types.hh"
namespace SparcISA
{
enum MiscRegIndex
{
/** Ancillary State Registers */
// MISCREG_Y,
// MISCREG_CCR,
MISCREG_ASI,
MISCREG_TICK,
MISCREG_FPRS,
MISCREG_PCR,
MISCREG_PIC,
MISCREG_GSR,
MISCREG_SOFTINT_SET,
MISCREG_SOFTINT_CLR,
MISCREG_SOFTINT, /* 10 */
MISCREG_TICK_CMPR,
MISCREG_STICK,
MISCREG_STICK_CMPR,
/** Privilged Registers */
MISCREG_TPC,
MISCREG_TNPC,
MISCREG_TSTATE,
MISCREG_TT,
MISCREG_PRIVTICK,
MISCREG_TBA,
MISCREG_PSTATE, /* 20 */
MISCREG_TL,
MISCREG_PIL,
MISCREG_CWP,
// MISCREG_CANSAVE,
// MISCREG_CANRESTORE,
// MISCREG_CLEANWIN,
// MISCREG_OTHERWIN,
// MISCREG_WSTATE,
MISCREG_GL,
/** Hyper privileged registers */
MISCREG_HPSTATE, /* 30 */
MISCREG_HTSTATE,
MISCREG_HINTP,
MISCREG_HTBA,
MISCREG_HVER,
MISCREG_STRAND_STS_REG,
MISCREG_HSTICK_CMPR,
/** Floating Point Status Register */
MISCREG_FSR,
/** MMU Internal Registers */
MISCREG_MMU_P_CONTEXT,
MISCREG_MMU_S_CONTEXT, /* 40 */
MISCREG_MMU_PART_ID,
MISCREG_MMU_LSU_CTRL,
/** Scratchpad regiscers **/
MISCREG_SCRATCHPAD_R0, /* 60 */
MISCREG_SCRATCHPAD_R1,
MISCREG_SCRATCHPAD_R2,
MISCREG_SCRATCHPAD_R3,
MISCREG_SCRATCHPAD_R4,
MISCREG_SCRATCHPAD_R5,
MISCREG_SCRATCHPAD_R6,
MISCREG_SCRATCHPAD_R7,
/* CPU Queue Registers */
MISCREG_QUEUE_CPU_MONDO_HEAD,
MISCREG_QUEUE_CPU_MONDO_TAIL,
MISCREG_QUEUE_DEV_MONDO_HEAD, /* 70 */
MISCREG_QUEUE_DEV_MONDO_TAIL,
MISCREG_QUEUE_RES_ERROR_HEAD,
MISCREG_QUEUE_RES_ERROR_TAIL,
MISCREG_QUEUE_NRES_ERROR_HEAD,
MISCREG_QUEUE_NRES_ERROR_TAIL,
/* All the data for the TLB packed up in one register. */
MISCREG_TLB_DATA,
MISCREG_NUMMISCREGS
};
BitUnion64(HPSTATE)
Bitfield<0> tlz;
Bitfield<2> hpriv;
Bitfield<5> red;
Bitfield<10> ibe;
Bitfield<11> id; // this impl. dependent (id) field m
EndBitUnion(HPSTATE)
BitUnion16(PSTATE)
Bitfield<1> ie;
Bitfield<2> priv;
Bitfield<3> am;
Bitfield<4> pef;
Bitfield<6, 7> mm;
Bitfield<8> tle;
Bitfield<9> cle;
Bitfield<10> pid0;
Bitfield<11> pid1;
EndBitUnion(PSTATE)
struct STS
{
const static int st_idle = 0x00;
const static int st_wait = 0x01;
const static int st_halt = 0x02;
const static int st_run = 0x05;
const static int st_spec_run = 0x07;
const static int st_spec_rdy = 0x13;
const static int st_ready = 0x19;
const static int active = 0x01;
const static int speculative = 0x04;
const static int shft_id = 8;
const static int shft_fsm0 = 31;
const static int shft_fsm1 = 26;
const static int shft_fsm2 = 21;
const static int shft_fsm3 = 16;
};
const int NumMiscArchRegs = MISCREG_NUMMISCREGS;
const int NumMiscRegs = MISCREG_NUMMISCREGS;
}
#endif

View File

@ -0,0 +1,62 @@
/*
* 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_SPARC_MMAPPED_IPR_HH__
#define __ARCH_SPARC_MMAPPED_IPR_HH__
/**
* @file
*
* ISA-specific helper functions for memory mapped IPR accesses.
*/
#include "arch/sparc/tlb.hh"
#include "cpu/thread_context.hh"
#include "mem/packet.hh"
namespace SparcISA
{
inline Tick
handleIprRead(ThreadContext *xc, Packet *pkt)
{
return xc->getDTBPtr()->doMmuRegRead(xc, pkt);
}
inline Tick
handleIprWrite(ThreadContext *xc, Packet *pkt)
{
return xc->getDTBPtr()->doMmuRegWrite(xc, pkt);
}
} // namespace SparcISA
#endif

View File

@ -0,0 +1,70 @@
/*
* Copyright (c) 2011 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_SPARC_MT_HH__
#define __ARCH_SPARC_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 SparcISA
{
template <class TC>
inline unsigned
getVirtProcNum(TC *tc)
{
fatal("Sparc is not setup for multithreaded ISA extensions");
return 0;
}
template <class TC>
inline unsigned
getTargetThread(TC *tc)
{
fatal("Sparc is not setup for multithreaded ISA extensions");
return 0;
}
} // namespace SparcISA
#endif

View File

@ -0,0 +1,100 @@
/*
* 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: Gabe Black
*/
#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/nativetrace.hh"
#include "arch/sparc/registers.hh"
#include "cpu/thread_context.hh"
#include "params/SparcNativeTrace.hh"
#include "sim/byteswap.hh"
namespace Trace {
static const char *intRegNames[SparcISA::NumIntArchRegs] = {
// Global registers
"g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
// Output registers
"o0", "o1", "o2", "o3", "o4", "o5", "o6", "o7",
// Local registers
"l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
// Input registers
"i0", "i1", "i2", "i3", "i4", "i5", "i6", "i7",
};
void
Trace::SparcNativeTrace::check(NativeTraceRecord *record)
{
ThreadContext *tc = record->getThread();
uint64_t regVal, realRegVal;
// Integer registers
// I doubt a real SPARC will describe more integer registers than this.
assert(SparcISA::NumIntArchRegs == 32);
const char **regName = intRegNames;
for (int i = 0; i < SparcISA::NumIntArchRegs; i++) {
regVal = tc->readIntReg(i);
read(&realRegVal, sizeof(realRegVal));
realRegVal = SparcISA::gtoh(realRegVal);
checkReg(*(regName++), regVal, realRegVal);
}
SparcISA::PCState pc = tc->pcState();
// PC
read(&realRegVal, sizeof(realRegVal));
realRegVal = SparcISA::gtoh(realRegVal);
regVal = pc.npc();
checkReg("pc", regVal, realRegVal);
// NPC
read(&realRegVal, sizeof(realRegVal));
realRegVal = SparcISA::gtoh(realRegVal);
pc.nnpc();
checkReg("npc", regVal, realRegVal);
// CCR
read(&realRegVal, sizeof(realRegVal));
realRegVal = SparcISA::gtoh(realRegVal);
regVal = tc->readIntReg(SparcISA::NumIntArchRegs + 2);
checkReg("ccr", regVal, realRegVal);
}
} // namespace Trace
////////////////////////////////////////////////////////////////////////
//
// ExeTracer Simulation Object
//
Trace::SparcNativeTrace *
SparcNativeTraceParams::create()
{
return new Trace::SparcNativeTrace(this);
};

View File

@ -0,0 +1,52 @@
/*
* 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: Gabe Black
*/
#ifndef __ARCH_SPARC_NATIVETRACE_HH__
#define __ARCH_SPARC_NATIVETRACE_HH__
#include "base/types.hh"
#include "cpu/nativetrace.hh"
class ThreadContext;
namespace Trace {
class SparcNativeTrace : public NativeTrace
{
public:
SparcNativeTrace(const Params *p) : NativeTrace(p)
{}
void check(NativeTraceRecord *record);
};
} // namespace Trace
#endif // __CPU_NATIVETRACE_HH__

View File

@ -0,0 +1,75 @@
/*
* 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
*/
#include "arch/sparc/pagetable.hh"
#include "sim/serialize.hh"
namespace SparcISA
{
void
TlbEntry::serialize(std::ostream &os)
{
SERIALIZE_SCALAR(range.va);
SERIALIZE_SCALAR(range.size);
SERIALIZE_SCALAR(range.contextId);
SERIALIZE_SCALAR(range.partitionId);
SERIALIZE_SCALAR(range.real);
uint64_t entry4u = 0;
if (valid)
entry4u = pte();
SERIALIZE_SCALAR(entry4u);
SERIALIZE_SCALAR(used);
SERIALIZE_SCALAR(valid);
}
void
TlbEntry::unserialize(Checkpoint *cp, const std::string &section)
{
UNSERIALIZE_SCALAR(range.va);
UNSERIALIZE_SCALAR(range.size);
UNSERIALIZE_SCALAR(range.contextId);
UNSERIALIZE_SCALAR(range.partitionId);
UNSERIALIZE_SCALAR(range.real);
uint64_t entry4u;
UNSERIALIZE_SCALAR(entry4u);
if (entry4u)
pte.populate(entry4u);
UNSERIALIZE_SCALAR(used);
UNSERIALIZE_SCALAR(valid);
}
int PageTableEntry::pageSizes[] =
{ 8 * 1024, 64 * 1024, 0, 4 * 1024 * 1024, 0, 256 * 1024 * 1024L} ;
}

View File

@ -0,0 +1,283 @@
/*
* 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_SPARC_PAGETABLE_HH__
#define __ARCH_SPARC_PAGETABLE_HH__
#include <cassert>
#include "arch/sparc/isa_traits.hh"
#include "base/bitfield.hh"
#include "base/misc.hh"
class Checkpoint;
namespace SparcISA {
struct VAddr
{
VAddr(Addr a) { panic("not implemented yet."); }
};
class TteTag
{
private:
uint64_t entry;
bool populated;
public:
TteTag() : entry(0), populated(false) {}
TteTag(uint64_t e) : entry(e), populated(true) {}
const TteTag &
operator=(uint64_t e)
{
populated = true;
entry = e;
return *this;
}
bool valid() const { assert(populated); return !bits(entry,62,62); }
Addr va() const { assert(populated); return bits(entry,41,0); }
};
class PageTableEntry
{
public:
enum EntryType {
sun4v,
sun4u,
invalid
};
private:
uint64_t entry;
EntryType type;
uint64_t entry4u;
bool populated;
public:
PageTableEntry() : entry(0), type(invalid), populated(false)
{}
PageTableEntry(uint64_t e, EntryType t = sun4u)
: entry(e), type(t), populated(true)
{
populate(entry, type);
}
void
populate(uint64_t e, EntryType t = sun4u)
{
entry = e;
type = t;
populated = true;
// If we get a sun4v format TTE, turn it into a sun4u
if (type == sun4u)
entry4u = entry;
else {
entry4u = 0;
entry4u |= mbits(entry,63,63); // valid
entry4u |= bits(entry,1,0) << 61; // size[1:0]
entry4u |= bits(entry,62,62) << 60; // nfo
entry4u |= bits(entry,12,12) << 59; // ie
entry4u |= bits(entry,2,2) << 48; // size[2]
entry4u |= mbits(entry,39,13); // paddr
entry4u |= bits(entry,61,61) << 6;; // locked
entry4u |= bits(entry,10,10) << 5; // cp
entry4u |= bits(entry,9,9) << 4; // cv
entry4u |= bits(entry,11,11) << 3; // e
entry4u |= bits(entry,8,8) << 2; // p
entry4u |= bits(entry,6,6) << 1; // w
}
}
void
clear()
{
populated = false;
}
static int pageSizes[6];
uint64_t operator()() const { assert(populated); return entry4u; }
const PageTableEntry &
operator=(uint64_t e)
{
populated = true;
entry4u = e;
return *this;
}
const PageTableEntry &
operator=(const PageTableEntry &e)
{
populated = true;
entry4u = e.entry4u;
type = e.type;
return *this;
}
bool valid() const { return bits(entry4u,63,63) && populated; }
uint8_t
_size() const
{
assert(populated);
return bits(entry4u, 62,61) | bits(entry4u, 48,48) << 2;
}
Addr size() const { assert(_size() < 6); return pageSizes[_size()]; }
Addr sizeMask() const { return size() - 1; }
bool ie() const { return bits(entry4u, 59,59); }
Addr pfn() const { assert(populated); return bits(entry4u,39,13); }
Addr paddr() const { assert(populated); return mbits(entry4u, 39,13);}
bool locked() const { assert(populated); return bits(entry4u,6,6); }
bool cv() const { assert(populated); return bits(entry4u,4,4); }
bool cp() const { assert(populated); return bits(entry4u,5,5); }
bool priv() const { assert(populated); return bits(entry4u,2,2); }
bool writable() const { assert(populated); return bits(entry4u,1,1); }
bool nofault() const { assert(populated); return bits(entry4u,60,60); }
bool sideffect() const { assert(populated); return bits(entry4u,3,3); }
Addr paddrMask() const { assert(populated); return paddr() & ~sizeMask(); }
Addr
translate(Addr vaddr) const
{
assert(populated);
Addr mask = sizeMask();
return (paddr() & ~mask) | (vaddr & mask);
}
};
struct TlbRange
{
Addr va;
Addr size;
int contextId;
int partitionId;
bool real;
inline bool
operator<(const TlbRange &r2) const
{
if (real && !r2.real)
return true;
if (!real && r2.real)
return false;
if (!real && !r2.real) {
if (contextId < r2.contextId)
return true;
else if (contextId > r2.contextId)
return false;
}
if (partitionId < r2.partitionId)
return true;
else if (partitionId > r2.partitionId)
return false;
if (va < r2.va)
return true;
return false;
}
inline bool
operator==(const TlbRange &r2) const
{
return va == r2.va &&
size == r2.size &&
contextId == r2.contextId &&
partitionId == r2.partitionId &&
real == r2.real;
}
};
struct TlbEntry
{
TlbEntry()
{}
TlbEntry(Addr asn, Addr vaddr, Addr paddr)
{
uint64_t entry = 0;
entry |= 1ULL << 1; // Writable
entry |= 0ULL << 2; // Available in nonpriveleged mode
entry |= 0ULL << 3; // No side effects
entry |= 1ULL << 4; // Virtually cachable
entry |= 1ULL << 5; // Physically cachable
entry |= 0ULL << 6; // Not locked
entry |= mbits(paddr, 39, 13); // Physical address
entry |= 0ULL << 48; // size = 8k
entry |= 0uLL << 59; // Endianness not inverted
entry |= 0ULL << 60; // Not no fault only
entry |= 0ULL << 61; // size = 8k
entry |= 1ULL << 63; // valid
pte = PageTableEntry(entry);
range.va = vaddr;
range.size = 8*(1<<10);
range.contextId = asn;
range.partitionId = 0;
range.real = false;
valid = true;
}
TlbRange range;
PageTableEntry pte;
bool used;
bool valid;
Addr
pageStart()
{
return pte.paddr();
}
void
updateVaddr(Addr new_vaddr)
{
range.va = new_vaddr;
}
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
};
} // namespace SparcISA
#endif // __ARCH_SPARC_PAGE_TABLE_HH__

View File

@ -0,0 +1,559 @@
/*
* 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/sparc/asi.hh"
#include "arch/sparc/handlers.hh"
#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/process.hh"
#include "arch/sparc/registers.hh"
#include "arch/sparc/types.hh"
#include "base/loader/elf_object.hh"
#include "base/loader/object_file.hh"
#include "base/misc.hh"
#include "cpu/thread_context.hh"
#include "debug/Stack.hh"
#include "mem/page_table.hh"
#include "sim/process_impl.hh"
#include "sim/system.hh"
using namespace std;
using namespace SparcISA;
static const int FirstArgumentReg = 8;
SparcLiveProcess::SparcLiveProcess(LiveProcessParams * params,
ObjectFile *objFile, Addr _StackBias)
: LiveProcess(params, objFile), StackBias(_StackBias)
{
// XXX all the below need to be updated for SPARC - Ali
brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize();
brk_point = roundUp(brk_point, VMPageSize);
// Set pointer for next thread stack. Reserve 8M for main stack.
next_thread_stack_base = stack_base - (8 * 1024 * 1024);
// Initialize these to 0s
fillStart = 0;
spillStart = 0;
}
void
SparcLiveProcess::handleTrap(int trapNum, ThreadContext *tc)
{
PCState pc = tc->pcState();
switch (trapNum) {
case 0x01: // Software breakpoint
warn("Software breakpoint encountered at pc %#x.\n", pc.pc());
break;
case 0x02: // Division by zero
warn("Software signaled a division by zero at pc %#x.\n", pc.pc());
break;
case 0x03: // Flush window trap
flushWindows(tc);
break;
case 0x04: // Clean windows
warn("Ignoring process request for clean register "
"windows at pc %#x.\n", pc.pc());
break;
case 0x05: // Range check
warn("Software signaled a range check at pc %#x.\n", pc.pc());
break;
case 0x06: // Fix alignment
warn("Ignoring process request for os assisted unaligned accesses "
"at pc %#x.\n", pc.pc());
break;
case 0x07: // Integer overflow
warn("Software signaled an integer overflow at pc %#x.\n", pc.pc());
break;
case 0x32: // Get integer condition codes
warn("Ignoring process request to get the integer condition codes "
"at pc %#x.\n", pc.pc());
break;
case 0x33: // Set integer condition codes
warn("Ignoring process request to set the integer condition codes "
"at pc %#x.\n", pc.pc());
break;
default:
panic("Unimplemented trap to operating system: trap number %#x.\n", trapNum);
}
}
void
SparcLiveProcess::initState()
{
LiveProcess::initState();
ThreadContext *tc = system->getThreadContext(contextIds[0]);
// From the SPARC ABI
// Setup default FP state
tc->setMiscRegNoEffect(MISCREG_FSR, 0);
tc->setMiscRegNoEffect(MISCREG_TICK, 0);
/*
* Register window management registers
*/
// No windows contain info from other programs
// tc->setMiscRegNoEffect(MISCREG_OTHERWIN, 0);
tc->setIntReg(NumIntArchRegs + 6, 0);
// There are no windows to pop
// tc->setMiscRegNoEffect(MISCREG_CANRESTORE, 0);
tc->setIntReg(NumIntArchRegs + 4, 0);
// All windows are available to save into
// tc->setMiscRegNoEffect(MISCREG_CANSAVE, NWindows - 2);
tc->setIntReg(NumIntArchRegs + 3, NWindows - 2);
// All windows are "clean"
// tc->setMiscRegNoEffect(MISCREG_CLEANWIN, NWindows);
tc->setIntReg(NumIntArchRegs + 5, NWindows);
// Start with register window 0
tc->setMiscReg(MISCREG_CWP, 0);
// Always use spill and fill traps 0
// tc->setMiscRegNoEffect(MISCREG_WSTATE, 0);
tc->setIntReg(NumIntArchRegs + 7, 0);
// Set the trap level to 0
tc->setMiscRegNoEffect(MISCREG_TL, 0);
// Set the ASI register to something fixed
tc->setMiscRegNoEffect(MISCREG_ASI, ASI_PRIMARY);
/*
* T1 specific registers
*/
// Turn on the icache, dcache, dtb translation, and itb translation.
tc->setMiscRegNoEffect(MISCREG_MMU_LSU_CTRL, 15);
}
void
Sparc32LiveProcess::initState()
{
SparcLiveProcess::initState();
ThreadContext *tc = system->getThreadContext(contextIds[0]);
// The process runs in user mode with 32 bit addresses
PSTATE pstate = 0;
pstate.ie = 1;
pstate.am = 1;
tc->setMiscReg(MISCREG_PSTATE, pstate);
argsInit(32 / 8, VMPageSize);
}
void
Sparc64LiveProcess::initState()
{
SparcLiveProcess::initState();
ThreadContext *tc = system->getThreadContext(contextIds[0]);
// The process runs in user mode
PSTATE pstate = 0;
pstate.ie = 1;
tc->setMiscReg(MISCREG_PSTATE, pstate);
argsInit(sizeof(IntReg), VMPageSize);
}
template<class IntType>
void
SparcLiveProcess::argsInit(int pageSize)
{
int intSize = sizeof(IntType);
typedef AuxVector<IntType> auxv_t;
std::vector<auxv_t> auxv;
string filename;
if (argv.size() < 1)
filename = "";
else
filename = argv[0];
// Even for a 32 bit process, the ABI says we still need to
// maintain double word alignment of the stack pointer.
uint64_t align = 16;
// load object file into target memory
objFile->loadSections(initVirtMem);
enum hardwareCaps
{
M5_HWCAP_SPARC_FLUSH = 1,
M5_HWCAP_SPARC_STBAR = 2,
M5_HWCAP_SPARC_SWAP = 4,
M5_HWCAP_SPARC_MULDIV = 8,
M5_HWCAP_SPARC_V9 = 16,
// This one should technically only be set
// if there is a cheetah or cheetah_plus tlb,
// but we'll use it all the time
M5_HWCAP_SPARC_ULTRA3 = 32
};
const int64_t hwcap =
M5_HWCAP_SPARC_FLUSH |
M5_HWCAP_SPARC_STBAR |
M5_HWCAP_SPARC_SWAP |
M5_HWCAP_SPARC_MULDIV |
M5_HWCAP_SPARC_V9 |
M5_HWCAP_SPARC_ULTRA3;
// Setup the auxilliary vectors. These will already have endian conversion.
// Auxilliary vectors are loaded only for elf formatted executables.
ElfObject * elfObject = dynamic_cast<ElfObject *>(objFile);
if (elfObject) {
// Bits which describe the system hardware capabilities
auxv.push_back(auxv_t(M5_AT_HWCAP, hwcap));
// The system page size
auxv.push_back(auxv_t(M5_AT_PAGESZ, SparcISA::VMPageSize));
// Defined to be 100 in the kernel source.
// Frequency at which times() increments
auxv.push_back(auxv_t(M5_AT_CLKTCK, 100));
// For statically linked executables, this is the virtual address of the
// program header tables if they appear in the executable image
auxv.push_back(auxv_t(M5_AT_PHDR, elfObject->programHeaderTable()));
// This is the size of a program header entry from the elf file.
auxv.push_back(auxv_t(M5_AT_PHENT, elfObject->programHeaderSize()));
// This is the number of program headers from the original elf file.
auxv.push_back(auxv_t(M5_AT_PHNUM, elfObject->programHeaderCount()));
// This is the address of the elf "interpreter", It should be set
// to 0 for regular executables. It should be something else
// (not sure what) for dynamic libraries.
auxv.push_back(auxv_t(M5_AT_BASE, 0));
// This is hardwired to 0 in the elf loading code in the kernel
auxv.push_back(auxv_t(M5_AT_FLAGS, 0));
// The entry point to the program
auxv.push_back(auxv_t(M5_AT_ENTRY, objFile->entryPoint()));
// Different user and group IDs
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()));
// Whether to enable "secure mode" in the executable
auxv.push_back(auxv_t(M5_AT_SECURE, 0));
}
// Figure out how big the initial stack needs to be
// The unaccounted for 8 byte 0 at the top of the stack
int sentry_size = 8;
// This is the name of the file which is present on the initial stack
// It's purpose is to let the user space linker examine the original file.
int file_name_size = filename.size() + 1;
int env_data_size = 0;
for (int i = 0; i < envp.size(); ++i) {
env_data_size += envp[i].size() + 1;
}
int arg_data_size = 0;
for (int i = 0; i < argv.size(); ++i) {
arg_data_size += argv[i].size() + 1;
}
// The info_block.
int base_info_block_size =
sentry_size + file_name_size + env_data_size + arg_data_size;
int info_block_size = roundUp(base_info_block_size, align);
int info_block_padding = info_block_size - base_info_block_size;
// Each auxilliary vector is two words
int aux_array_size = intSize * 2 * (auxv.size() + 1);
int envp_array_size = intSize * (envp.size() + 1);
int argv_array_size = intSize * (argv.size() + 1);
int argc_size = intSize;
int window_save_size = intSize * 16;
// Figure out the size of the contents of the actual initial frame
int frame_size =
aux_array_size +
envp_array_size +
argv_array_size +
argc_size +
window_save_size;
// There needs to be padding after the auxiliary vector data so that the
// very bottom of the stack is aligned properly.
int aligned_partial_size = roundUp(frame_size, align);
int aux_padding = aligned_partial_size - frame_size;
int space_needed =
info_block_size +
aux_padding +
frame_size;
stack_min = stack_base - space_needed;
stack_min = roundDown(stack_min, align);
stack_size = stack_base - stack_min;
// Allocate space for the stack
allocateMem(roundDown(stack_min, pageSize), roundUp(stack_size, pageSize));
// map out initial stack contents
IntType sentry_base = stack_base - sentry_size;
IntType file_name_base = sentry_base - file_name_size;
IntType env_data_base = file_name_base - env_data_size;
IntType arg_data_base = env_data_base - arg_data_size;
IntType auxv_array_base = arg_data_base -
info_block_padding - aux_array_size - aux_padding;
IntType envp_array_base = auxv_array_base - envp_array_size;
IntType argv_array_base = envp_array_base - argv_array_size;
IntType argc_base = argv_array_base - argc_size;
#if TRACING_ON
IntType window_save_base = argc_base - window_save_size;
#endif
DPRINTF(Stack, "The addresses of items on the initial stack:\n");
DPRINTF(Stack, "%#x - sentry NULL\n", sentry_base);
DPRINTF(Stack, "filename = %s\n", filename);
DPRINTF(Stack, "%#x - file name\n", file_name_base);
DPRINTF(Stack, "%#x - env data\n", env_data_base);
DPRINTF(Stack, "%#x - arg data\n", arg_data_base);
DPRINTF(Stack, "%#x - auxv array\n", auxv_array_base);
DPRINTF(Stack, "%#x - envp array\n", envp_array_base);
DPRINTF(Stack, "%#x - argv array\n", argv_array_base);
DPRINTF(Stack, "%#x - argc \n", argc_base);
DPRINTF(Stack, "%#x - window save\n", window_save_base);
DPRINTF(Stack, "%#x - stack min\n", stack_min);
assert(window_save_base == stack_min);
// write contents to stack
// figure out argc
IntType argc = argv.size();
IntType guestArgc = SparcISA::htog(argc);
// Write out the sentry void *
uint64_t sentry_NULL = 0;
initVirtMem.writeBlob(sentry_base,
(uint8_t*)&sentry_NULL, sentry_size);
// Write the file name
initVirtMem.writeString(file_name_base, filename.c_str());
// Copy the aux stuff
for (int 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);
}
// Write out the terminating zeroed auxilliary vector
const IntType zero = 0;
initVirtMem.writeBlob(auxv_array_base + intSize * 2 * auxv.size(),
(uint8_t*)&zero, intSize);
initVirtMem.writeBlob(auxv_array_base + intSize * (2 * auxv.size() + 1),
(uint8_t*)&zero, intSize);
copyStringArray(envp, envp_array_base, env_data_base, initVirtMem);
copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem);
initVirtMem.writeBlob(argc_base, (uint8_t*)&guestArgc, intSize);
// Set up space for the trap handlers into the processes address space.
// Since the stack grows down and there is reserved address space abov
// it, we can put stuff above it and stay out of the way.
fillStart = stack_base;
spillStart = fillStart + sizeof(MachInst) * numFillInsts;
ThreadContext *tc = system->getThreadContext(contextIds[0]);
// Set up the thread context to start running the process
// assert(NumArgumentRegs >= 2);
// tc->setIntReg(ArgumentReg[0], argc);
// tc->setIntReg(ArgumentReg[1], argv_array_base);
tc->setIntReg(StackPointerReg, stack_min - StackBias);
// %g1 is a pointer to a function that should be run at exit. Since we
// don't have anything like that, it should be set to 0.
tc->setIntReg(1, 0);
tc->pcState(objFile->entryPoint());
// Align the "stack_min" to a page boundary.
stack_min = roundDown(stack_min, pageSize);
// num_processes++;
}
void
Sparc64LiveProcess::argsInit(int intSize, int pageSize)
{
SparcLiveProcess::argsInit<uint64_t>(pageSize);
// Stuff the trap handlers into the process address space
initVirtMem.writeBlob(fillStart,
(uint8_t*)fillHandler64, sizeof(MachInst) * numFillInsts);
initVirtMem.writeBlob(spillStart,
(uint8_t*)spillHandler64, sizeof(MachInst) * numSpillInsts);
}
void
Sparc32LiveProcess::argsInit(int intSize, int pageSize)
{
SparcLiveProcess::argsInit<uint32_t>(pageSize);
// Stuff the trap handlers into the process address space
initVirtMem.writeBlob(fillStart,
(uint8_t*)fillHandler32, sizeof(MachInst) * numFillInsts);
initVirtMem.writeBlob(spillStart,
(uint8_t*)spillHandler32, sizeof(MachInst) * numSpillInsts);
}
void Sparc32LiveProcess::flushWindows(ThreadContext *tc)
{
IntReg Cansave = tc->readIntReg(NumIntArchRegs + 3);
IntReg Canrestore = tc->readIntReg(NumIntArchRegs + 4);
IntReg Otherwin = tc->readIntReg(NumIntArchRegs + 6);
MiscReg CWP = tc->readMiscReg(MISCREG_CWP);
MiscReg origCWP = CWP;
CWP = (CWP + Cansave + 2) % NWindows;
while (NWindows - 2 - Cansave != 0) {
if (Otherwin) {
panic("Otherwin non-zero.\n");
} else {
tc->setMiscReg(MISCREG_CWP, CWP);
// Do the stores
IntReg sp = tc->readIntReg(StackPointerReg);
for (int index = 16; index < 32; index++) {
uint32_t regVal = tc->readIntReg(index);
regVal = htog(regVal);
if (!tc->getMemProxy().tryWriteBlob(
sp + (index - 16) * 4, (uint8_t *)&regVal, 4)) {
warn("Failed to save register to the stack when "
"flushing windows.\n");
}
}
Canrestore--;
Cansave++;
CWP = (CWP + 1) % NWindows;
}
}
tc->setIntReg(NumIntArchRegs + 3, Cansave);
tc->setIntReg(NumIntArchRegs + 4, Canrestore);
tc->setMiscReg(MISCREG_CWP, origCWP);
}
void
Sparc64LiveProcess::flushWindows(ThreadContext *tc)
{
IntReg Cansave = tc->readIntReg(NumIntArchRegs + 3);
IntReg Canrestore = tc->readIntReg(NumIntArchRegs + 4);
IntReg Otherwin = tc->readIntReg(NumIntArchRegs + 6);
MiscReg CWP = tc->readMiscReg(MISCREG_CWP);
MiscReg origCWP = CWP;
CWP = (CWP + Cansave + 2) % NWindows;
while (NWindows - 2 - Cansave != 0) {
if (Otherwin) {
panic("Otherwin non-zero.\n");
} else {
tc->setMiscReg(MISCREG_CWP, CWP);
// Do the stores
IntReg sp = tc->readIntReg(StackPointerReg);
for (int index = 16; index < 32; index++) {
IntReg regVal = tc->readIntReg(index);
regVal = htog(regVal);
if (!tc->getMemProxy().tryWriteBlob(
sp + 2047 + (index - 16) * 8, (uint8_t *)&regVal, 8)) {
warn("Failed to save register to the stack when "
"flushing windows.\n");
}
}
Canrestore--;
Cansave++;
CWP = (CWP + 1) % NWindows;
}
}
tc->setIntReg(NumIntArchRegs + 3, Cansave);
tc->setIntReg(NumIntArchRegs + 4, Canrestore);
tc->setMiscReg(MISCREG_CWP, origCWP);
}
IntReg
Sparc32LiveProcess::getSyscallArg(ThreadContext *tc, int &i)
{
assert(i < 6);
return bits(tc->readIntReg(FirstArgumentReg + i++), 31, 0);
}
void
Sparc32LiveProcess::setSyscallArg(ThreadContext *tc, int i, IntReg val)
{
assert(i < 6);
tc->setIntReg(FirstArgumentReg + i, bits(val, 31, 0));
}
IntReg
Sparc64LiveProcess::getSyscallArg(ThreadContext *tc, int &i)
{
assert(i < 6);
return tc->readIntReg(FirstArgumentReg + i++);
}
void
Sparc64LiveProcess::setSyscallArg(ThreadContext *tc, int i, IntReg val)
{
assert(i < 6);
tc->setIntReg(FirstArgumentReg + i, val);
}
void
SparcLiveProcess::setSyscallReturn(ThreadContext *tc,
SyscallReturn return_value)
{
// check for error condition. SPARC syscall convention is to
// indicate success/failure in reg the carry bit of the ccr
// and put the return value itself in the standard return value reg ().
PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
if (return_value.successful()) {
// no error, clear XCC.C
tc->setIntReg(NumIntArchRegs + 2,
tc->readIntReg(NumIntArchRegs + 2) & 0xEE);
IntReg val = return_value.value();
if (pstate.am)
val = bits(val, 31, 0);
tc->setIntReg(ReturnValueReg, val);
} else {
// got an error, set XCC.C
tc->setIntReg(NumIntArchRegs + 2,
tc->readIntReg(NumIntArchRegs + 2) | 0x11);
IntReg val = -return_value.value();
if (pstate.am)
val = bits(val, 31, 0);
tc->setIntReg(ReturnValueReg, val);
}
}

View File

@ -0,0 +1,128 @@
/*
* 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 __SPARC_PROCESS_HH__
#define __SPARC_PROCESS_HH__
#include <string>
#include <vector>
#include "sim/byteswap.hh"
#include "sim/process.hh"
class ObjectFile;
class System;
class SparcLiveProcess : public LiveProcess
{
protected:
const Addr StackBias;
// The locations of the fill and spill handlers
Addr fillStart, spillStart;
SparcLiveProcess(LiveProcessParams * params,
ObjectFile *objFile, Addr _StackBias);
void initState();
template<class IntType>
void argsInit(int pageSize);
public:
// Handles traps which request services from the operating system
virtual void handleTrap(int trapNum, ThreadContext *tc);
Addr readFillStart() { return fillStart; }
Addr readSpillStart() { return spillStart; }
virtual void flushWindows(ThreadContext *tc) = 0;
void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value);
};
class Sparc32LiveProcess : public SparcLiveProcess
{
protected:
Sparc32LiveProcess(LiveProcessParams * params, ObjectFile *objFile) :
SparcLiveProcess(params, objFile, 0)
{
// Set up stack. On SPARC Linux, stack goes from the top of memory
// downward, less the hole for the kernel address space.
stack_base = (Addr)0xf0000000ULL;
// Set up region for mmaps.
mmap_start = mmap_end = 0x70000000;
}
void initState();
public:
void argsInit(int intSize, int pageSize);
void flushWindows(ThreadContext *tc);
SparcISA::IntReg getSyscallArg(ThreadContext *tc, int &i);
void setSyscallArg(ThreadContext *tc, int i, SparcISA::IntReg val);
};
class Sparc64LiveProcess : public SparcLiveProcess
{
protected:
Sparc64LiveProcess(LiveProcessParams * params, ObjectFile *objFile) :
SparcLiveProcess(params, objFile, 2047)
{
// Set up stack. On SPARC Linux, stack goes from the top of memory
// downward, less the hole for the kernel address space.
stack_base = (Addr)0x80000000000ULL;
// Set up region for mmaps. Tru64 seems to start just above 0 and
// grow up from there.
mmap_start = mmap_end = 0xfffff80000000000ULL;
}
void initState();
public:
void argsInit(int intSize, int pageSize);
void flushWindows(ThreadContext *tc);
SparcISA::IntReg getSyscallArg(ThreadContext *tc, int &i);
void setSyscallArg(ThreadContext *tc, int i, SparcISA::IntReg val);
};
#endif // __SPARC_PROCESS_HH__

View File

@ -0,0 +1,85 @@
/*
* 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
* Ali Saidi
*/
#ifndef __ARCH_SPARC_REGISTERS_HH__
#define __ARCH_SPARC_REGISTERS_HH__
#include "arch/sparc/generated/max_inst_regs.hh"
#include "arch/sparc/miscregs.hh"
#include "arch/sparc/sparc_traits.hh"
#include "base/types.hh"
namespace SparcISA
{
using SparcISAInst::MaxInstSrcRegs;
using SparcISAInst::MaxInstDestRegs;
using SparcISAInst::MaxMiscDestRegs;
typedef uint64_t IntReg;
typedef uint64_t MiscReg;
typedef float FloatReg;
typedef uint32_t FloatRegBits;
typedef union
{
IntReg intReg;
FloatReg fpreg;
MiscReg ctrlreg;
} AnyReg;
typedef uint16_t RegIndex;
// These enumerate all the registers for dependence tracking.
enum DependenceTags {
FP_Base_DepTag = 32*3+9,
Ctrl_Base_DepTag = FP_Base_DepTag + 64,
Max_DepTag = Ctrl_Base_DepTag + NumMiscRegs
};
// semantically meaningful register indices
const int ZeroReg = 0; // architecturally meaningful
// the rest of these depend on the ABI
const int ReturnAddressReg = 31; // post call, precall is 15
const int ReturnValueReg = 8; // Post return, 24 is pre-return.
const int StackPointerReg = 14;
const int FramePointerReg = 30;
// Some OS syscall use a second register (o1) to return a second value
const int SyscallPseudoReturnReg = 9;
const int NumIntArchRegs = 32;
const int NumIntRegs = (MaxGL + 1) * 8 + NWindows * 16 + NumMicroIntRegs;
const int TotalNumRegs = NumIntRegs + NumFloatRegs + NumMiscRegs;
} // namespace SparcISA
#endif

View File

@ -0,0 +1,254 @@
/*
* 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/sparc/remote_gdb.hh"
#include "arch/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/GDBRead.hh"
#include "mem/page_table.hh"
#include "mem/physical.hh"
#include "mem/port.hh"
#include "sim/byteswap.hh"
#include "sim/full_system.hh"
#include "sim/process.hh"
#include "sim/system.hh"
using namespace std;
using namespace SparcISA;
RemoteGDB::RemoteGDB(System *_system, ThreadContext *c)
: BaseRemoteGDB(_system, c, NumGDBRegs), nextBkpt(0)
{}
///////////////////////////////////////////////////////////
// RemoteGDB::acc
//
// Determine if the mapping at va..(va+len) is valid.
//
bool
RemoteGDB::acc(Addr va, size_t len)
{
//@Todo In NetBSD, this function checks if all addresses
// from va to va + len have valid page map entries. Not
// sure how this will work for other OSes or in general.
if (FullSystem) {
if (va)
return true;
return false;
} else {
TlbEntry entry;
// Check to make sure the first byte is mapped into the processes
// address space.
if (context->getProcessPtr()->pTable->lookup(va, entry))
return true;
return false;
}
}
///////////////////////////////////////////////////////////
// RemoteGDB::getregs
//
// Translate the kernel debugger register format into
// the GDB register format.
void
RemoteGDB::getregs()
{
memset(gdbregs.regs, 0, gdbregs.size);
PCState pc = context->pcState();
PSTATE pstate = context->readMiscReg(MISCREG_PSTATE);
if (pstate.am) {
uint32_t *regs;
regs = (uint32_t*)gdbregs.regs;
regs[Reg32Pc] = htobe((uint32_t)pc.pc());
regs[Reg32Npc] = htobe((uint32_t)pc.npc());
for (int x = RegG0; x <= RegI0 + 7; x++)
regs[x] = htobe((uint32_t)context->readIntReg(x - RegG0));
regs[Reg32Y] = htobe((uint32_t)context->readIntReg(NumIntArchRegs + 1));
regs[Reg32Psr] = htobe((uint32_t)pstate);
regs[Reg32Fsr] = htobe((uint32_t)context->readMiscReg(MISCREG_FSR));
regs[Reg32Csr] = htobe((uint32_t)context->readIntReg(NumIntArchRegs + 2));
} else {
gdbregs.regs[RegPc] = htobe(pc.pc());
gdbregs.regs[RegNpc] = htobe(pc.npc());
for (int x = RegG0; x <= RegI0 + 7; x++)
gdbregs.regs[x] = htobe(context->readIntReg(x - RegG0));
gdbregs.regs[RegFsr] = htobe(context->readMiscReg(MISCREG_FSR));
gdbregs.regs[RegFprs] = htobe(context->readMiscReg(MISCREG_FPRS));
gdbregs.regs[RegY] = htobe(context->readIntReg(NumIntArchRegs + 1));
gdbregs.regs[RegState] = htobe(
context->readMiscReg(MISCREG_CWP) |
pstate << 8 |
context->readMiscReg(MISCREG_ASI) << 24 |
context->readIntReg(NumIntArchRegs + 2) << 32);
}
DPRINTF(GDBRead, "PC=%#x\n", gdbregs.regs[RegPc]);
// Floating point registers are left at 0 in netbsd
// All registers other than the pc, npc and int regs
// are ignored as well.
}
///////////////////////////////////////////////////////////
// RemoteGDB::setregs
//
// Translate the GDB register format into the kernel
// debugger register format.
//
void
RemoteGDB::setregs()
{
PCState pc;
pc.pc(gdbregs.regs[RegPc]);
pc.npc(gdbregs.regs[RegNpc]);
pc.nnpc(pc.npc() + sizeof(MachInst));
pc.upc(0);
pc.nupc(1);
context->pcState(pc);
for (int x = RegG0; x <= RegI0 + 7; x++)
context->setIntReg(x - RegG0, gdbregs.regs[x]);
// Only the integer registers, pc and npc are set in netbsd
}
void
RemoteGDB::clearSingleStep()
{
if (nextBkpt)
clearTempBreakpoint(nextBkpt);
}
void
RemoteGDB::setSingleStep()
{
nextBkpt = context->pcState().npc();
setTempBreakpoint(nextBkpt);
}

View File

@ -0,0 +1,78 @@
/*
* 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_SPARC_REMOTE_GDB_HH__
#define __ARCH_SPARC_REMOTE_GDB_HH__
#include <map>
#include "arch/sparc/types.hh"
#include "base/pollevent.hh"
#include "base/remote_gdb.hh"
#include "cpu/pc_event.hh"
class System;
class ThreadContext;
namespace SparcISA
{
class RemoteGDB : public BaseRemoteGDB
{
protected:
enum RegisterConstants
{
RegG0 = 0, RegO0 = 8, RegL0 = 16, RegI0 = 24,
RegF0 = 32,
RegPc = 64, RegNpc, RegState, RegFsr, RegFprs, RegY,
/*RegState contains data in same format as tstate */
Reg32Y = 64, Reg32Psr = 65, Reg32Tbr = 66, Reg32Pc = 67,
Reg32Npc = 68, Reg32Fsr = 69, Reg32Csr = 70,
NumGDBRegs
};
public:
RemoteGDB(System *system, ThreadContext *context);
bool acc(Addr addr, size_t len);
protected:
void getregs();
void setregs();
void clearSingleStep();
void setSingleStep();
Addr nextBkpt;
};
}
#endif /* __ARCH_SPARC_REMOTE_GDB_H__ */

View File

@ -0,0 +1,341 @@
/*
* 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: Ali Saidi
*/
#include "arch/sparc/solaris/process.hh"
#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/registers.hh"
#include "base/trace.hh"
#include "cpu/thread_context.hh"
#include "kern/solaris/solaris.hh"
#include "sim/process.hh"
#include "sim/syscall_emul.hh"
using namespace std;
using namespace SparcISA;
/// Target uname() handler.
static SyscallReturn
unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
ThreadContext *tc)
{
int index = 0;
TypedBufferArg<Solaris::utsname> name(process->getSyscallArg(tc, index));
strcpy(name->sysname, "SunOS");
strcpy(name->nodename, "m5.eecs.umich.edu");
strcpy(name->release, "5.9"); //?? do we want this or something newer?
strcpy(name->version, "Generic_118558-21");
strcpy(name->machine, "sun4u");
name.copyOut(tc->getMemProxy());
return 0;
}
SyscallDesc SparcSolarisProcess::syscallDescs[] = {
/* 0 */ SyscallDesc("syscall", unimplementedFunc),
/* 1 */ SyscallDesc("exit", exitFunc),
/* 2 */ SyscallDesc("fork", unimplementedFunc),
/* 3 */ SyscallDesc("read", readFunc),
/* 4 */ SyscallDesc("write", writeFunc),
/* 5 */ SyscallDesc("open", openFunc<SparcSolaris>),
/* 6 */ SyscallDesc("close", closeFunc),
/* 7 */ SyscallDesc("wait", unimplementedFunc),
/* 8 */ SyscallDesc("creat", unimplementedFunc),
/* 9 */ SyscallDesc("link", unimplementedFunc),
/* 10 */ SyscallDesc("unlink", unlinkFunc),
/* 11 */ SyscallDesc("exec", unimplementedFunc),
/* 12 */ SyscallDesc("chdir", unimplementedFunc),
/* 13 */ SyscallDesc("time", unimplementedFunc),
/* 14 */ SyscallDesc("mknod", unimplementedFunc),
/* 15 */ SyscallDesc("chmod", chmodFunc<Solaris>),
/* 16 */ SyscallDesc("chown", chownFunc),
/* 17 */ SyscallDesc("brk", brkFunc),
/* 18 */ SyscallDesc("stat", unimplementedFunc),
/* 19 */ SyscallDesc("lseek", lseekFunc),
/* 20 */ SyscallDesc("getpid", getpidFunc),
/* 21 */ SyscallDesc("mount", unimplementedFunc),
/* 22 */ SyscallDesc("umount", unimplementedFunc),
/* 23 */ SyscallDesc("setuid", setuidFunc),
/* 24 */ SyscallDesc("getuid", getuidFunc),
/* 25 */ SyscallDesc("stime", unimplementedFunc),
/* 26 */ SyscallDesc("pcsample", unimplementedFunc),
/* 27 */ SyscallDesc("alarm", unimplementedFunc),
/* 28 */ SyscallDesc("fstat", fstatFunc<SparcSolaris>),
/* 29 */ SyscallDesc("pause", unimplementedFunc),
/* 30 */ SyscallDesc("utime", unimplementedFunc),
/* 31 */ SyscallDesc("stty", unimplementedFunc),
/* 32 */ SyscallDesc("gtty", unimplementedFunc),
/* 33 */ SyscallDesc("access", unimplementedFunc),
/* 34 */ SyscallDesc("nice", unimplementedFunc),
/* 35 */ SyscallDesc("statfs", unimplementedFunc),
/* 36 */ SyscallDesc("sync", unimplementedFunc),
/* 37 */ SyscallDesc("kill", unimplementedFunc),
/* 38 */ SyscallDesc("fstatfs", unimplementedFunc),
/* 39 */ SyscallDesc("pgrpsys", unimplementedFunc),
/* 40 */ SyscallDesc("xenix", unimplementedFunc),
/* 41 */ SyscallDesc("dup", unimplementedFunc),
/* 42 */ SyscallDesc("pipe", pipePseudoFunc),
/* 43 */ SyscallDesc("times", unimplementedFunc),
/* 44 */ SyscallDesc("profil", unimplementedFunc),
/* 45 */ SyscallDesc("plock", unimplementedFunc),
/* 46 */ SyscallDesc("setgid", unimplementedFunc),
/* 47 */ SyscallDesc("getgid", getgidFunc),
/* 48 */ SyscallDesc("signal", unimplementedFunc),
/* 49 */ SyscallDesc("msgsys", unimplementedFunc),
/* 50 */ SyscallDesc("syssun", unimplementedFunc),
/* 51 */ SyscallDesc("acct", unimplementedFunc),
/* 52 */ SyscallDesc("shmsys", unimplementedFunc),
/* 53 */ SyscallDesc("semsys", unimplementedFunc),
/* 54 */ SyscallDesc("ioctl", unimplementedFunc),
/* 55 */ SyscallDesc("uadmin", unimplementedFunc),
/* 56 */ SyscallDesc("RESERVED", unimplementedFunc),
/* 57 */ SyscallDesc("utssys", unimplementedFunc),
/* 58 */ SyscallDesc("fdsync", unimplementedFunc),
/* 59 */ SyscallDesc("execve", unimplementedFunc),
/* 60 */ SyscallDesc("umask", umaskFunc),
/* 61 */ SyscallDesc("chroot", unimplementedFunc),
/* 62 */ SyscallDesc("fcntl", unimplementedFunc),
/* 63 */ SyscallDesc("ulimit", unimplementedFunc),
/* 64 */ SyscallDesc("reserved_64", unimplementedFunc),
/* 65 */ SyscallDesc("reserved_65", unimplementedFunc),
/* 66 */ SyscallDesc("reserved_66", unimplementedFunc),
/* 67 */ SyscallDesc("reserved_67", unimplementedFunc),
/* 68 */ SyscallDesc("reserved_68", unimplementedFunc),
/* 69 */ SyscallDesc("reserved_69", unimplementedFunc),
/* 70 */ SyscallDesc("tasksys", unimplementedFunc),
/* 71 */ SyscallDesc("acctctl", unimplementedFunc),
/* 72 */ SyscallDesc("reserved_72", unimplementedFunc),
/* 73 */ SyscallDesc("getpagesizes", unimplementedFunc),
/* 74 */ SyscallDesc("rctlsys", unimplementedFunc),
/* 75 */ SyscallDesc("issetugid", unimplementedFunc),
/* 76 */ SyscallDesc("fsat", unimplementedFunc),
/* 77 */ SyscallDesc("lwp_park", unimplementedFunc),
/* 78 */ SyscallDesc("sendfilev", unimplementedFunc),
/* 79 */ SyscallDesc("rmdir", unimplementedFunc),
/* 80 */ SyscallDesc("mkdir", unimplementedFunc),
/* 81 */ SyscallDesc("getdents", unimplementedFunc),
/* 82 */ SyscallDesc("reserved_82", unimplementedFunc),
/* 83 */ SyscallDesc("reserved_83", unimplementedFunc),
/* 84 */ SyscallDesc("sysfs", unimplementedFunc),
/* 85 */ SyscallDesc("getmsg", unimplementedFunc),
/* 86 */ SyscallDesc("putmsg", unimplementedFunc),
/* 87 */ SyscallDesc("poll", unimplementedFunc),
/* 88 */ SyscallDesc("lstat", unimplementedFunc),
/* 89 */ SyscallDesc("symlink", unimplementedFunc),
/* 90 */ SyscallDesc("readlink", readlinkFunc),
/* 91 */ SyscallDesc("setgroups", unimplementedFunc),
/* 92 */ SyscallDesc("getgroups", unimplementedFunc),
/* 93 */ SyscallDesc("fchmod", unimplementedFunc),
/* 94 */ SyscallDesc("fchown", unimplementedFunc),
/* 95 */ SyscallDesc("sigprocmask", unimplementedFunc),
/* 96 */ SyscallDesc("sigsuspend", unimplementedFunc),
/* 97 */ SyscallDesc("sigaltstack", unimplementedFunc),
/* 98 */ SyscallDesc("sigaction", unimplementedFunc),
/* 99 */ SyscallDesc("sigpending", unimplementedFunc),
/* 100 */ SyscallDesc("context", unimplementedFunc),
/* 101 */ SyscallDesc("evsys", unimplementedFunc),
/* 102 */ SyscallDesc("evtrapret", unimplementedFunc),
/* 103 */ SyscallDesc("statvfs", unimplementedFunc),
/* 104 */ SyscallDesc("fstatvfs", unimplementedFunc),
/* 105 */ SyscallDesc("getloadavg", unimplementedFunc),
/* 106 */ SyscallDesc("nfssys", unimplementedFunc),
/* 107 */ SyscallDesc("waitsys", unimplementedFunc),
/* 108 */ SyscallDesc("sigsendsys", unimplementedFunc),
/* 109 */ SyscallDesc("hrtsys", unimplementedFunc),
/* 110 */ SyscallDesc("acancel", unimplementedFunc),
/* 111 */ SyscallDesc("async", unimplementedFunc),
/* 112 */ SyscallDesc("priocntlsys", unimplementedFunc),
/* 113 */ SyscallDesc("pathconf", unimplementedFunc),
/* 114 */ SyscallDesc("mincore", unimplementedFunc),
/* 115 */ SyscallDesc("mmap", mmapFunc<SparcSolaris>),
/* 116 */ SyscallDesc("mprotect", unimplementedFunc),
/* 117 */ SyscallDesc("munmap", munmapFunc),
/* 118 */ SyscallDesc("fpathconf", unimplementedFunc),
/* 119 */ SyscallDesc("vfork", unimplementedFunc),
/* 120 */ SyscallDesc("fchdir", unimplementedFunc),
/* 121 */ SyscallDesc("readv", unimplementedFunc),
/* 122 */ SyscallDesc("writev", unimplementedFunc),
/* 123 */ SyscallDesc("xstat", unimplementedFunc),
/* 124 */ SyscallDesc("lxstat", unimplementedFunc),
/* 125 */ SyscallDesc("fxstat", unimplementedFunc),
/* 126 */ SyscallDesc("xmknod", unimplementedFunc),
/* 127 */ SyscallDesc("clocal", unimplementedFunc),
/* 128 */ SyscallDesc("setrlimit", unimplementedFunc),
/* 129 */ SyscallDesc("getrlimit", unimplementedFunc),
/* 130 */ SyscallDesc("lchown", unimplementedFunc),
/* 131 */ SyscallDesc("memcntl", unimplementedFunc),
/* 132 */ SyscallDesc("getpmsg", unimplementedFunc),
/* 133 */ SyscallDesc("putpmsg", unimplementedFunc),
/* 134 */ SyscallDesc("rename", unimplementedFunc),
/* 135 */ SyscallDesc("uname", unameFunc),
/* 136 */ SyscallDesc("setegid", unimplementedFunc),
/* 137 */ SyscallDesc("sysconfig", unimplementedFunc),
/* 138 */ SyscallDesc("adjtime", unimplementedFunc),
/* 139 */ SyscallDesc("systeminfo", unimplementedFunc),
/* 140 */ SyscallDesc("reserved_140", unimplementedFunc),
/* 141 */ SyscallDesc("seteuid", unimplementedFunc),
/* 142 */ SyscallDesc("vtrace", unimplementedFunc),
/* 143 */ SyscallDesc("fork1", unimplementedFunc),
/* 144 */ SyscallDesc("sigtimedwait", unimplementedFunc),
/* 145 */ SyscallDesc("lwp_info", unimplementedFunc),
/* 146 */ SyscallDesc("yield", unimplementedFunc),
/* 147 */ SyscallDesc("lwp_sema_wait", unimplementedFunc),
/* 148 */ SyscallDesc("lwp_sema_post", unimplementedFunc),
/* 149 */ SyscallDesc("lwp_sema_trywait", unimplementedFunc),
/* 150 */ SyscallDesc("lwp_detach", unimplementedFunc),
/* 151 */ SyscallDesc("corectl", unimplementedFunc),
/* 152 */ SyscallDesc("modctl", unimplementedFunc),
/* 153 */ SyscallDesc("fchroot", unimplementedFunc),
/* 154 */ SyscallDesc("utimes", unimplementedFunc),
/* 155 */ SyscallDesc("vhangup", unimplementedFunc),
/* 156 */ SyscallDesc("gettimeofday", unimplementedFunc),
/* 157 */ SyscallDesc("getitimer", unimplementedFunc),
/* 158 */ SyscallDesc("setitimer", unimplementedFunc),
/* 159 */ SyscallDesc("lwp_create", unimplementedFunc),
/* 160 */ SyscallDesc("lwp_exit", unimplementedFunc),
/* 161 */ SyscallDesc("lwp_suspend", unimplementedFunc),
/* 162 */ SyscallDesc("lwp_continue", unimplementedFunc),
/* 163 */ SyscallDesc("lwp_kill", unimplementedFunc),
/* 164 */ SyscallDesc("lwp_self", unimplementedFunc),
/* 165 */ SyscallDesc("lwp_setprivate", unimplementedFunc),
/* 166 */ SyscallDesc("lwp_getprivate", unimplementedFunc),
/* 167 */ SyscallDesc("lwp_wait", unimplementedFunc),
/* 168 */ SyscallDesc("lwp_mutex_wakeup", unimplementedFunc),
/* 169 */ SyscallDesc("lwp_mutex_lock", unimplementedFunc),
/* 170 */ SyscallDesc("lwp_cond_wait", unimplementedFunc),
/* 171 */ SyscallDesc("lwp_cond_signal", unimplementedFunc),
/* 172 */ SyscallDesc("lwp_cond_broadcast", unimplementedFunc),
/* 173 */ SyscallDesc("pread", unimplementedFunc),
/* 174 */ SyscallDesc("pwrite", unimplementedFunc),
/* 175 */ SyscallDesc("llseek", unimplementedFunc),
/* 176 */ SyscallDesc("inst_sync", unimplementedFunc),
/* 177 */ SyscallDesc("srmlimitsys", unimplementedFunc),
/* 178 */ SyscallDesc("kaio", unimplementedFunc),
/* 179 */ SyscallDesc("cpc", unimplementedFunc),
/* 180 */ SyscallDesc("lgrpsys_meminfosys", unimplementedFunc),
/* 181 */ SyscallDesc("rusagesys", unimplementedFunc),
/* 182 */ SyscallDesc("reserved_182", unimplementedFunc),
/* 183 */ SyscallDesc("reserved_183", unimplementedFunc),
/* 184 */ SyscallDesc("tsolsys", unimplementedFunc),
/* 185 */ SyscallDesc("acl", unimplementedFunc),
/* 186 */ SyscallDesc("auditsys", unimplementedFunc),
/* 187 */ SyscallDesc("processor_bind", unimplementedFunc),
/* 188 */ SyscallDesc("processor_info", unimplementedFunc),
/* 189 */ SyscallDesc("p_online", unimplementedFunc),
/* 190 */ SyscallDesc("sigqueue", unimplementedFunc),
/* 191 */ SyscallDesc("clock_gettime", unimplementedFunc),
/* 192 */ SyscallDesc("clock_settime", unimplementedFunc),
/* 193 */ SyscallDesc("clock_getres", unimplementedFunc),
/* 194 */ SyscallDesc("timer_create", unimplementedFunc),
/* 195 */ SyscallDesc("timer_delete", unimplementedFunc),
/* 196 */ SyscallDesc("timer_settime", unimplementedFunc),
/* 197 */ SyscallDesc("timer_gettime", unimplementedFunc),
/* 198 */ SyscallDesc("timer_getoverrun", unimplementedFunc),
/* 199 */ SyscallDesc("nanosleep", unimplementedFunc),
/* 200 */ SyscallDesc("facl", unimplementedFunc),
/* 201 */ SyscallDesc("door", unimplementedFunc),
/* 202 */ SyscallDesc("setreuid", unimplementedFunc),
/* 203 */ SyscallDesc("setregid", unimplementedFunc),
/* 204 */ SyscallDesc("install_utrap", unimplementedFunc),
/* 205 */ SyscallDesc("signotify", unimplementedFunc),
/* 206 */ SyscallDesc("schedctl", unimplementedFunc),
/* 207 */ SyscallDesc("pset", unimplementedFunc),
/* 208 */ SyscallDesc("sparc_utrap_install", unimplementedFunc),
/* 209 */ SyscallDesc("resolvepath", unimplementedFunc),
/* 210 */ SyscallDesc("signotifywait", unimplementedFunc),
/* 211 */ SyscallDesc("lwp_sigredirect", unimplementedFunc),
/* 212 */ SyscallDesc("lwp_alarm", unimplementedFunc),
/* 213 */ SyscallDesc("getdents64", unimplementedFunc),
/* 214 */ SyscallDesc("mmap64", unimplementedFunc),
/* 215 */ SyscallDesc("stat64", unimplementedFunc),
/* 216 */ SyscallDesc("lstat64", unimplementedFunc),
/* 217 */ SyscallDesc("fstat64", unimplementedFunc),
/* 218 */ SyscallDesc("statvfs64", unimplementedFunc),
/* 219 */ SyscallDesc("fstatvfs64", unimplementedFunc),
/* 220 */ SyscallDesc("setrlimit64", unimplementedFunc),
/* 221 */ SyscallDesc("getrlimit64", unimplementedFunc),
/* 222 */ SyscallDesc("pread64", unimplementedFunc),
/* 223 */ SyscallDesc("pwrite64", unimplementedFunc),
/* 224 */ SyscallDesc("creat64", unimplementedFunc),
/* 225 */ SyscallDesc("open64", unimplementedFunc),
/* 226 */ SyscallDesc("rpcsys", unimplementedFunc),
/* 227 */ SyscallDesc("reserved_227", unimplementedFunc),
/* 228 */ SyscallDesc("reserved_228", unimplementedFunc),
/* 229 */ SyscallDesc("reserved_229", unimplementedFunc),
/* 230 */ SyscallDesc("so_socket", unimplementedFunc),
/* 231 */ SyscallDesc("so_socketpair", unimplementedFunc),
/* 232 */ SyscallDesc("bind", unimplementedFunc),
/* 233 */ SyscallDesc("listen", unimplementedFunc),
/* 234 */ SyscallDesc("accept", unimplementedFunc),
/* 235 */ SyscallDesc("connect", unimplementedFunc),
/* 236 */ SyscallDesc("shutdown", unimplementedFunc),
/* 237 */ SyscallDesc("recv", unimplementedFunc),
/* 238 */ SyscallDesc("recvfrom", unimplementedFunc),
/* 239 */ SyscallDesc("recvmsg", unimplementedFunc),
/* 240 */ SyscallDesc("send", unimplementedFunc),
/* 241 */ SyscallDesc("sendmsg", unimplementedFunc),
/* 242 */ SyscallDesc("sendto", unimplementedFunc),
/* 243 */ SyscallDesc("getpeername", unimplementedFunc),
/* 244 */ SyscallDesc("getsockname", unimplementedFunc),
/* 245 */ SyscallDesc("getsockopt", unimplementedFunc),
/* 246 */ SyscallDesc("setsockopt", unimplementedFunc),
/* 247 */ SyscallDesc("sockconfig", unimplementedFunc),
/* 248 */ SyscallDesc("ntp_gettime", unimplementedFunc),
/* 249 */ SyscallDesc("ntp_adjtime", unimplementedFunc),
/* 250 */ SyscallDesc("lwp_mutex_unlock", unimplementedFunc),
/* 251 */ SyscallDesc("lwp_mutex_trylock", unimplementedFunc),
/* 252 */ SyscallDesc("lwp_mutex_init", unimplementedFunc),
/* 253 */ SyscallDesc("cladm", unimplementedFunc),
/* 254 */ SyscallDesc("lwp_sigtimedwait", unimplementedFunc),
/* 255 */ SyscallDesc("umount2", unimplementedFunc)
};
SparcSolarisProcess::SparcSolarisProcess(LiveProcessParams * params,
ObjectFile *objFile)
: Sparc64LiveProcess(params, objFile),
Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc))
{
// The sparc syscall table must be <= 284 entries because that is all there
// is space for.
assert(Num_Syscall_Descs <= 284);
}
SyscallDesc*
SparcSolarisProcess::getDesc(int callnum)
{
if (callnum < 0 || callnum >= Num_Syscall_Descs)
return NULL;
return &syscallDescs[callnum];
}

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: Ali Saidi
*/
#ifndef __SPARC_SOLARIS_PROCESS_HH__
#define __SPARC_SOLARIS_PROCESS_HH__
#include "arch/sparc/solaris/solaris.hh"
#include "arch/sparc/process.hh"
#include "sim/process.hh"
namespace SparcISA {
/// A process with emulated SPARC/Solaris syscalls.
class SparcSolarisProcess : public Sparc64LiveProcess
{
public:
/// Constructor.
SparcSolarisProcess(LiveProcessParams * params, ObjectFile *objFile);
virtual SyscallDesc* getDesc(int callnum);
/// The target system's hostname.
static const char *hostname;
/// Array of syscall descriptors, indexed by call number.
static SyscallDesc syscallDescs[];
const int Num_Syscall_Descs;
};
} // namespace SparcISA
#endif // __SPARC_SOLARIS_PROCESS_HH__

View File

@ -0,0 +1,78 @@
/*
* 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: Ali Saidi
*/
#include <fcntl.h>
#include "arch/sparc/solaris/solaris.hh"
// open(2) flags translation table
OpenFlagTransTable SparcSolaris::openFlagTable[] = {
#ifdef _MSC_VER
{ SparcSolaris::TGT_O_RDONLY, _O_RDONLY },
{ SparcSolaris::TGT_O_WRONLY, _O_WRONLY },
{ SparcSolaris::TGT_O_RDWR, _O_RDWR },
{ SparcSolaris::TGT_O_APPEND, _O_APPEND },
{ SparcSolaris::TGT_O_CREAT, _O_CREAT },
{ SparcSolaris::TGT_O_TRUNC, _O_TRUNC },
{ SparcSolaris::TGT_O_EXCL, _O_EXCL },
#ifdef _O_NONBLOCK
{ SparcSolaris::TGT_O_NONBLOCK, _O_NONBLOCK },
{ SparcSolaris::TGT_O_NDELAY , _O_NONBLOCK },
#endif
#ifdef _O_NOCTTY
{ SparcSolaris::TGT_O_NOCTTY, _O_NOCTTY },
#endif
#ifdef _O_SYNC
{ SparcSolaris::TGT_O_SYNC, _O_SYNC },
{ SparcSolaris::TGT_O_DSYNC, _O_SYNC },
{ SparcSolaris::TGT_O_RSYNC, _O_SYNC },
#endif
#else /* !_MSC_VER */
{ SparcSolaris::TGT_O_RDONLY, O_RDONLY },
{ SparcSolaris::TGT_O_WRONLY, O_WRONLY },
{ SparcSolaris::TGT_O_RDWR, O_RDWR },
{ SparcSolaris::TGT_O_APPEND, O_APPEND },
{ SparcSolaris::TGT_O_CREAT, O_CREAT },
{ SparcSolaris::TGT_O_TRUNC, O_TRUNC },
{ SparcSolaris::TGT_O_EXCL, O_EXCL },
{ SparcSolaris::TGT_O_NONBLOCK, O_NONBLOCK },
{ SparcSolaris::TGT_O_NDELAY , O_NONBLOCK },
{ SparcSolaris::TGT_O_NOCTTY, O_NOCTTY },
#ifdef O_SYNC
{ SparcSolaris::TGT_O_SYNC, O_SYNC },
{ SparcSolaris::TGT_O_DSYNC, O_SYNC },
{ SparcSolaris::TGT_O_RSYNC, O_SYNC },
#endif
#endif /* _MSC_VER */
};
const int SparcSolaris::NUM_OPEN_FLAGS =
(sizeof(SparcSolaris::openFlagTable)/sizeof(SparcSolaris::openFlagTable[0]));

View File

@ -0,0 +1,65 @@
/*
* 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: Ali Saidi
*/
#ifndef __ARCH_SPARC_SOLARIS_SOLARIS_HH__
#define __ARCH_SPARC_SOLARIS_SOLARIS_HH__
#include "kern/solaris/solaris.hh"
class SparcSolaris : public Solaris
{
public:
static OpenFlagTransTable openFlagTable[];
static const int TGT_O_RDONLY = 0x00000000; //!< O_RDONLY
static const int TGT_O_WRONLY = 0x00000001; //!< O_WRONLY
static const int TGT_O_RDWR = 0x00000002; //!< O_RDWR
static const int TGT_O_NDELAY = 0x00000004; //!< O_NONBLOCK
static const int TGT_O_APPEND = 0x00000008; //!< O_APPEND
static const int TGT_O_SYNC = 0x00000010; //!< O_SYNC
static const int TGT_O_DSYNC = 0x00000040; //!< O_SYNC
static const int TGT_O_RSYNC = 0x00008000; //!< O_SYNC
static const int TGT_O_NONBLOCK = 0x00000080; //!< O_NONBLOCK
static const int TGT_O_PRIV = 0x00001000; //??
static const int TGT_O_LARGEFILE = 0x00002000; //??
static const int TGT_O_CREAT = 0x00000100; //!< O_CREAT
static const int TGT_O_TRUNC = 0x00000200; //!< O_TRUNC
static const int TGT_O_EXCL = 0x00000400; //!< O_EXCL
static const int TGT_O_NOCTTY = 0x00000800; //!< O_NOCTTY
static const int TGT_O_XATTR = 0x00004000; //??
static const int NUM_OPEN_FLAGS;
static const unsigned TGT_MAP_ANONYMOUS = 0x100;
static const unsigned TGT_MAP_FIXED = 0x10;
};
#endif

View File

@ -0,0 +1,55 @@
/*
* 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_SPARC_SPARC_TRAITS_HH__
#define __ARCH_SPARC_SPARC_TRAITS_HH__
namespace SparcISA
{
// Max trap levels
const int MaxPTL = 2;
const int MaxTL = 6;
const int MaxGL = 3;
const int MaxPGL = 2;
// Number of register windows, can legally be 3 to 32
const int NWindows = 8;
// const int NumMicroIntRegs = 1;
const int NumMicroIntRegs = 9;
// const int NumRegularIntRegs = MaxGL * 8 + NWindows * 16;
// const int NumMicroIntRegs = 1;
// const int NumIntRegs = NumRegularIntRegs + NumMicroIntRegs;
const int NumFloatRegs = 64;
const int NumFloatArchRegs = NumFloatRegs;
// const int NumMiscRegs = 40;
}
#endif // __ARCH_SPARC_SPARC_TRAITS_HH__

View File

@ -0,0 +1,65 @@
/*
* 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_SPARC_STACKTRACE_HH__
#define __ARCH_SPARC_STACKTRACE_HH__
#include <vector>
#include "base/types.hh"
#include "cpu/static_inst.hh"
#include "debug/Stack.hh"
class ThreadContext;
namespace SparcISA
{
class StackTrace
{
private:
std::vector<Addr> stack;
public:
bool
trace(ThreadContext *tc, StaticInstPtr inst)
{
panic("StackTrace::trace not implemented for SPARC.\n");
return false;
}
const std::vector<Addr> &getstack() const { return stack; }
public:
void dprintf() {}
};
}
#endif // __ARCH_SPARC_STACKTRACE_HH__

View File

@ -0,0 +1,208 @@
/*
* Copyright (c) 2002-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
*/
#include "arch/sparc/system.hh"
#include "arch/vtophys.hh"
#include "base/loader/object_file.hh"
#include "base/loader/symtab.hh"
#include "base/trace.hh"
#include "mem/physical.hh"
#include "params/SparcSystem.hh"
#include "sim/byteswap.hh"
using namespace BigEndianGuest;
SparcSystem::SparcSystem(Params *p)
: System(p), sysTick(0)
{
resetSymtab = new SymbolTable;
hypervisorSymtab = new SymbolTable;
openbootSymtab = new SymbolTable;
nvramSymtab = new SymbolTable;
hypervisorDescSymtab = new SymbolTable;
partitionDescSymtab = new SymbolTable;
/**
* Load the boot code, and hypervisor into memory.
*/
// Read the reset binary
reset = createObjectFile(params()->reset_bin, true);
if (reset == NULL)
fatal("Could not load reset binary %s", params()->reset_bin);
// Read the openboot binary
openboot = createObjectFile(params()->openboot_bin, true);
if (openboot == NULL)
fatal("Could not load openboot bianry %s", params()->openboot_bin);
// Read the hypervisor binary
hypervisor = createObjectFile(params()->hypervisor_bin, true);
if (hypervisor == NULL)
fatal("Could not load hypervisor binary %s", params()->hypervisor_bin);
// Read the nvram image
nvram = createObjectFile(params()->nvram_bin, true);
if (nvram == NULL)
fatal("Could not load nvram image %s", params()->nvram_bin);
// Read the hypervisor description image
hypervisor_desc = createObjectFile(params()->hypervisor_desc_bin, true);
if (hypervisor_desc == NULL)
fatal("Could not load hypervisor description image %s",
params()->hypervisor_desc_bin);
// Read the partition description image
partition_desc = createObjectFile(params()->partition_desc_bin, true);
if (partition_desc == NULL)
fatal("Could not load partition description image %s",
params()->partition_desc_bin);
// load symbols
if (!reset->loadGlobalSymbols(resetSymtab))
panic("could not load reset symbols\n");
if (!openboot->loadGlobalSymbols(openbootSymtab))
panic("could not load openboot symbols\n");
if (!hypervisor->loadLocalSymbols(hypervisorSymtab))
panic("could not load hypervisor symbols\n");
if (!nvram->loadLocalSymbols(nvramSymtab))
panic("could not load nvram symbols\n");
if (!hypervisor_desc->loadLocalSymbols(hypervisorDescSymtab))
panic("could not load hypervisor description symbols\n");
if (!partition_desc->loadLocalSymbols(partitionDescSymtab))
panic("could not load partition description symbols\n");
// load symbols into debug table
if (!reset->loadGlobalSymbols(debugSymbolTable))
panic("could not load reset symbols\n");
if (!openboot->loadGlobalSymbols(debugSymbolTable))
panic("could not load openboot symbols\n");
if (!hypervisor->loadLocalSymbols(debugSymbolTable))
panic("could not load hypervisor symbols\n");
// Strip off the rom address so when the hypervisor is copied into memory we
// have symbols still
if (!hypervisor->loadLocalSymbols(debugSymbolTable, 0xFFFFFF))
panic("could not load hypervisor symbols\n");
if (!nvram->loadGlobalSymbols(debugSymbolTable))
panic("could not load reset symbols\n");
if (!hypervisor_desc->loadGlobalSymbols(debugSymbolTable))
panic("could not load hypervisor description symbols\n");
if (!partition_desc->loadLocalSymbols(debugSymbolTable))
panic("could not load partition description symbols\n");
}
void
SparcSystem::initState()
{
// Call the initialisation of the super class
System::initState();
// Load reset binary into memory
reset->setTextBase(params()->reset_addr);
reset->loadSections(physProxy);
// Load the openboot binary
openboot->setTextBase(params()->openboot_addr);
openboot->loadSections(physProxy);
// Load the hypervisor binary
hypervisor->setTextBase(params()->hypervisor_addr);
hypervisor->loadSections(physProxy);
// Load the nvram image
nvram->setTextBase(params()->nvram_addr);
nvram->loadSections(physProxy);
// Load the hypervisor description image
hypervisor_desc->setTextBase(params()->hypervisor_desc_addr);
hypervisor_desc->loadSections(physProxy);
// Load the partition description image
partition_desc->setTextBase(params()->partition_desc_addr);
partition_desc->loadSections(physProxy);
// @todo any fixup code over writing data in binaries on setting break
// events on functions should happen here.
}
SparcSystem::~SparcSystem()
{
delete resetSymtab;
delete hypervisorSymtab;
delete openbootSymtab;
delete nvramSymtab;
delete hypervisorDescSymtab;
delete partitionDescSymtab;
delete reset;
delete openboot;
delete hypervisor;
delete nvram;
delete hypervisor_desc;
delete partition_desc;
}
void
SparcSystem::serialize(std::ostream &os)
{
System::serialize(os);
resetSymtab->serialize("reset_symtab", os);
hypervisorSymtab->serialize("hypervisor_symtab", os);
openbootSymtab->serialize("openboot_symtab", os);
nvramSymtab->serialize("nvram_symtab", os);
hypervisorDescSymtab->serialize("hypervisor_desc_symtab", os);
partitionDescSymtab->serialize("partition_desc_symtab", os);
}
void
SparcSystem::unserialize(Checkpoint *cp, const std::string &section)
{
System::unserialize(cp,section);
resetSymtab->unserialize("reset_symtab", cp, section);
hypervisorSymtab->unserialize("hypervisor_symtab", cp, section);
openbootSymtab->unserialize("openboot_symtab", cp, section);
nvramSymtab->unserialize("nvram_symtab", cp, section);
hypervisorDescSymtab->unserialize("hypervisor_desc_symtab", cp, section);
partitionDescSymtab->unserialize("partition_desc_symtab", cp, section);
}
SparcSystem *
SparcSystemParams::create()
{
return new SparcSystem(this);
}

View File

@ -0,0 +1,135 @@
/*
* 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
*/
#ifndef __ARCH_SPARC_SYSTEM_HH__
#define __ARCH_SPARC_SYSTEM_HH__
#include <string>
#include <vector>
#include "base/loader/symtab.hh"
#include "cpu/pc_event.hh"
#include "kern/system_events.hh"
#include "params/SparcSystem.hh"
#include "sim/sim_object.hh"
#include "sim/system.hh"
class SparcSystem : public System
{
public:
typedef SparcSystemParams Params;
SparcSystem(Params *p);
~SparcSystem();
virtual void initState();
/**
* Serialization stuff
*/
public:
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string &section);
/** reset binary symbol table */
SymbolTable *resetSymtab;
/** hypervison binary symbol table */
SymbolTable *hypervisorSymtab;
/** openboot symbol table */
SymbolTable *openbootSymtab;
/** nvram symbol table? */
SymbolTable *nvramSymtab;
/** hypervisor desc symbol table? */
SymbolTable *hypervisorDescSymtab;
/** partition desc symbol table? */
SymbolTable *partitionDescSymtab;
/** Object pointer for the reset binary */
ObjectFile *reset;
/** Object pointer for the hypervisor code */
ObjectFile *hypervisor;
/** Object pointer for the openboot code */
ObjectFile *openboot;
/** Object pointer for the nvram image */
ObjectFile *nvram;
/** Object pointer for the hypervisor description image */
ObjectFile *hypervisor_desc;
/** Object pointer for the partition description image */
ObjectFile *partition_desc;
/** System Tick for syncronized tick across all cpus. */
Tick sysTick;
protected:
const Params *params() const { return (const Params *)_params; }
/** Add a function-based event to reset binary. */
template <class T>
T *
addResetFuncEvent(const char *lbl)
{
return addFuncEvent<T>(resetSymtab, lbl);
}
/** Add a function-based event to the hypervisor. */
template <class T>
T *
addHypervisorFuncEvent(const char *lbl)
{
return addFuncEvent<T>(hypervisorSymtab, lbl);
}
/** Add a function-based event to the openboot. */
template <class T>
T *
addOpenbootFuncEvent(const char *lbl)
{
return addFuncEvent<T>(openbootSymtab, lbl);
}
virtual Addr
fixFuncEventAddr(Addr addr)
{
//XXX This may eventually have to do something useful.
return addr;
}
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,196 @@
/*
* 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_SPARC_TLB_HH__
#define __ARCH_SPARC_TLB_HH__
#include "arch/sparc/asi.hh"
#include "arch/sparc/tlb_map.hh"
#include "base/misc.hh"
#include "mem/request.hh"
#include "params/SparcTLB.hh"
#include "sim/fault_fwd.hh"
#include "sim/tlb.hh"
class ThreadContext;
class Packet;
namespace SparcISA
{
class TLB : public BaseTLB
{
// These faults need to be able to populate the tlb in SE mode.
friend class FastInstructionAccessMMUMiss;
friend class FastDataAccessMMUMiss;
// TLB state
protected:
// Only used when this is the data TLB.
uint64_t sfar;
uint64_t c0_tsb_ps0;
uint64_t c0_tsb_ps1;
uint64_t c0_config;
uint64_t cx_tsb_ps0;
uint64_t cx_tsb_ps1;
uint64_t cx_config;
uint64_t sfsr;
uint64_t tag_access;
protected:
TlbMap lookupTable;;
typedef TlbMap::iterator MapIter;
TlbEntry *tlb;
int size;
int usedEntries;
int lastReplaced;
uint64_t cacheState;
bool cacheValid;
std::list<TlbEntry*> freeList;
enum FaultTypes {
OtherFault = 0,
PrivViolation = 0x1,
SideEffect = 0x2,
AtomicToIo = 0x4,
IllegalAsi = 0x8,
LoadFromNfo = 0x10,
VaOutOfRange = 0x20,
VaOutOfRangeJmp = 0x40
};
enum ContextType {
Primary = 0,
Secondary = 1,
Nucleus = 2
};
enum TsbPageSize {
Ps0,
Ps1
};
public:
/** lookup an entry in the TLB based on the partition id, and real bit if
* real is true or the partition id, and context id if real is false.
* @param va the virtual address not shifted (e.g. bottom 13 bits are 0)
* @param paritition_id partition this entry is for
* @param real is this a real->phys or virt->phys translation
* @param context_id if this is virt->phys what context
* @param update_used should ew update the used bits in the
* entries on not useful if we are trying to do a va->pa without
* mucking with any state for a debug read for example.
* @return A pointer to a tlb entry
*/
TlbEntry *lookup(Addr va, int partition_id, bool real, int context_id = 0,
bool update_used = true);
protected:
/** Insert a PTE into the TLB. */
void insert(Addr vpn, int partition_id, int context_id, bool real,
const PageTableEntry& PTE, int entry = -1);
/** Given an entry id, read that tlb entries' tag. */
uint64_t TagRead(int entry);
/** Remove all entries from the TLB */
void invalidateAll();
/** Remove all non-locked entries from the tlb that match partition id. */
void demapAll(int partition_id);
/** Remove all entries that match a given context/partition id. */
void demapContext(int partition_id, int context_id);
/** Remve all entries that match a certain partition id, (contextid), and
* va). */
void demapPage(Addr va, int partition_id, bool real, int context_id);
/** Checks if the virtual address provided is a valid one. */
bool validVirtualAddress(Addr va, bool am);
void writeSfsr(bool write, ContextType ct,
bool se, FaultTypes ft, int asi);
void clearUsedBits();
void writeTagAccess(Addr va, int context);
Fault translateInst(RequestPtr req, ThreadContext *tc);
Fault translateData(RequestPtr req, ThreadContext *tc, bool write);
public:
typedef SparcTLBParams Params;
TLB(const Params *p);
void
demapPage(Addr vaddr, uint64_t asn)
{
panic("demapPage(Addr) is not implemented.\n");
}
void dumpAll();
Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode);
void translateTiming(RequestPtr req, ThreadContext *tc,
Translation *translation, Mode mode);
/** Stub function for compilation support with CheckerCPU. SPARC ISA
* does not support the Checker model at the moment
*/
Fault translateFunctional(RequestPtr req, ThreadContext *tc, Mode mode);
Tick doMmuRegRead(ThreadContext *tc, Packet *pkt);
Tick doMmuRegWrite(ThreadContext *tc, Packet *pkt);
void GetTsbPtr(ThreadContext *tc, Addr addr, int ctx, Addr *ptrs);
// Checkpointing
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string &section);
/** Give an entry id, read that tlb entries' tte */
uint64_t TteRead(int entry);
private:
void writeSfsr(Addr a, bool write, ContextType ct,
bool se, FaultTypes ft, int asi);
uint64_t MakeTsbPtr(TsbPageSize ps, uint64_t tag_access, uint64_t c0_tsb,
uint64_t c0_config, uint64_t cX_tsb, uint64_t cX_config);
TlbEntry *cacheEntry[2];
ASI cacheAsi[2];
};
}
#endif // __ARCH_SPARC_TLB_HH__

View File

@ -0,0 +1,169 @@
/*
* 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_SPARC_TLB_MAP_HH__
#define __ARCH_SPARC_TLB_MAP_HH__
#include <map>
#include "arch/sparc/pagetable.hh"
namespace SparcISA
{
class TlbMap
{
private:
typedef std::map<TlbRange, TlbEntry*> RangeMap;
RangeMap tree;
public:
typedef RangeMap::iterator iterator;
iterator
find(const TlbRange &r)
{
iterator i;
i = tree.upper_bound(r);
if (i == tree.begin()) {
if (r.real == i->first.real &&
r.partitionId == i->first.partitionId &&
i->first.va < r.va + r.size &&
i->first.va+i->first.size >= r.va &&
(r.real || r.contextId == i->first.contextId))
return i;
else
// Nothing could match, so return end()
return tree.end();
}
i--;
if (r.real != i->first.real)
return tree.end();
if (!r.real && r.contextId != i->first.contextId)
return tree.end();
if (r.partitionId != i->first.partitionId)
return tree.end();
if (i->first.va <= r.va+r.size &&
i->first.va+i->first.size >= r.va)
return i;
return tree.end();
}
bool
intersect(const TlbRange &r)
{
iterator i;
i = find(r);
if (i != tree.end())
return true;
return false;
}
iterator
insert(TlbRange &r, TlbEntry *d)
{
if (intersect(r))
return tree.end();
return tree.insert(std::make_pair(r, d)).first;
}
size_t
erase(TlbRange k)
{
return tree.erase(k);
}
void
erase(iterator p)
{
tree.erase(p);
}
void
erase(iterator p, iterator q)
{
tree.erase(p,q);
}
void
clear()
{
tree.erase(tree.begin(), tree.end());
}
iterator
begin()
{
return tree.begin();
}
iterator
end()
{
return tree.end();
}
size_t
size()
{
return tree.size();
}
bool
empty()
{
return tree.empty();
}
void
print()
{
iterator i;
i = tree.begin();
while (i != tree.end()) {
std::cout << std::hex << i->first.va << " " << i->first.size << " " <<
i->first.contextId << " " << i->first.partitionId << " " <<
i->first.real << " " << i->second << std::endl;
i++;
}
}
};
};
#endif // __ARCH_SPARC_TLB_MAP_HH__

View File

@ -0,0 +1,50 @@
/*
* 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_SPARC_TYPES_HH__
#define __ARCH_SPARC_TYPES_HH__
#include "arch/generic/types.hh"
#include "base/bigint.hh"
#include "base/types.hh"
namespace SparcISA
{
typedef uint32_t MachInst;
typedef uint64_t ExtMachInst;
typedef GenericISA::DelaySlotUPCState<MachInst> PCState;
typedef Twin64_t LargestRead;
}
#endif

View File

@ -0,0 +1,375 @@
/*
* 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.
*/
#include "arch/sparc/isa.hh"
#include "arch/sparc/kernel_stats.hh"
#include "arch/sparc/registers.hh"
#include "base/bitfield.hh"
#include "base/trace.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
#include "debug/Quiesce.hh"
#include "debug/Timer.hh"
#include "sim/system.hh"
#include "sim/full_system.hh"
using namespace SparcISA;
using namespace std;
void
ISA::checkSoftInt(ThreadContext *tc)
{
BaseCPU *cpu = tc->getCpuPtr();
// If PIL < 14, copy over the tm and sm bits
if (pil < 14 && softint & 0x10000)
cpu->postInterrupt(IT_SOFT_INT, 16);
else
cpu->clearInterrupt(IT_SOFT_INT, 16);
if (pil < 14 && softint & 0x1)
cpu->postInterrupt(IT_SOFT_INT, 0);
else
cpu->clearInterrupt(IT_SOFT_INT, 0);
// Copy over any of the other bits that are set
for (int bit = 15; bit > 0; --bit) {
if (1 << bit & softint && bit > pil)
cpu->postInterrupt(IT_SOFT_INT, bit);
else
cpu->clearInterrupt(IT_SOFT_INT, bit);
}
}
// These functions map register indices to names
static inline string
getMiscRegName(RegIndex index)
{
static string miscRegName[NumMiscRegs] =
{/*"y", "ccr",*/ "asi", "tick", "fprs", "pcr", "pic",
"gsr", "softint_set", "softint_clr", "softint", "tick_cmpr",
"stick", "stick_cmpr",
"tpc", "tnpc", "tstate", "tt", "privtick", "tba", "pstate", "tl",
"pil", "cwp", /*"cansave", "canrestore", "cleanwin", "otherwin",
"wstate",*/ "gl",
"hpstate", "htstate", "hintp", "htba", "hver", "strand_sts_reg",
"hstick_cmpr",
"fsr", "prictx", "secctx", "partId", "lsuCtrlReg",
"scratch0", "scratch1", "scratch2", "scratch3", "scratch4",
"scratch5", "scratch6", "scratch7", "cpuMondoHead", "cpuMondoTail",
"devMondoHead", "devMondoTail", "resErrorHead", "resErrorTail",
"nresErrorHead", "nresErrorTail", "TlbData" };
return miscRegName[index];
}
void
ISA::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc)
{
BaseCPU *cpu = tc->getCpuPtr();
int64_t time;
switch (miscReg) {
/* Full system only ASRs */
case MISCREG_SOFTINT:
setMiscRegNoEffect(miscReg, val);;
checkSoftInt(tc);
break;
case MISCREG_SOFTINT_CLR:
return setMiscReg(MISCREG_SOFTINT, ~val & softint, tc);
case MISCREG_SOFTINT_SET:
return setMiscReg(MISCREG_SOFTINT, val | softint, tc);
case MISCREG_TICK_CMPR:
if (tickCompare == NULL)
tickCompare = new TickCompareEvent(this, tc);
setMiscRegNoEffect(miscReg, val);
if ((tick_cmpr & ~mask(63)) && tickCompare->scheduled())
cpu->deschedule(tickCompare);
time = (tick_cmpr & mask(63)) - (tick & mask(63));
if (!(tick_cmpr & ~mask(63)) && time > 0) {
if (tickCompare->scheduled())
cpu->deschedule(tickCompare);
cpu->schedule(tickCompare, curTick() + time * cpu->ticks(1));
}
panic("writing to TICK compare register %#X\n", val);
break;
case MISCREG_STICK_CMPR:
if (sTickCompare == NULL)
sTickCompare = new STickCompareEvent(this, tc);
setMiscRegNoEffect(miscReg, val);
if ((stick_cmpr & ~mask(63)) && sTickCompare->scheduled())
cpu->deschedule(sTickCompare);
time = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) -
cpu->instCount();
if (!(stick_cmpr & ~mask(63)) && time > 0) {
if (sTickCompare->scheduled())
cpu->deschedule(sTickCompare);
cpu->schedule(sTickCompare, curTick() + time * cpu->ticks(1));
}
DPRINTF(Timer, "writing to sTICK compare register value %#X\n", val);
break;
case MISCREG_PSTATE:
setMiscRegNoEffect(miscReg, val);
case MISCREG_PIL:
setMiscRegNoEffect(miscReg, val);
checkSoftInt(tc);
break;
case MISCREG_HVER:
panic("Shouldn't be writing HVER\n");
case MISCREG_HINTP:
setMiscRegNoEffect(miscReg, val);
if (hintp)
cpu->postInterrupt(IT_HINTP, 0);
else
cpu->clearInterrupt(IT_HINTP, 0);
break;
case MISCREG_HTBA:
// clear lower 7 bits on writes.
setMiscRegNoEffect(miscReg, val & ULL(~0x7FFF));
break;
case MISCREG_QUEUE_CPU_MONDO_HEAD:
case MISCREG_QUEUE_CPU_MONDO_TAIL:
setMiscRegNoEffect(miscReg, val);
if (cpu_mondo_head != cpu_mondo_tail)
cpu->postInterrupt(IT_CPU_MONDO, 0);
else
cpu->clearInterrupt(IT_CPU_MONDO, 0);
break;
case MISCREG_QUEUE_DEV_MONDO_HEAD:
case MISCREG_QUEUE_DEV_MONDO_TAIL:
setMiscRegNoEffect(miscReg, val);
if (dev_mondo_head != dev_mondo_tail)
cpu->postInterrupt(IT_DEV_MONDO, 0);
else
cpu->clearInterrupt(IT_DEV_MONDO, 0);
break;
case MISCREG_QUEUE_RES_ERROR_HEAD:
case MISCREG_QUEUE_RES_ERROR_TAIL:
setMiscRegNoEffect(miscReg, val);
if (res_error_head != res_error_tail)
cpu->postInterrupt(IT_RES_ERROR, 0);
else
cpu->clearInterrupt(IT_RES_ERROR, 0);
break;
case MISCREG_QUEUE_NRES_ERROR_HEAD:
case MISCREG_QUEUE_NRES_ERROR_TAIL:
setMiscRegNoEffect(miscReg, val);
// This one doesn't have an interrupt to report to the guest OS
break;
case MISCREG_HSTICK_CMPR:
if (hSTickCompare == NULL)
hSTickCompare = new HSTickCompareEvent(this, tc);
setMiscRegNoEffect(miscReg, val);
if ((hstick_cmpr & ~mask(63)) && hSTickCompare->scheduled())
cpu->deschedule(hSTickCompare);
time = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) -
cpu->instCount();
if (!(hstick_cmpr & ~mask(63)) && time > 0) {
if (hSTickCompare->scheduled())
cpu->deschedule(hSTickCompare);
cpu->schedule(hSTickCompare, curTick() + time * cpu->ticks(1));
}
DPRINTF(Timer, "writing to hsTICK compare register value %#X\n", val);
break;
case MISCREG_HPSTATE:
{
HPSTATE newVal = val;
newVal.id = 1;
// T1000 spec says impl. dependent val must always be 1
setMiscRegNoEffect(miscReg, newVal);
newVal = hpstate;
if (newVal.tlz && tl == 0 && !newVal.hpriv)
cpu->postInterrupt(IT_TRAP_LEVEL_ZERO, 0);
else
cpu->clearInterrupt(IT_TRAP_LEVEL_ZERO, 0);
break;
}
case MISCREG_HTSTATE:
setMiscRegNoEffect(miscReg, val);
break;
case MISCREG_STRAND_STS_REG:
if (bits(val,2,2))
panic("No support for setting spec_en bit\n");
setMiscRegNoEffect(miscReg, bits(val,0,0));
if (!bits(val,0,0)) {
DPRINTF(Quiesce, "Cpu executed quiescing instruction\n");
// Time to go to sleep
tc->suspend();
if (FullSystem && tc->getKernelStats())
tc->getKernelStats()->quiesce();
}
break;
default:
panic("Invalid write to FS misc register %s\n",
getMiscRegName(miscReg));
}
}
MiscReg
ISA::readFSReg(int miscReg, ThreadContext * tc)
{
uint64_t temp;
switch (miscReg) {
/* Privileged registers. */
case MISCREG_QUEUE_CPU_MONDO_HEAD:
case MISCREG_QUEUE_CPU_MONDO_TAIL:
case MISCREG_QUEUE_DEV_MONDO_HEAD:
case MISCREG_QUEUE_DEV_MONDO_TAIL:
case MISCREG_QUEUE_RES_ERROR_HEAD:
case MISCREG_QUEUE_RES_ERROR_TAIL:
case MISCREG_QUEUE_NRES_ERROR_HEAD:
case MISCREG_QUEUE_NRES_ERROR_TAIL:
case MISCREG_SOFTINT:
case MISCREG_TICK_CMPR:
case MISCREG_STICK_CMPR:
case MISCREG_PIL:
case MISCREG_HPSTATE:
case MISCREG_HINTP:
case MISCREG_HTSTATE:
case MISCREG_HSTICK_CMPR:
return readMiscRegNoEffect(miscReg) ;
case MISCREG_HTBA:
return readMiscRegNoEffect(miscReg) & ULL(~0x7FFF);
case MISCREG_HVER:
// XXX set to match Legion
return ULL(0x3e) << 48 |
ULL(0x23) << 32 |
ULL(0x20) << 24 |
// MaxGL << 16 | XXX For some reason legion doesn't set GL
MaxTL << 8 |
(NWindows -1) << 0;
case MISCREG_STRAND_STS_REG:
System *sys;
int x;
sys = tc->getSystemPtr();
temp = readMiscRegNoEffect(miscReg) & (STS::active | STS::speculative);
// Check that the CPU array is fully populated
// (by calling getNumCPus())
assert(sys->numContexts() > tc->contextId());
temp |= tc->contextId() << STS::shft_id;
for (x = tc->contextId() & ~3; x < sys->threadContexts.size(); x++) {
switch (sys->threadContexts[x]->status()) {
case ThreadContext::Active:
temp |= STS::st_run << (STS::shft_fsm0 -
((x & 0x3) * (STS::shft_fsm0-STS::shft_fsm1)));
break;
case ThreadContext::Suspended:
// should this be idle?
temp |= STS::st_idle << (STS::shft_fsm0 -
((x & 0x3) * (STS::shft_fsm0-STS::shft_fsm1)));
break;
case ThreadContext::Halted:
temp |= STS::st_halt << (STS::shft_fsm0 -
((x & 0x3) * (STS::shft_fsm0-STS::shft_fsm1)));
break;
default:
panic("What state are we in?!\n");
} // switch
} // for
return temp;
default:
panic("Invalid read to FS misc register\n");
}
}
void
ISA::processTickCompare(ThreadContext *tc)
{
panic("tick compare not implemented\n");
}
void
ISA::processSTickCompare(ThreadContext *tc)
{
BaseCPU *cpu = tc->getCpuPtr();
// since our microcode instructions take two cycles we need to check if
// we're actually at the correct cycle or we need to wait a little while
// more
int ticks;
ticks = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) -
cpu->instCount();
assert(ticks >= 0 && "stick compare missed interrupt cycle");
if (ticks == 0 || tc->status() == ThreadContext::Suspended) {
DPRINTF(Timer, "STick compare cycle reached at %#x\n",
(stick_cmpr & mask(63)));
if (!(tc->readMiscRegNoEffect(MISCREG_STICK_CMPR) & (ULL(1) << 63))) {
setMiscReg(MISCREG_SOFTINT, softint | (ULL(1) << 16), tc);
}
} else {
cpu->schedule(sTickCompare, curTick() + ticks * cpu->ticks(1));
}
}
void
ISA::processHSTickCompare(ThreadContext *tc)
{
BaseCPU *cpu = tc->getCpuPtr();
// since our microcode instructions take two cycles we need to check if
// we're actually at the correct cycle or we need to wait a little while
// more
int ticks;
if ( tc->status() == ThreadContext::Halted)
return;
ticks = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) -
cpu->instCount();
assert(ticks >= 0 && "hstick compare missed interrupt cycle");
if (ticks == 0 || tc->status() == ThreadContext::Suspended) {
DPRINTF(Timer, "HSTick compare cycle reached at %#x\n",
(stick_cmpr & mask(63)));
if (!(tc->readMiscRegNoEffect(MISCREG_HSTICK_CMPR) & (ULL(1) << 63))) {
setMiscReg(MISCREG_HINTP, 1, tc);
}
// Need to do something to cause interrupt to happen here !!! @todo
} else {
cpu->schedule(hSTickCompare, curTick() + ticks * cpu->ticks(1));
}
}

View File

@ -0,0 +1,261 @@
/*
* 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
* Ali Saidi
*/
#include "arch/sparc/faults.hh"
#include "arch/sparc/utility.hh"
#include "arch/sparc/vtophys.hh"
#include "mem/fs_translating_port_proxy.hh"
namespace SparcISA {
// The caller uses %o0-%05 for the first 6 arguments even if their floating
// point. Double precision floating point values take two registers/args.
// Quads, structs, and unions are passed as pointers. All arguments beyond
// the sixth are passed on the stack past the 16 word window save area,
// space for the struct/union return pointer, and space reserved for the
// first 6 arguments which the caller may use but doesn't have to.
uint64_t
getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
{
if (!FullSystem) {
panic("getArgument() only implemented for full system\n");
M5_DUMMY_RETURN
}
const int NumArgumentRegs = 6;
if (number < NumArgumentRegs) {
return tc->readIntReg(8 + number);
} else {
Addr sp = tc->readIntReg(StackPointerReg);
FSTranslatingPortProxy &vp = tc->getVirtProxy();
uint64_t arg = vp.read<uint64_t>(sp + 92 +
(number-NumArgumentRegs) * sizeof(uint64_t));
return arg;
}
}
void
copyMiscRegs(ThreadContext *src, ThreadContext *dest)
{
uint8_t tl = src->readMiscRegNoEffect(MISCREG_TL);
// Read all the trap level dependent registers and save them off
for (int i = 1; i <= MaxTL; i++) {
src->setMiscRegNoEffect(MISCREG_TL, i);
dest->setMiscRegNoEffect(MISCREG_TL, i);
dest->setMiscRegNoEffect(MISCREG_TT,
src->readMiscRegNoEffect(MISCREG_TT));
dest->setMiscRegNoEffect(MISCREG_TPC,
src->readMiscRegNoEffect(MISCREG_TPC));
dest->setMiscRegNoEffect(MISCREG_TNPC,
src->readMiscRegNoEffect(MISCREG_TNPC));
dest->setMiscRegNoEffect(MISCREG_TSTATE,
src->readMiscRegNoEffect(MISCREG_TSTATE));
}
// Save off the traplevel
dest->setMiscRegNoEffect(MISCREG_TL, tl);
src->setMiscRegNoEffect(MISCREG_TL, tl);
// ASRs
// dest->setMiscRegNoEffect(MISCREG_Y,
// src->readMiscRegNoEffect(MISCREG_Y));
// dest->setMiscRegNoEffect(MISCREG_CCR,
// src->readMiscRegNoEffect(MISCREG_CCR));
dest->setMiscRegNoEffect(MISCREG_ASI,
src->readMiscRegNoEffect(MISCREG_ASI));
dest->setMiscRegNoEffect(MISCREG_TICK,
src->readMiscRegNoEffect(MISCREG_TICK));
dest->setMiscRegNoEffect(MISCREG_FPRS,
src->readMiscRegNoEffect(MISCREG_FPRS));
dest->setMiscRegNoEffect(MISCREG_SOFTINT,
src->readMiscRegNoEffect(MISCREG_SOFTINT));
dest->setMiscRegNoEffect(MISCREG_TICK_CMPR,
src->readMiscRegNoEffect(MISCREG_TICK_CMPR));
dest->setMiscRegNoEffect(MISCREG_STICK,
src->readMiscRegNoEffect(MISCREG_STICK));
dest->setMiscRegNoEffect(MISCREG_STICK_CMPR,
src->readMiscRegNoEffect(MISCREG_STICK_CMPR));
// Priv Registers
dest->setMiscRegNoEffect(MISCREG_TICK,
src->readMiscRegNoEffect(MISCREG_TICK));
dest->setMiscRegNoEffect(MISCREG_TBA,
src->readMiscRegNoEffect(MISCREG_TBA));
dest->setMiscRegNoEffect(MISCREG_PSTATE,
src->readMiscRegNoEffect(MISCREG_PSTATE));
dest->setMiscRegNoEffect(MISCREG_PIL,
src->readMiscRegNoEffect(MISCREG_PIL));
dest->setMiscReg(MISCREG_CWP,
src->readMiscRegNoEffect(MISCREG_CWP));
// dest->setMiscRegNoEffect(MISCREG_CANSAVE,
// src->readMiscRegNoEffect(MISCREG_CANSAVE));
// dest->setMiscRegNoEffect(MISCREG_CANRESTORE,
// src->readMiscRegNoEffect(MISCREG_CANRESTORE));
// dest->setMiscRegNoEffect(MISCREG_OTHERWIN,
// src->readMiscRegNoEffect(MISCREG_OTHERWIN));
// dest->setMiscRegNoEffect(MISCREG_CLEANWIN,
// src->readMiscRegNoEffect(MISCREG_CLEANWIN));
// dest->setMiscRegNoEffect(MISCREG_WSTATE,
// src->readMiscRegNoEffect(MISCREG_WSTATE));
dest->setMiscReg(MISCREG_GL, src->readMiscRegNoEffect(MISCREG_GL));
// Hyperprivilged registers
dest->setMiscRegNoEffect(MISCREG_HPSTATE,
src->readMiscRegNoEffect(MISCREG_HPSTATE));
dest->setMiscRegNoEffect(MISCREG_HINTP,
src->readMiscRegNoEffect(MISCREG_HINTP));
dest->setMiscRegNoEffect(MISCREG_HTBA,
src->readMiscRegNoEffect(MISCREG_HTBA));
dest->setMiscRegNoEffect(MISCREG_STRAND_STS_REG,
src->readMiscRegNoEffect(MISCREG_STRAND_STS_REG));
dest->setMiscRegNoEffect(MISCREG_HSTICK_CMPR,
src->readMiscRegNoEffect(MISCREG_HSTICK_CMPR));
// FSR
dest->setMiscRegNoEffect(MISCREG_FSR,
src->readMiscRegNoEffect(MISCREG_FSR));
// Strand Status Register
dest->setMiscRegNoEffect(MISCREG_STRAND_STS_REG,
src->readMiscRegNoEffect(MISCREG_STRAND_STS_REG));
// MMU Registers
dest->setMiscRegNoEffect(MISCREG_MMU_P_CONTEXT,
src->readMiscRegNoEffect(MISCREG_MMU_P_CONTEXT));
dest->setMiscRegNoEffect(MISCREG_MMU_S_CONTEXT,
src->readMiscRegNoEffect(MISCREG_MMU_S_CONTEXT));
dest->setMiscRegNoEffect(MISCREG_MMU_PART_ID,
src->readMiscRegNoEffect(MISCREG_MMU_PART_ID));
dest->setMiscRegNoEffect(MISCREG_MMU_LSU_CTRL,
src->readMiscRegNoEffect(MISCREG_MMU_LSU_CTRL));
// Scratchpad Registers
dest->setMiscRegNoEffect(MISCREG_SCRATCHPAD_R0,
src->readMiscRegNoEffect(MISCREG_SCRATCHPAD_R0));
dest->setMiscRegNoEffect(MISCREG_SCRATCHPAD_R1,
src->readMiscRegNoEffect(MISCREG_SCRATCHPAD_R1));
dest->setMiscRegNoEffect(MISCREG_SCRATCHPAD_R2,
src->readMiscRegNoEffect(MISCREG_SCRATCHPAD_R2));
dest->setMiscRegNoEffect(MISCREG_SCRATCHPAD_R3,
src->readMiscRegNoEffect(MISCREG_SCRATCHPAD_R3));
dest->setMiscRegNoEffect(MISCREG_SCRATCHPAD_R4,
src->readMiscRegNoEffect(MISCREG_SCRATCHPAD_R4));
dest->setMiscRegNoEffect(MISCREG_SCRATCHPAD_R5,
src->readMiscRegNoEffect(MISCREG_SCRATCHPAD_R5));
dest->setMiscRegNoEffect(MISCREG_SCRATCHPAD_R6,
src->readMiscRegNoEffect(MISCREG_SCRATCHPAD_R6));
dest->setMiscRegNoEffect(MISCREG_SCRATCHPAD_R7,
src->readMiscRegNoEffect(MISCREG_SCRATCHPAD_R7));
// Queue Registers
dest->setMiscRegNoEffect(MISCREG_QUEUE_CPU_MONDO_HEAD,
src->readMiscRegNoEffect(MISCREG_QUEUE_CPU_MONDO_HEAD));
dest->setMiscRegNoEffect(MISCREG_QUEUE_CPU_MONDO_TAIL,
src->readMiscRegNoEffect(MISCREG_QUEUE_CPU_MONDO_TAIL));
dest->setMiscRegNoEffect(MISCREG_QUEUE_DEV_MONDO_HEAD,
src->readMiscRegNoEffect(MISCREG_QUEUE_DEV_MONDO_HEAD));
dest->setMiscRegNoEffect(MISCREG_QUEUE_DEV_MONDO_TAIL,
src->readMiscRegNoEffect(MISCREG_QUEUE_DEV_MONDO_TAIL));
dest->setMiscRegNoEffect(MISCREG_QUEUE_RES_ERROR_HEAD,
src->readMiscRegNoEffect(MISCREG_QUEUE_RES_ERROR_HEAD));
dest->setMiscRegNoEffect(MISCREG_QUEUE_RES_ERROR_TAIL,
src->readMiscRegNoEffect(MISCREG_QUEUE_RES_ERROR_TAIL));
dest->setMiscRegNoEffect(MISCREG_QUEUE_NRES_ERROR_HEAD,
src->readMiscRegNoEffect(MISCREG_QUEUE_NRES_ERROR_HEAD));
dest->setMiscRegNoEffect(MISCREG_QUEUE_NRES_ERROR_TAIL,
src->readMiscRegNoEffect(MISCREG_QUEUE_NRES_ERROR_TAIL));
}
void
copyRegs(ThreadContext *src, ThreadContext *dest)
{
// First loop through the integer registers.
int old_gl = src->readMiscRegNoEffect(MISCREG_GL);
int old_cwp = src->readMiscRegNoEffect(MISCREG_CWP);
// Globals
for (int x = 0; x < MaxGL; ++x) {
src->setMiscReg(MISCREG_GL, x);
dest->setMiscReg(MISCREG_GL, x);
// Skip %g0 which is always zero.
for (int y = 1; y < 8; y++)
dest->setIntReg(y, src->readIntReg(y));
}
// Locals and ins. Outs are all also ins.
for (int x = 0; x < NWindows; ++x) {
src->setMiscReg(MISCREG_CWP, x);
dest->setMiscReg(MISCREG_CWP, x);
for (int y = 16; y < 32; y++)
dest->setIntReg(y, src->readIntReg(y));
}
// Microcode reg and pseudo int regs (misc regs in the integer regfile).
for (int y = NumIntArchRegs; y < NumIntArchRegs + NumMicroIntRegs; ++y)
dest->setIntReg(y, src->readIntReg(y));
// Restore src's GL, CWP
src->setMiscReg(MISCREG_GL, old_gl);
src->setMiscReg(MISCREG_CWP, old_cwp);
// Then loop through the floating point registers.
for (int i = 0; i < SparcISA::NumFloatArchRegs; ++i) {
dest->setFloatRegBits(i, src->readFloatRegBits(i));
}
// Copy misc. registers
copyMiscRegs(src, dest);
// Lastly copy PC/NPC
dest->pcState(src->pcState());
}
void
skipFunction(ThreadContext *tc)
{
TheISA::PCState newPC = tc->pcState();
newPC.set(tc->readIntReg(ReturnAddressReg));
tc->pcState(newPC);
}
void
initCPU(ThreadContext *tc, int cpuId)
{
static Fault por = new PowerOnReset();
if (cpuId == 0)
por->invoke(tc);
}
} // namespace SPARC_ISA

View File

@ -0,0 +1,103 @@
/*
* 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_SPARC_UTILITY_HH__
#define __ARCH_SPARC_UTILITY_HH__
#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/registers.hh"
#include "arch/sparc/tlb.hh"
#include "base/bitfield.hh"
#include "base/misc.hh"
#include "cpu/static_inst.hh"
#include "cpu/thread_context.hh"
#include "sim/fault_fwd.hh"
#include "sim/full_system.hh"
namespace SparcISA
{
inline PCState
buildRetPC(const PCState &curPC, const PCState &callPC)
{
PCState ret = callPC;
ret.uEnd();
ret.pc(curPC.npc());
return ret;
}
uint64_t getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp);
static inline bool
inUserMode(ThreadContext *tc)
{
PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
return !(pstate.priv || hpstate.hpriv);
}
/**
* Function to insure ISA semantics about 0 registers.
* @param tc The thread context.
*/
template <class TC>
void zeroRegisters(TC *tc);
void initCPU(ThreadContext *tc, int cpuId);
inline void
startupCPU(ThreadContext *tc, int cpuId)
{
// Other CPUs will get activated by IPIs
if (cpuId == 0 || !FullSystem)
tc->activate(0);
}
void copyRegs(ThreadContext *src, ThreadContext *dest);
void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
void skipFunction(ThreadContext *tc);
inline void
advancePC(PCState &pc, const StaticInstPtr inst)
{
inst->advancePC(pc);
}
inline uint64_t
getExecutingAsid(ThreadContext *tc)
{
return tc->readMiscRegNoEffect(MISCREG_MMU_P_CONTEXT);
}
} // namespace SparcISA
#endif

View File

@ -0,0 +1,133 @@
/*
* 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
*/
#include <string>
#include "arch/sparc/tlb.hh"
#include "arch/sparc/vtophys.hh"
#include "base/chunk_generator.hh"
#include "base/compiler.hh"
#include "base/trace.hh"
#include "cpu/thread_context.hh"
#include "debug/VtoPhys.hh"
#include "mem/port_proxy.hh"
using namespace std;
namespace SparcISA {
Addr
vtophys(Addr vaddr)
{
// In SPARC it's almost always impossible to turn a VA->PA w/o a
// context The only times we can kinda do it are if we have a
// SegKPM mapping and can find the real address in the tlb or we
// have a physical adddress already (beacuse we are looking at the
// hypervisor) Either case is rare, so we'll just panic.
panic("vtophys() without context on SPARC largly worthless\n");
M5_DUMMY_RETURN;
}
Addr
vtophys(ThreadContext *tc, Addr addr)
{
// Here we have many options and are really implementing something like
// a fill handler to find the address since there isn't a multilevel
// table for us to walk around.
//
// 1. We are currently hyperpriv, return the address unmodified
// 2. The mmu is off return(ra->pa)
// 3. We are currently priv, use ctx0* tsbs to find the page
// 4. We are not priv, use ctxN0* tsbs to find the page
// For all accesses we check the tlbs first since it's possible that
// long standing pages (e.g. locked kernel mappings) won't be in the tsb
uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA);
bool hpriv = bits(tlbdata,0,0);
// bool priv = bits(tlbdata,2,2);
bool addr_mask = bits(tlbdata,3,3);
bool data_real = !bits(tlbdata,5,5);
bool inst_real = !bits(tlbdata,4,4);
bool ctx_zero = bits(tlbdata,18,16) > 0;
int part_id = bits(tlbdata,15,8);
int pri_context = bits(tlbdata,47,32);
// int sec_context = bits(tlbdata,63,48);
PortProxy &mem = tc->getPhysProxy();
TLB* itb = tc->getITBPtr();
TLB* dtb = tc->getDTBPtr();
TlbEntry* tbe;
PageTableEntry pte;
Addr tsbs[4];
Addr va_tag;
TteTag ttetag;
if (hpriv)
return addr;
if (addr_mask)
addr = addr & VAddrAMask;
tbe = dtb->lookup(addr, part_id, data_real, ctx_zero ? 0 : pri_context ,
false);
if (tbe)
goto foundtbe;
tbe = itb->lookup(addr, part_id, inst_real, ctx_zero ? 0 : pri_context,
false);
if (tbe)
goto foundtbe;
// We didn't find it in the tlbs, so lets look at the TSBs
dtb->GetTsbPtr(tc, addr, ctx_zero ? 0 : pri_context, tsbs);
va_tag = bits(addr, 63, 22);
for (int x = 0; x < 4; x++) {
ttetag = betoh(mem.read<uint64_t>(tsbs[x]));
if (ttetag.valid() && ttetag.va() == va_tag) {
uint64_t entry = mem.read<uint64_t>(tsbs[x]) + sizeof(uint64_t);
// I think it's sun4v at least!
pte.populate(betoh(entry), PageTableEntry::sun4v);
DPRINTF(VtoPhys, "Virtual(%#x)->Physical(%#x) found in TTE\n",
addr, pte.translate(addr));
goto foundpte;
}
}
panic("couldn't translate %#x\n", addr);
foundtbe:
pte = tbe->pte;
DPRINTF(VtoPhys, "Virtual(%#x)->Physical(%#x) found in TLB\n", addr,
pte.translate(addr));
foundpte:
return pte.translate(addr);
}
} // namespace SparcISA

View File

@ -0,0 +1,47 @@
/*
* 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_SPARC_VTOPHYS_H__
#define __ARCH_SPARC_VTOPHYS_H__
#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/pagetable.hh"
class ThreadContext;
namespace SparcISA {
Addr vtophys(Addr vaddr);
Addr vtophys(ThreadContext *tc, Addr vaddr);
};
#endif // __ARCH_SPARC_VTOPHYS_H__