/* -*- c++ -*- * File : vci_io_bridge.h * Copyright (c) UPMC, Lip6, SoC * Date : 16/04/2012 * Authors: Cassio Fraga, Alain Greiner * * SOCLIB_LGPL_HEADER_BEGIN * * This file is part of SoCLib, GNU LGPLv2.1. * * SoCLib is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; version 2.1 of the License. * * SoCLib 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with SoCLib; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA * * SOCLIB_LGPL_HEADER_END */ ///////////////////////////////////////////////////////////////////////////////// // This TSAR component is a bridge to access external peripherals // connected to an external I/O bus (such as Hypertransport or PCIe). // It connects three VCI networks: // // - INT network : to receive both configuration requests from processors // or software driven data access to peripherals. // - RAM network : to send DMA transactions initiated by peripherals // directly to the RAM (or L3 caches). // - IOX network : to receive DMA transactions from peripherals, or to send // configuration or data transactions to peripherals. // // Regarding DMA transactions initiated by external peripherals, it provides // an - optional - IOMMU service : the 32 bits virtual address is translated // to a (up to) 40 bits physical address by a standard SoCLib generic TLB. // In case of TLB MISS, the DMA transaction is stalled until the TLB is updated. // In case of page fault (illegal access), a VCI error is returned to the // faulty peripheral. ///////////////////////////////////////////////////////////////////////////////// // General Constraints: // // - All VCI fields have the same widths on the RAM and IOX networks, // and the VCI DATA field is 64 bits. // - Only the VCI DATA field differ between INT and IOX/RAM networks, // as the VCI DATA field is 32 bits. // - The common VCI ADDRESS width cannot be larger than 64 bits. // - All VCI transactions must be included in a single cache line. // - Page Tables must have the format required by the SoCLib generic_tlb. // - IO's segments must be the same in INT and IOX networks // - Write operations on IOMMU configuration registers (PTPR, ACTIVE) are // delayed until DMA_TLB FSM is IDLE. It should, preferably, be done before // starting any transfers. Pseudo register INVAL may be modified any time. //////////////////////////////////////////////////////////////////////////////// ///////TODO List/////////////////////////////////////////////////////////////// // - Ne pas garder tous les champs WRITE CMD dans les FIFO a chaque flit // (seulement 'data' et 'be') // - Traiter complêtement les codes d'erreur en réponse à une transaction // WTI write /////////////////////////////////////////////////////////////////////////////// #ifndef SOCLIB_CABA_VCI_IO_BRIDGE_H #define SOCLIB_CABA_VCI_IO_BRIDGE_H #include #include #include "caba_base_module.h" #include "generic_fifo.h" #include "generic_tlb.h" #include "mapping_table.h" #include "address_decoding_table.h" #include "static_assert.h" #include "vci_initiator.h" #include "vci_target.h" #include "../../../include/soclib/io_bridge.h" namespace soclib { namespace caba { using namespace soclib::common; /////////////////////////////////////////////////////////////////////////////////// template class VciIoBridge /////////////////////////////////////////////////////////////////////////////////// : public soclib::caba::BaseModule { // Data and be fields have different widths on INT and EXT networks typedef typename vci_param_ext::data_t ext_data_t; typedef typename vci_param_int::data_t int_data_t; typedef typename vci_param_ext::be_t ext_be_t; typedef typename vci_param_int::be_t ext_in_t; // Other fields must be equal typedef typename vci_param_int::fast_addr_t vci_addr_t; typedef typename vci_param_int::srcid_t vci_srcid_t; typedef typename vci_param_int::trdid_t vci_trdid_t; typedef typename vci_param_int::pktid_t vci_pktid_t; typedef typename vci_param_int::plen_t vci_plen_t; typedef typename vci_param_int::cmd_t vci_cmd_t; typedef typename vci_param_int::contig_t vci_contig_t; typedef typename vci_param_int::eop_t vci_eop_t; typedef typename vci_param_int::const_t vci_cons_t; typedef typename vci_param_int::wrap_t vci_wrap_t; typedef typename vci_param_int::clen_t vci_clen_t; typedef typename vci_param_int::cfixed_t vci_cfixed_t; typedef typename vci_param_int::rerror_t vci_rerror_t; enum { CACHE_LINE_MASK = 0xFFFFFFFFC0LL, PPN1_MASK = 0x0007FFFF, PPN2_MASK = 0x0FFFFFFF, K_PAGE_OFFSET_MASK = 0x00000FFF, M_PAGE_OFFSET_MASK = 0x001FFFFF, PTE2_LINE_OFFSET = 0x00007000, // bits 12,13,14. PTE1_LINE_OFFSET = 0x01E00000, // bits 21,22,23,24 }; // States for DMA_CMD FSM (from IOX to RAM) enum dma_cmd_fsm_state { DMA_CMD_IDLE, DMA_CMD_FIFO_PUT_CMD, DMA_CMD_FIFO_PUT_RSP, DMA_CMD_MISS_WAIT, DMA_CMD_WAIT_EOP, }; // States for DMA_RSP FSM (from RAM to IOX) enum dma_rsp_fsm_state { DMA_RSP_IDLE, DMA_RSP_FIFO_PUT, }; // States for TLB_MISS FSM enum dma_tlb_fsm_state { TLB_IDLE, TLB_MISS, TLB_PTE1_GET, TLB_PTE1_SELECT, TLB_PTE1_UPDT, TLB_PTE2_GET, TLB_PTE2_SELECT, TLB_PTE2_UPDT, TLB_WAIT, TLB_RETURN, TLB_INVAL_CHECK, }; // States for CONFIG_CMD FSM (from INT to IOX) enum config_cmd_fsm_state { CONFIG_CMD_IDLE, CONFIG_CMD_NEXT, CONFIG_CMD_PUT, CONFIG_CMD_RSP, }; // states for CONFIG_RSP FSM (from IOX to INT) enum config_rsp_fsm_state { CONFIG_RSP_IDLE, CONFIG_RSP_PUT_LO, CONFIG_RSP_PUT_HI, CONFIG_RSP_PUT_UNC, }; // States for MISS_WTI_CMD FSM (to INT network) enum miss_wti_cmd_state { MISS_WTI_CMD_IDLE, MISS_WTI_CMD_WTI, MISS_WTI_CMD_MISS, }; // States for MISS_WTI_RSP FSM (from INT network) enum miss_wti_rsp_state { MISS_WTI_RSP_IDLE, MISS_WTI_RSP_WTI, MISS_WTI_RSP_MISS, }; // PKTID values for TLB MISS and WTI transactions enum pktid_values_e { PKTID_READ = 0x0, // TSAR code for read data uncached PKTID_WRITE = 0x4, // TSAR code for write }; // Miss types for iotlb enum tlb_miss_type_e { PTE1_MISS, PTE2_MISS, }; public: sc_in p_clk; sc_in p_resetn; sc_in* p_irq[32]; // not always constructed soclib::caba::VciInitiator p_vci_ini_ram; soclib::caba::VciTarget p_vci_tgt_iox; soclib::caba::VciInitiator p_vci_ini_iox; soclib::caba::VciTarget p_vci_tgt_int; soclib::caba::VciInitiator p_vci_ini_int; private: const size_t m_words; const bool m_has_irqs; // INT & IOX Networks std::list m_int_seglist; const vci_srcid_t m_int_srcid; // local SRCID on INT network std::list m_iox_seglist; // TLB parameters const size_t m_iotlb_ways; const size_t m_iotlb_sets; // debug variables uint32_t m_debug_start_cycle; bool m_debug_ok; bool m_debug_activated; /////////////////////////////// // MEMORY MAPPED REGISTERS /////////////////////////////// sc_signal r_iommu_ptpr; // page table pointer register sc_signal r_iommu_active; // iotlb mode sc_signal r_iommu_bvar; // iommu bad virtual address sc_signal r_iommu_etr; // iommu error type sc_signal r_iommu_bad_id; // SRCID of faulty peripheral sc_signal r_iommu_wti_enable; // enable WTI transactions sc_signal r_iommu_wti_paddr; // address of IOMMU WTI sc_signal* r_iommu_peri_wti; // array[32] WTI for peripherals /////////////////////////////////// // DMA_CMD FSM REGISTERS /////////////////////////////////// sc_signal r_dma_cmd_fsm; sc_signal r_dma_cmd_vaddr; // input virtual address sc_signal r_dma_cmd_paddr; // output physical address /////////////////////////////////// // DMA_RSP FSM REGISTERS /////////////////////////////////// sc_signal r_dma_rsp_fsm; /////////////////////////////////// // CONFIG_CMD FSM REGISTERS /////////////////////////////////// sc_signal r_config_cmd_fsm; sc_signal r_config_cmd_rdata; sc_signal r_config_cmd_error; sc_signal r_config_cmd_inval_vaddr; sc_signal r_config_cmd_wdata; sc_signal r_config_cmd_be; sc_signal r_config_cmd_cmd; sc_signal r_config_cmd_address; sc_signal r_config_cmd_srcid; sc_signal r_config_cmd_pktid; sc_signal r_config_cmd_trdid; sc_signal r_config_cmd_plen; sc_signal r_config_cmd_clen; sc_signal r_config_cmd_cons; sc_signal r_config_cmd_contig; sc_signal r_config_cmd_cfixed; sc_signal r_config_cmd_wrap; sc_signal r_config_cmd_eop; /////////////////////////////////// // CONFIG_RSP FSM REGISTERS /////////////////////////////////// sc_signal r_config_rsp_fsm; /////////////////////////////////// // TLB FSM REGISTERS /////////////////////////////////// sc_signal r_tlb_fsm; // state register sc_signal r_waiting_transaction; // Flag for returning from sc_signal r_tlb_miss_type; sc_signal r_tlb_miss_error; sc_signal r_tlb_paddr; // physical address of pte sc_signal r_tlb_pte_flags; // pte1 or first word of pte2 sc_signal r_tlb_pte_ppn; // second word of pte2 sc_signal r_tlb_way; // selected way in tlb sc_signal r_tlb_set; // selected set in tlb uint32_t* r_tlb_buf_data; // prefetch buffer for PTEs sc_signal r_tlb_buf_valid; // one valit flag for all PTEs sc_signal r_tlb_buf_tag; // cache line number sc_signal r_tlb_buf_vaddr; // virtual address first PTE sc_signal r_tlb_buf_big_page; // ??? /////////////////////////////////// // MISS_WTI_CMD FSM REGISTERS /////////////////////////////////// sc_signal r_miss_wti_cmd_fsm; sc_signal r_miss_wti_cmd_index; /////////////////////////////////// // MISS_WTI_RSP FSM REGISTERS /////////////////////////////////// sc_signal r_miss_wti_rsp_fsm; sc_signal r_miss_wti_rsp_error; sc_signal r_miss_wti_rsp_count; ///////////////////////////////////////////////////// // ALLOCATORS for CONFIG_RSP fifo & DMA_RSP fifo ///////////////////////////////////////////////////// sc_signal r_alloc_fifo_config_rsp_local; sc_signal r_alloc_fifo_dma_rsp_local; ////////////////////////////////// // IRQ FSM registers ////////////////////////////////// sc_signal* r_irq_pending; // array[32] sc_signal* r_irq_request; // array[32] ////////////////////////////////////////////////////////////////// // IOTLB ////////////////////////////////////////////////////////////////// GenericTlb r_iotlb; ////////////////////////////////////////////////////////////////// // Inter-FSM communications ////////////////////////////////////////////////////////////////// // between DMA_CMD and TLB FSM sc_signal r_dma_tlb_req; // between CONFIG_CMD FSM and TLB FSM sc_signal r_config_tlb_req; // between TLB FSM and MISS_WTI FSM sc_signal r_tlb_miss_req; ///////////////////////// // FIFOs ///////////////////////// // ouput FIFO to VCI INI port on RAM network (VCI command) GenericFifo m_dma_cmd_addr_fifo; GenericFifo m_dma_cmd_srcid_fifo; GenericFifo m_dma_cmd_trdid_fifo; GenericFifo m_dma_cmd_pktid_fifo; GenericFifo m_dma_cmd_be_fifo; GenericFifo m_dma_cmd_cmd_fifo; GenericFifo m_dma_cmd_contig_fifo; GenericFifo m_dma_cmd_data_fifo; GenericFifo m_dma_cmd_eop_fifo; GenericFifo m_dma_cmd_cons_fifo; GenericFifo m_dma_cmd_plen_fifo; GenericFifo m_dma_cmd_wrap_fifo; GenericFifo m_dma_cmd_cfixed_fifo; GenericFifo m_dma_cmd_clen_fifo; // output FIFO to VCI TGT port on IOX network (VCI response) GenericFifo m_dma_rsp_data_fifo; GenericFifo m_dma_rsp_rsrcid_fifo; GenericFifo m_dma_rsp_rtrdid_fifo; GenericFifo m_dma_rsp_rpktid_fifo; GenericFifo m_dma_rsp_reop_fifo; GenericFifo m_dma_rsp_rerror_fifo; // output FIFO to VCI INI port on IOX network (VCI command) GenericFifo m_config_cmd_addr_fifo; GenericFifo m_config_cmd_srcid_fifo; GenericFifo m_config_cmd_trdid_fifo; GenericFifo m_config_cmd_pktid_fifo; GenericFifo m_config_cmd_be_fifo; GenericFifo m_config_cmd_cmd_fifo; GenericFifo m_config_cmd_contig_fifo; GenericFifo m_config_cmd_data_fifo; GenericFifo m_config_cmd_eop_fifo; GenericFifo m_config_cmd_cons_fifo; GenericFifo m_config_cmd_plen_fifo; GenericFifo m_config_cmd_wrap_fifo; GenericFifo m_config_cmd_cfixed_fifo; GenericFifo m_config_cmd_clen_fifo; // output FIFO to VCI TGT port on INT network (VCI response) GenericFifo m_config_rsp_data_fifo; GenericFifo m_config_rsp_rsrcid_fifo; GenericFifo m_config_rsp_rtrdid_fifo; GenericFifo m_config_rsp_rpktid_fifo; GenericFifo m_config_rsp_reop_fifo; GenericFifo m_config_rsp_rerror_fifo; //////////////////////////////// // Activity counters //////////////////////////////// uint32_t m_cpt_total_cycles; // total number of cycles // TLB activity counters uint32_t m_cpt_iotlb_read; // number of iotlb read uint32_t m_cpt_iotlb_miss; // number of iotlb miss uint32_t m_cost_iotlb_miss; // number of wait cycles (not treatment itself) uint32_t m_cpt_iotlbmiss_transaction; // number of tlb miss transactions uint32_t m_cost_iotlbmiss_transaction; // cumulated duration tlb miss transactions //Transaction Tabs (TRTs) activity counters uint32_t m_cpt_trt_dma_full; // DMA TRT full when a new command arrives uint32_t m_cpt_trt_dma_full_cost; // total number of cycles blocked uint32_t m_cpt_trt_config_full; // Config TRT full when a new command arrives uint32_t m_cpt_trt_config_full_cost; // total number of cycles blocked // FSM activity counters // unused on print_stats uint32_t m_cpt_fsm_dma_cmd [32]; uint32_t m_cpt_fsm_dma_rsp [32]; uint32_t m_cpt_fsm_tlb [32]; uint32_t m_cpt_fsm_config_cmd [32]; uint32_t m_cpt_fsm_config_rsp [32]; uint32_t m_cpt_fsm_miss_wti_cmd [32]; uint32_t m_cpt_fsm_miss_wti_rsp [32]; protected: SC_HAS_PROCESS(VciIoBridge); public: VciIoBridge( sc_module_name insname, const soclib::common::MappingTable &mt_ext, // external network const soclib::common::MappingTable &mt_int, // internal network const soclib::common::MappingTable &mt_iox, // iox network const soclib::common::IntTab &int_tgtid, // INT network TGTID const soclib::common::IntTab &int_srcid, // INT network SRCID const soclib::common::IntTab &iox_tgtid, // IOX network TGTID const bool has_irqs, // component has irq ports const size_t dcache_words, const size_t iotlb_ways, const size_t iotlb_sets, const uint32_t debug_start_cycle, const bool debug_ok ); ~VciIoBridge(); void print_stats(); void clear_stats(); void print_trace(size_t mode = 0); private: void transition(); void genMoore(); }; }} #endif /* SOCLIB_CABA_VCI_CC_VCACHE_WRAPPER_V4_H */ // Local Variables: // tab-width: 4 // c-basic-offset: 4 // c-file-offsets:((innamespace . 0)(inline-open . 0)) // indent-tabs-mode: nil // End: // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4