// ========== 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 // have any questions. // // ========== Copyright Header End ============================================ #include #include "niu_int_dev.vrh" #include "niu_int_mgr.vrh" #include "niu_ldgintr_utils.vrh" extern CNiuIntrMgr NiuIntrMgr; class CNiuIntrTest { // variables integer timer = 10; // Test can change this integer random_intr_timer = 0; integer sys_err_mask_prog=0; integer dev68grp=0; integer dev68grpbound=0; bit[68:0] virt_on = 69'h0; bit[4:0] sidTab[]; local bit[4:0] sids[32]; 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) ) { integer i; for(i=0;i<64;i++) group_already_bound[i] = 0; if(rx_v ==-1) { virt_on[31:0] = random(); } else virt_on[31:0] = rx_v; if(tx_v ==-1) { virt_on[63:32] = random(); } else virt_on[63:32] = tx_v; printf(" CNiuIntrTest::new Virtualization Vector - %x \n",virt_on); compute_random_sids(); 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) { integer i; CNiuLdgEx ldgEx[64]; for(i=0;i<64;i++) { if(groups[i]) { ldgEx[i] = new(i); NiuIntrMgr.ldg[i] = ldgEx[i]; } } } task CNiuIntrTest::compute_random_virt_grp_no(){ bit[5:0] rand_rx_gids[]; bit[5:0] rand_tx_gids[]; integer func_binding_type = 0; bit [3:0] rand_max_15; integer i; bit[5:0] r; 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; fixed_function_no = 1; } if(get_plus_arg( CHECK, "RANDOM_INTR_TIMER")) { random_intr_timer = 1; } else random_intr_timer = 0; for(i=0;i<32;i++){ r = random(); if(assoc_index(CHECK,rand_rx_gids,r)) { // recompute i--; } else { rand_rx_gids[r] = 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); } } for(i=0;i<32;i++){ r = random(); if(assoc_index(CHECK,rand_tx_gids,r)) { // recompute i--; } else { rand_tx_gids[r] = 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(){ bit[4:0] rand_sids[]; integer i; bit[4:0] r; for(i=0;i<32;i++){ r = random(); if(assoc_index(CHECK,rand_sids,r)) { // recompute i--; } else { rand_sids[r] = r; sids[i] = r; } } } function bit[6:0] CNiuIntrTest::getSid(integer group,integer func){ bit[1:0] f; bit[4:0] g; f= func ; g = group ; getSid = {f,sids[g]}; } function integer CNiuIntrTest::getLdgNo(integer func){ integer min, max; min = 0 +16*func; max = 15 +16*func; getLdgNo = random() %16 +min; } function integer CNiuIntrTest::getFuncNo(integer g) { if(g<=15) getFuncNo = 0; 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; integer group_bound; if(dev==null) { device_to_remove = device_id; } else { device_to_remove = dev.dev_id; } group_bound = dev_to_grp_bind[device_to_remove]; if(group_bound ==-1) { printf("CNiuIntrTest::RemoveDevice:ERROR Device ID - %d Not bound to any group \n",device_to_remove); return; } 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) ){ integer func; integer group; bit[6:0] sid; integer grp_num; integer rx_or_tx; integer id; integer skip_virt; // 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 // .... // .... id = dev.dev_id; // compute dma id from device_id if(dev.dev_id<32) { rx_or_tx = 1; // 0 - Tx 1 - Rx id = dev.dev_id; skip_virt = 0; } else if(dev.dev_id<63) { rx_or_tx = 0; // 0 - Tx 1 - Rx id = dev.dev_id - 32; skip_virt = 0; } else { // This device is either MAC or one of the error device // cannot do virtualization on these skip_virt = 1; } if(fixed_function_no) { if(rx_or_tx) { grp_num = virt_rx_dma_binds[id]; } else { grp_num = virt_tx_dma_binds[id]; } group_info = grp_num; printf("FIXED FUNCTION NO!! Group - %d \n",group_info); skip_virt = 1; } if(virt_on[dev.dev_id] && (skip_virt==0) ) { if(rx_or_tx) { grp_num = virt_rx_dma_binds[id]; } else { 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 group_info = dev68grp; } if(group_info ==-1) { // pick up a random group for this device group = random()%64; func = getFuncNo(group); } else { group = group_info; func = getFuncNo(group_info); } if(group_already_bound[group]!=0) { printf(" Group - %d Already has members - Not programming SID for this group\n",group); } else { // bind this group group_already_bound[group]++; if(sid_from_test==-1) 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 if(random_intr_timer) NiuIntrMgr.ldg[group].SetIntrMgm(1/*Arm*/,timer + random()%timer /*Timer*/); // Set up Arm bit else 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.pioSetMasks(mask); dev_to_grp_bind [dev.dev_id] = group; NiuIntrMgr.ldg[group].ldgbind(dev); if(dev.dev_id==68) { dev68grp = group; if(sys_err_mask_prog==0) { NiuIntrMgr.ldg[group].SetErrMask(0);// programs all 0s for now... sys_err_mask_prog = 1; } } if(virt_on[dev.dev_id] && (skip_virt==0) ) { NiuIntrMgr.ldg[group].dis_pio_virt = 0; } }