// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: N2ExceptionPEUCtx.vr
// Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
// 4150 Network Circle, Santa Clara, California 95054, U.S.A.
// * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; version 2 of the License.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// For the avoidance of doubt, and except that if any non-GPL license
// choice is available it will apply instead, Sun elects to use only
// the General Public License version 2 (GPLv2) at this time for any
// software where a choice of GPL license versions is made
// available with the language indicating that GPLv2 or any later version
// may be used, or where a choice of which version of the GPL is applied is
// otherwise unspecified.
// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
// CA 95054 USA or visit www.sun.com if you need additional information or
// ========== Copyright Header End ============================================
class ExceptionPEUCtx extends PEUCtxBase
local integer f_errQueue;
static bit[4:0] f_badType = PEC_PCI__TYPE_MEM;
static PEC_ERRtype f_lpuErr = e_ERR_none;
static integer f_count = 0;
static bit [1:0] f_injectType = 0;
task new( string a_name, PEUTestEnv a_env, string a_mode )
task SetOffset( integer a_offs )
protected function CTStrategyBase ProvideStrategy()
ErrChkPEUStr errChk; // The guy who checks error state
EdbErrPEUStr edbErr; // Generate an EDB parity error
EhbErrPEUStr ehbErr; // Generate an EHB parity error
IhbErrPEUStr ihbErr; // Generate an IHB parity error
LinkErrPEUStr linkErr; // Pull down the "link up" signal
LpuErrPEUStr lpuErr; // Present an LPU-detected error
TimeOutPEUStr timeOut; // Let a non-posted PIO request time out
ReplayPEUStr replay; // Cause a replay to take place by a nak or timeout
InErrPEUStr ingressErr; // Provide bad parity for an ingress TLP
EgrParErrStr egrParErr; // Egress Injected Parity Errors
IngParErrStr ingParErr; // Ingress Injected Parity Errors
// If the "StratStop" (within the base
// context class) has been set, then
// just return a base context which
ProvideStrategy = nullStr;
// The first strategy? Build a
// mailbox and fire up the guy
// who'll check interrupt status
// The test uses "NumStrat" to tell us
// how many errors to generate.
// Every error-generating strategy will
// add something to the "f_errQueue".
f_errQueue = alloc( MAILBOX, 0, 1 );
errChk = new( f_env, f_errQueue, this.NumStrat-1 );
// The "errChk" strategy will enable
// interrupt checking when it's done.
if ( f_expectInterrupt ) f_env.disableInterrupt();
ProvideStrategy = errChk;
// The directed "EDB parity" test
// injects a parity error for some
// request type (or completion).
else if ( f_mode == "EDB" )
edbErr.SetErrQueue( f_errQueue );
edbErr.SetType( f_badType );
ProvideStrategy = edbErr;
// The directed "EHB parity" test
// injects a parity error for some
// request type (or completion).
else if ( f_mode == "EHB" )
ehbErr.SetErrQueue( f_errQueue );
ehbErr.SetType( f_badType );
ProvideStrategy = ehbErr;
// The directed "IHB parity" test
// injects a parity error for some
// request type (or completion).
else if ( f_mode == "IHB" )
ihbErr.SetErrQueue( f_errQueue );
ihbErr.SetType( f_badType );
ProvideStrategy = ihbErr;
// injects a parity error
// on a egress PIO packet
else if ( f_mode == "EgrPar" )
egrParErr = new( f_env );
egrParErr.SetErrQueue( f_errQueue );
egrParErr.SetInjectType( f_injectType );
ProvideStrategy = egrParErr;
// injects a parity error
else if ( f_mode == "IngPar" )
ingParErr = new( f_env );
ingParErr.SetErrQueue( f_errQueue );
ingParErr.SetInjectType( f_injectType );
ProvideStrategy = ingParErr;
// The directed "link down" test
// just pulls down the "link up" signal.
else if ( f_mode == "Link" )
linkErr.SetErrQueue( f_errQueue );
ProvideStrategy = linkErr;
// A LPU-detected error? Find the next
else if ( f_mode == "LPU" )
lpuErr.SetErrQueue( f_errQueue );
while( lpuErr.SetError(f_lpuErr) ) f_lpuErr++;
ProvideStrategy = lpuErr;
// An ingress parity error?
// A "header" error is one which appears
// in the first 4DWs of the TLP.
else if ( f_mode == "ITP data" )
ingressErr = new( f_env );
ingressErr.SetErrQueue( f_errQueue );
ingressErr.SetOffset( f_offset + 16 );
ingressErr.SetOffset( f_offset );
ingressErr.SetOffset( f_count + 16 );
ProvideStrategy = ingressErr;
else if ( f_mode == "ITP hdr" )
ingressErr = new( f_env );
ingressErr.SetErrQueue( f_errQueue );
ingressErr.SetOffset( (f_count % 16) + 1);
ProvideStrategy = ingressErr;
// A PIO request times out?
else if ( f_mode == "Time-out" )
timeOut.SetErrQueue( f_errQueue );
ProvideStrategy = timeOut;
// A replay caused by a timeout
else if ( f_mode == "Replay-Timeout" )
replay.SetErrQueue( f_errQueue );
replay.SetType( "timeout" );
ProvideStrategy = replay;
// A replay count rollover caused by a timeout
else if ( f_mode == "Replay-Timeout-Rollover" )
replay.SetErrQueue( f_errQueue );
replay.SetType( "timeout" );
replay.SetNmbrReplays( 4 );
ProvideStrategy = replay;
// A replay count rollover caused by NAKs
else if ( f_mode == "Replay-Nak-Rollover" )
replay.SetErrQueue( f_errQueue );
replay.SetNmbrReplays( 4 );
ProvideStrategy = replay;
// A random drain-state test?
// Then just supply any nasty exception.
else if ( f_mode == "Drain" )
if ( get_plus_arg( CHECK, "vera_random_seed=" ) )
seed = get_plus_arg( NUM, "vera_random_seed=" );
if ( seed >= 1 && seed <= 4 )
printf( "Exception: An EHB parity error... DW-%0d\n", seed-1 );
ehbErr.SetErrQueue( f_errQueue );
if ( f_env.nonpostedWriteStalled() )
ehbErr.SetType( PEC_PCI__TYPE_CPL );
ehbErr.SetMask( 1 << (seed-1) );
ProvideStrategy = ehbErr;
else if ( seed >= 5 && seed <= 8 )
printf( "Exception: An IHB parity error... DW-%0d\n", seed-5 );
ihbErr.SetErrQueue( f_errQueue );
ihbErr.SetMask( 1 << (seed-5) );
ProvideStrategy = ihbErr;
else if ( seed >= 9 && seed <= 15 )
printf( "Exception: An EDB parity error... DW-%0d\n", seed-9 );
edbErr.SetErrQueue( f_errQueue );
if ( f_env.nonpostedWriteStalled() )
edbErr.SetType( PEC_PCI__TYPE_CPL );
edbErr.SetMask( 1 << (seed-9) );
if ( seed <= 12 ) edbErr.SetBndy( 0 );
ProvideStrategy = edbErr;
printf( "Exception: An EDB parity error... only DW\n" );
edbErr.SetErrQueue( f_errQueue );
if ( f_env.nonpostedWriteStalled() )
edbErr.SetType( PEC_PCI__TYPE_CPL );
edbErr.SetMask( 4'b1111 );
ProvideStrategy = edbErr;
1: { /* ITP header parity */
printf( "Exception: An ITP (header) parity error\n" );
ingressErr = new( f_env );
ingressErr.SetErrQueue( f_errQueue );
ingressErr.SetOffset( urandom() % 16 + 1 );
ProvideStrategy = ingressErr;
printf( "Exception: The link drops\n" );
linkErr.SetErrQueue( f_errQueue );
ProvideStrategy = linkErr;
printf( "Exception: An IHB parity error\n" );
ihbErr.SetErrQueue( f_errQueue );
ProvideStrategy = ihbErr;
printf( "Exception: An EDB parity error\n" );
edbErr.SetErrQueue( f_errQueue );
if ( f_env.nonpostedWriteStalled() )
edbErr.SetType( PEC_PCI__TYPE_CPL );
ProvideStrategy = edbErr;
printf( "Exception: An EHB parity error\n" );
ehbErr.SetErrQueue( f_errQueue );
if ( f_env.nonpostedWriteStalled() )
ehbErr.SetType( PEC_PCI__TYPE_CPL );
ProvideStrategy = ehbErr;
// None of the above? A null strategy
ProvideStrategy = nullStr;
} /* end ProvideStrategy */
protected function CTStrategyBase FinalizeParms( CTStrategyBase a_strategy )
FinalizeParms = a_strategy;
} /* end FinalizeParms */
} /* end ExceptionPEUCtx */