// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: niu_intr_setup.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 ============================================
#include <vera_defines.vrh>
#include "niu_int_dev.vrh"
#include "niu_int_mgr.vrh"
#include "niu_ldgintr_utils.vrh"
extern CNiuIntrMgr NiuIntrMgr;
integer timer = 10; // Test can change this
integer random_intr_timer = 0;
integer sys_err_mask_prog=0;
bit[68:0] virt_on = 69'h0;
integer fixed_function_no = 0;
local bit[5:0] virt_rx_dma_binds[32];
local bit[5:0] virt_tx_dma_binds[32];
local integer dev_to_grp_bind[69];
local integer group_already_bound[64];
task InitDevice ( CNiuIntrDev dev, integer group_info, (integer mask = 0),(integer sid_from_test=-1) );
task RemoveDevice (integer device_id, (CNiuIntrDev dev=null) );
local function integer getFuncNo(integer g);
local task compute_random_sids();
local task compute_random_virt_grp_no();
local function bit [6:0] getSid(integer group,integer func);
local function integer getLdgNo(integer func);
task new( (integer tx_v = -1), (integer rx_v = -1) );
task use_alt_ldg(bit[63:0] groups);
task CNiuIntrTest::new( (integer tx_v = -1), (integer rx_v = -1) ) {
for(i=0;i<64;i++) group_already_bound[i] = 0;
virt_on[31:0] = random();
} else virt_on[31:0] = rx_v;
virt_on[63:32] = random();
} else virt_on[63:32] = tx_v;
printf(" CNiuIntrTest::new Virtualization Vector - %x \n",virt_on);
compute_random_virt_grp_no();
for(i=0;i<68;i++) dev_to_grp_bind[i] = -1;
task CNiuIntrTest::use_alt_ldg(bit[63:0] groups) {
NiuIntrMgr.ldg[i] = ldgEx[i];
task CNiuIntrTest::compute_random_virt_grp_no(){
integer func_binding_type = 0;
if(get_plus_arg( CHECK, "RXTX_PIO_STRESS_BINDING=")) {
func_binding_type = get_plus_arg( NUM, "RXTX_PIO_STRESS_BINDING=");
func_binding_type = func_binding_type % 4;
if(get_plus_arg( CHECK, "RANDOM_INTR_TIMER")) {
} else random_intr_timer = 0;
if(assoc_index(CHECK,rand_rx_gids,r)) {
virt_rx_dma_binds[i] = r;
// Over write for stress testMatrix requirements
if(get_plus_arg( CHECK, "RXTX_PIO_STRESS_BINDING=")) {
// rand_max_15 = random();
virt_rx_dma_binds[i] = getLdgNo(func_binding_type);
printf(" virt_rx_dma_binds - %d i = %d\n",virt_rx_dma_binds[i],i);
if(assoc_index(CHECK,rand_tx_gids,r)) {
virt_tx_dma_binds[i] = r;
// Over write for stress testMatrix requirements
if(get_plus_arg( CHECK, "RXTX_PIO_STRESS_BINDING=")) {
// rand_max_15 = random();
virt_tx_dma_binds[i] = getLdgNo(func_binding_type);
printf(" virt_tx_dma_binds - %d i = %d\n",virt_tx_dma_binds[i],i);
task CNiuIntrTest::compute_random_sids(){
if(assoc_index(CHECK,rand_sids,r)) {
function bit[6:0] CNiuIntrTest::getSid(integer group,integer func){
function integer CNiuIntrTest::getLdgNo(integer func){
getLdgNo = random() %16 +min;
function integer CNiuIntrTest::getFuncNo(integer g) {
else if(g<=31) getFuncNo = 1;
else if(g<=47) getFuncNo = 2;
else if(g<=63) getFuncNo = 3;
else { printf("CNiuIntrTest::getFuncNo TESTBENCH ERROR Incorrect Group Specified !!\n");}
task CNiuIntrTest::RemoveDevice (integer device_id, (CNiuIntrDev dev=null) ){
// if device class is specified that takes precedence
// else take the device_id
integer device_to_remove;
device_to_remove = device_id;
device_to_remove = dev.dev_id;
group_bound = dev_to_grp_bind[device_to_remove];
printf("CNiuIntrTest::RemoveDevice:ERROR Device ID - %d Not bound to any group \n",device_to_remove);
NiuIntrMgr.ldg[group_bound].ldgunbind(device_to_remove);
group_already_bound[group_bound]--;
if(group_already_bound[group_bound]==0) {
// remove SID also from the table
NiuIntrMgr.invalidateSidTab(group_bound);
task CNiuIntrTest::InitDevice ( CNiuIntrDev dev, integer group_info, (integer mask = 0),(integer sid_from_test=-1) ){
// group determines the function to which this is going to be bound
// if virtualization is enabled this is determined by the dma-virtual bind
// if virtualization is not defined, this get determined by the ldg
// compute dma id from device_id
rx_or_tx = 1; // 0 - Tx 1 - Rx
} else if(dev.dev_id<63) {
rx_or_tx = 0; // 0 - Tx 1 - Rx
// This device is either MAC or one of the error device
// cannot do virtualization on these
grp_num = virt_rx_dma_binds[id];
grp_num = virt_tx_dma_binds[id];
printf("FIXED FUNCTION NO!! Group - %d \n",group_info);
if(virt_on[dev.dev_id] && (skip_virt==0) ) {
grp_num = virt_rx_dma_binds[id];
grp_num = virt_tx_dma_binds[id];
func = getFuncNo(grp_num);
dev.bind_to_group(grp_num);
group_info = getLdgNo(func);
if((dev.dev_id==68) && (dev68grpbound)) {
// override the group_info
// pick up a random group for this device
func = getFuncNo(group_info);
if(group_already_bound[group]!=0) {
printf(" Group - %d Already has members - Not programming SID for this group\n",group);
group_already_bound[group]++;
sid = getSid(group,func);
else sid = sid_from_test;
printf("CNiuIntrTest::InitDevice - SID - %x Group - %d Func - %d \n",sid,group,func);
NiuIntrMgr.updateSidTab(group,sid);
// Arm the initial interrupt
NiuIntrMgr.ldg[group].SetIntrMgm(1/*Arm*/,timer + random()%timer /*Timer*/); // Set up Arm bit
NiuIntrMgr.ldg[group].SetIntrMgm(1/*Arm*/,timer/*Timer*/); // Set up Arm bit
// Set up rearm flag - Need to be under test control
NiuIntrMgr.ldg[group].rearm = 1;
dev_to_grp_bind [dev.dev_id] = group;
NiuIntrMgr.ldg[group].ldgbind(dev);
if(sys_err_mask_prog==0) {
NiuIntrMgr.ldg[group].SetErrMask(0);// programs all 0s for now...
if(virt_on[dev.dev_id] && (skip_virt==0) ) {
NiuIntrMgr.ldg[group].dis_pio_virt = 0;