// ========== Copyright Header Begin ========================================== // // OpenSPARC T2 Processor File: niu_int_mgr.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_ldg.vrh" #include "niu_int_qmgr.vrh" #include "niu_int_sidmgr.vrh" #include "pio_driver.vrh" #ifdef NEPTUNE #include "Pcie_defines.vri" #include "Pcie_intr_util.vrh" #else #endif extern niu_gen_pio gen_pio_drv; #define DEASSERT_SEEN 100 #ifdef NEPTUNE extern Pcie_intr_util pcie_intr_util; #else #endif extern CNiuIntrQMgr NiuIntrQ; class CNiuIntrMgr { CSidShadowTab SidTab; CNiuLdg ldg[64]; bit [63:0] active_ldg; // Neptune Specific // event intx_sync[4]; integer INTX_BUG_FIX=0; integer intx_sync[4]; bit[63:0] ldg_func_map[4]; local integer deasset_mbox[4]; integer masks_before_isrs=0; task new(); task initLdg(bit [63:0] active_list); task SetTmrRes(bit[63:0] wdata); local task spGetIntMsg(); local task parseIntx(bit[3:0] assert_msg, bit[3:0] deassert_msg,CniuGenIntrMsg IntrMsg) ; local task procIntDevId(CniuGenIntrMsg IntrMsg) ; local task procIntMsi(CniuGenIntrMsg IntrMsg) ; local task procIntx(integer func,CniuGenIntrMsg IntrMsg) ; local task spawnprocIntx(integer func,CniuGenIntrMsg IntrMsg) ; function integer getFuncionNo(bit[3:0] msg); task bindLdgFunc(bit [63:0] list,integer func); task updateSidTab(integer gid, bit[6:0] sid); task invalidateSidTab(integer gid ); function integer get_DevIsr_Cnt(integer group_bind_no, integer dev_id) ; task CheckPendingFlags(); function integer CheckDevPendingFlag(integer device_no) ; } // Set up Tasks task CNiuIntrMgr::SetTmrRes(bit[63:0] wdata) { bit[63:0] address; address = LDGITMRES; gen_pio_drv.pio_wr(address,wdata); } task CNiuIntrMgr::new() { integer i; active_ldg = 0; SidTab = new(); for(i=0;i<4;i++) { // trigger(ON,intx_sync[i]); intx_sync[i] = alloc(SEMAPHORE,0,1,0); semaphore_put(intx_sync[i],1); ldg_func_map[i] = 0; deasset_mbox[i] = alloc(MAILBOX,0,1); } fork { spGetIntMsg(); } join none if(get_plus_arg(CHECK,"MASK_BEFORE_ISR")) { masks_before_isrs = 1; } if(get_plus_arg(CHECK,"INTX_BUG_FIX")) { INTX_BUG_FIX = 1; } } // SID Setup Tasks // LDG Setup Tasks task CNiuIntrMgr::initLdg(bit [63:0] active_list) { integer i; #ifdef NEPTUNE pcie_intr_util.setup_neptune_interrupts(); #else #endif for(i=0;i<64;i++) { if(active_list[i]) { ldg[i] = new(i); active_ldg[i] = 1; } } // bindLdgFunc(active_list,0); // TMP } task CNiuIntrMgr::invalidateSidTab(integer gid ){ SidTab.RemoveSidTab(gid); } task CNiuIntrMgr::updateSidTab(integer gid, bit[6:0] sid){ integer func; func = sid[6:5]; ldg_func_map[func] =ldg_func_map[func] | ( 1<>1; } if(( no_of_bits_valid > 5) ) { printf("ERROR CNiuIntrMgr::procIntMsi Incorrect value for IntrMsg.no_of_intr_alloc!! FIX THIS!! - %d\n",IntrMsg.no_of_intr_alloc); } no_of_intr_alloc = IntrMsg.no_of_intr_alloc; if(no_of_intr_alloc==0) { no_of_bits_valid = 0; } mask = 0; no_of_bits_masked = 5 - no_of_bits_valid ; no_of_possible_intr = 1<