Changeset 434 for trunk/modules/vci_io_bridge/caba/source/src
- Timestamp:
- Jul 12, 2013, 12:16:30 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/modules/vci_io_bridge/caba/source/src/vci_io_bridge.cpp
r405 r434 1 /* i*- c++ -*-C1 /* -*- c++ -*- 2 2 * File : vci_io_bridge.cpp 3 3 * Copyright (c) UPMC, Lip6, SoC 4 * Authors: Cassio Fraga, Alain Greiner 4 5 * 5 6 * SOCLIB_LGPL_HEADER_BEGIN … … 29 30 #include "../include/vci_io_bridge.h" 30 31 32 31 33 ////// debug services /////////////////////////////////////////////////////// 32 34 // All debug messages are conditionned by two variables: 33 35 // - compile time : DEBUG_*** : defined below 34 36 // - execution time : m_debug_*** : defined by constructor arguments 35 // m_debug_ *= (m_debug_ok) and (m_cpt_cycle > m_debug_start_cycle)37 // m_debug_activated = (m_debug_ok) and (m_cpt_cycle > m_debug_start_cycle) 36 38 ///////////////////////////////////////////////////////////////////////////////// 37 39 38 40 #define DEBUG_DMA_CMD 1 39 41 #define DEBUG_DMA_RSP 1 40 #define DEBUG_ DMA_TLB142 #define DEBUG_TLB_MISS 1 41 43 #define DEBUG_CONFIG_CMD 1 42 44 #define DEBUG_CONFIG_RSP 1 43 #define DEBUG_MISS_INIT 1 44 45 #define NEW_XRAM_VCI 0 46 47 #define IOMMU_ID 4097 45 #define DEBUG_MISS_WTI 1 48 46 49 47 namespace soclib { … … 52 50 namespace { 53 51 54 //DMA55 const char *dma_cmd_fsm_state_str[] ={52 const char *dma_cmd_fsm_state_str[] = 53 { 56 54 "DMA_CMD_IDLE", 57 "DMA_CMD_TRT_LOCK", 58 "DMA_CMD_TRT_WAIT", 59 "DMA_CMD_TRT_SET", 60 "DMA_CMD_FIFO_PUT", 61 "DMA_CMD_FIFO_MISS_PUT", 62 "DMA_CMD_TLB_MISS_WAIT", 63 "DMA_CMD_TLB_MISS_STORE", 64 "DMA_CMD_ERROR", 55 "DMA_CMD_FIFO_PUT_CMD", 56 "DMA_CMD_FIFO_PUT_RSP", 57 "DMA_CMD_MISS_WAIT", 58 "DMA_CMD_WAIT_EOP", 65 59 }; 66 60 67 const char *dma_rsp_fsm_state_str[] = { 61 const char *dma_rsp_fsm_state_str[] = 62 { 68 63 "DMA_RSP_IDLE", 69 "DMA_RSP_TRT_LOCK",70 64 "DMA_RSP_FIFO_PUT", 71 "DMA_RSP_FIFO_ERROR_PUT",72 };73 74 const char *alloc_trt_dma_fsm_state_str[] = {75 "ALLOC_TRT_DMA_CMD",76 "ALLOC_TRT_DMA_RSP",77 65 }; 78 66 79 const char * dma_tlb_fsm_state_str[] = {80 "DMA_TLB_IDLE",81 " DMA_TLB_MISS",82 " DMA_TLB_PTE1_GET",83 " DMA_TLB_PTE1_SELECT",84 " DMA_TLB_PTE1_UPDT",85 " DMA_TLB_PTE2_GET",86 " DMA_TLB_PTE2_SELECT",87 " DMA_TLB_PTE2_UPDT",88 " DMA_TLB_WAIT_TRANSACTION",89 " DMA_TLB_RETURN",90 " DMA_TLB_INVAL_CHECK",91 " DMA_TLB_INVAL_SCAN",67 const char *tlb_fsm_state_str[] = 68 { 69 "TLB_IDLE", 70 "TLB_MISS", 71 "TLB_PTE1_GET", 72 "TLB_PTE1_SELECT", 73 "TLB_PTE1_UPDT", 74 "TLB_PTE2_GET", 75 "TLB_PTE2_SELECT", 76 "TLB_PTE2_UPDT", 77 "TLB_WAIT", 78 "TLB_RETURN", 79 "TLB_INVAL_CHECK", 92 80 }; 93 81 94 //CONFIG95 const char *config_cmd_fsm_state_str[] ={82 const char *config_cmd_fsm_state_str[] = 83 { 96 84 "CONFIG_CMD_IDLE", 97 "CONFIG_CMD_TRT_LOCK", 98 "CONFIG_CMD_TRT_WAIT", 99 "CONFIG_CMD_TRT_SET", 100 "CONFIG_CMD_FIFO_PUT", 101 102 // IOB private configuration segment 103 "CONFIG_CMD_PTPR_WRITE", 104 "CONFIG_CMD_PTPR_READ", 105 "CONFIG_CMD_ACTIVE_WRITE", 106 "CONFIG_CMD_ACTIVE_READ", 107 "CONFIG_CMD_BVAR_READ", 108 "CONFIG_CMD_ETR_READ", 109 "CONFIG_CMD_BAD_ID_READ", 110 "CONFIG_CMD_INVAL_REQ", 111 "CONFIG_CMD_INVAL", 112 "CONFIG_CMD_IT_ADDR_IOMMU_WRITE_1", 113 "CONFIG_CMD_IT_ADDR_IOMMU_WRITE_2", 114 "CONFIG_CMD_IT_ADDR_IOMMU_READ_1", 115 "CONFIG_CMD_IT_ADDR_IOMMU_READ_2", 116 "CONFIG_CMD_IT_ADDR_WRITE_1", 117 "CONFIG_CMD_IT_ADDR_WRITE_2", 118 "CONFIG_CMD_IT_ADDR_READ_1", 119 "CONFIG_CMD_IT_ADDR_READ_2", 120 "CONFIG_CMD_ERROR_WAIT", 121 "CONFIG_CMD_ERROR_RSP", 85 "CONFIG_CMD_FIFO_PUT_CMD", 86 "CONFIG_CMD_FIFO_PUT_RSP", 122 87 }; 123 88 124 const char *config_rsp_fsm_state_str[] = { 89 const char *config_rsp_fsm_state_str[] = 90 { 125 91 "CONFIG_RSP_IDLE", 126 "CONFIG_RSP_TRT_LOCK",127 92 "CONFIG_RSP_FIFO_PUT", 128 93 }; 129 94 130 const char *alloc_trt_config_fsm_state_str[] = { 131 "ALLOC_TRT_CONFIG_CMD", 132 "ALLOC_TRT_CONFIG_RSP", 133 }; 134 135 //MISS TRANSACTIONS (to Direct Network) 136 const char *miss_init_fsm_state_str[] = { 137 "MISS_INIT_IDLE_MISS", 138 "MISS_INIT_IDLE_IRQ", 139 "MISS_INIT_IRQ_CMD", 140 "MISS_INIT_IRQ_RSP", 141 "MISS_INIT_TLB_MISS_CMD", 142 "MISS_INIT_TLB_MISS_RSP", 95 const char *miss_wti_fsm_state_str[] = { 96 "MISS_WTI_IDLE_MISS", 97 "MISS_WTI_IDLE_WTI", 98 "MISS_WTI_CMD_WTI", 99 "MISS_WTI_RSP_WTI", 100 "MISS_WTI_CMD_MISS", 101 "MISS_WTI_RSP_MISS", 143 102 }; 144 103 } 145 104 146 #define tmpl(...) template<typename vci_param_ d,typename vci_param_x, typename vci_param_io> __VA_ARGS__ VciIoBridge<vci_param_d,vci_param_x,vci_param_io>147 148 //////////////////////// /////////105 #define tmpl(...) template<typename vci_param_int,typename vci_param_ext> __VA_ARGS__ VciIoBridge<vci_param_int,vci_param_ext> 106 107 //////////////////////// 149 108 tmpl(/**/)::VciIoBridge( 150 109 sc_module_name name, 151 size_t nb_periph, 152 const soclib::common::MappingTable &mtx, 153 const soclib::common::MappingTable &mtd, 154 const soclib::common::MappingTable &mtio, 155 const soclib::common::Segment &seg_config_iob, 156 const soclib::common::IntTab &tgt_index_iocluster, 157 // const soclib::common::IntTab &tgt_index_config, 158 const soclib::common::IntTab &init_index_direct, 159 const soclib::common::IntTab &tgt_index_iospace, 160 const soclib::common::IntTab &init_index_iospace, 161 const soclib::common::IntTab &init_index_dma, 162 size_t dcache_words, 163 size_t iotlb_ways, 164 size_t iotlb_sets, 165 uint32_t debug_start_cycle, 166 bool debug_ok) 110 const soclib::common::MappingTable &mt_ext, 111 const soclib::common::MappingTable &mt_int, 112 const soclib::common::MappingTable &mt_iox, 113 const soclib::common::IntTab &int_tgtid, // INT network TGTID 114 const soclib::common::IntTab &int_srcid, // INT network SRCID 115 const soclib::common::IntTab &iox_tgtid, // IOX network TGTID 116 const bool has_irqs, 117 const size_t dcache_words, 118 const size_t iotlb_ways, 119 const size_t iotlb_sets, 120 const uint32_t debug_start_cycle, 121 const bool debug_ok) 167 122 : soclib::caba::BaseModule(name), 168 123 169 p_clk("clk"), 170 p_resetn("resetn"), 171 p_irq_in(soclib::common::alloc_elems<sc_core::sc_in<bool> >("irq_in", nb_periph)), 172 p_vci_ini_dma("vci_ini_dma"), 173 p_vci_tgt_dma("vci_tgt_dma"), 174 p_vci_ini_config("vci_ini_config"), 175 p_vci_tgt_config("vci_tgt_config"), 176 p_vci_ini_miss("vci_ini_miss"), 177 178 m_words(dcache_words), 179 m_nb_periph(nb_periph), 180 181 // m_locality_table_config(mtd.getLocalityTable<unsigned long>(tgt_index_iocluster)), 182 // These structures simulate what in hardware will be a correspondence table 183 // Between segments' base address on the direct space and on the IO space 184 // m_routing_table_config(mtd.getRoutingTable<unsigned long>(tgt_index_iocluster)), 185 //m_mtio(mtio), 186 187 m_transaction_tab_dma(2), 188 m_transaction_tab_config(1), 189 //Direct Network 190 // m_segment_config(mtd.getSegment(tgt_index_config)), 191 m_segment_config(seg_config_iob), 192 m_srcid_miss(mtx.indexForId(init_index_direct)), 193 //XRAM Network 194 m_srcid_dma(mtx.indexForId(init_index_dma)), 195 //IO Network 196 m_segment_io(mtio.getSegment(tgt_index_iospace)), 197 m_srcid_config(mtio.indexForId(init_index_iospace)), 124 p_clk("p_clk"), 125 p_resetn("p_resetn"), 126 p_vci_ini_ram("p_vci_ini_ram"), 127 p_vci_tgt_iox("p_vci_tgt_iox"), 128 p_vci_ini_iox("p_vci_ini_iox"), 129 p_vci_tgt_int("p_vci_tgt_int"), 130 p_vci_ini_int("p_vci_ini_int"), 131 132 m_words( dcache_words ), 133 m_has_irqs( has_irqs ), 134 135 // INT & IOX Network 136 m_int_seglist( mt_int.getSegmentList( int_tgtid )), 137 m_int_srcid( mt_int.indexForId( int_srcid )), 138 m_iox_seglist( mt_iox.getSegmentList( iox_tgtid )), 198 139 199 140 m_iotlb_ways(iotlb_ways), 200 141 m_iotlb_sets(iotlb_sets), 201 m_paddr_nbits(vci_param_d::N),202 142 203 143 m_debug_start_cycle(debug_start_cycle), 204 144 m_debug_ok(debug_ok), 205 145 146 // addressable registers 206 147 r_iommu_ptpr("r_iommu_ptpr"), 207 148 r_iommu_active("r_iommu_active"), … … 209 150 r_iommu_etr("r_iommu_etr"), 210 151 r_iommu_bad_id("r_iommu_bad_id"), 211 r_it_addr_iommu("r_it_addr_iommu"), 212 213 // DMA_CMD 152 r_iommu_wti_paddr("r_iommu_wti_paddr"), 153 r_iommu_peri_wti(alloc_elems<sc_signal<vci_addr_t> >("r_peri_wti_paddr", 32)), 154 155 // DMA_CMD FSM registers 214 156 r_dma_cmd_fsm("r_dma_cmd_fsm"), 215 r_dma_cmd_fsm_save("r_dma_cmd_fsm_save"), 216 r_miss_interrupt("r_miss_interrupt"), 217 r_dma_cmd_count("r_dma_cmd_count"), 218 r_dma_cmd_trt_index("r_dma_cmd_trt_index"), 219 r_dma_paddr("r_dma_paddr"), 220 // FIFOs 221 m_dma_cmd_addr_fifo("m_dma_cmd_addr_fifo",4), 222 //m_dma_cmd_length_fifo("m_dma_cmd_length_fifo",4), 223 m_dma_cmd_srcid_fifo("m_dma_cmd_srcid_fifo",4), 224 m_dma_cmd_trdid_fifo("m_dma_cmd_trdid_fifo",4), 225 m_dma_cmd_pktid_fifo("m_dma_cmd_pktid_fifo",4), 226 m_dma_cmd_be_fifo("m_dma_cmd_be_fifo",4), 227 m_dma_cmd_cmd_fifo("m_dma_cmd_cmd_fifo",4), 228 m_dma_cmd_contig_fifo("m_dma_cmd_contig_fifo",4), 229 m_dma_cmd_data_fifo("m_dma_cmd_data_fifo",4), 230 m_dma_cmd_eop_fifo("m_dma_cmd_eop_fifo",4), 231 m_dma_cmd_cons_fifo("m_dma_cmd_cons_fifo",4), 232 m_dma_cmd_plen_fifo("m_dma_cmd_plen_fifo",4), 233 m_dma_cmd_wrap_fifo("m_dma_cmd_wrap_fifo",4), 234 m_dma_cmd_cfixed_fifo("m_dma_cmd_cfixed_fifo",4), 235 m_dma_cmd_clen_fifo("m_dma_cmd_clen_fifo",4), 236 237 r_miss_paddr ("r_miss_paddr"), 238 r_miss_cmd ("r_miss_cmd"), 239 r_miss_contig ("r_miss_contig"), 240 r_miss_cons ("r_miss_cons"), 241 r_miss_plen ("r_miss_plen"), 242 r_miss_wrap ("r_miss_wrap"), 243 r_miss_cfixed ("r_miss_cfixed"), 244 r_miss_clen ("r_miss_clen"), 245 r_miss_srcid ("r_miss_srcid"), 246 r_miss_trdid ("r_miss_trdid"), 247 r_miss_pktid ("r_miss_pktid"), 248 249 r_dma_error_type("r_dma_error_type"), 250 r_dma_error_trdid("r_dma_error_trdid"), 251 r_dma_error_pktid("r_dma_error_pktid"), 252 253 254 r_dma_tlb_fsm("r_dma_tlb_fsm"), 157 r_dma_cmd_vaddr("r_dma_cmd_vaddr"), 158 r_dma_cmd_paddr("r_dma_cmd_paddr"), 159 160 //DMA_RSP FSM registers 161 r_dma_rsp_fsm("r_dma_rsp_fsm"), 162 163 // CONFIG_CMD FSM registers 164 r_config_cmd_fsm("r_config_cmd_fsm"), 165 r_config_cmd_rdata("r_config_cmd_rdata"), 166 r_config_cmd_error("r_config_cmd_error"), 167 r_config_cmd_inval_vaddr("r_config_cmd_inval_vaddr"), 168 169 // CONFIG_RSP FSM registers 170 r_config_rsp_fsm("r_config_rsp_fsm"), 171 172 // TLB FSM registers 173 r_tlb_fsm("r_tlb_fsm"), 255 174 r_waiting_transaction("r_waiting_transaction"), 256 175 r_tlb_miss_type("r_tlb_miss_type"), 257 258 259 r_iotlb_vaddr("r_iotlb_vaddr"), // virtual address for a tlb miss 260 r_iotlb_paddr("r_iotlb_paddr"), // physical address of pte 261 r_iotlb_pte_flags("r_iotlb_pte_flags"),// pte1 or first word of pte2 262 r_iotlb_pte_ppn("r_iotlb_pte_ppn"), // second word of pte2 263 r_iotlb_way("r_iotlb_way"), // selected way in tlb 264 r_iotlb_set("r_iotlb_set"), // selected set in tlb 265 266 r_iotlb("iotlb", IOMMU_ID, iotlb_ways,iotlb_sets,vci_param_d::N), 176 r_tlb_miss_error("r_tlb_miss_error"), 177 r_tlb_paddr("r_tlb_paddr"), 178 r_tlb_pte_flags("r_tlb_pte_flags"), 179 r_tlb_pte_ppn("r_tlb_pte_ppn"), 180 r_tlb_way("r_tlb_way"), 181 r_tlb_set("r_tlb_set"), 182 r_tlb_buf_valid("r_tlb_buf_valid"), 183 r_tlb_buf_tag("r_tlb_buf_tag"), 184 r_tlb_buf_vaddr("r_tlb_buf_vaddr"), 185 r_tlb_buf_big_page("r_tlb_buf_big_page"), 186 187 // MISS_WTI_CMD FSM registers 188 r_miss_wti_cmd_fsm("r_miss_wti_cmd_fsm"), 189 r_miss_wti_cmd_index("r_miss_wti_cmd_index"), 190 191 // MISS_WTI_CMD FSM registers 192 r_miss_wti_rsp_fsm("r_miss_wti_rsp_fsm"), 193 r_miss_wti_rsp_error("r_miss_wti_rsp_error"), 194 195 // allocator for CONFIG_RSP & DMA_RSP fifos 196 r_alloc_fifo_config_rsp_local("r_alloc_fifo_config_rsp_local"), 197 r_alloc_fifo_dma_rsp_local("r_alloc_fifo_dma_rsp_local"), 198 199 // IRQs registers 200 r_irq_pending(alloc_elems<sc_signal<bool> >("r_irq_pending", 32)), 201 r_irq_request(alloc_elems<sc_signal<bool> >("r_irq_request", 32)), 267 202 268 //DMA_RSP 269 r_dma_rsp_fsm("r_dma_rsp_fsm"), 270 r_dma_rtrdid("r_dma_rtrdid"), 271 r_dma_rsrcid("r_dma_rsrcid"), 272 //Fifo's 273 m_dma_rsp_data_fifo("m_dma_rsp_data_fifo",4), 274 m_dma_rsp_rsrcid_fifo("m_dma_rsp_rsrcid_fifo",4), 275 m_dma_rsp_rtrdid_fifo("m_dma_rsp_rtrdid_fifo",4), 276 m_dma_rsp_rpktid_fifo("m_dma_rsp_rpktid_fifo",4), 277 m_dma_rsp_reop_fifo("m_dma_rsp_reop_fifo",4), 278 m_dma_rsp_rerror_fifo("m_dma_rsp_rerror_fifo",4), 203 // TLB for IOMMU 204 r_iotlb("iotlb", 0, iotlb_ways, iotlb_sets, vci_param_int::N), 205 206 // Inter-FSM communications 207 r_dma_tlb_req("r_dma_tlb_req"), 208 r_config_tlb_req("r_config_tlb_req"), 209 r_tlb_miss_req("r_tlb_miss_req"), 279 210 280 r_dma_cmd_rsp_erase_req("r_dma_cmd_rsp_erase_req"), 281 r_dma_cmd_error_req("r_dma_cmd_error_req"), 282 r_dma_tlb_req("r_dma_tlb_req"), 283 r_tlb_dma_untreated("r_tlb_dma_untreated"), 284 r_dma_tlb_error_req("r_dma_tlb_error_req"), 285 r_config_tlb_req("r_config_tlb_req"), 286 r_config_tlb_inval_vaddr("r_config_tlb_inval_vaddr"), 287 288 // ALLOC TRT DMA 289 r_alloc_trt_dma_fsm("r_alloc_trt_dma_fsm"), 290 291 // CONFIG CMD 292 r_config_cmd_fsm("r_config_cmd_fsm"), 293 r_config_cmd_trt_index("r_config_cmd_trt_index"), 294 295 m_config_cmd_addr_fifo("m_config_cmd_addr_fifo",4), 296 //m_config_cmd_length_fifo("m_config_cmd_length_fifo",4), 297 m_config_cmd_srcid_fifo("m_config_cmd_srcid_fifo",4), 298 m_config_cmd_trdid_fifo("m_config_cmd_trdid_fifo",4), 299 m_config_cmd_pktid_fifo("m_config_cmd_pktid_fifo",4), 300 m_config_cmd_be_fifo("m_config_cmd_be_fifo",4), 301 m_config_cmd_cmd_fifo("m_config_cmd_cmd_fifo",4), 302 m_config_cmd_contig_fifo("m_config_cmd_contig_fifo",4), 303 m_config_cmd_data_fifo("m_config_cmd_data_fifo",4), 304 m_config_cmd_eop_fifo("m_config_cmd_eop_fifo",4), 305 m_config_cmd_cons_fifo("m_config_cmd_cons_fifo",4), 306 m_config_cmd_plen_fifo("m_config_cmd_plen_fifo",4), 307 m_config_cmd_wrap_fifo("m_config_cmd_wrap_fifo",4), 308 m_config_cmd_cfixed_fifo("m_config_cmd_cfixed_fifo",4), 309 m_config_cmd_clen_fifo("m_config_cmd_clen_fifo",4), 310 // Private configuration registers 311 r_config_error_type("r_config_error_type"), 312 r_config_first_word("r_config_first_word"), 313 r_it_index("r_it_index"), 314 //Fifo's 315 m_config_local_data_fifo("m_config_local_data_fifo",4), 316 m_config_local_rsrcid_fifo("m_config_local_rsrcid_fifo",4), 317 m_config_local_rtrdid_fifo("m_config_local_rtrdid_fifo",4), 318 m_config_local_rpktid_fifo("m_config_local_rpktid_fifo",4), 319 m_config_local_reop_fifo("m_config_local_reop_fifo",4), 320 m_config_local_rerror_fifo("m_config_local_rerror_fifo",4), 321 r_config_vaddr("r_config_vaddr"), 211 // DMA_CMD FIFOs 212 m_dma_cmd_addr_fifo("m_dma_cmd_addr_fifo",2), 213 m_dma_cmd_srcid_fifo("m_dma_cmd_srcid_fifo",2), 214 m_dma_cmd_trdid_fifo("m_dma_cmd_trdid_fifo",2), 215 m_dma_cmd_pktid_fifo("m_dma_cmd_pktid_fifo",2), 216 m_dma_cmd_be_fifo("m_dma_cmd_be_fifo",2), 217 m_dma_cmd_cmd_fifo("m_dma_cmd_cmd_fifo",2), 218 m_dma_cmd_contig_fifo("m_dma_cmd_contig_fifo",2), 219 m_dma_cmd_data_fifo("m_dma_cmd_data_fifo",2), 220 m_dma_cmd_eop_fifo("m_dma_cmd_eop_fifo",2), 221 m_dma_cmd_cons_fifo("m_dma_cmd_cons_fifo",2), 222 m_dma_cmd_plen_fifo("m_dma_cmd_plen_fifo",2), 223 m_dma_cmd_wrap_fifo("m_dma_cmd_wrap_fifo",2), 224 m_dma_cmd_cfixed_fifo("m_dma_cmd_cfixed_fifo",2), 225 m_dma_cmd_clen_fifo("m_dma_cmd_clen_fifo",2), 226 227 // DMA_RSP FIFOs 228 m_dma_rsp_data_fifo("m_dma_rsp_data_fifo",2), 229 m_dma_rsp_rsrcid_fifo("m_dma_rsp_rsrcid_fifo",2), 230 m_dma_rsp_rtrdid_fifo("m_dma_rsp_rtrdid_fifo",2), 231 m_dma_rsp_rpktid_fifo("m_dma_rsp_rpktid_fifo",2), 232 m_dma_rsp_reop_fifo("m_dma_rsp_reop_fifo",2), 233 m_dma_rsp_rerror_fifo("m_dma_rsp_rerror_fifo",2), 234 235 // CONFIG_CMD FIFOs 236 m_config_cmd_addr_fifo("m_config_cmd_addr_fifo",2), 237 m_config_cmd_srcid_fifo("m_config_cmd_srcid_fifo",2), 238 m_config_cmd_trdid_fifo("m_config_cmd_trdid_fifo",2), 239 m_config_cmd_pktid_fifo("m_config_cmd_pktid_fifo",2), 240 m_config_cmd_be_fifo("m_config_cmd_be_fifo",2), 241 m_config_cmd_cmd_fifo("m_config_cmd_cmd_fifo",2), 242 m_config_cmd_contig_fifo("m_config_cmd_contig_fifo",2), 243 m_config_cmd_data_fifo("m_config_cmd_data_fifo",2), 244 m_config_cmd_eop_fifo("m_config_cmd_eop_fifo",2), 245 m_config_cmd_cons_fifo("m_config_cmd_cons_fifo",2), 246 m_config_cmd_plen_fifo("m_config_cmd_plen_fifo",2), 247 m_config_cmd_wrap_fifo("m_config_cmd_wrap_fifo",2), 248 m_config_cmd_cfixed_fifo("m_config_cmd_cfixed_fifo",2), 249 m_config_cmd_clen_fifo("m_config_cmd_clen_fifo",2), 250 251 // CONFIG_RSP FIFOs 252 m_config_rsp_data_fifo("m_config_rsp_data_fifo",2), 253 m_config_rsp_rsrcid_fifo("m_config_rsp_rsrcid_fifo",2), 254 m_config_rsp_rtrdid_fifo("m_config_rsp_rtrdid_fifo",2), 255 m_config_rsp_rpktid_fifo("m_config_rsp_rpktid_fifo",2), 256 m_config_rsp_reop_fifo("m_config_rsp_reop_fifo",2), 257 m_config_rsp_rerror_fifo("m_config_rsp_rerror_fifo",2) 258 { 259 std::cout << " - Building VciIoBridge : " << name << std::endl; 260 261 // checking segments on INT network 262 assert ( ( not m_int_seglist.empty() ) and 263 "VCI_IO_BRIDGE ERROR : no segment allocated on INT network"); 264 265 std::list<soclib::common::Segment>::iterator int_seg; 266 for ( int_seg = m_int_seglist.begin() ; int_seg != m_int_seglist.end() ; int_seg++ ) 267 { 268 std::cout << " => segment " << int_seg->name() 269 << " / base = " << std::hex << int_seg->baseAddress() 270 << " / size = " << int_seg->size() << std::endl; 271 } 272 273 // checking segments on IOX network 274 assert ( ( not m_iox_seglist.empty() ) and 275 "VCI_IO_BRIDGE ERROR : no segment allocated on IOX network"); 276 277 std::list<soclib::common::Segment>::iterator iox_seg; 278 for ( iox_seg = m_iox_seglist.begin() ; iox_seg != m_iox_seglist.end() ; iox_seg++ ) 279 { 280 std::cout << " => segment " << iox_seg->name() 281 << " / base = " << std::hex << iox_seg->baseAddress() 282 << " / size = " << iox_seg->size() << std::endl; 283 } 284 285 assert( (vci_param_int::N == vci_param_ext::N) and 286 "VCI_IO_BRIDGE ERROR: VCI ADDRESS widths must be equal on the 3 networks"); 287 288 assert( (vci_param_int::N <= 64) and 289 "VCI_IO_BRIDGE ERROR: VCI ADDRESS width cannot be bigger than 64 bits"); 290 291 assert( ((vci_param_int::B == 4) or (vci_param_int::B == 8)) and 292 "VCI_IO_BRIDGE ERROR: VCI DATA width must be 32 or 64 bits on internal network"); 293 294 assert( ((vci_param_ext::B == 4) or (vci_param_ext::B == 8)) and 295 "VCI_IO_BRIDGE ERROR: VCI DATA width must be 32 or 64 bits on external network"); 296 297 assert( (vci_param_int::S == vci_param_ext::S) and 298 "VCI_IO_BRIDGE ERROR: SRCID widths must be equal on the 3 networks"); 299 300 // contruct 32 IRQ ports if required 301 if ( has_irqs ) 302 { 303 for ( size_t n=0 ; n<32 ; n++ ) p_irq[n] = new sc_core::sc_in<bool>; 304 } 322 305 323 // CONFIG RSP 324 r_config_rsp_fsm("r_config_rsp_fsm"), 325 r_config_rtrdid("r_config_rtrdid"), 326 r_config_rsrcid("r_config_rsrcid"), 327 //Fifo's 328 m_config_rsp_data_fifo("m_config_rsp_data_fifo",4), 329 m_config_rsp_rsrcid_fifo("m_config_rsp_rsrcid_fifo",4), 330 m_config_rsp_rtrdid_fifo("m_config_rsp_rtrdid_fifo",4), 331 m_config_rsp_rpktid_fifo("m_config_rsp_rpktid_fifo",4), 332 m_config_rsp_reop_fifo("m_config_rsp_reop_fifo",4), 333 m_config_rsp_rerror_fifo("m_config_rsp_rerror_fifo",4), 334 335 // Communication between CONFIG CMD and CONFIG RSP 336 r_config_cmd_rsp_erase_req("r_config_cmd_rsp_erase_req"), 337 338 // ALLOC TRT CONFIG 339 r_alloc_trt_config_fsm("r_alloc_trt_config_fsm"), 340 // MISS INIT 341 r_miss_init_fsm("r_miss_init_fsm"), 342 r_miss_rdata("r_miss_rdata"), 343 r_miss_rpktid("r_miss_rpktid"), 344 r_miss_rtrdid("r_miss_rtrdid"), 345 r_miss_rerror("r_miss_rerror"), 346 r_miss_reop("r_miss_reop"), 347 //r_miss_rsrcid("r_miss_rsrcid"), 348 r_miss_rsp_cpt("r_miss_rsp_cpt"), 349 //IRQ 350 r_irq_pending("r_irq_pending"), 351 r_irq_mask("r_irq_mask"), 352 r_irq_chosen("r_irq_chosen"), 353 354 r_tlb_miss_init_req("r_tlb_miss_init_req"), 355 r_miss_init_error("r_miss_init_error"), 356 357 r_miss_buf_valid("r_miss_buf_valid"), 358 r_miss_buf_tag("r_miss_buf_tag") 359 { 360 assert( (vci_param_d::N <= 64) and 361 "ADDRESS cannot be bigger than 64 bits"); 362 assert( (vci_param_x::B)*8 == 64 and (vci_param_io::B)*8 == 64 and 363 "DATA field must be 64 bits in Extern and IO Network"); 364 assert ( (vci_param_d::B)*8 == 32 365 and "Error: data field in Direct Noc must be 32 bits" ); 366 367 368 // Interruption Address vector, one entry for each IO 369 r_it_addr = new paddr_t[nb_periph]; 370 // One cache line buffer 371 r_miss_buf_data = new vci_data_t[dcache_words]; 372 // Command storage in case of miss TLB 373 // (dcache_words/2) => Maximal size of a write command 374 r_miss_data = new vci_data_t[dcache_words]; 375 r_miss_be = new vci_be_t[dcache_words]; 376 306 // Cache line buffer 307 r_tlb_buf_data = new uint32_t[dcache_words]; 308 377 309 SC_METHOD(transition); 378 310 dont_initialize(); … … 389 321 ///////////////////////////////////// 390 322 { 391 delete [] r_i t_addr;392 delete [] r_ miss_buf_data;393 delete [] r_miss_data;394 delete [] r_miss_be;395 soclib::common::dealloc_elems( p_irq_in, m_nb_periph);323 delete [] r_iommu_peri_wti; 324 delete [] r_tlb_buf_data; 325 soclib::common::dealloc_elems(p_irq, 32); 326 soclib::common::dealloc_elems(r_irq_request, 32); 327 soclib::common::dealloc_elems(r_irq_pending, 32); 396 328 } 397 329 … … 404 336 std::cout << std::dec << "IO_BRIDGE " << name() << std::endl; 405 337 406 std::cout << " " << dma_cmd_fsm_state_str[r_dma_cmd_fsm.read()]338 std::cout << " " << dma_cmd_fsm_state_str[r_dma_cmd_fsm.read()] 407 339 << " | " << dma_rsp_fsm_state_str[r_dma_rsp_fsm.read()] 408 << " | " << dma_tlb_fsm_state_str[r_dma_tlb_fsm.read()] 409 << " | " << alloc_trt_dma_fsm_state_str[r_alloc_trt_dma_fsm.read()] 340 << " | " << tlb_fsm_state_str[r_tlb_fsm.read()] 410 341 << " | " << config_cmd_fsm_state_str[r_config_cmd_fsm.read()] 411 342 << " | " << config_rsp_fsm_state_str[r_config_rsp_fsm.read()] 412 << " | " << alloc_trt_config_fsm_state_str[r_alloc_trt_config_fsm.read()] 413 << " | " << miss_init_fsm_state_str[r_miss_init_fsm.read()]; 414 std::cout << std::endl; 343 << " | " << miss_wti_fsm_state_str[r_miss_wti_cmd_fsm.read()] 344 << std::endl; 415 345 416 346 if(mode & 0x01) … … 424 354 } 425 355 } 426 427 428 356 429 357 //////////////////////// … … 447 375 m_cpt_iotlbmiss_transaction = 0; 448 376 m_cost_iotlbmiss_transaction = 0; 449 450 m_cpt_trt_dma_full = 0;451 m_cpt_trt_dma_full_cost = 0;452 m_cpt_trt_config_full = 0;453 m_cpt_trt_config_full_cost = 0;454 377 } 455 378 … … 460 383 if ( not p_resetn.read() ) 461 384 { 462 463 r_dma_cmd_fsm = DMA_CMD_IDLE; 464 r_dma_rsp_fsm = DMA_RSP_IDLE; 465 r_alloc_trt_dma_fsm = ALLOC_TRT_DMA_CMD; 466 r_dma_tlb_fsm = DMA_TLB_IDLE; 467 r_config_cmd_fsm = CONFIG_CMD_IDLE; 468 r_config_rsp_fsm = CONFIG_RSP_IDLE; 469 r_alloc_trt_config_fsm = ALLOC_TRT_CONFIG_CMD; 470 r_miss_init_fsm = MISS_INIT_IDLE_MISS; 471 472 //miss buffer invalidation 473 r_miss_buf_valid = false; 474 475 r_iommu_active = false; 476 477 r_dma_cmd_count = 0; 385 r_dma_cmd_fsm = DMA_CMD_IDLE; 386 r_dma_rsp_fsm = DMA_RSP_IDLE; 387 r_tlb_fsm = TLB_IDLE; 388 r_config_cmd_fsm = CONFIG_CMD_IDLE; 389 r_config_rsp_fsm = CONFIG_RSP_IDLE; 390 r_miss_wti_cmd_fsm = MISS_WTI_CMD_IDLE; 391 r_miss_wti_rsp_fsm = MISS_WTI_RSP_IDLE; 392 393 r_alloc_fifo_config_rsp_local = true; 394 r_alloc_fifo_dma_rsp_local = true; 395 396 r_tlb_buf_valid = false; 397 r_iommu_active = false; 398 r_iommu_wti_enable = false; 478 399 479 400 // initializing FIFOs … … 522 443 m_config_rsp_reop_fifo.init(); 523 444 524 m_config_local_rsrcid_fifo.init(); 525 m_config_local_rtrdid_fifo.init(); 526 m_config_local_rpktid_fifo.init(); 527 m_config_local_data_fifo.init(); 528 m_config_local_rerror_fifo.init(); 529 m_config_local_reop_fifo.init(); 530 531 //Communication between DMA_CMD and DMA_RSP 532 r_dma_cmd_rsp_erase_req =false; 533 r_dma_cmd_error_req =false; 534 //Communication between DMA_CMD and TLB 535 r_dma_tlb_req =false; 536 r_tlb_dma_untreated =false; 537 //Communication betweeen TLB and CONFIG_CMD 538 r_config_tlb_req =false; 539 r_config_tlb_inval_vaddr =false; 540 r_dma_tlb_error_req =false; 541 r_tlb_error_type =false; 542 //Communication between CONFIG_CMD and CONFIG_RSP 543 r_config_cmd_rsp_erase_req =false; 544 //Communication between TLB_MISS and MISS_INIT 545 r_tlb_miss_init_req =false; 546 r_miss_init_error =false; 547 // Debug variables 548 m_debug_dma_rsp_fsm = false; 549 m_debug_dma_cmd_fsm = false; 550 m_debug_dma_tlb_fsm = false; 551 m_debug_config_cmd_fsm = false; 552 m_debug_config_rsp_fsm = false; 553 m_debug_miss_init_fsm = false; 445 // SET/RESET Communication flip-flops 446 r_dma_tlb_req = false; 447 r_config_tlb_req = false; 448 r_tlb_miss_req = false; 449 450 // Debug variable 451 m_debug_activated = false; 554 452 555 r_irq_mask = 0xFFFFFFFF; 556 r_irq_chosen = 0; 453 for ( size_t n=0 ; n<32 ; n++ ) 454 { 455 r_irq_pending[n] = false; 456 r_irq_request[n] = false; 457 } 557 458 558 459 // activity counters 559 m_cpt_total_cycles = 0;560 m_cpt_iotlb_read = 0;561 m_cpt_iotlb_miss = 0;562 m_cpt_iotlbmiss_transaction 563 m_cost_iotlbmiss_transaction 460 m_cpt_total_cycles = 0; 461 m_cpt_iotlb_read = 0; 462 m_cpt_iotlb_miss = 0; 463 m_cpt_iotlbmiss_transaction = 0; 464 m_cost_iotlbmiss_transaction = 0; 564 465 565 m_cpt_trt_dma_full = 0;566 m_cpt_trt_dma_full_cost = 0;567 m_cpt_trt_config_full 568 m_cpt_trt_config_full_cost 466 m_cpt_trt_dma_full = 0; 467 m_cpt_trt_dma_full_cost = 0; 468 m_cpt_trt_config_full = 0; 469 m_cpt_trt_config_full_cost = 0; 569 470 570 471 for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_dma_cmd [i] = 0; 571 472 for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_dma_rsp [i] = 0; 572 for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_dma_tlb [i] = 0; 573 for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_alloc_trt_dma [i] = 0; 473 for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_tlb [i] = 0; 574 474 for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_config_cmd [i] = 0; 575 475 for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_config_rsp [i] = 0; 576 for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_alloc_trt_config [i] = 0; 577 for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_miss_init [i] = 0; 476 for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_miss_wti_cmd [i] = 0; 477 for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_miss_wti_rsp [i] = 0; 478 578 479 return; 579 480 } 580 481 482 // default values for FIFOs 483 bool dma_cmd_fifo_put = false; 484 bool dma_cmd_fifo_get = false; 485 486 bool dma_rsp_fifo_put = false; 487 bool dma_rsp_fifo_get = false; 581 488 582 //bool miss_unposted = false; 583 bool dma_cmd_fifo_put = false; 584 bool dma_cmd_fifo_get = false; 585 bool dma_rsp_fifo_put = false; 586 bool dma_rsp_fifo_get = false; 587 588 bool config_cmd_fifo_put = false; 589 bool config_cmd_fifo_get = false; 590 bool config_rsp_fifo_put = false; 591 bool config_rsp_fifo_get = false; 592 bool config_local_fifo_put = false; 593 bool config_local_fifo_get = false; 489 bool config_cmd_fifo_put = false; 490 bool config_cmd_fifo_get = false; 491 492 bool config_rsp_fifo_put = false; 493 bool config_rsp_fifo_get = false; 594 494 595 495 #ifdef INSTRUMENTATION 596 496 m_cpt_fsm_dma_cmd [r_dma_cmd_fsm.read()] ++; 597 497 m_cpt_fsm_dma_rsp [r_dma_rsp_fsm.read() ] ++; 598 m_cpt_fsm_dma_tlb [r_dma_tlb_fsm.read() ] ++; 599 m_cpt_fsm_alloc_trt_dma [r_alloc_trt_dma_fsm.read() ] ++; 498 m_cpt_fsm_tlb [r_tlb_fsm.read() ] ++; 600 499 m_cpt_fsm_config_cmd [r_config_cmd_fsm.read() ] ++; 601 500 m_cpt_fsm_config_rsp [r_config_rsp_fsm.read() ] ++; 602 m_cpt_fsm_ alloc_trt_config [r_alloc_trt_config_fsm.read() ] ++;603 m_cpt_fsm_miss_ init [r_miss_init_fsm.read() ] ++;501 m_cpt_fsm_miss_wti_cmd [r_miss_wti_cmd_fsm.read() ] ++; 502 m_cpt_fsm_miss_wti_rsp [r_miss_wti_rsp_fsm.read() ] ++; 604 503 #endif 605 504 606 505 m_cpt_total_cycles++; 607 506 608 m_debug_dma_cmd_fsm = (m_cpt_total_cycles > m_debug_start_cycle) and m_debug_ok; 609 m_debug_dma_rsp_fsm = (m_cpt_total_cycles > m_debug_start_cycle) and m_debug_ok; 610 m_debug_dma_tlb_fsm = (m_cpt_total_cycles > m_debug_start_cycle) and m_debug_ok; 611 m_debug_config_cmd_fsm = (m_cpt_total_cycles > m_debug_start_cycle) and m_debug_ok; 612 m_debug_config_rsp_fsm = (m_cpt_total_cycles > m_debug_start_cycle) and m_debug_ok; 613 m_debug_miss_init_fsm = (m_cpt_total_cycles > m_debug_start_cycle) and m_debug_ok; 614 615 ///////////////////////////////////////////////////////////////////// 616 // The DMA_CMD_FSM controls the following ressources: 617 // - r_dma_cmd_fsm 618 // - r_dma_srcid 619 // - r_dma_tlb_req (set) 620 // - r_tlb_dma_untreated (reset) 621 // - r_dma_cmd_rsp_erase_req (set) 507 m_debug_activated = (m_cpt_total_cycles > m_debug_start_cycle) and m_debug_ok; 508 509 ////////////////////////////////////////////////////////////////////////////// 510 // The DMA_CMD_FSM handles DMA transactions requested by peripherals 511 // It makes the address translation if IOMMU is activated. 622 512 /////////////////////////////////////////////////////////////////////////////// 623 513 624 514 switch( r_dma_cmd_fsm.read() ) 625 515 { 626 ////////////// 627 case DMA_CMD_IDLE: 628 { 629 // Treats an eventual request from TLB_MISS fsm 630 // to send a command whose miss treatment is now finished 631 if ( r_tlb_dma_untreated.read() ) 632 { 633 r_dma_cmd_fsm = DMA_CMD_TRT_LOCK;//before posting we must update TRT 634 r_dma_cmd_fsm_save = DMA_CMD_IDLE; 635 r_miss_interrupt = true; 636 break; 637 } 638 // Error during miss treatment 639 else if (r_dma_tlb_error_req.read()) 640 { 641 r_iommu_etr = r_tlb_error_type.read(); 642 r_iommu_bvar = r_iotlb_vaddr.read(); 643 r_iommu_bad_id = r_miss_srcid.read(); 644 // For DMA_RSP FSM 645 if(r_miss_cmd.read() == vci_param_io::CMD_WRITE) r_dma_error_type = WRITE_ERROR; 646 else r_dma_error_type = READ_ERROR; 647 r_dma_error_trdid = r_miss_trdid.read(); 648 r_dma_error_pktid = r_miss_pktid.read(); 649 650 r_dma_tlb_error_req = false; 651 r_dma_cmd_fsm = DMA_CMD_ERROR; 652 } 653 654 if ( p_vci_tgt_dma.cmdval.read() ) 516 ////////////////// 517 case DMA_CMD_IDLE: // waiting DMA VCI transaction 518 { 519 if ( p_vci_tgt_iox.cmdval.read() ) // compute physical address 655 520 { 656 if ( not r_iommu_active.read() ) // iotlb not activated521 if ( not r_iommu_active.read() ) // tlb not activated 657 522 { 658 // physical address 659 r_dma_paddr = (paddr_t)p_vci_tgt_dma.address.read(); 660 r_dma_cmd_fsm = DMA_CMD_TRT_LOCK; 523 #if DEBUG_DMA_CMD 524 if( m_debug_activated ) 525 std::cout << " <IOB DMA_CMD_IDLE> IOMMU not activated" << std::endl; 526 #endif 527 // put DMA transaction into DMA_CMD fifo 528 r_dma_cmd_paddr = p_vci_tgt_iox.address.read(); 529 r_dma_cmd_fsm = DMA_CMD_FIFO_PUT_CMD; 661 530 } 662 else if (r_ dma_tlb_fsm.read() == DMA_TLB_IDLE ||663 r_ dma_tlb_fsm.read() == DMA_TLB_WAIT_TRANSACTION ) // iotlb activated531 else if (r_tlb_fsm.read() == TLB_IDLE || 532 r_tlb_fsm.read() == TLB_WAIT ) // tlb access possible 664 533 { 665 paddr_t paddr; 666 667 668 // We compute physical address and check access rights : 669 // - If MMU not activated :the physical address is equal to the virtual 670 //address (identity mapping) and there is no access rights checking 671 // - If MMU activated : cacheability is defined by the C bit in the PTE, 672 // the physical address is obtained from the TLB, and the access rights are 673 // defined by the W bit in the PTE. 674 675 paddr_t iotlb_paddr; 534 vci_addr_t iotlb_paddr; 676 535 pte_info_t iotlb_flags; 677 536 size_t iotlb_way; 678 537 size_t iotlb_set; 679 paddr_t iotlb_nline; 680 bool iotlb_hit = false;; 681 538 vci_addr_t iotlb_nline; 539 bool iotlb_hit; 682 540 683 541 #ifdef INSTRUMENTATION 684 542 m_cpt_iotlb_read++; 685 543 #endif 686 687 iotlb_hit = r_iotlb.translate(p_vci_tgt_dma.address.read(), 688 &iotlb_paddr, 689 &iotlb_flags, 690 &iotlb_nline,// unused 691 &iotlb_way, // unused 692 &iotlb_set );// unused 544 iotlb_hit = r_iotlb.translate(p_vci_tgt_iox.address.read(), 545 &iotlb_paddr, 546 &iotlb_flags, 547 &iotlb_nline, // unused 548 &iotlb_way, // unused 549 &iotlb_set ); // unused 693 550 694 695 if ( iotlb_hit ) // tlb hit 551 if ( iotlb_hit ) // tlb hit 696 552 { 697 paddr = iotlb_paddr; 698 699 // access rights checking 700 if ( not iotlb_flags.w and 701 (p_vci_tgt_dma.cmd.read() == vci_param_io::CMD_WRITE) ) 553 if ( not iotlb_flags.w and // access right violation 554 (p_vci_tgt_iox.cmd.read() == vci_param_ext::CMD_WRITE) ) 702 555 { 703 r_iommu_etr = MMU_WRITE_ACCES_VIOLATION; 704 r_iommu_bvar = p_vci_tgt_dma.address.read(); 705 r_iommu_bad_id = p_vci_tgt_dma.srcid.read(); 706 r_dma_cmd_fsm = DMA_CMD_ERROR; 707 // For DMA_RSP 708 r_dma_error_type = WRITE_ERROR; 709 r_dma_error_trdid = p_vci_tgt_dma.trdid.read(); 710 r_dma_error_pktid = p_vci_tgt_dma.pktid.read(); 556 // put DMA response error into DMA_RSP fifo 557 r_iommu_etr = MMU_WRITE_ACCES_VIOLATION; 558 r_iommu_bvar = p_vci_tgt_iox.address.read(); 559 r_iommu_bad_id = p_vci_tgt_iox.srcid.read(); 560 r_dma_cmd_fsm = DMA_CMD_FIFO_PUT_RSP; 711 561 #if DEBUG_DMA_CMD 712 if( m_debug_dma_cmd_fsm ) 713 { 714 std::cout << " <IOB.DMA_CMD_IDLE> HIT in iotlb, but writable violation" << std::endl; 715 } 716 #endif 717 break; 562 if( m_debug_activated ) 563 std::cout << " <IOB DMA_CMD_IDLE> TLB HIT but writable violation" << std::endl; 564 #endif 718 565 } 719 720 // Physical address registration 721 r_dma_paddr = paddr; 722 r_dma_cmd_fsm = DMA_CMD_TRT_LOCK; 723 } 724 // TLB miss: we enter TLB_MISS treatment sub-fsm 725 else 566 else // no access rights violation 567 { 568 #if DEBUG_DMA_CMD 569 if( m_debug_activated ) 570 std::cout << " <IOB DMA_CMD_IDLE> TLB HIT" << std::endl; 571 #endif 572 // put DMA transaction into DMA_CMD fifo 573 r_dma_cmd_paddr = iotlb_paddr; 574 r_dma_cmd_fsm = DMA_CMD_FIFO_PUT_CMD; 575 } 576 } 577 else // TLB miss 726 578 { 727 579 … … 729 581 m_cpt_iotlb_miss++; 730 582 #endif 731 if( r_dma_tlb_req.read() || r_tlb_dma_untreated.read() || r_dma_tlb_error_req.read() ) 732 { 733 // There's already a ongoing request 734 // or a completed request but not yet put on FIFO. 735 // We stay blocked 736 r_dma_cmd_fsm = DMA_CMD_TLB_MISS_WAIT; 583 // register virtual address, and send request to TLB FSM 584 r_dma_cmd_vaddr = p_vci_tgt_iox.address.read(); 585 r_dma_tlb_req = true; 586 r_dma_cmd_fsm = DMA_CMD_MISS_WAIT; 737 587 #if DEBUG_DMA_CMD 738 if( m_debug_dma_cmd_fsm ) 739 { 740 std::cout << " <IOB.DMA_CMD_IDLE> MISS in iotlb. There is a pending request." << std::endl; 741 } 742 #endif 743 } 744 else 745 { 746 // We register request virtual address, to be used by DMA_TLB_MISS FSM 747 r_iotlb_vaddr = p_vci_tgt_dma.address.read(); 748 assert((r_dma_cmd_count.read() == 0) 749 and "ERROR: TRT counter should be 0"); 750 r_dma_tlb_req = true; 751 r_dma_cmd_fsm = DMA_CMD_TLB_MISS_STORE; 752 #if DEBUG_DMA_CMD 753 if( m_debug_dma_cmd_fsm ) 754 { 755 std::cout << " <IOB.DMA_CMD_IDLE> MISS in iotlb. No pending request." << std::endl; 756 } 757 #endif 758 } 588 if( m_debug_activated ) 589 std::cout << " <IOB DMA_CMD_IDLE> TLB MISS" << std::endl; 590 #endif 759 591 } // end !hit 760 592 } // end if tlb_activated … … 762 594 break; 763 595 } 764 ///////////////////////// 765 case DMA_CMD_TRT_LOCK: // Waiting for the lock to modify Transaction Table 766 { 767 if ( r_alloc_trt_dma_fsm.read() == ALLOC_TRT_DMA_CMD ) 768 { 769 770 #if DEBUG_DMA_CMD 771 if( m_debug_dma_cmd_fsm ) 772 { 773 std::cout << " <IOB.DMA_CMD_TRT_LOCK> Check the TRT" << std::endl; 774 } 775 #endif 776 size_t wok_index = 0; 777 bool wok = !m_transaction_tab_dma.full(wok_index); 778 779 if ( wok ) // TRT isn't full. Write the new transaction. 780 { 781 r_dma_cmd_trt_index = (vci_trdid_t)wok_index; 782 r_dma_cmd_fsm = DMA_CMD_TRT_SET; 783 } 784 else // wait an empty entry in TRT 785 { 786 r_dma_cmd_rsp_erase_req = true; 787 r_dma_cmd_fsm = DMA_CMD_TRT_WAIT; 788 #if DEBUG_DMA_CMD 789 if( m_debug_dma_cmd_fsm ) 790 { 791 std::cout << " <IOB.DMA_CMD_TRT_LOCK> TRT is full. Going to TRT_WAIT state" << std::endl; 792 } 793 #endif 596 ////////////////////////// 597 case DMA_CMD_FIFO_PUT_CMD: // put a DMA transaction in DMA_CMD fifo 598 // if contig, VCI address must be incremented 599 { 600 if ( p_vci_tgt_iox.cmdval && m_dma_cmd_addr_fifo.wok() ) 601 { 602 dma_cmd_fifo_put = true; 794 603 795 #ifdef INSTRUMENTATION 796 m_cpt_trt_dma_full++; 797 #endif 798 } 799 } 800 break; 801 } 802 //////////////// 803 case DMA_CMD_TRT_WAIT: // release the lock protecting the transaction tab 804 // waits that RSP erases an entry 805 { 806 #ifdef INSTRUMENTATION 807 m_cpt_trt_dma_full_cost++; 808 #endif 809 // DMA_RSP will notify an erase action by reseting this register 810 if(!r_dma_cmd_rsp_erase_req.read()) 811 { 812 r_dma_cmd_fsm = DMA_CMD_TRT_LOCK; // take the lock again 813 } 814 break; 815 } 816 //////////////////////// 817 case DMA_CMD_TRT_SET: // register a new transaction in TRT 818 { 819 if ( r_alloc_trt_dma_fsm.read() == ALLOC_TRT_DMA_CMD ) 820 { 821 if(r_miss_interrupt.read()) 822 { 823 m_transaction_tab_dma.set(r_dma_cmd_trt_index.read(), 824 r_miss_srcid.read(), 825 r_miss_trdid.read() ); 826 r_dma_cmd_fsm = DMA_CMD_FIFO_MISS_PUT; 827 } 828 else 829 { 830 m_transaction_tab_dma.set(r_dma_cmd_trt_index.read(), 831 p_vci_tgt_dma.srcid.read(), 832 p_vci_tgt_dma.trdid.read() ); 833 r_dma_cmd_fsm = DMA_CMD_FIFO_PUT; 834 } 835 #if DEBUG_DMA_CMD 836 if( m_debug_dma_cmd_fsm ) 837 { 838 std::cout << " <IOB.DMA_CMD_TRT_SET> Set a new entry in TRT" << std::endl; 839 if(r_miss_interrupt.read()) std::cout << " From the Network " << std::endl; 840 else std::cout << " From miss interruption" << std::endl; 841 } 842 #endif 843 } 844 break; 845 } 846 /////////////////////// 847 case DMA_CMD_FIFO_PUT: 848 { 849 if ( p_vci_tgt_dma.cmdval && m_dma_cmd_addr_fifo.wok() ) 850 { 851 dma_cmd_fifo_put = true; 852 //miss_unposted = false; 853 if( p_vci_tgt_dma.contig ) r_dma_paddr = r_dma_paddr.read() + 4; 854 if( p_vci_tgt_dma.eop ) r_dma_cmd_fsm = DMA_CMD_IDLE; 604 if ( p_vci_tgt_iox.contig.read() ) r_dma_cmd_paddr = r_dma_cmd_paddr.read() + 605 vci_param_ext::B; 606 607 if ( p_vci_tgt_iox.eop.read() ) r_dma_cmd_fsm = DMA_CMD_IDLE; 855 608 856 609 #if DEBUG_DMA_CMD 857 if( m_debug_dma_cmd_fsm ) 858 { 859 std::cout << " <IOB.DMA_CMD_FIFO_PUT> Push into cmd_fifo:" 860 << " address = " << std::hex << r_dma_paddr.read() 861 << " srcid = " << std::dec << m_srcid_dma 862 << " trdid = " << r_dma_cmd_trt_index.read() 863 << " wdata = " << std::hex << p_vci_tgt_dma.wdata.read() 864 << " be = " << p_vci_tgt_dma.be.read() 865 << " contig = " << p_vci_tgt_dma.contig.read() 866 << " eop = " << std::dec << p_vci_tgt_dma.eop.read() 867 << " plen = " << std::dec << p_vci_tgt_dma.plen.read() << std::endl; 868 } 869 #endif 610 if( m_debug_activated ) 611 std::cout << " <IOB DMA_CMD_FIFO_PUT_CMD> Push into DMA_CMD fifo:" 612 << " address = " << std::hex << r_dma_cmd_paddr.read() 613 << " srcid = " << p_vci_tgt_iox.srcid.read() 614 << " trdid = " << p_vci_tgt_iox.trdid.read() 615 << " wdata = " << p_vci_tgt_iox.wdata.read() 616 << " be = " << p_vci_tgt_iox.be.read() 617 << " contig = " << p_vci_tgt_iox.contig.read() 618 << " eop = " << std::dec << p_vci_tgt_iox.eop.read() 619 << " plen = " << std::dec << p_vci_tgt_iox.plen.read() << std::endl; 620 #endif 621 } 622 break; 623 } 624 ////////////////////// 625 case DMA_CMD_WAIT_EOP: // An error has been detected on the VCI DMA command 626 // consume the VCI packet before sending the error response 627 { 628 if ( p_vci_tgt_iox.eop.read() ) r_dma_cmd_fsm = DMA_CMD_FIFO_PUT_RSP; 629 break; 630 } 631 ////////////////////////// 632 case DMA_CMD_FIFO_PUT_RSP: // try to put a response error in DMA_RSP fifo 633 // The FIFO is shared with DMA_RSP FSM 634 // and we must we wait for allocation... 635 { 636 if ( r_alloc_fifo_dma_rsp_local.read() ) 637 { 638 dma_rsp_fifo_put = true; 639 640 if( m_dma_rsp_data_fifo.wok() ) 641 { 642 643 #if DEBUG_DMA_CMD 644 if( m_debug_activated ) 645 std::cout << " <IOB DMA_CMD_FIFO_PUT_RSP> Put a response error to a DMA transaction." 646 << std::endl; 647 #endif 648 r_dma_cmd_fsm = DMA_CMD_IDLE; 649 } 870 650 } 871 651 break; 872 652 } 873 653 /////////////////////// 874 case DMA_CMD_FIFO_MISS_PUT: 875 { 876 if ( m_dma_cmd_addr_fifo.wok() ) 877 { 878 dma_cmd_fifo_put = true; 879 //miss_unposted = true; 880 if( r_miss_contig.read() ) r_miss_paddr = r_miss_paddr.read() + 4; 881 882 if( r_dma_cmd_count.read() == 1 ) 654 case DMA_CMD_MISS_WAIT: // waiting completion of a TLB miss 655 // we must test a possible page fault error... 656 { 657 if ( not r_dma_tlb_req.read() ) // TLB miss completed 658 { 659 if ( r_tlb_miss_error.read() ) // Error reported by TLB FSM 883 660 { 884 r_tlb_dma_untreated = false; 885 r_miss_interrupt = false; 886 r_dma_cmd_fsm = r_dma_cmd_fsm_save.read(); 661 r_iommu_etr = MMU_READ_PT2_UNMAPPED; 662 r_iommu_bvar = r_dma_cmd_vaddr.read(); 663 r_iommu_bad_id = p_vci_tgt_iox.srcid.read(); 664 r_dma_cmd_fsm = DMA_CMD_FIFO_PUT_RSP; 887 665 } 888 r_dma_cmd_count = r_dma_cmd_count.read() - 1; 889 890 #if DEBUG_DMA_CMD 891 if( m_debug_dma_cmd_fsm ) 892 { 893 std::cout << " <IOB.DMA_CMD_FIFO_MISS_PUT> Push into cmd_fifo:" 894 << " counter = " << std::hex << r_dma_cmd_count.read() 895 << " address = " << std::hex << r_miss_paddr.read() 896 << " srcid = " << std::dec << r_miss_srcid.read() 897 << " trdid = " << r_miss_trdid.read() 898 << " wdata = " << std::hex << r_miss_data 899 << " be = " << r_miss_be 900 << " plen = " << std::dec << r_miss_plen.read() << std::endl; 901 } 902 #endif 903 } 904 break; 905 } 906 /////////////////// 907 case DMA_CMD_TLB_MISS_WAIT: // to store the miss request there must be 908 // neither an ongoing request, nor a unposted finished request 909 { 910 // Treats an eventual request from TLB_MISS fsm 911 // to send a command whose miss treatment is now finished 912 if ( r_tlb_dma_untreated.read() ) 913 { 914 r_dma_cmd_fsm = DMA_CMD_TRT_LOCK; //before posting we must update TRT 915 r_dma_cmd_fsm_save = DMA_CMD_TLB_MISS_WAIT; 916 r_miss_interrupt = true; 917 break; 918 } 919 // Error during miss treatment 920 else if (r_dma_tlb_error_req.read()) 921 { 922 r_iommu_etr = r_tlb_error_type.read(); 923 r_iommu_bvar = r_iotlb_vaddr.read(); 924 r_iommu_bad_id = r_miss_srcid.read(); 925 // For DMA_RSP FSM 926 if(r_miss_cmd.read() == vci_param_io::CMD_WRITE) r_dma_error_type = WRITE_ERROR; 927 else r_dma_error_type = READ_ERROR; 928 r_dma_error_trdid = r_miss_trdid.read(); 929 r_dma_error_pktid = r_miss_pktid.read(); 930 931 r_dma_tlb_error_req = false; 932 r_dma_cmd_fsm = DMA_CMD_ERROR; 933 } 934 935 #ifdef INSTRUMENTATION 936 m_cost_iotlb_miss++; // Now it represents misses' total blocking cost (not the treatment cost itself) 937 #endif 938 else if (not r_dma_tlb_req.read()) 939 { 940 r_dma_cmd_fsm = DMA_CMD_TLB_MISS_STORE; 941 assert((r_dma_cmd_count.read() == 0) and "ERROR: TRT counter should be 0"); 942 } 943 break; 944 } 945 /////////////////// 946 case DMA_CMD_TLB_MISS_STORE: 947 { 948 if ( p_vci_tgt_dma.cmdval.read()) 949 { 950 if(r_dma_cmd_count.read() == 0) 666 else // No error 951 667 { 952 r_miss_cmd = p_vci_tgt_dma.cmd.read(); 953 r_miss_contig = p_vci_tgt_dma.contig.read(); 954 r_miss_cons = p_vci_tgt_dma.cons.read(); 955 r_miss_plen = p_vci_tgt_dma.plen.read(); 956 r_miss_wrap = p_vci_tgt_dma.wrap.read(); 957 r_miss_cfixed = p_vci_tgt_dma.cfixed.read(); 958 r_miss_clen = p_vci_tgt_dma.clen.read(); 959 r_miss_srcid = p_vci_tgt_dma.srcid.read(); 960 r_miss_trdid = p_vci_tgt_dma.trdid.read(); 961 r_miss_pktid = p_vci_tgt_dma.pktid.read(); 962 963 // r_dma_tlb_req = true; 668 r_dma_cmd_fsm = DMA_CMD_IDLE; 964 669 } 965 966 r_miss_data[r_dma_cmd_count.read()] = p_vci_tgt_dma.wdata.read(); 967 r_miss_be[r_dma_cmd_count.read()] = p_vci_tgt_dma.be.read(); 968 969 r_dma_cmd_count = r_dma_cmd_count.read() + 1; 970 971 if( p_vci_tgt_dma.eop ) r_dma_cmd_fsm = DMA_CMD_IDLE; 972 973 #if DEBUG_DMA_CMD 974 if( m_debug_dma_cmd_fsm ) 975 { 976 std::cout << " <IOB.DMA_CMD_TLB_MISS_STORE> Storing VCI fields of command that originate the Miss:" 977 << " counter = " << std::hex << r_dma_cmd_count.read() 978 << " address = " << std::hex << p_vci_tgt_dma.address.read() 979 << " srcid = " << std::dec << p_vci_tgt_dma.srcid.read() 980 << " trdid = " << p_vci_tgt_dma.trdid.read() 981 << " wdata = " << std::hex << p_vci_tgt_dma.wdata.read() 982 << " be = " << p_vci_tgt_dma.be.read() 983 << " plen = " << std::dec << p_vci_tgt_dma.plen.read() << std::endl; 984 } 985 #endif 986 } 987 break; 988 } 989 /////////////////// 990 case DMA_CMD_ERROR: 991 { 992 // Wait in case of pending request 993 // it isn't the case, generally 994 if(!r_dma_cmd_error_req.read()) 995 { 996 r_dma_cmd_error_req = true; 997 r_dma_cmd_fsm = DMA_CMD_IDLE; 998 } 999 break; 1000 } 1001 } // end switch DMA_CMD_FSM 1002 1003 ///////////////////////////////////////////////////////////////////// 1004 // The DMA_RSP_FSM controls the following ressources: 1005 // - r_dma_rsp_fsm 1006 // - r_dma_cmd_rsp_erase_req (reset) 1007 // - r_fma_error_req (reset) 1008 // - 670 } 671 break; 672 } 673 } // end switch DMA_CMD FSM 674 1009 675 ////////////////////////////////////////////////////////////////////////////// 676 // The DMA_RSP_FSM handles the RAM responses to peripherals DMA transactions. 677 ////////////////////////////////////////////////////////////////////////////// 678 1010 679 switch( r_dma_rsp_fsm.read() ) 1011 680 { 1012 ////////////////// ///1013 case DMA_RSP_IDLE: 681 ////////////////// 682 case DMA_RSP_IDLE: // waiting a response from RAM betwork 1014 683 { 1015 // Interruption from DMA_CMD following an error 1016 if(r_dma_cmd_error_req.read()) r_dma_rsp_fsm = DMA_RSP_FIFO_ERROR_PUT; 1017 1018 if(p_vci_ini_dma.rspval.read()) 684 if ( p_vci_ini_ram.rspval.read() ) 1019 685 { 1020 r_dma_rsp_fsm = DMA_RSP_ TRT_LOCK;686 r_dma_rsp_fsm = DMA_RSP_FIFO_PUT; 1021 687 } 1022 688 break; 1023 689 } 1024 ///////////////////// 1025 case DMA_RSP_TRT_LOCK: 1026 { 1027 if ( r_alloc_trt_dma_fsm.read() == ALLOC_TRT_DMA_RSP ) 1028 { 1029 1030 #if DEBUG_DMA_RSP 1031 if( m_debug_dma_rsp_fsm ) 1032 { 1033 std::cout << " <IOB.DMA_RSP_TRT_LOCK> Erase entry" << std::endl; 1034 } 1035 #endif 1036 uint32_t trdid_xram = p_vci_ini_dma.rtrdid.read(); 1037 1038 r_dma_rsrcid = (vci_srcid_t)m_transaction_tab_dma.readSrcid(trdid_xram); 1039 r_dma_rtrdid = (vci_trdid_t)m_transaction_tab_dma.readTrdid(trdid_xram); 1040 m_transaction_tab_dma.erase(trdid_xram); 1041 if (r_dma_cmd_rsp_erase_req.read()) r_dma_cmd_rsp_erase_req = false; 1042 r_dma_rsp_fsm = DMA_RSP_FIFO_PUT; 1043 } 1044 break; 1045 } 1046 ////////////////// 690 ////////////////////// 1047 691 case DMA_RSP_FIFO_PUT: 1048 692 { 1049 if(p_vci_ini_ dma.rspval.read() && m_dma_rsp_data_fifo.wok())693 if(p_vci_ini_ram.rspval.read() and not r_alloc_fifo_dma_rsp_local.read() ) 1050 694 { 1051 695 dma_rsp_fifo_put = true; 1052 if(p_vci_ini_dma.reop.read()) r_dma_rsp_fsm = DMA_RSP_IDLE; 696 697 if(p_vci_ini_ram.reop.read()) r_dma_rsp_fsm = DMA_RSP_IDLE; 1053 698 1054 699 #if DEBUG_DMA_RSP 1055 if( m_debug_dma_rsp_fsm ) 1056 { 1057 std::cout << " <IOB.DMA_RSP_FIFO_PUT> Push into rsp_fifo:" 1058 << " rsrcid = " << std::dec << r_dma_rsrcid.read() 1059 << " rtrdid = " << r_dma_rtrdid.read() 1060 << " rdata = " << std::hex << p_vci_ini_dma.rdata.read() 1061 << std::endl; 1062 } 1063 #endif 1064 700 if( m_debug_activated ) 701 std::cout << " <IOB DMA_RSP_FIFO_PUT> Push response into DMA_RSP fifo:" 702 << " / rsrcid = " << std::hex << p_vci_ini_ram.rsrcid.read() 703 << " / rtrdid = " << p_vci_ini_ram.rtrdid.read() 704 << " / rdata = " << std::hex << p_vci_ini_ram.rdata.read() 705 << " / rerror = " << p_vci_ini_ram.rerror.read() 706 << " / reop = " << p_vci_ini_ram.reop.read() << std::endl; 707 #endif 1065 708 } 1066 709 break; 1067 710 } 1068 //////////////////1069 case DMA_RSP_FIFO_ERROR_PUT:1070 {1071 if(m_dma_rsp_data_fifo.wok())1072 {1073 dma_rsp_fifo_put = true;1074 r_dma_rsp_fsm = DMA_RSP_IDLE;1075 1076 #if DEBUG_DMA_RSP1077 if( m_debug_dma_rsp_fsm )1078 {1079 std::cout << " <IOB.DMA_RSP_FIFO_ERROR_PUT> Push into rsp_fifo:"1080 << " rsrcid = " << std::dec << r_iommu_bad_id.read()1081 << " rtrdid = " << r_dma_error_trdid.read()1082 << " rerror = " << r_dma_error_type.read()1083 << " rdata = " << std::hex << 01084 << std::endl;1085 }1086 #endif1087 1088 }1089 break;1090 }1091 711 } // end switch DMA_RSP_FSM 1092 712 1093 //////////////////////////////////////////////////////////////////////////// 1094 // The ALLOC_TRT_DMA fsm allocates the access to the Transaction Table (m_transaction_tab_dma) 1095 // with a round robin priority between 2 user FSMs : 1096 // - DMA_CMD : to set a new entry 1097 // - DMA_RSP : to read and erase an entry 1098 // The ressource is always allocated. 1099 //////////////////////////////////////////////////////////////////////////// 1100 1101 switch ( r_alloc_trt_dma_fsm.read() ) 1102 { 1103 /////////////////// 1104 case ALLOC_TRT_DMA_CMD: 1105 { 1106 if ( r_dma_cmd_fsm.read() != DMA_CMD_TRT_LOCK ) 1107 { 1108 if (r_dma_rsp_fsm.read() == DMA_RSP_TRT_LOCK) r_alloc_trt_dma_fsm = ALLOC_TRT_DMA_RSP; 1109 } 1110 break; 1111 } 1112 /////////////////// 1113 case ALLOC_TRT_DMA_RSP: 1114 { 1115 if (r_dma_rsp_fsm.read() != DMA_RSP_TRT_LOCK) 1116 { 1117 if (r_dma_cmd_fsm.read() == DMA_CMD_TRT_LOCK) r_alloc_trt_dma_fsm = ALLOC_TRT_DMA_CMD; 1118 } 1119 break; 1120 } 1121 } // end switch r_alloc_trt_dma_fsm 1122 1123 1124 //////////////////////////////////////////////////////////////////////////// 1125 // The DMA_TLB_MISS FSM handles an IOTLB miss. It blocks the TGT_FSM. 1126 // Input argument is: 1127 // - r_iotlb_vaddr 1128 // - r_dma_tlb_req (reset) 1129 // - r_tlb_miss_init_req (set) 1130 // - r_config_tlb_req (reset) 1131 // - r_tlb_dma_untreated (set) 1132 // 1133 // This fsm searchs the requested PTE on the prefetch buffer. 1134 // In case of miss, it accesses the XRAM to find the missing TLB entry, 713 ////////////////////////////////////////////////////////////////////////////////// 714 // The TLB FSM handles TLB miss request (from DMA_CMD FSM), 715 // and the PTE inval request (from CONFIG_CMD FSM). 716 // PTE inval request have highest priority. In case of TLB miss, 717 // this fsm searchs the requested PTE on the prefetch buffer. 718 // In case of buffer miss, it request the MISS_WTI FSM to access the memory. 1135 719 // It bypass the first level page table access if possible. 1136 // It directly updates the iotlb, and writes into the1137 // r_mmu_ins_* or r_mmu_data* error reporting registers.720 // It reset the r_dma_tlb_req flip-flop to signal TLB miss completion. 721 // An unexpected, but possible page fault is signaled in r_tlb_miss_error flip_flop. 1138 722 //////////////////////////////////////////////////////////////////////////////////// 1139 switch (r_dma_tlb_fsm.read()) 1140 { 1141 case DMA_TLB_IDLE: 1142 { 1143 if(r_config_tlb_req) 1144 { 1145 r_config_tlb_req = false; 723 724 switch (r_tlb_fsm.read()) 725 { 726 ////////////// 727 case TLB_IDLE: // In case of TLB miss request, chek the prefetch buffer first 728 // PTE inval request are handled as unmaskable interrupts 729 { 730 if ( r_config_tlb_req ) // Request from CONFIG FSM for a PTE invalidation 731 { 732 r_config_tlb_req = false; 1146 733 r_waiting_transaction = false; 1147 r_dma_tlb_fsm = DMA_TLB_INVAL_CHECK; 1148 // Request from CONFIG FSM following an PTE invalidation signal by OS 1149 } 1150 // Miss in IOTLB 1151 else if(r_dma_tlb_req.read()) 1152 { 1153 // Checking prefetch buffer, by the virtual address 1154 if(!r_miss_buf_first_level) 1155 { 1156 if( r_miss_buf_valid && 1157 (r_miss_buf_vaddr_begin.read() == 1158 (r_iotlb_vaddr.read()& ~PTE2_LINE_OFFSET & ~K_PAGE_OFFSET_MASK))) 734 r_tlb_fsm = TLB_INVAL_CHECK; 735 } 736 737 else if ( r_dma_tlb_req.read() ) // request from DMA_CMD for a TLB Miss 738 { 739 // Checking prefetch buffer 740 if( not r_tlb_buf_big_page ) // small page => PTE2 1159 741 { 1160 // Hit 1161 size_t pte_offset = (r_iotlb_vaddr.read()& PTE2_LINE_OFFSET)>>12; 1162 1163 1164 uint32_t pte_flags = r_miss_buf_data[2*pte_offset]; 1165 uint32_t pte_ppn = r_miss_buf_data[2*pte_offset+1]; //because PTE2 is 2 words long 742 if( r_tlb_buf_valid && // Hit on prefetch buffer 743 (r_tlb_buf_vaddr.read() == 744 (r_dma_cmd_vaddr.read()& ~PTE2_LINE_OFFSET & ~K_PAGE_OFFSET_MASK))) 745 { 746 size_t pte_offset = (r_dma_cmd_vaddr.read()& PTE2_LINE_OFFSET)>>12; 747 uint32_t pte_flags = r_tlb_buf_data[2*pte_offset]; 748 uint32_t pte_ppn = r_tlb_buf_data[2*pte_offset+1]; 1166 749 1167 // Bit valid checking 1168 if ( not ( pte_flags & PTE_V_MASK) ) // unmapped 1169 { 1170 //must not occur! 1171 std::cout << "IOMMU ERROR : " << name() << " DMA_TLB_IDLE state" << std::endl 1172 << "The Page Table entry ins't valid (unmapped)" << std::endl; 750 // Bit valid checking 751 if ( not ( pte_flags & PTE_V_MASK) ) // unmapped 752 { 753 std::cout << "VCI_IO_BRIDGE ERROR : " << name() 754 << " Page Table entry unmapped" << std::endl; 1173 755 1174 r_tlb_error_type = MMU_READ_PT2_UNMAPPED; 1175 r_dma_tlb_error_req = true; 1176 r_dma_tlb_req = false; 1177 1178 #if DEBUG_DMA_TLB 1179 if ( m_debug_dma_tlb_fsm ) 1180 { 1181 std::cout << " <IOB.DMA_TLB_IDLE> PTE2 Unmapped" 1182 << std::hex << " / paddr = " << r_iotlb_paddr.read() 1183 << std::hex << " / PTE (first word) = " << pte_flags << std::endl; 1184 } 1185 #endif 1186 break; 1187 } 1188 1189 r_iotlb_pte_flags = pte_flags; 1190 r_iotlb_pte_ppn = pte_ppn; 1191 r_dma_tlb_fsm = DMA_TLB_PTE2_SELECT; 1192 1193 #if DEBUG_DMA_TLB 1194 if ( m_debug_dma_tlb_fsm ) 1195 { 1196 std::cout << " <IOB.DMA_TLB_IDLE> Hit on the prefetch buffer for PTE2:" 1197 << " PTE_FLAGS = " << std::hex << pte_flags 1198 << " PTE_PPN = " << std::hex << pte_ppn << std::endl; 1199 } 1200 #endif 1201 break; 756 r_tlb_miss_error = true; 757 r_dma_tlb_req = false; 758 #if DEBUG_TLB_MISS 759 if ( m_debug_activated ) 760 std::cout << " <IOB TLB_IDLE> PTE2 Unmapped" << std::hex 761 << " / paddr = " << r_tlb_paddr.read() 762 << " / PTE_FLAGS = " << pte_flags 763 << " / PTE_PPN = " << pte_ppn << std::endl; 764 #endif 765 break; 766 } 767 768 // valid PTE2 : we must update the TLB 769 r_tlb_pte_flags = pte_flags; 770 r_tlb_pte_ppn = pte_ppn; 771 r_tlb_fsm = TLB_PTE2_SELECT; 772 #if DEBUG_TLB_MISS 773 if ( m_debug_activated ) 774 std::cout << " <IOB TLB_IDLE> Hit on prefetch buffer: PTE2" << std::hex 775 << " / PTE_FLAGS = " << pte_flags 776 << " / PTE_PPN = " << pte_ppn << std::endl; 777 #endif 778 break; 779 } 1202 780 } 1203 } 1204 else // First level entries on buffer. Unused if only small pages 1205 { 1206 if( r_miss_buf_valid && 1207 (r_miss_buf_vaddr_begin.read() == 1208 (r_iotlb_vaddr.read()& ~PTE1_LINE_OFFSET & ~M_PAGE_OFFSET_MASK ))) 1209 // The virtual address corresponds to one entry on the buffer line 781 else // big page => PTE1 1210 782 { 1211 // Hit 1212 size_t pte_offset = (r_iotlb_vaddr.read()& PTE1_LINE_OFFSET)>>21; 1213 1214 uint32_t pte_flags = r_miss_buf_data[pte_offset]; 783 if( r_tlb_buf_valid && // Hit on prefetch buffer 784 (r_tlb_buf_vaddr.read() == 785 (r_dma_cmd_vaddr.read()& ~PTE1_LINE_OFFSET & ~M_PAGE_OFFSET_MASK ))) 786 { 787 size_t pte_offset = (r_dma_cmd_vaddr.read()& PTE1_LINE_OFFSET)>>21; 788 uint32_t pte_flags = r_tlb_buf_data[pte_offset]; 1215 789 1216 // Bit valid checking 1217 if ( not ( pte_flags & PTE_V_MASK) ) // unmapped 1218 { 1219 //must not occur! 1220 std::cout << "IOMMU ERROR " << name() << "DMA_TLB_IDLE state" << std::endl 1221 << "The Page Table entry ins't valid (unmapped)" << std::endl; 790 // Bit valid checking 791 if ( not ( pte_flags & PTE_V_MASK) ) // unmapped 792 { 793 std::cout << "VCI_IO_BRIDGE ERROR : " << name() 794 << " Page Table entry unmapped" << std::endl; 1222 795 1223 r_tlb_error_type = MMU_READ_PT1_UNMAPPED; 1224 r_dma_tlb_error_req = true; 1225 r_dma_tlb_req = false; 1226 1227 #if DEBUG_DMA_TLB 1228 if ( m_debug_dma_tlb_fsm ) 1229 { 1230 std::cout << " <IOB.DMA_TLB_IDLE> First level entry Unmapped" 1231 << std::hex << " / paddr = " << r_iotlb_paddr.read() 1232 << std::hex << " / PTE = " << pte_flags << std::endl; 1233 } 1234 #endif 1235 break; 1236 } 1237 1238 if( pte_flags & PTE_T_MASK ) // PTD : me must access PT2 1239 { 1240 // register bypass 1241 r_iotlb.set_bypass( r_iotlb_vaddr.read(), 1242 pte_flags & ((1 << (m_paddr_nbits-PAGE_K_NBITS)) - 1), 1243 0); //nline, unused 1244 1245 //&PTE2 = PTBA + IX2 * 8 1246 // ps: PAGE_K_NBITS corresponds also to the size of a second level page table 1247 r_iotlb_paddr = (paddr_t)(pte_flags & ((1<<(m_paddr_nbits-PAGE_K_NBITS))-1)) << PAGE_K_NBITS | 1248 (paddr_t)(((r_iotlb_vaddr.read() & PTD_ID2_MASK) >> PAGE_K_NBITS) << 3); 1249 r_tlb_miss_init_req = true; 1250 r_tlb_miss_type = PTE2_MISS; 1251 r_dma_tlb_fsm = DMA_TLB_WAIT_TRANSACTION; 796 r_tlb_miss_error = true; 797 r_dma_tlb_req = false; 798 #if DEBUG_TLB_MISS 799 if ( m_debug_activated ) 800 std::cout << " <IOB TLB_IDLE> PTE1 Unmapped" << std::hex 801 << " / paddr = " << r_tlb_paddr.read() 802 << " / PTE = " << pte_flags << std::endl; 803 #endif 804 break; 805 } 806 807 // valid PTE1 : we must update the TLB 808 r_tlb_pte_flags = pte_flags; 809 r_tlb_fsm = TLB_PTE1_SELECT; 810 #if DEBUG_TLB_MISS 811 if ( m_debug_activated ) 812 std::cout << " <IOB TLB_PTE1_GET> Hit on prefetch buffer: PTE1" << std::hex 813 << " / paddr = " << r_tlb_paddr.read() 814 << std::hex << " / PTE1 = " << pte_flags << std::endl; 815 #endif 816 break; 817 } 818 } 819 820 // prefetch buffer miss 821 r_tlb_fsm = TLB_MISS; 822 823 #if DEBUG_TLB_MISS 824 if ( m_debug_activated ) 825 std::cout << " <IOB TLB_IDLE> Miss on prefetch buffer" 826 << std::hex << " / vaddr = " << r_dma_cmd_vaddr.read() << std::endl; 827 #endif 828 } 829 break; 830 } 831 ////////////// 832 case TLB_MISS: // handling tlb miss 833 { 834 uint32_t ptba = 0; 835 bool bypass; 836 vci_addr_t pte_paddr; 837 1252 838 #ifdef INSTRUMENTATION 1253 839 m_cpt_iotlbmiss_transaction++; 1254 840 #endif 1255 1256 #if DEBUG_DMA_TLB1257 if ( m_debug_dma_tlb_fsm )1258 {1259 std::cout << " <IOB.DMA_TLB_IDLE> Hit on prefetch, but it is a PTD.Search PTE2"1260 << std::hex << " / paddr = " << r_iotlb_paddr.read()1261 << std::hex << " / PTD = " << pte_flags << std::endl;1262 }1263 #endif1264 }1265 else // PTE1 : we must update the TLB1266 // Should not occur if working only with small pages1267 {1268 r_iotlb_pte_flags = pte_flags;1269 r_dma_tlb_fsm = DMA_TLB_PTE1_SELECT;1270 1271 #if DEBUG_DMA_TLB1272 if ( m_debug_dma_tlb_fsm )1273 {1274 std::cout << " <IOB.DMA_TLB_PTE1_GET> Success. Big page"1275 << std::hex << " / paddr = " << r_iotlb_paddr.read()1276 << std::hex << " / PTE1 = " << pte_flags << std::endl;1277 }1278 #endif1279 }1280 break;1281 }1282 }1283 1284 r_dma_tlb_fsm = DMA_TLB_MISS;1285 1286 #if DEBUG_DMA_TLB1287 if ( m_debug_dma_tlb_fsm )1288 {1289 std::cout << " <IOB.DMA_TLB_IDLE> Miss on prefetch."1290 << std::hex << " / vaddr = " << r_iotlb_vaddr.read() << std::endl;1291 }1292 #endif1293 }1294 break;1295 }1296 /////////////////////1297 case DMA_TLB_MISS: // handling all tlb miss1298 {1299 uint32_t ptba = 0; //28 bits en TSAR1300 bool bypass;1301 paddr_t pte_paddr;1302 1303 841 // evaluate bypass in order to skip first level page table access 1304 bypass = r_iotlb.get_bypass(r_ iotlb_vaddr.read(), &ptba);842 bypass = r_iotlb.get_bypass(r_dma_cmd_vaddr.read(), &ptba); 1305 843 1306 // Request to MISS_INIT_FSM to start transaction on Direct Network844 // Request MISS_WTI_FSM a transaction on INT Network 1307 845 if ( not bypass ) // Read PTE1/PTD1 in XRAM 1308 846 { 1309 // VOIR CONVENTION >> 13 1310 pte_paddr = (paddr_t)((r_iommu_ptpr.read()) << (INDEX1_NBITS+2)) | 1311 (paddr_t)((r_iotlb_vaddr.read() >> PAGE_M_NBITS) << 2); 1312 r_iotlb_paddr = pte_paddr; 847 848 #if DEBUG_TLB_MISS 849 if ( m_debug_activated ) 850 std::cout << " <IOB TLB_MISS> Read PTE1/PTD1 in memory" << std::endl; 851 #endif 852 pte_paddr = (vci_addr_t)((r_iommu_ptpr.read()) << (INDEX1_NBITS+2)) | 853 (vci_addr_t)((r_dma_cmd_vaddr.read() >> PAGE_M_NBITS) << 2); 854 r_tlb_paddr = pte_paddr; 1313 855 1314 r_tlb_miss_init_req = true; 1315 r_tlb_miss_type = PTE1_MISS; 1316 r_dma_tlb_fsm = DMA_TLB_WAIT_TRANSACTION; 1317 #ifdef INSTRUMENTATION 1318 m_cpt_iotlbmiss_transaction++; 1319 #endif 856 r_tlb_miss_req = true; 857 r_tlb_miss_type = PTE1_MISS; 858 r_tlb_fsm = TLB_WAIT; 1320 859 } 1321 860 else // Read PTE2 in XRAM 1322 861 { 862 863 #if DEBUG_TLB_MISS 864 if ( m_debug_activated ) 865 std::cout << " <IOB TLB_MISS> Read PTE2 in memory" << std::endl; 866 #endif 1323 867 //&PTE2 = PTBA + IX2 * 8 1324 pte_paddr = ( paddr_t)ptba << PAGE_K_NBITS |1325 ( paddr_t)(r_iotlb_vaddr.read()&PTD_ID2_MASK)>>(PAGE_K_NBITS-3);868 pte_paddr = (vci_addr_t)ptba << PAGE_K_NBITS | 869 (vci_addr_t)(r_dma_cmd_vaddr.read()&PTD_ID2_MASK)>>(PAGE_K_NBITS-3); 1326 870 1327 r_ iotlb_paddr = pte_paddr;871 r_tlb_paddr = pte_paddr; 1328 872 1329 r_tlb_miss_init_req = true; 1330 r_tlb_miss_type = PTE2_MISS; 1331 r_dma_tlb_fsm = DMA_TLB_WAIT_TRANSACTION; 1332 #ifdef INSTRUMENTATION 1333 m_cpt_iotlbmiss_transaction++; 1334 #endif 1335 } 1336 1337 #if DEBUG_DMA_TLB 1338 if ( m_debug_dma_tlb_fsm ) 1339 { 1340 std::cout << " <IOB.DMA_TLB_MISS> IOTLB miss"; 1341 std::cout << " / VADDR = " << std::hex << r_iotlb_vaddr.read() 1342 << " / BYPASS = " << bypass 1343 << " / PTE_ADR = " << pte_paddr << std::endl; 1344 } 1345 #endif 1346 1347 break; 1348 } 1349 ///////////////////////// 1350 case DMA_TLB_PTE1_GET: // Try to read a PT1 entry in the miss buffer 873 r_tlb_miss_req = true; 874 r_tlb_miss_type = PTE2_MISS; 875 r_tlb_fsm = TLB_WAIT; 876 } 877 878 break; 879 } 880 ////////////////// 881 case TLB_PTE1_GET: // Try to read a PT1 entry in the miss buffer 1351 882 { 1352 883 1353 884 uint32_t entry; 1354 885 1355 paddr_t line_number = (paddr_t)((r_iotlb_paddr.read())&(CACHE_LINE_MASK));1356 size_t word_position = (size_t)( ((r_ iotlb_paddr.read())&(~CACHE_LINE_MASK))>>2 );886 vci_addr_t line_number = (vci_addr_t)((r_tlb_paddr.read())&(CACHE_LINE_MASK)); 887 size_t word_position = (size_t)( ((r_tlb_paddr.read())&(~CACHE_LINE_MASK))>>2 ); 1357 888 1358 889 // Hit test. Just to verify. 1359 890 // Hit must happen, since we've just finished its' miss transaction 1360 bool hit = (r_ miss_buf_valid && (r_miss_buf_tag.read()== line_number) );891 bool hit = (r_tlb_buf_valid && (r_tlb_buf_tag.read()== line_number) ); 1361 892 assert(hit and "Error: No hit on prefetch buffer after Miss Transaction"); 1362 893 1363 entry = r_ miss_buf_data[word_position];894 entry = r_tlb_buf_data[word_position]; 1364 895 1365 896 // Bit valid checking … … 1367 898 { 1368 899 //must not occur! 1369 std::cout << "IOMMU ERROR " << name() << " DMA_TLB_IDLE state" << std::endl900 std::cout << "IOMMU ERROR " << name() << "TLB_IDLE state" << std::endl 1370 901 << "The Page Table entry ins't valid (unmapped)" << std::endl; 1371 902 1372 r_tlb_ error_type = MMU_READ_PT1_UNMAPPED;1373 r_dma_tlb_ error_req = true;1374 r_ dma_tlb_req = false;1375 r_dma_tlb_fsm = DMA_TLB_IDLE; 1376 #if DEBUG_ DMA_TLB1377 if ( m_debug_ dma_tlb_fsm)903 r_tlb_miss_error = true; 904 r_dma_tlb_req = false; 905 r_tlb_fsm = TLB_IDLE; 906 907 #if DEBUG_TLB_MISS 908 if ( m_debug_activated ) 1378 909 { 1379 std::cout << " <IOB .DMA_PTE1_GET> First level entry Unmapped"1380 << std::hex << " / paddr = " << r_ iotlb_paddr.read()910 std::cout << " <IOB DMA_PTE1_GET> First level entry Unmapped" 911 << std::hex << " / paddr = " << r_tlb_paddr.read() 1381 912 << std::hex << " / PTE = " << entry << std::endl; 1382 913 } … … 1388 919 { 1389 920 // register bypass 1390 r_iotlb.set_bypass( r_ iotlb_vaddr.read(),1391 entry & ((1 << ( m_paddr_nbits-PAGE_K_NBITS)) - 1),921 r_iotlb.set_bypass( r_dma_cmd_vaddr.read(), 922 entry & ((1 << (vci_param_int::N-PAGE_K_NBITS)) - 1), 1392 923 0); //nline, unused 1393 924 1394 925 //&PTE2 = PTBA + IX2 * 8 1395 926 // ps: PAGE_K_NBITS corresponds also to the size of a second level page table 1396 r_iotlb_paddr = (paddr_t)(entry & ((1<<(m_paddr_nbits-PAGE_K_NBITS))-1)) << PAGE_K_NBITS | 1397 (paddr_t)(((r_iotlb_vaddr.read() & PTD_ID2_MASK) >> PAGE_K_NBITS) << 3); 1398 r_tlb_miss_init_req = true; 1399 r_tlb_miss_type = PTE2_MISS; 1400 r_dma_tlb_fsm = DMA_TLB_WAIT_TRANSACTION; 927 r_tlb_paddr = (vci_addr_t)(entry & ((1<<(vci_param_int::N-PAGE_K_NBITS))-1)) << PAGE_K_NBITS | 928 (vci_addr_t)(((r_dma_cmd_vaddr.read() & PTD_ID2_MASK) >> PAGE_K_NBITS) << 3); 929 r_tlb_miss_req = true; 930 r_tlb_miss_type = PTE2_MISS; 931 r_tlb_fsm = TLB_WAIT; 932 1401 933 #ifdef INSTRUMENTATION 1402 934 m_cpt_iotlbmiss_transaction++; 1403 935 #endif 1404 936 1405 #if DEBUG_DMA_TLB 1406 if ( m_debug_dma_tlb_fsm ) 1407 { 1408 std::cout << " <IOB.DMA_TLB_PTE1_GET> Success. Search PTE2" 1409 << std::hex << " / paddr = " << r_iotlb_paddr.read() 1410 << std::hex << " / PTD = " << entry << std::endl; 1411 } 937 #if DEBUG_TLB_MISS 938 if ( m_debug_activated ) 939 std::cout << " <IOB TLB_PTE1_GET> Success. Search PTE2" << std::hex 940 << " / PADDR = " << r_tlb_paddr.read() 941 << " / PTD = " << entry << std::endl; 1412 942 #endif 1413 943 } … … 1415 945 // Should not occur if working only with small pages 1416 946 { 1417 r_iotlb_pte_flags = entry; 1418 r_dma_tlb_fsm = DMA_TLB_PTE1_SELECT; 1419 1420 #if DEBUG_DMA_TLB 1421 if ( m_debug_dma_tlb_fsm ) 1422 { 1423 std::cout << " <IOB.DMA_TLB_PTE1_GET> Success. Big page" 1424 << std::hex << " / paddr = " << r_iotlb_paddr.read() 1425 << std::hex << " / PTE1 = " << entry << std::endl; 1426 } 1427 #endif 1428 } 1429 1430 break; 1431 } 1432 //////////////////////////// 1433 case DMA_TLB_PTE1_SELECT: // select a slot for PTE1 947 r_tlb_pte_flags = entry; 948 r_tlb_fsm = TLB_PTE1_SELECT; 949 950 #if DEBUG_TLB_MISS 951 if ( m_debug_activated ) 952 std::cout << " <IOB TLB_PTE1_GET> Success. Big page" 953 << std::hex << " / paddr = " << r_tlb_paddr.read() 954 << std::hex << " / PTE1 = " << entry << std::endl; 955 #endif 956 } 957 break; 958 } 959 ///////////////////// 960 case TLB_PTE1_SELECT: // select a slot for PTE1 1434 961 { 1435 962 size_t way; 1436 963 size_t set; 1437 964 1438 r_iotlb.select( r_ iotlb_vaddr.read(),965 r_iotlb.select( r_dma_cmd_vaddr.read(), 1439 966 true, // PTE1 1440 967 &way, … … 1444 971 #endif 1445 972 1446 #if DEBUG_DMA_TLB 1447 if ( m_debug_dma_tlb_fsm ) 1448 { 1449 std::cout << " <IOB.DMA_TLB_PTE1_SELECT> Select a slot in IOTLB:"; 1450 std::cout << " way = " << std::dec << way 1451 << " / set = " << set << std::endl; 1452 } 1453 #endif 1454 r_iotlb_way = way; 1455 r_iotlb_set = set; 1456 r_dma_tlb_fsm = DMA_TLB_PTE1_UPDT; 1457 break; 1458 } 1459 ////////////////////////// 1460 case DMA_TLB_PTE1_UPDT: // write a new PTE1 in tlb 1461 // not necessary to treat the L/R bit 1462 { 1463 //(OLD) paddr_t nline = r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words)+2); 1464 uint32_t pte = r_iotlb_pte_flags.read(); 973 #if DEBUG_TLB_MISS 974 if ( m_debug_activated ) 975 std::cout << " <IOB TLB_PTE1_SELECT> Select a slot in TLB" 976 << " / way = " << std::dec << way 977 << " / set = " << set << std::endl; 978 #endif 979 r_tlb_way = way; 980 r_tlb_set = set; 981 r_tlb_fsm = TLB_PTE1_UPDT; 982 break; 983 } 984 /////////////////// 985 case TLB_PTE1_UPDT: // write a new PTE1 in tlb 986 // not necessary to treat the L/R bit 987 { 988 uint32_t pte = r_tlb_pte_flags.read(); 1465 989 1466 r_ miss_paddr = (paddr_t)( ((r_iotlb_pte_flags.read() & PPN1_MASK) << 21)1467 | (r_ iotlb_vaddr.read()& M_PAGE_OFFSET_MASK) );990 r_tlb_paddr = (vci_addr_t)( ((r_tlb_pte_flags.read() & PPN1_MASK) << 21) 991 | (r_dma_cmd_vaddr.read()& M_PAGE_OFFSET_MASK) ); 1468 992 1469 993 // update TLB … … 1471 995 pte, 1472 996 0, // argument unused for a PTE1 1473 r_ iotlb_vaddr.read(),1474 r_ iotlb_way.read(),1475 r_ iotlb_set.read(),997 r_dma_cmd_vaddr.read(), 998 r_tlb_way.read(), 999 r_tlb_set.read(), 1476 1000 0 ); //we set nline = 0 1477 1001 #ifdef INSTRUMENTATION … … 1479 1003 #endif 1480 1004 1481 #if DEBUG_ DMA_TLB1482 if ( m_debug_ dma_tlb_fsm)1005 #if DEBUG_TLB_MISS 1006 if ( m_debug_activated ) 1483 1007 { 1484 std::cout << " <IOB.DMA_TLB_PTE1_UPDT> write PTE1 in IOTLB"; 1485 std::cout << " / set = " << std::dec << r_iotlb_set.read()1486 << " / way = " << r_iotlb_way.read() << std::endl;1487 1008 std::cout << " <IOB TLB_PTE1_UPDT> write PTE1 in TLB" 1009 << " / set = " << std::dec << r_tlb_set.read() 1010 << " / way = " << r_tlb_way.read() << std::endl; 1011 r_iotlb.printTrace(); 1488 1012 } 1489 1013 #endif 1490 1014 // next state 1491 r_ dma_tlb_fsm = DMA_TLB_RETURN; // exit sub-fsm1492 break; 1493 } 1494 ////////////////// ///////1495 case DMA_TLB_PTE2_GET: // Try to read a PTE2 (64 bits) in the miss buffer1015 r_tlb_fsm = TLB_RETURN; // exit sub-fsm 1016 break; 1017 } 1018 ////////////////// 1019 case TLB_PTE2_GET: // Try to read a PTE2 (64 bits) in the miss buffer 1496 1020 { 1497 1021 uint32_t pte_flags; 1498 1022 uint32_t pte_ppn; 1499 1023 1500 paddr_t line_number = (paddr_t)((r_iotlb_paddr.read())&(CACHE_LINE_MASK));1501 size_t word_position = (size_t)( ((r_ iotlb_paddr.read())&(~CACHE_LINE_MASK))>>2 );1024 vci_addr_t line_number = (vci_addr_t)((r_tlb_paddr.read())&(CACHE_LINE_MASK)); 1025 size_t word_position = (size_t)( ((r_tlb_paddr.read())&(~CACHE_LINE_MASK))>>2 ); 1502 1026 1503 1027 1504 1028 // Hit test. Just to verify. 1505 bool hit = (r_ miss_buf_valid && (r_miss_buf_tag.read()== line_number) );1029 bool hit = (r_tlb_buf_valid && (r_tlb_buf_tag.read()== line_number) ); 1506 1030 assert(hit and "Error: No hit on prefetch buffer after Miss Transaction"); 1507 pte_flags= r_ miss_buf_data[word_position];1508 pte_ppn= r_ miss_buf_data[word_position+1]; //because PTE2 is 2 words long1031 pte_flags= r_tlb_buf_data[word_position]; 1032 pte_ppn= r_tlb_buf_data[word_position+1]; //because PTE2 is 2 words long 1509 1033 // Bit valid checking 1510 1034 if ( not ( pte_flags & PTE_V_MASK) ) // unmapped 1511 1035 { 1512 1036 //must not occur! 1513 std::cout << "IOMMU ERROR " << name() << " DMA_TLB_IDLE state" << std::endl1037 std::cout << "IOMMU ERROR " << name() << "TLB_IDLE state" << std::endl 1514 1038 << "The Page Table entry ins't valid (unmapped)" << std::endl; 1515 1039 1516 r_tlb_error_type = MMU_READ_PT2_UNMAPPED; 1517 r_dma_tlb_error_req = true; 1518 r_dma_tlb_req = false; 1519 r_dma_tlb_fsm = DMA_TLB_IDLE; 1520 #if DEBUG_DMA_TLB 1521 if ( m_debug_dma_tlb_fsm ) 1522 { 1523 std::cout << " <IOB.DMA_TLB_PTE2_GET> PTE2 Unmapped" 1524 << std::hex << " / paddr = " << r_iotlb_paddr.read() 1525 << std::hex << " / PTE = " << pte_flags << std::endl; 1526 } 1527 #endif 1528 break; 1040 r_tlb_miss_error = true; 1041 r_dma_tlb_req = false; 1042 r_tlb_fsm = TLB_IDLE; 1043 1044 #if DEBUG_TLB_MISS 1045 if ( m_debug_activated ) 1046 std::cout << " <IOB TLB_PTE2_GET> PTE2 Unmapped" << std::hex 1047 << " / PADDR = " << r_tlb_paddr.read() 1048 << " / PTE = " << pte_flags << std::endl; 1049 #endif 1050 break; 1529 1051 } 1530 1052 1531 r_ iotlb_pte_flags = pte_flags;1532 r_ iotlb_pte_ppn = pte_ppn;1533 r_ dma_tlb_fsm = DMA_TLB_PTE2_SELECT;1053 r_tlb_pte_flags = pte_flags; 1054 r_tlb_pte_ppn = pte_ppn; 1055 r_tlb_fsm = TLB_PTE2_SELECT; 1534 1056 1535 #if DEBUG_DMA_TLB 1536 if ( m_debug_dma_tlb_fsm ) 1537 { 1538 std::cout << " <IOB.DMA_TLB_PTE2_GET> Mapped:" 1539 << " PTE_FLAGS = " << std::hex << pte_flags 1540 << " PTE_PPN = " << std::hex << pte_ppn << std::endl; 1541 } 1057 #if DEBUG_TLB_MISS 1058 if ( m_debug_activated ) 1059 std::cout << " <IOB TLB_PTE2_GET> Mapped" << std::hex 1060 << " / PTE_FLAGS = " << pte_flags 1061 << " / PTE_PPN = " << pte_ppn << std::endl; 1542 1062 #endif 1543 1063 break; 1544 1064 } 1545 1065 //////////////////////////// 1546 case DMA_TLB_PTE2_SELECT: // select a slot for PTE21066 case TLB_PTE2_SELECT: // select a slot for PTE2 1547 1067 { 1548 1068 size_t way; 1549 1069 size_t set; 1550 1070 1551 r_iotlb.select( r_ iotlb_vaddr.read(),1071 r_iotlb.select( r_dma_cmd_vaddr.read(), 1552 1072 false, // PTE2 1553 1073 &way, … … 1557 1077 #endif 1558 1078 1559 #if DEBUG_ DMA_TLB1560 if ( m_debug_ dma_tlb_fsm)1079 #if DEBUG_TLB_MISS 1080 if ( m_debug_activated ) 1561 1081 { 1562 std::cout << " <IOB .DMA_TLB_PTE2_SELECT> Select a slot in IOTLB:";1082 std::cout << " <IOB TLB_PTE2_SELECT> Select a slot in IOTLB:"; 1563 1083 std::cout << " way = " << std::dec << way 1564 1084 << " / set = " << set << std::endl; 1565 1085 } 1566 1086 #endif 1567 r_iotlb_way = way; 1568 r_iotlb_set = set; 1569 r_dma_tlb_fsm = DMA_TLB_PTE2_UPDT; 1570 break; 1571 } 1572 ////////////////////////// 1573 case DMA_TLB_PTE2_UPDT: // write a new PTE2 in tlb 1574 // not necessary to treat the L/R bit 1575 { 1576 //(OLD) paddr_t nline = r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words)+2); 1577 uint32_t pte_flags = r_iotlb_pte_flags.read(); 1578 uint32_t pte_ppn = r_iotlb_pte_ppn.read(); 1087 r_tlb_way = way; 1088 r_tlb_set = set; 1089 r_tlb_fsm = TLB_PTE2_UPDT; 1090 break; 1091 } 1092 /////////////////// 1093 case TLB_PTE2_UPDT: // write a new PTE2 in tlb 1094 // not necessary to treat the L/R bit 1095 { 1096 uint32_t pte_flags = r_tlb_pte_flags.read(); 1097 uint32_t pte_ppn = r_tlb_pte_ppn.read(); 1579 1098 1580 r_ miss_paddr = (paddr_t)( ((r_iotlb_pte_ppn.read() & PPN2_MASK) << 12)1581 | (r_ iotlb_vaddr.read()& K_PAGE_OFFSET_MASK) );1099 r_tlb_paddr = (vci_addr_t)( ((r_tlb_pte_ppn.read() & PPN2_MASK) << 12) 1100 | (r_dma_cmd_vaddr.read()& K_PAGE_OFFSET_MASK) ); 1582 1101 1583 1102 // update TLB for a PTE2 … … 1585 1104 pte_flags, 1586 1105 pte_ppn, 1587 r_ iotlb_vaddr.read(),1588 r_ iotlb_way.read(),1589 r_ iotlb_set.read(),1106 r_dma_cmd_vaddr.read(), 1107 r_tlb_way.read(), 1108 r_tlb_set.read(), 1590 1109 0 ); // nline = 0 1591 1110 #ifdef INSTRUMENTATION … … 1593 1112 #endif 1594 1113 1595 #if DEBUG_ DMA_TLB1596 if ( m_debug_ dma_tlb_fsm)1114 #if DEBUG_TLB_MISS 1115 if ( m_debug_activated ) 1597 1116 { 1598 std::cout << " <IOB .DMA_TLB_PTE2_UPDT> write PTE2 in IOTLB";1599 std::cout << " / set = " << std::dec << r_ iotlb_set.read()1600 << " / way = " << r_ iotlb_way.read() << std::endl;1117 std::cout << " <IOB TLB_PTE2_UPDT> write PTE2 in IOTLB"; 1118 std::cout << " / set = " << std::dec << r_tlb_set.read() 1119 << " / way = " << r_tlb_way.read() << std::endl; 1601 1120 r_iotlb.printTrace(); 1602 1121 } 1603 1122 #endif 1604 1123 // next state 1605 r_ dma_tlb_fsm = DMA_TLB_RETURN; // exit sub-fsm1606 break; 1607 } 1608 ////////////// /////////1609 case DMA_TLB_WAIT_TRANSACTION:1610 {1611 // CONFIG FSM request following a invalidation signal sent by OS.1612 if (r_config_tlb_req)1124 r_tlb_fsm = TLB_RETURN; 1125 break; 1126 } 1127 ////////////// 1128 case TLB_WAIT: // waiting completion of a miss transaction from MISS_WTI FSM 1129 // PTE inval request are handled as unmaskable interrupts 1130 { 1131 if ( r_config_tlb_req ) // Request from CONFIG FSM for a PTE invalidation 1613 1132 { 1614 1133 r_config_tlb_req = false; 1615 1134 r_waiting_transaction = true; 1616 r_ dma_tlb_fsm = DMA_TLB_INVAL_CHECK;1135 r_tlb_fsm = TLB_INVAL_CHECK; 1617 1136 } 1618 1137 … … 1620 1139 m_cost_iotlbmiss_transaction++; 1621 1140 #endif 1622 if ( not r_tlb_miss_ init_req ) // Miss transaction is done1141 if ( not r_tlb_miss_req ) // Miss transaction is done 1623 1142 { 1624 if ( r_miss_ init_error.read() ) // bus error1143 if ( r_miss_wti_rsp_error.read() ) // bus error 1625 1144 { 1626 r_miss_init_error = false; 1627 r_tlb_error_type = MMU_READ_DATA_ILLEGAL_ACCESS; 1628 r_dma_tlb_error_req = true; 1629 r_dma_tlb_req = false; 1630 r_dma_tlb_fsm = DMA_TLB_IDLE; 1145 r_miss_wti_rsp_error = false; 1146 r_tlb_miss_error = true; 1147 r_dma_tlb_req = false; 1148 r_tlb_fsm = TLB_IDLE; 1631 1149 } 1632 1150 else if(r_tlb_miss_type == PTE1_MISS) 1633 1151 { 1634 r_dma_tlb_fsm = DMA_TLB_PTE1_GET; 1635 1152 r_tlb_fsm = TLB_PTE1_GET; 1636 1153 } 1637 1154 else 1638 1155 { 1639 r_ dma_tlb_fsm = DMA_TLB_PTE2_GET;1156 r_tlb_fsm = TLB_PTE2_GET; 1640 1157 } 1641 1158 } 1642 1159 break; 1643 1160 } 1644 /////////////////////// 1645 case DMA_TLB_RETURN: // return to caller depending on tlb miss type 1646 { 1647 #if DEBUG_DMA_TLB 1648 if ( m_debug_dma_tlb_fsm ) 1649 { 1650 std::cout << " <IOB.DMA_TLB_RETURN> IOTLB MISS completed" << std::endl; 1651 } 1652 #endif 1653 r_dma_tlb_req = false; 1654 r_tlb_dma_untreated = true; 1655 r_dma_tlb_fsm = DMA_TLB_IDLE; 1656 break; 1657 } 1658 ////////////////////// 1659 case DMA_TLB_INVAL_CHECK: // request from CONFIG FSM to invalidate all PTE on a given line 1660 // This state checks the necessity to invalidate prefetch buffer 1161 //////////////// 1162 case TLB_RETURN: // reset r_dma_tlb_req flip-flop to signal TLB miss completion 1163 // possible errors are signaled through r_tlb_miss_error 1164 { 1165 #if DEBUG_TLB_MISS 1166 if ( m_debug_activated ) 1167 std::cout << " <IOB TLB_RETURN> IOTLB MISS completed" << std::endl; 1168 #endif 1169 r_dma_tlb_req = false; 1170 r_tlb_fsm = TLB_IDLE; 1171 break; 1172 } 1173 ///////////////////// 1174 case TLB_INVAL_CHECK: // request from CONFIG_FSM to invalidate all PTE in a given line 1175 // checks the necessity to invalidate prefetch buffer 1661 1176 { 1662 1177 // If a transaction is pending, no need to invalidate the prefetch 1663 1178 // We can ignore it, since we'll replace the line. 1664 1179 // The new line is necessarily up-to-date 1665 if(!r_waiting_transaction.read() && r_ miss_buf_valid)1666 { 1667 if(!r_ miss_buf_first_level)1180 if(!r_waiting_transaction.read() && r_tlb_buf_valid) 1181 { 1182 if(!r_tlb_buf_big_page) 1668 1183 { 1669 if( r_ miss_buf_vaddr_begin.read() ==1670 (r_config_ tlb_inval_vaddr.read()& ~PTE2_LINE_OFFSET) )1184 if( r_tlb_buf_vaddr.read() == 1185 (r_config_cmd_inval_vaddr.read()& ~PTE2_LINE_OFFSET) ) 1671 1186 // The virtual address corresponds to one entry on the buffer line 1672 1187 { 1673 r_ miss_buf_valid = false; //change here for individual invalidation1188 r_tlb_buf_valid = false; //change here for individual invalidation 1674 1189 } 1675 1190 } 1676 1191 else // First level entries on buffer. Unused if only small pages 1677 1192 { 1678 if( r_ miss_buf_vaddr_begin.read() ==1679 (r_config_ tlb_inval_vaddr.read()& ~PTE1_LINE_OFFSET) )1193 if( r_tlb_buf_vaddr.read() == 1194 (r_config_cmd_inval_vaddr.read()& ~PTE1_LINE_OFFSET) ) 1680 1195 // The virtual address corresponds to one entry on the buffer line 1681 1196 { 1682 r_ miss_buf_valid = false; //change here for individual invalidation1197 r_tlb_buf_valid = false; //change here for individual invalidation 1683 1198 } 1684 1199 } … … 1687 1202 // Invalidation on IOTLB 1688 1203 bool ok; 1689 ok = r_iotlb.inval(r_config_ tlb_inval_vaddr.read());1204 ok = r_iotlb.inval(r_config_cmd_inval_vaddr.read()); 1690 1205 1691 if(r_waiting_transaction.read()) r_ dma_tlb_fsm =DMA_TLB_WAIT_TRANSACTION;1692 else r_ dma_tlb_fsm = DMA_TLB_IDLE;1206 if(r_waiting_transaction.read()) r_tlb_fsm =TLB_WAIT; 1207 else r_tlb_fsm = TLB_IDLE; 1693 1208 break; 1694 1209 } 1695 } //end switch r_ dma_tlb_fsm1210 } //end switch r_tlb_fsm 1696 1211 1697 1698 ///////////////////////////////////////////////////////////////////// 1699 // The CONFIG_CMD_FSM is similar to the DMA_CMD_FSM, but without miss TLB treatment. 1700 // It controls the following ressources: 1701 // - r_config_cmd_fsm 1702 // 1703 // - r_config_cmd_rsp_erase_req (set) 1704 // - r_config_tlb_req (set) 1705 ///////////////////////////////////////////////////////////////////// 1212 //////////////////////////////////////////////////////////////////////////////// 1213 // The CONFIG_CMD_FSM handles the VCI commands from the INT network. 1214 // This FSM is mainly intended to handle single flit config transactions, 1215 // but it can also handle software driven, multi-flits data transactions. 1216 // - The configuration requests can be local (IO_BRIDGE config registers) 1217 // or remote (config registers of peripherals on IOX network). 1218 // - The data requests are always remote. 1219 // In case of local config, this FSM put a VCI response in CONFIG_RSP fifo. 1220 // In case of remote transaction, it put the VCI command in CONFIG_CMD fifo. 1221 /////////////////////////////////////////////////////////////////////////////// 1706 1222 1707 1223 switch( r_config_cmd_fsm.read() ) 1708 1224 { 1709 ////////////// 1710 case CONFIG_CMD_IDLE: 1711 { 1712 if ( p_vci_tgt_config.cmdval.read() ) 1713 { 1225 ///////////////////// 1226 case CONFIG_CMD_IDLE: // waiting VCI command 1227 { 1228 if ( p_vci_tgt_int.cmdval.read() ) 1229 { 1230 1714 1231 #if DEBUG_CONFIG_CMD 1715 if( m_debug_config_cmd_fsm ) 1716 { 1717 std::cout << " <IOB.CONFIG_CMD_IDLE> Configuration command received!" <<std::endl; 1718 std::cout << " address = " << std::hex << p_vci_tgt_config.address.read() 1719 << " srcid = " << std::dec << p_vci_tgt_config.srcid.read() 1720 << " trdid = " << p_vci_tgt_config.trdid.read() 1721 << " wdata = " << std::hex << p_vci_tgt_config.wdata.read() 1722 << " be = " << p_vci_tgt_config.be.read() 1723 << " plen = " << std::dec << p_vci_tgt_config.plen.read() << std::endl; 1724 } 1725 #endif 1726 paddr_t config_paddr = p_vci_tgt_config.address.read(); 1727 1728 // // Just to verify 1729 // if(! m_locality_table_config[config_paddr] ) //cannot receive remote packets 1730 // { 1731 // std::cout << "IOB ERROR " << name() << " CONFIG_CMD_IDLE state" << std::endl 1732 // << "Received a remote packet" << std::endl; 1733 // exit(0); 1734 // } 1735 1736 bool read = (p_vci_tgt_config.cmd.read() == vci_param_d::CMD_READ); 1737 1738 uint32_t cell = (uint32_t)((config_paddr & 0x1FF)>>2); 1739 1740 // Treatement of received command 1741 // Verifies error, tests if the the command is for IOB itself 1232 if( m_debug_activated ) 1233 std::cout << " <IOB CONFIG_CMD_IDLE> Command received" 1234 << " / address = " << std::hex << p_vci_tgt_int.address.read() 1235 << " / srcid = " << std::dec << p_vci_tgt_int.srcid.read() 1236 << " / trdid = " << p_vci_tgt_int.trdid.read() 1237 << " / wdata = " << std::hex << p_vci_tgt_int.wdata.read() 1238 << " / be = " << p_vci_tgt_int.be.read() 1239 << " / plen = " << std::dec << p_vci_tgt_int.plen.read() 1240 << " / eop = " << p_vci_tgt_int.eop.read() << std::endl; 1241 #endif 1242 vci_addr_t paddr = p_vci_tgt_int.address.read(); 1243 bool read = (p_vci_tgt_int.cmd.read() == vci_param_int::CMD_READ); 1244 uint32_t cell = (uint32_t)((paddr & 0x1FF)>>2); 1742 1245 1743 // To IOB itself 1744 if(m_segment_config.contains(config_paddr)) 1246 // The "local" segment must be the first in the seglist 1247 soclib::common::Segment seg = m_int_seglist.front(); 1248 1249 if ( seg.contains(paddr) ) // IO_BRIDGE itself 1745 1250 { 1746 if(!read && (cell == IOB_IOMMU_PTPR)) 1747 r_config_cmd_fsm = CONFIG_CMD_PTPR_WRITE; 1748 else if(read && (cell == IOB_IOMMU_PTPR)) 1749 r_config_cmd_fsm = CONFIG_CMD_PTPR_READ; 1750 else if(!read && (cell == IOB_IOMMU_ACTIVE)) 1751 r_config_cmd_fsm = CONFIG_CMD_ACTIVE_WRITE; 1752 else if(read && (cell == IOB_IOMMU_ACTIVE)) 1753 r_config_cmd_fsm = CONFIG_CMD_ACTIVE_READ; 1754 else if(read && (cell == IOB_IOMMU_BVAR)) 1755 r_config_cmd_fsm = CONFIG_CMD_BVAR_READ; 1756 else if(read && (cell == IOB_IOMMU_ETR)) 1757 r_config_cmd_fsm = CONFIG_CMD_ETR_READ; 1758 else if(read && (cell == IOB_IOMMU_BAD_ID)) 1759 r_config_cmd_fsm = CONFIG_CMD_BAD_ID_READ; 1760 // PTE invalidation signaled by the OS 1761 else if(!read && (cell == IOB_INVAL_PTE)) 1762 r_config_cmd_fsm = CONFIG_CMD_INVAL_REQ; 1763 else if(!read && (cell == IOB_IT_ADDR_IOMMU_LO)) 1764 r_config_cmd_fsm = CONFIG_CMD_IT_ADDR_IOMMU_WRITE_1; 1765 else if(read && (cell == IOB_IT_ADDR_IOMMU_LO)) 1766 r_config_cmd_fsm = CONFIG_CMD_IT_ADDR_IOMMU_READ_1; 1767 else if( !read && ((cell >= IOB_IT_ADDR_BEGIN)&& 1768 ( cell< (IOB_IT_ADDR_BEGIN +2*m_nb_periph-1) ) ) ) 1769 { 1770 // a factor two shows up because the registres come in couples 1771 r_it_index = (cell - IOB_IT_ADDR_BEGIN)/2; 1772 r_config_cmd_fsm = CONFIG_CMD_IT_ADDR_WRITE_1; 1251 uint32_t rdata = 0; 1252 bool rerror = false; 1253 1254 if ( not read && (cell == IOB_IOMMU_PTPR) ) // WRITE PTPR 1255 { 1256 r_iommu_ptpr = (uint32_t)p_vci_tgt_int.wdata.read(); 1257 } 1258 else if ( read && (cell == IOB_IOMMU_PTPR) ) // READ PTPR 1259 { 1260 rdata = r_iommu_ptpr.read(); 1261 } 1262 else if( not read && (cell == IOB_WTI_ENABLE)) // WRITE WTI_ENABLE 1263 { 1264 r_iommu_wti_enable = p_vci_tgt_int.wdata.read(); 1265 } 1266 else if( read && (cell == IOB_WTI_ENABLE)) // READ WTI ENABLE 1267 { 1268 rdata = r_iommu_wti_enable.read(); 1269 } 1270 else if( read && (cell == IOB_IOMMU_BVAR)) // READ BVAR 1271 { 1272 rdata = r_iommu_bvar.read(); 1273 } 1274 else if( read && (cell == IOB_IOMMU_ETR)) // READ ETR 1275 { 1276 rdata = r_iommu_etr.read(); 1277 } 1278 else if( read && (cell == IOB_IOMMU_BAD_ID)) // READ BAD_ID 1279 { 1280 rdata = r_iommu_bad_id.read(); 1281 } 1282 else if( not read && (cell == IOB_INVAL_PTE)) // WRITE INVAL_PTE 1283 { 1284 r_config_tlb_req = true; 1285 r_config_cmd_inval_vaddr = (uint32_t)p_vci_tgt_int.wdata.read(); 1286 } 1287 else if( not read && (cell == IOB_WTI_ADDR_LO)) // WRITE WTI_PADDR_LO 1288 { 1289 r_iommu_wti_paddr = (vci_addr_t)p_vci_tgt_int.wdata.read(); 1290 } 1291 else if( read && (cell == IOB_WTI_ADDR_LO)) // READ WTI_PADDR_LO 1292 { 1293 rdata = (uint32_t)r_iommu_wti_paddr.read(); 1294 } 1295 else if( not read && (cell == IOB_WTI_ADDR_HI)) // WRITE WTI_PADDR_HI 1296 { 1297 r_iommu_wti_paddr = (r_iommu_wti_paddr.read() & 0x00000000FFFFFFFFLL) | 1298 ((vci_addr_t)p_vci_tgt_int.wdata.read())<<32; 1299 } 1300 else if( read && (cell == IOB_WTI_ADDR_HI)) // READ WTI_PADDR_HI 1301 { 1302 rdata = (uint32_t)(r_iommu_wti_paddr.read()>>32); 1303 } 1304 else if( not read && ((cell >= IOB_PERI_WTI_BEGIN) // WRITE PERI WTI 1305 && (cell< (IOB_PERI_WTI_BEGIN + 64))) ) 1306 { 1307 size_t index = (cell - IOB_PERI_WTI_BEGIN)/2; 1308 bool high = (cell - IOB_PERI_WTI_BEGIN)%2; 1309 if ( high ) r_iommu_peri_wti[index] = // set 32 MSB bits 1310 (r_iommu_peri_wti[index].read() & 0x00000000FFFFFFFFLL) | 1311 ((vci_addr_t)p_vci_tgt_int.wdata.read())<<32; 1312 else r_iommu_peri_wti[index] = // set 32 LSB bits 1313 (vci_addr_t)p_vci_tgt_int.wdata.read(); 1773 1314 } 1774 else if( read && ((cell >= IOB_IT_ADDR_BEGIN)&& 1775 (cell< (IOB_IT_ADDR_BEGIN +2*m_nb_periph-1))) ) 1776 { 1777 r_it_index = (cell - IOB_IT_ADDR_BEGIN)/2; 1778 r_config_cmd_fsm = CONFIG_CMD_IT_ADDR_READ_1; 1779 } 1780 else 1781 //Error. Wrong address, or invalid operation. 1782 { 1783 if(read) r_config_error_type = READ_ERROR; 1784 else r_config_error_type = WRITE_ERROR; 1785 r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT; 1786 } 1315 else if( read && ((cell >= IOB_PERI_WTI_BEGIN) // READ PERI WTI 1316 && (cell< (IOB_PERI_WTI_BEGIN + 64))) ) 1317 { 1318 size_t index = (cell - IOB_PERI_WTI_BEGIN)/2; 1319 bool high = (cell - IOB_PERI_WTI_BEGIN)%2; 1320 if ( high ) rdata = (uint32_t)(r_iommu_peri_wti[index].read()>>32); 1321 else rdata = (uint32_t)(r_iommu_peri_wti[index].read()); 1322 } 1323 else // Error: Wrong address, or invalid operation. 1324 { 1325 rerror = true; 1326 } 1327 r_config_cmd_rdata = rdata; 1328 r_config_cmd_error = rerror; 1329 r_config_cmd_fsm = CONFIG_CMD_FIFO_PUT_RSP; 1787 1330 } 1788 // Must route the command to the correct IO 1789 else 1331 else // remote peripheral 1790 1332 { 1791 if(!p_vci_tgt_config.eop.read()) 1792 { 1793 //Error 1794 if(read) r_config_error_type = READ_ERROR; 1795 else r_config_error_type = WRITE_ERROR; 1796 r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT; 1797 } 1798 1799 // Find the corresponding address on IO Space 1800 // int tgt_index = m_routing_table_config[config_paddr]; 1801 //#if DEBUG_CONFIG_CMD 1802 //if( m_debug_config_cmd_fsm ) 1803 //{ 1804 // std::cout << " <IOB.CONFIG_CMD_IDLE> Routing a configuration packet" <<std::endl 1805 // << "Target Index on Direct NoC: " << tgt_index << std::endl; 1806 //} 1807 //#endif 1808 // soclib::common::Segment io_segment = m_mtio.getSegment(IntTab(tgt_index)); 1809 // #define L2 soclib::common::uint32_log2 1810 // paddr_t offset_mask = ( (1 << L2(io_segment.size())) - 1); 1811 // #undef L2 1812 // r_config_vaddr = (vaddr_t)( io_segment.baseAddress() | 1813 // (vaddr_t)(config_paddr & offset_mask) ); 1814 1815 // TODO So far, it is in identity mapping 1816 r_config_vaddr = (vaddr_t) config_paddr ; 1817 r_config_cmd_fsm = CONFIG_CMD_TRT_LOCK; 1818 1333 r_config_cmd_fsm = CONFIG_CMD_FIFO_PUT_CMD; 1819 1334 } 1820 1821 1822 1335 } // end if cmdval 1823 1336 break; 1824 1337 } 1825 ///////////////////////// 1826 case CONFIG_CMD_TRT_LOCK: // Waiting for the lock to modify Transaction Table 1827 { 1828 if ( r_alloc_trt_config_fsm.read() == ALLOC_TRT_CONFIG_CMD ) 1338 ///////////////////////////// 1339 case CONFIG_CMD_FIFO_PUT_CMD: // transmit VCI command from the INT network 1340 // to the CONFIG_CMD fifo to IOX network 1341 { 1342 config_cmd_fifo_put = true; 1343 1344 if ( p_vci_tgt_int.cmdval.read() and m_config_cmd_addr_fifo.wok() ) 1829 1345 { 1830 1346 1831 1347 #if DEBUG_CONFIG_CMD 1832 if( m_debug_config_cmd_fsm ) 1833 { 1834 std::cout << " <IOB.CONFIG_CMD_TRT_LOCK> Check the TRT" << std::endl; 1835 } 1836 #endif 1837 size_t wok_index = 0; 1838 bool wok = !m_transaction_tab_config.full(wok_index); 1839 1840 if ( wok ) // TRT isn't full. Write the new transaction. 1348 if( m_debug_activated ) 1349 std::cout << " <IOB CONFIG_CMD_FIFO_PUT_CMD> Transmit VCI command to IOX network" 1350 << " : address = " << std::hex << p_vci_tgt_int.address.read() 1351 << " / srcid = " << p_vci_tgt_int.srcid.read() 1352 << std::endl; 1353 #endif 1354 if( p_vci_tgt_int.eop.read() ) r_config_cmd_fsm = CONFIG_CMD_IDLE; 1355 } 1356 break; 1357 } 1358 ///////////////////////////// 1359 case CONFIG_CMD_FIFO_PUT_RSP: // Try to put a response in CONFIG_RSP fifo, 1360 // for a local configuration transaction. 1361 // The FIFO is shared with CONFIG_RSP FSM 1362 // and must we wait for allocation... 1363 { 1364 if ( p_vci_tgt_int.cmdval.read() and r_alloc_fifo_config_rsp_local.read() ) 1365 { 1366 config_rsp_fifo_put = true; 1367 1368 if ( m_config_rsp_data_fifo.wok() ) 1841 1369 { 1842 r_config_cmd_trt_index = (vci_trdid_t)wok_index; 1843 r_config_cmd_fsm = CONFIG_CMD_TRT_SET; 1844 } 1845 else // wait an empty entry in TRT 1846 { 1847 r_config_cmd_fsm = CONFIG_CMD_TRT_WAIT; 1848 r_config_cmd_rsp_erase_req = true; 1370 1849 1371 #if DEBUG_CONFIG_CMD 1850 if( m_debug_config_cmd_fsm ) 1851 { 1852 std::cout << " <IOB.CONFIG_CMD_TRT_LOCK> TRT is full. Going to TRT_WAIT state" << std::endl; 1853 } 1854 #endif 1855 1856 #ifdef INSTRUMENTATION 1857 m_cpt_trt_config_full++; 1858 #endif 1372 if( m_debug_activated ) 1373 std::cout << " <IOB CONFIG_CMD_FIFO_PUT_RSP> Response to a local configuration request" 1374 << std::endl; 1375 #endif 1376 if( p_vci_tgt_int.eop.read() ) r_config_cmd_fsm = CONFIG_CMD_IDLE; 1859 1377 } 1860 1378 } 1861 1379 break; 1862 1380 } 1863 //////////////// 1864 case CONFIG_CMD_TRT_WAIT: // release the lock protecting the transaction tab 1865 // waits that RSP erases an entry 1866 { 1867 #ifdef INSTRUMENTATION 1868 m_cpt_trt_config_full_cost++; 1869 #endif 1870 // CONFIG_RSP will notify an erase action by reseting this register 1871 if(!r_config_cmd_rsp_erase_req.read()) 1872 { 1873 r_config_cmd_fsm = CONFIG_CMD_TRT_LOCK; // take the lock again 1874 } 1875 break; 1876 } 1877 //////////////////////// 1878 case CONFIG_CMD_TRT_SET: // register a new transaction in TRT 1879 { 1880 if ( r_alloc_trt_config_fsm.read() == ALLOC_TRT_CONFIG_CMD ) 1881 { 1882 m_transaction_tab_config.set( r_config_cmd_trt_index.read(), 1883 p_vci_tgt_config.srcid.read(), 1884 p_vci_tgt_config.trdid.read() ); 1885 1886 r_config_cmd_fsm = CONFIG_CMD_FIFO_PUT; 1887 #if DEBUG_CONFIG_CMD 1888 if( m_debug_config_cmd_fsm ) 1889 { 1890 std::cout << " <IOB.CONFIG_CMD_TRT_SET> Set a new entry in TRT" << std::endl; 1891 } 1892 #endif 1893 } 1894 break; 1895 } 1896 /////////////////////// 1897 case CONFIG_CMD_FIFO_PUT: 1898 { 1899 if ( p_vci_tgt_config.cmdval && m_config_cmd_addr_fifo.wok() ) 1900 { 1901 config_cmd_fifo_put = true; 1902 if( p_vci_tgt_config.eop ) r_config_cmd_fsm = CONFIG_CMD_IDLE; 1903 1904 #if DEBUG_CONFIG_CMD 1905 if( m_debug_config_cmd_fsm ) 1906 { 1907 std::cout << " <IOB.CONFIG_CMD_FIFO_PUT> Push into config_cmd_fifo:" 1908 << " address = " << std::hex << r_config_vaddr.read() 1909 << " srcid = " << std::dec << m_srcid_config 1910 << " trdid = " << r_config_cmd_trt_index.read() 1911 << " wdata = " << std::hex << p_vci_tgt_config.wdata.read() 1912 << " be = " << p_vci_tgt_config.be.read() 1913 << " plen = " << std::dec << p_vci_tgt_config.plen.read() << std::endl; 1914 } 1915 #endif 1916 } 1917 break; 1918 } 1919 1920 /////////////////////////////// 1921 // Private Configuration States 1922 /////////////////////////////// 1923 1924 ////////////////// 1925 case CONFIG_CMD_PTPR_WRITE: // Convention- The word received is in the format: 1926 // 00000 BASE_ADDRESS[39:13] 1927 // Same pattern as in iommu_ptpr register 1928 { 1929 if ( p_vci_tgt_config.cmdval.read() && m_config_local_data_fifo.wok() 1930 && r_dma_tlb_fsm == DMA_TLB_IDLE ) 1931 { 1932 // This verification could have been done on IDLE state 1933 // It would save us one cycle 1934 if ( !p_vci_tgt_config.eop.read() ) 1935 { 1936 std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_PTPR_WRITE state" << std::endl; 1937 std::cout << " PTPR write command must contain one single flit" << std::endl; 1938 r_config_error_type = WRITE_ERROR; 1939 r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT; 1940 break; 1941 } 1942 1943 // Depends on the convention 1944 r_iommu_ptpr = (uint32_t)(p_vci_tgt_config.wdata.read()); 1945 1946 config_local_fifo_put = true; 1947 r_config_cmd_fsm = CONFIG_CMD_IDLE; 1948 1949 #if DEBUG_CONFIG_CMD 1950 if( m_debug_config_cmd_fsm ) 1951 { 1952 std::cout << " <IOB.CONFIG_CMD_PTPR_WRITE> PTPR received:" 1953 << "r_iommu_ptpr = " << std::hex << (p_vci_tgt_config.wdata.read()) 1954 <<std::endl; 1955 } 1956 #endif 1957 } 1958 break; 1959 } 1381 } // end switch CONFIG_CMD FSM 1382 1383 ////////////////////////////////////////////////////////////////////////////// 1384 // The CONFIG_RSP_FSM handles the VCI responses from the periherals 1385 // on the IOX network and writes the responses in the CONFIG_RSP fifo. 1386 // The VCI response flit is only consumed in the FIFO_PUT state. 1387 // This FSM is mainly intended to handle single flit config transactions, 1388 // but it can also handle software driven, multi-flits data transactions. 1389 ////////////////////////////////////////////////////////////////////////////// 1390 1391 switch( r_config_rsp_fsm.read() ) 1392 { 1960 1393 ///////////////////// 1961 case CONFIG_CMD_ACTIVE_WRITE: 1962 { 1963 if ( p_vci_tgt_config.cmdval.read() && m_config_local_data_fifo.wok() 1964 && r_dma_tlb_fsm == DMA_TLB_IDLE ) 1965 { 1966 // This verification could have been done on IDLE state 1967 // It would save us one cycle 1968 if ( !p_vci_tgt_config.eop.read() ) 1969 { 1970 std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_ACTIVE_WRITE state" << std::endl; 1971 std::cout << " ACTIVE write command must contain one single flit" << std::endl; 1972 r_config_error_type = WRITE_ERROR; 1973 r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT; 1974 break; 1975 } 1976 1977 r_iommu_active = (p_vci_tgt_config.wdata.read() != 0); 1978 1979 config_local_fifo_put = true; 1980 r_config_cmd_fsm = CONFIG_CMD_IDLE; 1981 } 1982 break; 1983 } 1984 /////////////////// 1985 case CONFIG_CMD_INVAL_REQ: // Blocks in case of untreated request 1986 { 1987 if ( !r_config_tlb_req.read() ) 1988 { 1989 r_config_tlb_req = true; 1990 r_config_cmd_fsm = CONFIG_CMD_INVAL; 1991 } 1992 break; 1993 } 1994 /////////////////// 1995 case CONFIG_CMD_INVAL: // Consuming the 32bit Virtual Address of the invalidated page 1996 { 1997 if ( p_vci_tgt_config.cmdval.read() && 1998 m_config_local_data_fifo.wok() ) 1999 { 2000 2001 if ( !p_vci_tgt_config.eop.read() ) 2002 { 2003 std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_INVAL state" << std::endl; 2004 std::cout << " PTE invalidation commands must contain one single flit" << std::endl; 2005 r_config_error_type = WRITE_ERROR; 2006 r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT; 2007 break; 2008 } 2009 2010 assert( (p_vci_tgt_config.wdata.read()& K_PAGE_OFFSET_MASK) == 0 2011 and " Error : Invalid format for Page Virtual Address. At least the 12 LSB bits must be zero"); 2012 2013 r_config_tlb_inval_vaddr = (vaddr_t)(p_vci_tgt_config.wdata.read()); 2014 2015 config_local_fifo_put = true; 2016 r_config_cmd_fsm = CONFIG_CMD_IDLE; 2017 } 2018 break; 2019 } 2020 ////////////////// 2021 case CONFIG_CMD_IT_ADDR_IOMMU_WRITE_1: 2022 { 2023 if ( p_vci_tgt_config.cmdval.read() && m_config_local_data_fifo.wok()) 2024 { 2025 if(vci_param_d::N <= 32) 2026 { 2027 // address holds in one single flit 2028 if (!p_vci_tgt_config.eop.read() ) 2029 { 2030 2031 std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_IT_ADDR_IOMMU_WRITE_1 state" << std::endl; 2032 std::cout << " PTE invalidation command should contain just one flit" << std::endl; 2033 r_config_error_type = WRITE_ERROR; 2034 r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT; 2035 } 2036 else 2037 { 2038 // If physical address holds on a single word 2039 r_it_addr[r_it_index.read()] = (paddr_t)(p_vci_tgt_config.wdata.read()); 2040 2041 config_local_fifo_put = true; 2042 r_config_cmd_fsm = CONFIG_CMD_IDLE; 2043 } 2044 2045 } 2046 else 2047 { 2048 // two flits are required to send address 2049 if ( p_vci_tgt_config.eop.read() ) 2050 { 2051 2052 std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_IT_ADDR_IOMMU_WRITE_1 state" << std::endl; 2053 std::cout << " PTE invalidation commands should contain two flits" << std::endl; 2054 r_config_error_type = WRITE_ERROR; 2055 r_config_cmd_fsm = CONFIG_CMD_ERROR_RSP; 2056 } 2057 else 2058 { 2059 r_config_first_word = p_vci_tgt_config.wdata.read(); 2060 r_config_cmd_fsm = CONFIG_CMD_IT_ADDR_IOMMU_WRITE_2; 2061 } 2062 } 2063 } 2064 break; 2065 } 2066 ///////////////// 2067 case CONFIG_CMD_IT_ADDR_IOMMU_WRITE_2: 2068 { 2069 if ( p_vci_tgt_config.cmdval.read() && m_config_local_data_fifo.wok() ) 2070 { 2071 if ( !p_vci_tgt_config.eop.read() ) 2072 { 2073 std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_IT_IOMMU_WRITE_2 state" << std::endl; 2074 std::cout << " PTE invalidation commands must contain two flits" << std::endl; 2075 r_config_error_type = WRITE_ERROR; 2076 r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT; 2077 break; 2078 } 2079 2080 // Depends on the convention 2081 size_t mask_msb = (1 << (vci_param_d::N - 32)) - 1 ; 2082 r_it_addr_iommu = (paddr_t)(r_config_first_word.read() | 2083 ((p_vci_tgt_config.wdata.read()& mask_msb)<<32)); 2084 2085 config_local_fifo_put = true; 2086 r_config_cmd_fsm = CONFIG_CMD_IDLE; 2087 } 2088 } 2089 ////////////////// 2090 case CONFIG_CMD_IT_ADDR_WRITE_1: 2091 { 2092 if ( p_vci_tgt_config.cmdval.read() && m_config_local_data_fifo.wok()) 2093 { 2094 if(vci_param_d::N <= 32) 2095 { 2096 // address holds in one single flit 2097 if (!p_vci_tgt_config.eop.read() ) 2098 { 2099 2100 std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_IT_ADDR_WRITE_1 state" << std::endl; 2101 std::cout << " PTE invalidation command should contain just one flit" << std::endl; 2102 r_config_error_type = WRITE_ERROR; 2103 r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT; 2104 2105 2106 } 2107 else 2108 { 2109 // If physical address holds on a single word 2110 r_it_addr[r_it_index.read()] = (paddr_t)(p_vci_tgt_config.wdata.read()); 2111 2112 config_local_fifo_put = true; 2113 r_config_cmd_fsm = CONFIG_CMD_IDLE; 2114 } 2115 2116 } 2117 else 2118 { 2119 // two flits are required to send address 2120 if ( p_vci_tgt_config.eop.read() ) 2121 { 2122 2123 std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_IT_ADDR_WRITE_1 state" << std::endl; 2124 std::cout << " PTE invalidation commands should contain two flits" << std::endl; 2125 r_config_error_type = WRITE_ERROR; 2126 r_config_cmd_fsm = CONFIG_CMD_ERROR_RSP; 2127 } 2128 else 2129 { 2130 r_config_first_word = p_vci_tgt_config.wdata.read(); 2131 r_config_cmd_fsm = CONFIG_CMD_IT_ADDR_WRITE_2; 2132 } 2133 } 2134 } 2135 break; 2136 } 2137 ///////////////// 2138 case CONFIG_CMD_IT_ADDR_WRITE_2: 2139 { 2140 if ( p_vci_tgt_config.cmdval.read() && m_config_local_data_fifo.wok() ) 2141 { 2142 if ( !p_vci_tgt_config.eop.read() ) 2143 { 2144 std::cout << "CONFIG_CMD ERROR " << name() << " CONFIG_CMD_IT_ADDR_WRITE_2 state" << std::endl; 2145 std::cout << " PTE invalidation commands must contain two flits" << std::endl; 2146 r_config_error_type = WRITE_ERROR; 2147 r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT; 2148 break; 2149 } 2150 2151 // Depends on the convention 2152 size_t mask_msb = (1 << (vci_param_d::N - 32)) - 1 ; 2153 r_it_addr[r_it_index.read()] = (paddr_t)(r_config_first_word.read() | 2154 ((p_vci_tgt_config.wdata.read()& mask_msb)<<32)); 2155 2156 config_local_fifo_put = true; 2157 r_config_cmd_fsm = CONFIG_CMD_IDLE; 2158 } 2159 } 2160 ////////////////// 2161 case CONFIG_CMD_PTPR_READ: 2162 case CONFIG_CMD_ACTIVE_READ: 2163 case CONFIG_CMD_BVAR_READ: 2164 case CONFIG_CMD_ETR_READ: 2165 case CONFIG_CMD_BAD_ID_READ: 2166 case CONFIG_CMD_IT_ADDR_IOMMU_READ_1: 2167 case CONFIG_CMD_IT_ADDR_READ_1: 2168 { 2169 if ( p_vci_tgt_config.cmdval.read() && m_config_local_data_fifo.wok() ) 2170 { 2171 // This verification could have been done on IDLE state 2172 // It would save us one cycle 2173 if ( !p_vci_tgt_config.eop.read() ) 2174 { 2175 std::cout << "CONFIG_CMD ERROR " << name() << config_cmd_fsm_state_str[r_config_cmd_fsm.read()] << std::endl; 2176 std::cout << " Read commands must contain one single flit" << std::endl; 2177 r_config_error_type = READ_ERROR; 2178 r_config_cmd_fsm = CONFIG_CMD_ERROR_WAIT; 2179 break; 2180 } 2181 2182 // fifo data receives the content of the corresponding register 2183 // (depending on the current state) 2184 config_local_fifo_put = true; 2185 if(r_config_cmd_fsm.read()== CONFIG_CMD_IT_ADDR_READ_1) 2186 r_config_cmd_fsm = CONFIG_CMD_IT_ADDR_READ_2; 2187 else if(r_config_cmd_fsm.read()== CONFIG_CMD_IT_ADDR_IOMMU_READ_1) 2188 r_config_cmd_fsm = CONFIG_CMD_IT_ADDR_IOMMU_READ_2; 2189 else 2190 r_config_cmd_fsm = CONFIG_CMD_IDLE; 2191 } 2192 break; 2193 } 2194 ////////////////// 2195 case CONFIG_CMD_IT_ADDR_READ_2: 2196 case CONFIG_CMD_IT_ADDR_IOMMU_READ_2: 2197 { 2198 if ( p_vci_tgt_config.cmdval.read() && m_config_local_data_fifo.wok() ) 2199 { 2200 config_local_fifo_put = true; 2201 r_config_cmd_fsm = CONFIG_CMD_IDLE; 2202 } 2203 } 2204 ////////////////// 2205 case CONFIG_CMD_ERROR_WAIT: //receives the other flits of the same transaction 2206 { 2207 if ( p_vci_tgt_config.cmdval.read() && p_vci_tgt_config.eop.read() ) 2208 r_config_cmd_fsm = CONFIG_CMD_ERROR_RSP; 2209 } 2210 /////////////////// 2211 case CONFIG_CMD_ERROR_RSP: 2212 { 2213 if ( m_config_local_data_fifo.wok() ) 2214 { 2215 config_local_fifo_put = true; 2216 r_config_cmd_fsm = CONFIG_CMD_IDLE; 2217 } 2218 break; 2219 } 2220 2221 } // end switch CONFIG_CMD FSM 2222 2223 ///////////////////////////////////////////////////////////////////// 2224 // The CONFIG_RSP_FSM controls the following ressources: 2225 // - r_config_rsp_fsm 2226 // - r_config_cmd_rsp_erase_req (reset) 2227 // - 2228 // - 2229 ////////////////////////////////////////////////////////////////////////////// 2230 switch( r_config_rsp_fsm.read() ) 2231 { 2232 ///////////////////// 2233 case CONFIG_RSP_IDLE: 1394 case CONFIG_RSP_IDLE: // waiting a VCI response from IOX network 2234 1395 { 2235 if (p_vci_ini_config.rspval.read())1396 if ( p_vci_ini_iox.rspval.read() ) 2236 1397 { 2237 r_config_rsp_fsm = CONFIG_RSP_ TRT_LOCK;1398 r_config_rsp_fsm = CONFIG_RSP_FIFO_PUT; 2238 1399 } 2239 1400 break; 2240 1401 } 2241 ///////////////////// 2242 case CONFIG_RSP_TRT_LOCK: 2243 { 2244 if ( r_alloc_trt_config_fsm.read() == ALLOC_TRT_CONFIG_RSP ) 2245 { 2246 2247 #if DEBUG_CONFIG_RSP 2248 if( m_debug_config_rsp_fsm ) 2249 { 2250 std::cout << " <IOB.CONFIG_RSP_TRT_LOCK> Read and erase entry" << std::endl; 2251 } 2252 #endif 2253 uint32_t trdid_iospace = p_vci_ini_config.rtrdid.read(); 2254 2255 r_config_rsrcid = (vci_srcid_t)m_transaction_tab_config.readSrcid(trdid_iospace); 2256 r_config_rtrdid = (vci_trdid_t)m_transaction_tab_config.readTrdid(trdid_iospace); 2257 m_transaction_tab_config.erase(trdid_iospace); 2258 if (r_config_cmd_rsp_erase_req.read()) r_config_cmd_rsp_erase_req = false; 2259 r_config_rsp_fsm = CONFIG_RSP_FIFO_PUT; 2260 } 2261 break; 2262 } 2263 ////////////////// 2264 case CONFIG_RSP_FIFO_PUT: 2265 { 2266 if(p_vci_ini_config.rspval.read() && m_config_rsp_data_fifo.wok()) 1402 ///////////////////////// 1403 case CONFIG_RSP_FIFO_PUT: // try to write into CONFIG_RSP fifo 1404 // as soon as it is allocated 1405 { 1406 if ( p_vci_ini_iox.rspval.read() and not r_alloc_fifo_config_rsp_local.read() ) 2267 1407 { 2268 1408 config_rsp_fifo_put = true; 2269 if(p_vci_ini_config.reop.read()) r_config_rsp_fsm = CONFIG_RSP_IDLE; 1409 1410 if ( m_config_rsp_data_fifo.wok() ) 1411 { 1412 if ( p_vci_ini_iox.reop.read() ) r_config_rsp_fsm = CONFIG_RSP_IDLE; 2270 1413 2271 1414 #if DEBUG_CONFIG_RSP 2272 if( m_debug_ config_rsp_fsm)2273 { 2274 std::cout << " <IOB.CONFIG_RSP_FIFO_PUT> Push into rsp_fifo:"2275 << " rsrcid = " << std::dec << r_config_rsrcid.read()2276 << " rtrdid = " << r_config_rtrdid.read()2277 << " rdata = " << std::hex << p_vci_ini_config.rdata.read()2278 << std::endl;2279 } 2280 #endif 1415 if( m_debug_activated ) 1416 std::cout << " <IOB CONFIG_RSP_FIFO_PUT> Push response into CONFIG_RSP fifo:" 1417 << " / rsrcid = " << std::hex << p_vci_ini_iox.rsrcid.read() 1418 << " / rtrdid = " << p_vci_ini_iox.rtrdid.read() 1419 << " / rdata = " << p_vci_ini_iox.rdata.read() 1420 << " / reop = " << p_vci_ini_iox.reop.read() 1421 << " / rerror = " << p_vci_ini_iox.rerror.read() << std::endl; 1422 #endif 1423 } 2281 1424 2282 1425 } … … 2285 1428 } // end switch CONFIG_RSP FSM 2286 1429 2287 2288 //////////////////////////////////////////////////////////////////////////// 2289 // The ALLOC_TRT_CONFIG fsm allocates the access to the Transaction Table (m_transaction_tab_config) 2290 // with a round robin priority between 2 user FSMs : 2291 // - CONFIG_CMD : to set a new entry 2292 // - CONFIG_RSP : to read and erase an entry 2293 // The ressource is always allocated. 1430 ///////////////////////////////////////////////////////////////////////////////// 1431 // If the IOB component has IRQ ports, the IRQ FSM detects all changes 1432 // on the 32 p_irq[i] ports and request a VCI write transaction to the 1433 // MISS_INIT FSM, using the 64 r_irq_request[i] and r_irq_pending[i] flip-flops. 1434 ///////////////////////////////////////////////////////////////////////////////// 1435 1436 if ( m_has_irqs ) 1437 { 1438 for ( size_t i = 0; i<32; ++i ) 1439 { 1440 r_irq_request[i] = ( p_irq[i]->read() == not r_irq_pending[i].read() ); 1441 r_irq_pending[i] = p_irq[i]->read(); 1442 } 1443 } 1444 1445 /////////////////////////////////////////////////////////////////////////////////// 1446 // The MISS_WTI_CMD FSM send VCI commands on the Internal Network. 1447 // It handles PTE MISS requests from TLB_MISS FSM and software IRQs. 1448 // It supports several simultaneous VCI transactions. 2294 1449 //////////////////////////////////////////////////////////////////////////////////// 2295 2296 switch ( r_alloc_trt_config_fsm.read() )2297 {2298 ///////////////////2299 case ALLOC_TRT_CONFIG_CMD:2300 {2301 if ( r_config_cmd_fsm.read() != CONFIG_CMD_TRT_LOCK )2302 {2303 if (r_config_rsp_fsm.read() == CONFIG_RSP_TRT_LOCK) r_alloc_trt_config_fsm = ALLOC_TRT_CONFIG_RSP;2304 }2305 }2306 ///////////////////2307 case ALLOC_TRT_CONFIG_RSP:2308 {2309 if (r_config_rsp_fsm.read() != CONFIG_RSP_TRT_LOCK)2310 {2311 if (r_config_cmd_fsm.read() == CONFIG_CMD_TRT_LOCK) r_alloc_trt_config_fsm = ALLOC_TRT_CONFIG_CMD;2312 }2313 }2314 } // end switch r_alloc_trt_config_fsm2315 2316 ////////////////////////////////////////////////////////////////////////////2317 // The MISS_INIT FSM sends a page table entry miss request into Direct Noc2318 // It controls the following ressources:2319 // - r_miss_init_fsm2320 // - r_tlb_miss_init_req (reset)2321 // - r_miss_buf_data2322 // - r_miss_buf_valid2323 // - r_miss_buf_tag2324 ////////////////////////////////////////////////////////////////////////////////////2325 2326 // Building the interruption vector (systematically)2327 uint32_t irq_demands = 0;2328 for ( size_t i = 0; i<m_nb_periph; ++i )2329 irq_demands |= (p_irq_in[i].read() ? 1 : 0) << i;2330 2331 // For next cycle:2332 // Afectation of the new pending vector.2333 // Not useful, unless Irq choice is postponed to next cycle2334 r_irq_pending = irq_demands & r_irq_mask.read();2335 // Updating Mask2336 r_irq_mask = r_irq_mask.read()| ~irq_demands;2337 2338 1450 2339 switch ( r_miss_ init_fsm.read() )2340 { 2341 ////////////// 2342 case MISS_ INIT_IDLE_MISS:2343 { 2344 if (r_tlb_miss_init_req.read())1451 switch ( r_miss_wti_cmd_fsm.read() ) 1452 { 1453 /////////////////////// 1454 case MISS_WTI_CMD_IDLE: // TLB MISS have highest priority 1455 { 1456 if ( r_tlb_miss_req.read() ) 2345 1457 { 2346 r_miss_ init_fsm = MISS_INIT_TLB_MISS_CMD;1458 r_miss_wti_cmd_fsm = MISS_WTI_CMD_MISS; 2347 1459 } 2348 else if (irq_demands & r_irq_mask.read()){ 2349 // Choosing one interruption to send 2350 // Find the first bit 1 2351 // starting by the bit just after the last chosen 2352 size_t i = (r_irq_chosen.read() + 1)% m_nb_periph; 1460 else if ( r_iommu_wti_enable.read() ) 1461 { 1462 // checking if there is a new pending interrupt 2353 1463 bool found = false; 2354 do 2355 { 2356 if(irq_demands & r_irq_mask.read() & (1<<i)) 2357 { 2358 r_irq_chosen = i; 2359 found = true; 2360 } 2361 i = (i+1) % m_nb_periph; 2362 } 2363 while(i != r_irq_chosen.read()+1 && !found); 2364 2365 r_miss_init_fsm = MISS_INIT_IRQ_CMD; 1464 size_t n; 1465 for ( n = 0 ; (n < 32) and not found ; n++ ) 1466 { 1467 if ( r_irq_request[n] ) found = true; 1468 } 1469 if ( found ) 1470 { 1471 r_miss_wti_cmd_index = n; 1472 r_miss_wti_cmd_fsm = MISS_WTI_CMD_WTI; 1473 } 2366 1474 } 2367 1475 break; 2368 1476 } 2369 ////////////// 2370 case MISS_INIT_IDLE_IRQ: 2371 { 2372 if (irq_demands & r_irq_mask.read()){ 2373 // Choosing one interruption to send 2374 // Find the first bit 1 2375 // starting by the bit just after the last chosen 2376 size_t i = (r_irq_chosen.read() + 1)% m_nb_periph; 2377 bool found = false; 2378 do 2379 { 2380 if(irq_demands & r_irq_mask.read() & (1<<i)) 2381 { 2382 r_irq_chosen = i; 2383 found = true; 2384 } 2385 i = (i+1) % m_nb_periph; 2386 } 2387 while(i != r_irq_chosen.read()+1 && !found); 2388 2389 r_miss_init_fsm = MISS_INIT_IRQ_CMD; 2390 } 2391 else if(r_tlb_miss_init_req.read()) 1477 ////////////////////// 1478 case MISS_WTI_CMD_WTI: // send a single flit IRQ WRITE on INT Network 1479 // address is defined by IRQ_VECTOR[r_miss_wti_index] 1480 // data is defined by r_irq_pending[r_miss_wti_index] 1481 { 1482 if ( p_vci_ini_int.cmdack ) 2392 1483 { 2393 r_miss_init_fsm = MISS_INIT_TLB_MISS_CMD; 2394 } 2395 break; 2396 } 2397 ///////////////////////// // send a read request to Direct Network 2398 case MISS_INIT_IRQ_CMD: 2399 { 2400 if ( p_vci_ini_miss.cmdack ) 2401 { 2402 // Masking chosen interruption, until it is resolved 2403 r_irq_mask = r_irq_mask.read() & ~(1<<r_irq_chosen.read()); 2404 r_miss_init_fsm = MISS_INIT_IRQ_RSP; 2405 2406 #if DEBUG_MISS_INIT 2407 if( m_debug_miss_init_fsm ) 2408 { 2409 std::cout << " <IOB.MISS_INIT_IRQ_CMD> Send write (irq) command to XICU" 2410 << " irq ID = " << std::dec << r_irq_chosen.read() 2411 << " new mask = " << std::hex << (r_irq_mask.read() & ~(1<<r_irq_chosen.read())) 2412 << std::endl; 2413 } 2414 #endif 2415 } 2416 break; 2417 } 2418 ////////////////// 2419 case MISS_INIT_IRQ_RSP: 2420 { 2421 if ( p_vci_ini_miss.rspval.read() ) 2422 { 2423 // It is a WRITE command, response in one single flit long 2424 assert( p_vci_ini_miss.reop.read() and "Write answer should have one single flit" ); 2425 bool error; 2426 2427 if ( (p_vci_ini_miss.rerror.read()&0x1) != 0 ) // error reported 2428 { 2429 // TODO traiter error 2430 error = true; 2431 } 2432 r_miss_init_fsm = MISS_INIT_IDLE_MISS; 1484 // reset the request 1485 r_irq_request[r_miss_wti_cmd_index.read()] = false; 1486 r_miss_wti_cmd_fsm = MISS_WTI_RSP_WTI; 1487 1488 #if DEBUG_MISS_WTI 1489 if( m_debug_activated ) 1490 std::cout << " <IOB MISS_WTI_CMD_WTI> Send WTI write command on Internal Network" 1491 << " / IRQID = " << std::dec << r_miss_wti_cmd_index.read() << std::endl; 1492 #endif 2433 1493 } 2434 1494 break; 2435 1495 } 2436 ///////////////////////// // send a read request to Direct Network 2437 case MISS_INIT_TLB_MISS_CMD: 2438 { 2439 if ( p_vci_ini_miss.cmdack ) 2440 { 2441 r_miss_rsp_cpt = 0; //counter for the response flits 2442 r_miss_buf_tag = ( (r_iotlb_paddr.read()) & CACHE_LINE_MASK ); 2443 r_miss_buf_valid = true; 1496 /////////////////////// 1497 case MISS_WTI_CMD_MISS: // send a TLB MISS request on INT Network 1498 { 1499 if ( p_vci_ini_int.cmdack ) 1500 { 1501 r_tlb_buf_tag = ( (r_tlb_paddr.read()) & CACHE_LINE_MASK ); 1502 r_tlb_buf_valid = true; 2444 1503 2445 if(r_tlb_miss_type.read()== PTE1_MISS) 2446 r_miss_buf_vaddr_begin =(r_iotlb_vaddr.read() & ~M_PAGE_OFFSET_MASK & ~PTE1_LINE_OFFSET); 2447 else 2448 r_miss_buf_vaddr_begin =(r_iotlb_vaddr.read() & ~K_PAGE_OFFSET_MASK & ~PTE2_LINE_OFFSET); 1504 if( r_tlb_miss_type.read() == PTE1_MISS ) 1505 r_tlb_buf_vaddr = (r_dma_cmd_vaddr.read() & 1506 ~M_PAGE_OFFSET_MASK & ~PTE1_LINE_OFFSET); 1507 else 1508 r_tlb_buf_vaddr = (r_dma_cmd_vaddr.read() & 1509 ~K_PAGE_OFFSET_MASK & ~PTE2_LINE_OFFSET); 2449 1510 2450 r_miss_init_fsm = MISS_INIT_TLB_MISS_RSP; 2451 2452 #if DEBUG_MISS_INIT 2453 if( m_debug_miss_init_fsm ) 2454 { 2455 std::cout << " <IOB.MISS_INIT_TLB_MISS_CMD> Send read (tlb entry) request to MEM CACHE: " 2456 << " | address : "<< std::hex <<(paddr_t)((r_iotlb_paddr.read())& CACHE_LINE_MASK) 2457 << std::endl; 2458 } 2459 #endif 2460 } 1511 r_miss_wti_cmd_fsm = MISS_WTI_RSP_MISS; 1512 1513 #if DEBUG_MISS_WTI 1514 if( m_debug_activated ) 1515 std::cout << " <IOB MISS_WTI_CMD_MISS> Send TLB MISS command on Internal Network" << std::hex 1516 << " / address = " <<(vci_addr_t)((r_tlb_paddr.read())& CACHE_LINE_MASK) << std::endl; 1517 #endif 1518 } 2461 1519 break; 2462 1520 } 2463 ////////////////// 2464 case MISS_INIT_TLB_MISS_RSP: 2465 { 2466 if ( p_vci_ini_miss.rspval.read() ) 1521 } // end switch r_miss_wti_cmd_fsm 1522 1523 /////////////////////////////////////////////////////////////////////////////////// 1524 // The MISS_WTI_RSP FSM handles VCI responses on the Internal Network. 1525 // it can be response to TLB MISS (read transaction) or WTI (write transaction). 1526 // It supports several simultaneous VCI transactions. 1527 //////////////////////////////////////////////////////////////////////////////////// 1528 1529 switch ( r_miss_wti_rsp_fsm.read() ) 1530 { 1531 case MISS_WTI_RSP_IDLE: // waiting a VCI response 1532 { 1533 if ( p_vci_ini_int.rspval.read() ) 2467 1534 { 2468 if ( (p_vci_ini_miss.rerror.read()&0x1) != 0 ) // error reported 2469 { 2470 r_miss_init_error = true; 2471 if ( p_vci_ini_miss.reop.read() ) 1535 if ( p_vci_ini_int.rpktid.read() == PKTID_READ ) // it's a TLB MISS response 1536 { 1537 r_miss_wti_rsp_fsm = MISS_WTI_RSP_MISS; 1538 r_miss_wti_rsp_count = 0; 1539 } 1540 else // it's a WTI WRITE response 1541 { 1542 r_miss_wti_rsp_fsm = MISS_WTI_RSP_WTI; 1543 1544 } 1545 } 1546 break; 1547 } 1548 ////////////////////// 1549 case MISS_WTI_RSP_WTI: // Handling response to a WTI transaction 1550 { 1551 assert( p_vci_ini_int.reop.read() and 1552 "VCI_IO_BRIDGE ERROR: IRQ Write response should have one single flit" ); 1553 1554 assert( ( (p_vci_ini_int.rerror.read()&0x1) == 0 ) and 1555 "VCI_IO_BRIDGE ERROR: IRQ Write response error !!!" ); 1556 // TODO traiter error using the IOMMU IRQ 1557 1558 #if DEBUG_MISS_WTI 1559 if( m_debug_activated ) 1560 std::cout << " <IOB MISS_WTI_RSP_WTI> Response to WTI write" << std::endl; 1561 #endif 1562 r_miss_wti_rsp_fsm = MISS_WTI_RSP_IDLE; 1563 break; 1564 } 1565 /////////////////////// 1566 case MISS_WTI_RSP_MISS: // Handling response to a TLB MISS transaction 1567 { 1568 if ( p_vci_ini_int.rspval.read() ) 1569 { 1570 if ( (p_vci_ini_int.rerror.read()&0x1) != 0 ) // error reported 1571 { 1572 r_miss_wti_rsp_error = true; 1573 if ( p_vci_ini_int.reop.read() ) 2472 1574 { 2473 r_miss_ init_fsm = MISS_INIT_IDLE_IRQ;2474 r_tlb_miss_ init_req = false;1575 r_miss_wti_cmd_fsm = MISS_WTI_RSP_IDLE; 1576 r_tlb_miss_req = false; 2475 1577 } 2476 #if DEBUG_MISS_INIT 2477 if( m_debug_miss_init_fsm ) 2478 { 2479 std::cout << " <IOB.MISS_INIT_TLB_MISS_RSP> ERROR " << std::endl; 2480 } 2481 #endif 2482 } 2483 else 1578 #if DEBUG_MISS_WTI 1579 if( m_debug_activated ) 1580 std::cout << " <IOB MISS_WTI_RSP_MISS> ERROR " << std::endl; 1581 #endif 1582 } 1583 else // no error 2484 1584 { 2485 bool eop = p_vci_ini_miss.reop.read(); 2486 2487 2488 #if DEBUG_MISS_INIT 2489 if( m_debug_miss_init_fsm ) 2490 { 2491 std::cout << " <IOB.MISS_INIT_TLB_MISS_RSP> Response from Mem Cache to a read (tlb entry) transaction. Count = " << r_miss_rsp_cpt.read() 2492 <<" | Data = " << std::hex << p_vci_ini_miss.rdata.read() << std::endl; 2493 } 2494 #endif 2495 2496 assert(((eop == (r_miss_rsp_cpt.read() == (m_words-1))) ) 2497 and "Error : invalid length for a response from MEM CACHE"); 2498 r_miss_buf_data[r_miss_rsp_cpt] = (uint32_t)p_vci_ini_miss.rdata.read(); 2499 2500 r_miss_rsp_cpt = r_miss_rsp_cpt.read() + 1; 1585 bool eop = p_vci_ini_int.reop.read(); 1586 1587 #if DEBUG_MISS_WTI 1588 if( m_debug_activated ) 1589 std::cout << " <IOB MISS_WTI_RSP_MISS> Response to a tlb miss transaction" 1590 << " / Count = " << r_miss_wti_rsp_count.read() 1591 << " / Data = " << std::hex << p_vci_ini_int.rdata.read() << std::endl; 1592 #endif 1593 assert(((eop == (r_miss_wti_rsp_count.read() == (m_words-1)))) and 1594 "VCI_IO_BRIDGE ERROR: invalid length for a TLB MISS response"); 1595 1596 r_tlb_buf_data[r_miss_wti_rsp_count.read()] = p_vci_ini_int.rdata.read(); 1597 r_miss_wti_rsp_count = r_miss_wti_rsp_count.read() + 1; 2501 1598 2502 1599 if ( eop ) 2503 1600 { 2504 r_tlb_miss_ init_req = false; //reset the request flip-flop2505 r_miss_ init_fsm = MISS_INIT_IDLE_IRQ;1601 r_tlb_miss_req = false; //reset the request flip-flop 1602 r_miss_wti_cmd_fsm = MISS_WTI_RSP_IDLE; 2506 1603 } 2507 2508 1604 } 2509 1605 } 2510 1606 break; 2511 1607 } 2512 2513 } // end switch r_miss_init_fsm 1608 } // end switch r_miss_wti_rsp_fsm 1609 1610 ///////////////////////////////////////////////////////////////////////// 1611 // This flip-flop allocates the access to the CONFIG_RSP fifo 1612 // with a round robin priority between 2 clients FSMs : 1613 // - CONFIG_CMD : to put a response to a local config command. 1614 // - CONFIG_RSP : to put a response to a peripheral config command. 1615 // The ressource is always allocated. 1616 // A new allocation occurs when the owner FSM is not using it, 1617 // and the other FSM is requiring it. 1618 ///////////////////////////////////////////////////////////////////////// 2514 1619 2515 ////////////////////////////////// 2516 // Fifo consumption arbitration // 2517 ////////////////////////////////// 1620 if ( r_alloc_fifo_config_rsp_local.read() ) 1621 { 1622 if ( (r_config_rsp_fsm.read() == CONFIG_RSP_FIFO_PUT) and 1623 (r_config_cmd_fsm.read() != CONFIG_CMD_FIFO_PUT_RSP) ) 1624 r_alloc_fifo_config_rsp_local = false; 1625 } 1626 else 1627 { 1628 if ( (r_config_cmd_fsm.read() == CONFIG_CMD_FIFO_PUT_RSP) and 1629 (r_config_rsp_fsm.read() != CONFIG_RSP_FIFO_PUT) ) 1630 r_alloc_fifo_config_rsp_local = true; 1631 } 1632 1633 ///////////////////////////////////////////////////////////////////////// 1634 // This flip-flop allocates the access to the DMA_RSP fifo 1635 // with a round robin priority between 2 clients FSMs : 1636 // - DMA_CMD : to put a error response in case of bad address translation 1637 // - DMA_RSP : to put a normal response to a DMA transaction. 1638 // The ressource is always allocated. 1639 // A new allocation occurs when the owner FSM is not using it, 1640 // and the other FSM is requiring it. 1641 ///////////////////////////////////////////////////////////////////////// 2518 1642 2519 // Round Robin priority for CONFIG_RSP FIFO consumption 2520 r_config_rsp_fifo_local_priority = ! r_config_rsp_fifo_local_priority.read(); 2521 2522 //DMA CMD 2523 dma_cmd_fifo_get = (p_vci_ini_dma.cmdack.read() && m_dma_cmd_addr_fifo.rok()); 2524 // DMA RSP 2525 dma_rsp_fifo_get = (p_vci_tgt_dma.rspack.read() && m_dma_rsp_data_fifo.rok()); 2526 // CONFIG CMD 2527 config_cmd_fifo_get = (p_vci_ini_config.cmdack.read() && m_config_cmd_addr_fifo.rok() ); 2528 // CONFIG RSP, detemines wich fifo to consume 2529 if(r_config_rsp_fifo_local_priority) 2530 { 2531 if(m_config_local_data_fifo.rok()) config_local_fifo_get = p_vci_tgt_config.rspack.read(); 2532 else if (m_config_rsp_data_fifo.rok()) config_rsp_fifo_get = p_vci_tgt_config.rspack.read(); 2533 2534 } 2535 else 2536 { 2537 if (m_config_rsp_data_fifo.rok()) config_rsp_fifo_get = p_vci_tgt_config.rspack.read(); 2538 else if(m_config_local_data_fifo.rok()) config_local_fifo_get = p_vci_tgt_config.rspack.read(); 2539 } 2540 /////////////// 2541 //DMA_CMD Fifo 2542 /////////////// 2543 if(r_miss_interrupt) 2544 { 2545 m_dma_cmd_addr_fifo.update( dma_cmd_fifo_get, 2546 dma_cmd_fifo_put, 2547 r_miss_paddr.read() ); 2548 m_dma_cmd_cmd_fifo.update( dma_cmd_fifo_get, 2549 dma_cmd_fifo_put, 2550 r_miss_cmd.read() ); 2551 m_dma_cmd_contig_fifo.update( dma_cmd_fifo_get, 2552 dma_cmd_fifo_put, 2553 r_miss_contig.read() ); 2554 m_dma_cmd_cons_fifo.update( dma_cmd_fifo_get, 2555 dma_cmd_fifo_put, 2556 r_miss_cons.read() ); 2557 m_dma_cmd_plen_fifo.update( dma_cmd_fifo_get, 2558 dma_cmd_fifo_put, 2559 r_miss_plen.read() ); 2560 m_dma_cmd_wrap_fifo.update( dma_cmd_fifo_get, 2561 dma_cmd_fifo_put, 2562 r_miss_wrap.read() ); 2563 m_dma_cmd_cfixed_fifo.update( dma_cmd_fifo_get, 2564 dma_cmd_fifo_put, 2565 r_miss_cfixed.read() ); 2566 m_dma_cmd_clen_fifo.update( dma_cmd_fifo_get, 2567 dma_cmd_fifo_put, 2568 r_miss_clen.read() ); 2569 m_dma_cmd_srcid_fifo.update( dma_cmd_fifo_get, 2570 dma_cmd_fifo_put, 2571 m_srcid_dma ); //r_miss_srcid.read() 2572 m_dma_cmd_trdid_fifo.update( dma_cmd_fifo_get, 2573 dma_cmd_fifo_put, 2574 r_miss_trdid.read() ); 2575 m_dma_cmd_pktid_fifo.update( dma_cmd_fifo_get, 2576 dma_cmd_fifo_put, 2577 r_miss_pktid.read() ); 2578 m_dma_cmd_data_fifo.update( dma_cmd_fifo_get, 2579 dma_cmd_fifo_put, 2580 r_miss_data[r_dma_cmd_count.read()-1] ); 2581 m_dma_cmd_be_fifo.update( dma_cmd_fifo_get, 2582 dma_cmd_fifo_put, 2583 r_miss_be[r_dma_cmd_count.read()-1] ); 2584 m_dma_cmd_eop_fifo.update( dma_cmd_fifo_get, 2585 dma_cmd_fifo_put, 2586 (r_dma_cmd_count.read() == 1) ); 1643 if ( r_alloc_fifo_dma_rsp_local.read() ) 1644 { 1645 if ( (r_dma_rsp_fsm.read() == DMA_RSP_FIFO_PUT) and 1646 (r_dma_cmd_fsm.read() != DMA_CMD_FIFO_PUT_RSP) ) 1647 r_alloc_fifo_dma_rsp_local = false; 2587 1648 } 2588 1649 else 2589 1650 { 2590 m_dma_cmd_addr_fifo.update( dma_cmd_fifo_get, 2591 dma_cmd_fifo_put, 2592 r_dma_paddr.read() ); 2593 m_dma_cmd_cmd_fifo.update( dma_cmd_fifo_get, 2594 dma_cmd_fifo_put, 2595 p_vci_tgt_dma.cmd.read() ); 2596 m_dma_cmd_contig_fifo.update( dma_cmd_fifo_get, 2597 dma_cmd_fifo_put, 2598 p_vci_tgt_dma.contig.read() ); 2599 m_dma_cmd_cons_fifo.update( dma_cmd_fifo_get, 2600 dma_cmd_fifo_put, 2601 p_vci_tgt_dma.cons.read() ); 2602 m_dma_cmd_plen_fifo.update( dma_cmd_fifo_get, 2603 dma_cmd_fifo_put, 2604 p_vci_tgt_dma.plen.read() ); 2605 m_dma_cmd_wrap_fifo.update( dma_cmd_fifo_get, 2606 dma_cmd_fifo_put, 2607 p_vci_tgt_dma.wrap.read() ); 2608 m_dma_cmd_cfixed_fifo.update( dma_cmd_fifo_get, 2609 dma_cmd_fifo_put, 2610 p_vci_tgt_dma.cfixed.read() ); 2611 m_dma_cmd_clen_fifo.update( dma_cmd_fifo_get, 2612 dma_cmd_fifo_put, 2613 p_vci_tgt_dma.clen.read() ); 2614 m_dma_cmd_srcid_fifo.update( dma_cmd_fifo_get, 2615 dma_cmd_fifo_put, 2616 m_srcid_dma ); 2617 m_dma_cmd_trdid_fifo.update( dma_cmd_fifo_get, 2618 dma_cmd_fifo_put, 2619 r_dma_cmd_trt_index.read() ); 2620 m_dma_cmd_pktid_fifo.update( dma_cmd_fifo_get, 2621 dma_cmd_fifo_put, 2622 p_vci_tgt_dma.pktid.read() ); 2623 m_dma_cmd_data_fifo.update( dma_cmd_fifo_get, 2624 dma_cmd_fifo_put, 2625 p_vci_tgt_dma.wdata.read() ); // TODO change 2626 // For 64bits XRAM 2627 m_dma_cmd_be_fifo.update( dma_cmd_fifo_get, 2628 dma_cmd_fifo_put, 2629 p_vci_tgt_dma.be.read() ); 2630 m_dma_cmd_eop_fifo.update( dma_cmd_fifo_get, 2631 dma_cmd_fifo_put, 2632 p_vci_tgt_dma.eop.read() ); 2633 } 2634 2635 /////////////// 2636 //DMA_RSP Fifo 2637 /////////////// 2638 if(r_dma_rsp_fsm.read() == DMA_RSP_FIFO_ERROR_PUT) 2639 { 2640 m_dma_rsp_data_fifo.update( dma_rsp_fifo_get, 2641 dma_rsp_fifo_put, 2642 0 ); 1651 if ( (r_dma_cmd_fsm.read() == DMA_CMD_FIFO_PUT_RSP) and 1652 (r_dma_rsp_fsm.read() != DMA_RSP_FIFO_PUT) ) 1653 r_alloc_fifo_dma_rsp_local = true; 1654 } 1655 1656 // Define GET signals for all output FIFOs 1657 dma_cmd_fifo_get = p_vci_ini_ram.cmdack.read(); 1658 dma_rsp_fifo_get = p_vci_tgt_iox.rspack.read(); 1659 config_cmd_fifo_get = p_vci_ini_iox.cmdack.read(); 1660 config_rsp_fifo_get = p_vci_tgt_int.rspack.read(); 1661 1662 /////////////////////////////////////////////////////////// 1663 // DMA_CMD fifo update 1664 // One writer : DMA_CMD FSM 1665 /////////////////////////////////////////////////////////// 1666 1667 m_dma_cmd_addr_fifo.update( dma_cmd_fifo_get, 1668 dma_cmd_fifo_put, 1669 r_dma_cmd_paddr.read() ); // address translation 1670 m_dma_cmd_cmd_fifo.update( dma_cmd_fifo_get, 1671 dma_cmd_fifo_put, 1672 p_vci_tgt_iox.cmd.read() ); 1673 m_dma_cmd_contig_fifo.update( dma_cmd_fifo_get, 1674 dma_cmd_fifo_put, 1675 p_vci_tgt_iox.contig.read() ); 1676 m_dma_cmd_cons_fifo.update( dma_cmd_fifo_get, 1677 dma_cmd_fifo_put, 1678 p_vci_tgt_iox.cons.read() ); 1679 m_dma_cmd_plen_fifo.update( dma_cmd_fifo_get, 1680 dma_cmd_fifo_put, 1681 p_vci_tgt_iox.plen.read() ); 1682 m_dma_cmd_wrap_fifo.update( dma_cmd_fifo_get, 1683 dma_cmd_fifo_put, 1684 p_vci_tgt_iox.wrap.read() ); 1685 m_dma_cmd_cfixed_fifo.update( dma_cmd_fifo_get, 1686 dma_cmd_fifo_put, 1687 p_vci_tgt_iox.cfixed.read() ); 1688 m_dma_cmd_clen_fifo.update( dma_cmd_fifo_get, 1689 dma_cmd_fifo_put, 1690 p_vci_tgt_iox.clen.read() ); 1691 m_dma_cmd_srcid_fifo.update( dma_cmd_fifo_get, 1692 dma_cmd_fifo_put, 1693 p_vci_tgt_iox.srcid.read() ); 1694 m_dma_cmd_trdid_fifo.update( dma_cmd_fifo_get, 1695 dma_cmd_fifo_put, 1696 p_vci_tgt_iox.trdid.read() ); 1697 m_dma_cmd_pktid_fifo.update( dma_cmd_fifo_get, 1698 dma_cmd_fifo_put, 1699 p_vci_tgt_iox.pktid.read() ); 1700 m_dma_cmd_data_fifo.update( dma_cmd_fifo_get, 1701 dma_cmd_fifo_put, 1702 p_vci_tgt_iox.wdata.read() ); 1703 m_dma_cmd_be_fifo.update( dma_cmd_fifo_get, 1704 dma_cmd_fifo_put, 1705 p_vci_tgt_iox.be.read() ); 1706 m_dma_cmd_eop_fifo.update( dma_cmd_fifo_get, 1707 dma_cmd_fifo_put, 1708 p_vci_tgt_iox.eop.read() ); 1709 1710 ////////////////////////////////////////////////////////////// 1711 // DMA_RSP fifo update 1712 // Two writers : DMA_CMD FSM & DMA_RSP FSM 1713 ////////////////////////////////////////////////////////////// 1714 1715 if (r_alloc_fifo_dma_rsp_local.read() ) // owner is DMA_CMD FSM 1716 // local response for a translation error 1717 { 1718 m_dma_rsp_data_fifo.update( dma_rsp_fifo_get, 1719 dma_rsp_fifo_put, 1720 0 ); // no data if error 2643 1721 m_dma_rsp_rsrcid_fifo.update( dma_rsp_fifo_get, 2644 dma_rsp_fifo_put,2645 r_iommu_bad_id.read() );1722 dma_rsp_fifo_put, 1723 p_vci_tgt_iox.rsrcid.read() ); 2646 1724 m_dma_rsp_rtrdid_fifo.update( dma_rsp_fifo_get, 2647 dma_rsp_fifo_put,2648 r_dma_error_trdid.read() );1725 dma_rsp_fifo_put, 1726 p_vci_tgt_iox.rtrdid.read() ); 2649 1727 m_dma_rsp_rpktid_fifo.update( dma_rsp_fifo_get, 2650 dma_rsp_fifo_put,2651 r_dma_error_pktid.read() );2652 m_dma_rsp_reop_fifo.update( dma_rsp_fifo_get,2653 dma_rsp_fifo_put,2654 true );1728 dma_rsp_fifo_put, 1729 p_vci_tgt_iox.rpktid.read() ); 1730 m_dma_rsp_reop_fifo.update( dma_rsp_fifo_get, 1731 dma_rsp_fifo_put, 1732 true ); // single flit response 2655 1733 m_dma_rsp_rerror_fifo.update( dma_rsp_fifo_get, 2656 1734 dma_rsp_fifo_put, 2657 r_dma_error_type.read() ); 2658 } 2659 else 2660 { 2661 m_dma_rsp_data_fifo.update( dma_rsp_fifo_get, 2662 dma_rsp_fifo_put, 2663 p_vci_ini_dma.rdata.read() ); 1735 1 ); // error 1736 } 1737 else // owner is DMA_RSP FSM 1738 // normal response to a DMA transaction 1739 { 1740 m_dma_rsp_data_fifo.update( dma_rsp_fifo_get, 1741 dma_rsp_fifo_put, 1742 p_vci_ini_ram.rdata.read() ); 2664 1743 m_dma_rsp_rsrcid_fifo.update( dma_rsp_fifo_get, 2665 dma_rsp_fifo_put,2666 r_dma_rsrcid.read() );1744 dma_rsp_fifo_put, 1745 p_vci_ini_ram.rsrcid.read() ); 2667 1746 m_dma_rsp_rtrdid_fifo.update( dma_rsp_fifo_get, 2668 dma_rsp_fifo_put,2669 r_dma_rtrdid.read() );1747 dma_rsp_fifo_put, 1748 p_vci_ini_ram.rtrdid.read() ); 2670 1749 m_dma_rsp_rpktid_fifo.update( dma_rsp_fifo_get, 2671 dma_rsp_fifo_put,2672 p_vci_ini_dma.rpktid.read() );2673 m_dma_rsp_reop_fifo.update( dma_rsp_fifo_get,2674 dma_rsp_fifo_put,2675 p_vci_ini_dma.reop.read() );1750 dma_rsp_fifo_put, 1751 p_vci_ini_ram.rpktid.read() ); 1752 m_dma_rsp_reop_fifo.update( dma_rsp_fifo_get, 1753 dma_rsp_fifo_put, 1754 p_vci_ini_ram.reop.read() ); 2676 1755 m_dma_rsp_rerror_fifo.update( dma_rsp_fifo_get, 2677 1756 dma_rsp_fifo_put, 2678 p_vci_ini_dma.rerror.read() ); 2679 } 2680 2681 ////////////////// 2682 //CONFIG_CMD Fifo 2683 ////////////////// 2684 m_config_cmd_addr_fifo.update( config_cmd_fifo_get, 2685 config_cmd_fifo_put, 2686 r_config_vaddr.read() ); 2687 m_config_cmd_cmd_fifo.update( config_cmd_fifo_get, 2688 config_cmd_fifo_put, 2689 p_vci_tgt_config.cmd.read() ); 1757 p_vci_ini_ram.rerror.read() ); 1758 } 1759 1760 //////////////////////////////////////////////////////////////// 1761 // CONFIG_CMD fifo update 1762 // One writer : CONFIG_CMD FSM 1763 //////////////////////////////////////////////////////////////// 1764 1765 m_config_cmd_addr_fifo.update( config_cmd_fifo_get, 1766 config_cmd_fifo_put, 1767 p_vci_tgt_int.address.read() ); 1768 m_config_cmd_cmd_fifo.update( config_cmd_fifo_get, 1769 config_cmd_fifo_put, 1770 p_vci_tgt_int.cmd.read() ); 2690 1771 m_config_cmd_contig_fifo.update( config_cmd_fifo_get, 2691 config_cmd_fifo_put,2692 p_vci_tgt_config.contig.read() );2693 m_config_cmd_cons_fifo.update( config_cmd_fifo_get,2694 config_cmd_fifo_put,2695 p_vci_tgt_config.cons.read() );2696 m_config_cmd_plen_fifo.update( config_cmd_fifo_get,2697 config_cmd_fifo_put,2698 p_vci_tgt_config.plen.read() );2699 m_config_cmd_wrap_fifo.update( config_cmd_fifo_get,2700 config_cmd_fifo_put,2701 p_vci_tgt_config.wrap.read() );1772 config_cmd_fifo_put, 1773 p_vci_tgt_int.contig.read() ); 1774 m_config_cmd_cons_fifo.update( config_cmd_fifo_get, 1775 config_cmd_fifo_put, 1776 p_vci_tgt_int.cons.read() ); 1777 m_config_cmd_plen_fifo.update( config_cmd_fifo_get, 1778 config_cmd_fifo_put, 1779 p_vci_tgt_int.plen.read() ); 1780 m_config_cmd_wrap_fifo.update( config_cmd_fifo_get, 1781 config_cmd_fifo_put, 1782 p_vci_tgt_int.wrap.read() ); 2702 1783 m_config_cmd_cfixed_fifo.update( config_cmd_fifo_get, 2703 config_cmd_fifo_put,2704 p_vci_tgt_config.cfixed.read() );2705 m_config_cmd_clen_fifo.update( config_cmd_fifo_get,2706 config_cmd_fifo_put,2707 p_vci_tgt_config.clen.read() );2708 m_config_cmd_srcid_fifo.update( config_cmd_fifo_get,2709 config_cmd_fifo_put,2710 m_srcid_config);2711 m_config_cmd_trdid_fifo.update( config_cmd_fifo_get,2712 config_cmd_fifo_put,2713 r_config_cmd_trt_index.read() );2714 m_config_cmd_pktid_fifo.update( config_cmd_fifo_get,2715 config_cmd_fifo_put,2716 p_vci_tgt_config.pktid.read() );2717 m_config_cmd_data_fifo.update( config_cmd_fifo_get,2718 config_cmd_fifo_put,2719 p_vci_tgt_config.wdata.read() );2720 m_config_cmd_be_fifo.update( config_cmd_fifo_get,2721 config_cmd_fifo_put,2722 p_vci_tgt_config.be.read() );2723 m_config_cmd_eop_fifo.update( config_cmd_fifo_get,2724 config_cmd_fifo_put,2725 p_vci_tgt_ config.eop.read() );1784 config_cmd_fifo_put, 1785 p_vci_tgt_int.cfixed.read() ); 1786 m_config_cmd_clen_fifo.update( config_cmd_fifo_get, 1787 config_cmd_fifo_put, 1788 p_vci_tgt_int.clen.read() ); 1789 m_config_cmd_srcid_fifo.update( config_cmd_fifo_get, 1790 config_cmd_fifo_put, 1791 p_vci_tgt_int.srcid.read() ); 1792 m_config_cmd_trdid_fifo.update( config_cmd_fifo_get, 1793 config_cmd_fifo_put, 1794 p_vci_tgt_int.trdid.read() ); 1795 m_config_cmd_pktid_fifo.update( config_cmd_fifo_get, 1796 config_cmd_fifo_put, 1797 p_vci_tgt_int.pktid.read() ); 1798 m_config_cmd_data_fifo.update( config_cmd_fifo_get, 1799 config_cmd_fifo_put, 1800 (ext_data_t)p_vci_tgt_int.wdata.read() ); 1801 m_config_cmd_be_fifo.update( config_cmd_fifo_get, 1802 config_cmd_fifo_put, 1803 p_vci_tgt_int.be.read() ); 1804 m_config_cmd_eop_fifo.update( config_cmd_fifo_get, 1805 config_cmd_fifo_put, 1806 p_vci_tgt_int.eop.read() ); 2726 1807 2727 ////////////////// 2728 //CONFIG_RSP Fifo 2729 ////////////////// 2730 m_config_rsp_data_fifo.update( config_rsp_fifo_get, 2731 config_rsp_fifo_put, 2732 p_vci_ini_config.rdata.read() ); 2733 m_config_rsp_rsrcid_fifo.update( config_rsp_fifo_get, 2734 config_rsp_fifo_put, 2735 r_config_rsrcid.read() ); 2736 m_config_rsp_rtrdid_fifo.update( config_rsp_fifo_get, 2737 config_rsp_fifo_put, 2738 r_config_rtrdid.read() ); 2739 m_config_rsp_rpktid_fifo.update( config_rsp_fifo_get, 2740 config_rsp_fifo_put, 2741 p_vci_ini_config.rpktid.read() ); 2742 m_config_rsp_reop_fifo.update( config_rsp_fifo_get, 2743 config_rsp_fifo_put, 2744 p_vci_ini_config.reop.read() ); 2745 m_config_rsp_rerror_fifo.update( config_rsp_fifo_get, 2746 config_rsp_fifo_put, 2747 p_vci_ini_config.rerror.read() ); 1808 ////////////////////////////////////////////////////////////////////////// 1809 // CONFIG_RSP fifo update 1810 // There is two writers : CONFIG_CMD FSM & CONFIG_RSP FSM 1811 ////////////////////////////////////////////////////////////////////////// 1812 1813 if ( r_alloc_fifo_config_rsp_local.read() ) // owner is CONFIG_CMD FSM 1814 // response for a local config transaction 1815 { 1816 m_config_rsp_data_fifo.update( config_rsp_fifo_get, 1817 config_rsp_fifo_put, 1818 (int_data_t)r_config_cmd_rdata.read() ); 1819 m_config_rsp_rsrcid_fifo.update( config_rsp_fifo_get, 1820 config_rsp_fifo_put, 1821 p_vci_tgt_int.srcid.read() ); 1822 m_config_rsp_rtrdid_fifo.update( config_rsp_fifo_get, 1823 config_rsp_fifo_put, 1824 p_vci_tgt_int.trdid.read() ); 1825 m_config_rsp_rpktid_fifo.update( config_rsp_fifo_get, 1826 config_rsp_fifo_put, 1827 p_vci_tgt_int.pktid.read() ); 1828 m_config_rsp_reop_fifo.update( config_rsp_fifo_get, 1829 config_rsp_fifo_put, 1830 true ); // local config are one flit 1831 m_config_rsp_rerror_fifo.update( config_rsp_fifo_get, 1832 config_rsp_fifo_put, 1833 r_config_cmd_error.read() ); 1834 } 1835 else // owner is CONFIG_RSP FSM 1836 // response for a remote transaction 1837 { 1838 m_config_rsp_data_fifo.update( config_rsp_fifo_get, 1839 config_rsp_fifo_put, 1840 (int_data_t)p_vci_ini_iox.rdata.read() ); 1841 m_config_rsp_rsrcid_fifo.update( config_rsp_fifo_get, 1842 config_rsp_fifo_put, 1843 p_vci_ini_iox.rsrcid.read() ); 1844 m_config_rsp_rtrdid_fifo.update( config_rsp_fifo_get, 1845 config_rsp_fifo_put, 1846 p_vci_ini_iox.rtrdid.read() ); 1847 m_config_rsp_rpktid_fifo.update( config_rsp_fifo_get, 1848 config_rsp_fifo_put, 1849 p_vci_ini_iox.rpktid.read() ); 1850 m_config_rsp_reop_fifo.update( config_rsp_fifo_get, 1851 config_rsp_fifo_put, 1852 p_vci_ini_iox.reop.read() ); 1853 m_config_rsp_rerror_fifo.update( config_rsp_fifo_get, 1854 config_rsp_fifo_put, 1855 p_vci_ini_iox.rerror.read() ); 1856 } 2748 1857 2749 ///////////////////////2750 //CONFIG Local RSP Fifo2751 ///////////////////////2752 m_config_local_rsrcid_fifo.update( config_local_fifo_get,2753 config_local_fifo_put,2754 p_vci_tgt_config.srcid.read() );2755 m_config_local_rtrdid_fifo.update( config_local_fifo_get,2756 config_local_fifo_put,2757 p_vci_tgt_config.trdid.read() );2758 m_config_local_rpktid_fifo.update( config_local_fifo_get,2759 config_local_fifo_put,2760 p_vci_tgt_config.pktid.read() );2761 2762 switch( r_config_cmd_fsm.read() )2763 {2764 case CONFIG_CMD_PTPR_WRITE:2765 case CONFIG_CMD_ACTIVE_WRITE:2766 case CONFIG_CMD_IT_ADDR_IOMMU_WRITE_2:2767 case CONFIG_CMD_IT_ADDR_WRITE_2:2768 case CONFIG_CMD_INVAL:2769 m_config_local_data_fifo.update( config_local_fifo_get,2770 config_local_fifo_put,2771 0);2772 m_config_local_rerror_fifo.update( config_local_fifo_get,2773 config_local_fifo_put,2774 WRITE_OK );2775 m_config_local_reop_fifo.update( config_local_fifo_get,2776 config_local_fifo_put,2777 true );2778 break;2779 case CONFIG_CMD_PTPR_READ:2780 m_config_local_data_fifo.update( config_local_fifo_get,2781 config_local_fifo_put,2782 r_iommu_ptpr.read());2783 m_config_local_rerror_fifo.update( config_local_fifo_get,2784 config_local_fifo_put,2785 READ_OK );2786 m_config_local_reop_fifo.update( config_local_fifo_get,2787 config_local_fifo_put,2788 true );2789 break;2790 case CONFIG_CMD_ACTIVE_READ:2791 m_config_local_data_fifo.update( config_local_fifo_get,2792 config_local_fifo_put,2793 r_iommu_active.read());2794 m_config_local_rerror_fifo.update( config_local_fifo_get,2795 config_local_fifo_put,2796 READ_OK );2797 m_config_local_reop_fifo.update( config_local_fifo_get,2798 config_local_fifo_put,2799 true );2800 break;2801 case CONFIG_CMD_BVAR_READ:2802 m_config_local_data_fifo.update( config_local_fifo_get,2803 config_local_fifo_put,2804 r_iommu_bvar.read());2805 m_config_local_rerror_fifo.update( config_local_fifo_get,2806 config_local_fifo_put,2807 READ_OK );2808 m_config_local_reop_fifo.update( config_local_fifo_get,2809 config_local_fifo_put,2810 true );2811 break;2812 case CONFIG_CMD_ETR_READ:2813 m_config_local_data_fifo.update( config_local_fifo_get,2814 config_local_fifo_put,2815 r_iommu_etr.read());2816 m_config_local_rerror_fifo.update( config_local_fifo_get,2817 config_local_fifo_put,2818 READ_OK );2819 m_config_local_reop_fifo.update( config_local_fifo_get,2820 config_local_fifo_put,2821 true );2822 break;2823 case CONFIG_CMD_BAD_ID_READ:2824 m_config_local_data_fifo.update( config_local_fifo_get,2825 config_local_fifo_put,2826 r_iommu_bad_id.read());2827 m_config_local_rerror_fifo.update( config_local_fifo_get,2828 config_local_fifo_put,2829 READ_OK );2830 m_config_local_reop_fifo.update( config_local_fifo_get,2831 config_local_fifo_put,2832 true );2833 break;2834 case CONFIG_CMD_IT_ADDR_IOMMU_READ_1:2835 m_config_local_data_fifo.update( config_local_fifo_get,2836 config_local_fifo_put,2837 (uint32_t)(r_it_addr_iommu.read() & 0xFFFFFFFF) );2838 m_config_local_rerror_fifo.update( config_local_fifo_get,2839 config_local_fifo_put,2840 READ_OK );2841 m_config_local_reop_fifo.update( config_local_fifo_get,2842 config_local_fifo_put,2843 false );2844 break;2845 case CONFIG_CMD_IT_ADDR_IOMMU_READ_2:2846 m_config_local_data_fifo.update( config_local_fifo_get,2847 config_local_fifo_put,2848 (uint32_t)((r_it_addr_iommu.read()>>32)&0xFF) );2849 m_config_local_rerror_fifo.update( config_local_fifo_get,2850 config_local_fifo_put,2851 READ_OK );2852 m_config_local_reop_fifo.update( config_local_fifo_get,2853 config_local_fifo_put,2854 true );2855 break;2856 case CONFIG_CMD_IT_ADDR_READ_1:2857 m_config_local_data_fifo.update( config_local_fifo_get,2858 config_local_fifo_put,2859 (uint32_t)(r_it_addr[r_it_index.read()] & 0xFFFFFFFF) );2860 m_config_local_rerror_fifo.update( config_local_fifo_get,2861 config_local_fifo_put,2862 READ_OK );2863 m_config_local_reop_fifo.update( config_local_fifo_get,2864 config_local_fifo_put,2865 false );2866 break;2867 case CONFIG_CMD_IT_ADDR_READ_2:2868 m_config_local_data_fifo.update( config_local_fifo_get,2869 config_local_fifo_put,2870 (uint32_t)((r_it_addr[r_it_index.read()]>>32)&0xFF) );2871 m_config_local_rerror_fifo.update( config_local_fifo_get,2872 config_local_fifo_put,2873 READ_OK );2874 m_config_local_reop_fifo.update( config_local_fifo_get,2875 config_local_fifo_put,2876 true );2877 break;2878 case CONFIG_CMD_ERROR_RSP:2879 m_config_local_data_fifo.update( config_local_fifo_get,2880 config_local_fifo_put,2881 0);2882 m_config_local_rerror_fifo.update( config_local_fifo_get,2883 config_local_fifo_put,2884 r_config_error_type.read() );2885 m_config_local_reop_fifo.update( config_local_fifo_get,2886 config_local_fifo_put,2887 true );2888 break;2889 default:2890 m_config_local_data_fifo.update( config_local_fifo_get,2891 config_local_fifo_put,2892 0);2893 m_config_local_rerror_fifo.update( config_local_fifo_get,2894 config_local_fifo_put,2895 0 );2896 m_config_local_reop_fifo.update( config_local_fifo_get,2897 config_local_fifo_put,2898 false );2899 break;2900 }2901 2902 1858 } // end transition() 2903 1859 … … 2906 1862 /////////////////////// 2907 1863 { 2908 ////////////////// 2909 // DMA Commands // 2910 ////////////////// 1864 // VCI initiator command on RAM network 1865 // directly the content of the dma_cmd FIFO 1866 1867 p_vci_ini_ram.cmdval = m_dma_cmd_addr_fifo.rok(); 1868 p_vci_ini_ram.address = m_dma_cmd_addr_fifo.read(); 1869 p_vci_ini_ram.be = m_dma_cmd_be_fifo.read(); 1870 p_vci_ini_ram.cmd = m_dma_cmd_cmd_fifo.read(); 1871 p_vci_ini_ram.contig = m_dma_cmd_contig_fifo.read(); 1872 p_vci_ini_ram.wdata = m_dma_cmd_data_fifo.read(); 1873 p_vci_ini_ram.eop = m_dma_cmd_eop_fifo.read(); 1874 p_vci_ini_ram.cons = m_dma_cmd_cons_fifo.read(); 1875 p_vci_ini_ram.plen = m_dma_cmd_plen_fifo.read(); 1876 p_vci_ini_ram.wrap = m_dma_cmd_wrap_fifo.read(); 1877 p_vci_ini_ram.cfixed = m_dma_cmd_cfixed_fifo.read(); 1878 p_vci_ini_ram.clen = m_dma_cmd_clen_fifo.read(); 1879 p_vci_ini_ram.trdid = m_dma_cmd_trdid_fifo.read(); 1880 p_vci_ini_ram.pktid = m_dma_cmd_pktid_fifo.read(); 1881 p_vci_ini_ram.srcid = m_dma_cmd_srcid_fifo.read(); 2911 1882 2912 // VCI initiator command on the xram network 2913 if(m_dma_cmd_addr_fifo.rok()) 2914 //&& p_vci_ini_dma.cmdack.read()) 2915 { 2916 p_vci_ini_dma.cmdval = true; 2917 #if NEW_XRAM_VCI 2918 p_vci_ini_dma.address = (paddr_t_x)(m_dma_cmd_addr_fifo.read() >> 6 ) 2919 #else 2920 p_vci_ini_dma.address = m_dma_cmd_addr_fifo.read(); 2921 #endif 2922 2923 p_vci_ini_dma.be = m_dma_cmd_be_fifo.read(); 2924 p_vci_ini_dma.cmd = m_dma_cmd_cmd_fifo.read(); 2925 p_vci_ini_dma.contig = m_dma_cmd_contig_fifo.read(); 2926 #if NEW_XRAM_VCI 2927 //TODO for 64 bits field 2928 #else 2929 p_vci_ini_dma.wdata = m_dma_cmd_data_fifo.read(); // The first is in param_x 2930 // the second in param_io 2931 #endif 2932 p_vci_ini_dma.eop = m_dma_cmd_eop_fifo.read(); 2933 p_vci_ini_dma.cons = m_dma_cmd_cons_fifo.read(); 2934 p_vci_ini_dma.plen = m_dma_cmd_plen_fifo.read(); 2935 p_vci_ini_dma.wrap = m_dma_cmd_wrap_fifo.read(); 2936 p_vci_ini_dma.cfixed = m_dma_cmd_cfixed_fifo.read(); 2937 p_vci_ini_dma.clen = m_dma_cmd_clen_fifo.read(); 2938 p_vci_ini_dma.trdid = m_dma_cmd_trdid_fifo.read(); 2939 p_vci_ini_dma.pktid = m_dma_cmd_pktid_fifo.read(); 2940 p_vci_ini_dma.srcid = m_dma_cmd_srcid_fifo.read(); 2941 } 2942 else 2943 { 2944 p_vci_ini_dma.cmdval = false; 2945 p_vci_ini_dma.address = 0; 2946 p_vci_ini_dma.be = 0; 2947 p_vci_ini_dma.cmd = vci_param_x::CMD_NOP; 2948 p_vci_ini_dma.contig = false; 2949 p_vci_ini_dma.wdata = 0; 2950 p_vci_ini_dma.eop = false; 2951 p_vci_ini_dma.cons = true; 2952 p_vci_ini_dma.plen = 0; 2953 p_vci_ini_dma.wrap = false; 2954 p_vci_ini_dma.cfixed = false; 2955 p_vci_ini_dma.clen = 0; 2956 p_vci_ini_dma.trdid = 0; 2957 p_vci_ini_dma.pktid = 0; 2958 } 2959 2960 // VCI target command on the IO network 2961 // it depends on the DMA_CMD FSM state 1883 // VCI target command ack on IOX network 1884 // depends on the DMA_CMD FSM state 2962 1885 2963 1886 switch ( r_dma_cmd_fsm.read() ) 2964 1887 { 2965 1888 case DMA_CMD_IDLE: 2966 case DMA_CMD_TRT_LOCK: 2967 case DMA_CMD_TRT_WAIT: 2968 case DMA_CMD_TRT_SET: 2969 p_vci_tgt_dma.cmdack = false; 2970 break; 2971 case DMA_CMD_FIFO_PUT: 2972 case DMA_CMD_FIFO_MISS_PUT: 2973 p_vci_tgt_dma.cmdack = m_dma_cmd_addr_fifo.wok(); 2974 break; 2975 case DMA_CMD_TLB_MISS_WAIT: 2976 p_vci_tgt_dma.cmdack = false; 2977 break; 2978 case DMA_CMD_TLB_MISS_STORE: 2979 p_vci_tgt_dma.cmdack = true; 2980 break; 2981 case DMA_CMD_ERROR: 2982 p_vci_tgt_dma.cmdack = !r_dma_cmd_error_req.read(); 1889 case DMA_CMD_MISS_WAIT: 1890 p_vci_tgt_iox.cmdack = false; 1891 break; 1892 case DMA_CMD_WAIT_EOP: 1893 p_vci_tgt_iox.cmdack = true; 1894 break; 1895 case DMA_CMD_FIFO_PUT_CMD: 1896 p_vci_tgt_iox.cmdack = m_dma_cmd_addr_fifo.wok(); 1897 break; 1898 case DMA_CMD_FIFO_PUT_RSP: 1899 p_vci_tgt_iox.cmdack = m_dma_rsp_data_fifo.wok(); 2983 1900 break; 2984 1901 }// end switch r_dma_cmd_fsm 2985 1902 2986 ////////////////// 2987 // DMA Responses// 2988 ////////////////// 1903 // VCI target response on IOX network 1904 // directly the content of the DMA_RSP FIFO 1905 1906 p_vci_tgt_iox.rspval = m_dma_rsp_data_fifo.rok(); 1907 p_vci_tgt_iox.rsrcid = m_dma_rsp_rsrcid_fifo.read(); 1908 p_vci_tgt_iox.rtrdid = m_dma_rsp_rtrdid_fifo.read(); 1909 p_vci_tgt_iox.rpktid = m_dma_rsp_rpktid_fifo.read(); 1910 p_vci_tgt_iox.rdata = m_dma_rsp_data_fifo.read(); 1911 p_vci_tgt_iox.rerror = m_dma_rsp_rerror_fifo.read(); 1912 p_vci_tgt_iox.reop = m_dma_rsp_reop_fifo.read(); 1913 1914 // VCI initiator response on the RAM Network 1915 // depends on the DMA_RSP FSM state 1916 1917 p_vci_ini_ram.rspack = m_dma_rsp_data_fifo.wok() and 1918 (r_dma_rsp_fsm.read() == DMA_RSP_FIFO_PUT) and 1919 not r_alloc_fifo_dma_rsp_local.read(); 1920 1921 // VCI initiator command on IOX network 1922 // directly the content of the CONFIG_CMD FIFO 1923 1924 p_vci_ini_iox.cmdval = m_config_cmd_addr_fifo.rok(); 1925 p_vci_ini_iox.address = m_config_cmd_addr_fifo.read(); 1926 p_vci_ini_iox.be = m_config_cmd_be_fifo.read(); 1927 p_vci_ini_iox.cmd = m_config_cmd_cmd_fifo.read(); 1928 p_vci_ini_iox.contig = m_config_cmd_contig_fifo.read(); 1929 p_vci_ini_iox.wdata = (ext_data_t)m_config_cmd_data_fifo.read(); 1930 p_vci_ini_iox.eop = m_config_cmd_eop_fifo.read(); 1931 p_vci_ini_iox.cons = m_config_cmd_cons_fifo.read(); 1932 p_vci_ini_iox.plen = m_config_cmd_plen_fifo.read(); 1933 p_vci_ini_iox.wrap = m_config_cmd_wrap_fifo.read(); 1934 p_vci_ini_iox.cfixed = m_config_cmd_cfixed_fifo.read(); 1935 p_vci_ini_iox.clen = m_config_cmd_clen_fifo.read(); 1936 p_vci_ini_iox.trdid = m_config_cmd_trdid_fifo.read(); 1937 p_vci_ini_iox.pktid = m_config_cmd_pktid_fifo.read(); 1938 p_vci_ini_iox.srcid = m_config_cmd_srcid_fifo.read(); 2989 1939 2990 // VCI target response on the IO network 2991 if(m_dma_rsp_data_fifo.rok()) 2992 { 2993 p_vci_tgt_dma.rspval = true; 2994 p_vci_tgt_dma.rsrcid = m_dma_rsp_rsrcid_fifo.read(); 2995 p_vci_tgt_dma.rtrdid = m_dma_rsp_rtrdid_fifo.read(); 2996 2997 p_vci_tgt_dma.rpktid = m_dma_rsp_rpktid_fifo.read(); 1940 // VCI target command ack on INT network 1941 // it depends on the CONFIG_CMD FSM state 1942 1943 switch ( r_config_cmd_fsm.read() ) 1944 { 1945 case CONFIG_CMD_IDLE: 1946 p_vci_tgt_int.cmdack = false; 1947 break; 1948 case CONFIG_CMD_FIFO_PUT_CMD: 1949 p_vci_tgt_int.cmdack = m_config_cmd_addr_fifo.wok(); 1950 break; 1951 case CONFIG_CMD_FIFO_PUT_RSP: 1952 p_vci_tgt_int.cmdack = m_config_rsp_data_fifo.wok() and 1953 r_alloc_fifo_config_rsp_local.read(); 1954 break; 1955 }// end switch r_config_cmd_fsm 1956 1957 // VCI target response on INT network 1958 // directly the content of the CONFIG_RSP FIFO 1959 1960 p_vci_tgt_int.rspval = m_config_rsp_data_fifo.rok(); 1961 p_vci_tgt_int.rsrcid = m_config_rsp_rsrcid_fifo.read(); 1962 p_vci_tgt_int.rtrdid = m_config_rsp_rtrdid_fifo.read(); 1963 p_vci_tgt_int.rpktid = m_config_rsp_rpktid_fifo.read(); 1964 p_vci_tgt_int.rdata = m_config_rsp_data_fifo.read(); 1965 p_vci_tgt_int.rerror = m_config_rsp_rerror_fifo.read(); 1966 p_vci_tgt_int.reop = m_config_rsp_reop_fifo.read(); 2998 1967 2999 #if NEW_XRAM_VCI 3000 //TODO for 64 bit data field 3001 #else 3002 p_vci_tgt_dma.rdata = m_dma_rsp_data_fifo.read(); // The first is in param_io 3003 // the second in param_x 3004 #endif 3005 3006 p_vci_tgt_dma.rerror = m_dma_rsp_rerror_fifo.read(); 3007 p_vci_tgt_dma.reop = m_dma_rsp_reop_fifo.read(); 3008 } 3009 else 3010 { 3011 p_vci_tgt_dma.rspval = false; 3012 3013 p_vci_tgt_dma.rsrcid = 0; 3014 p_vci_tgt_dma.rdata = 0; 3015 p_vci_tgt_dma.rpktid = 0; 3016 p_vci_tgt_dma.rtrdid = 0; 3017 p_vci_tgt_dma.rerror = 0; 3018 p_vci_tgt_dma.reop = false; 3019 3020 } 3021 3022 // VCI initiator response on the Xram Network 3023 // it depends on the DMA_RSP FSM state 3024 switch ( r_dma_rsp_fsm.read() ) 3025 { 3026 case DMA_RSP_IDLE: 3027 case DMA_RSP_TRT_LOCK: 3028 case DMA_RSP_FIFO_ERROR_PUT: 3029 { 3030 p_vci_ini_dma.rspack = false; 3031 break; 3032 } 3033 case DMA_RSP_FIFO_PUT: 3034 { 3035 p_vci_ini_dma.rspack = m_dma_rsp_data_fifo.wok(); 3036 break; 3037 } 3038 }// end switch r_dma_rsp_fsm 3039 3040 ///////////////////// 3041 // CONFIG Commands // 3042 ///////////////////// 3043 3044 // VCI initiator command on the IO network 3045 if(m_config_cmd_addr_fifo.rok()) 3046 { 3047 p_vci_ini_config.cmdval = true; 3048 #if NEW_XRAM_VCI 3049 p_vci_ini_config.address = (paddr_t_x)(m_config_cmd_addr_fifo.read() >> 6 ) 3050 #else 3051 p_vci_ini_config.address = m_config_cmd_addr_fifo.read(); 3052 #endif 3053 3054 p_vci_ini_config.be = (vci_be_t_x)m_config_cmd_be_fifo.read(); 3055 p_vci_ini_config.cmd = m_config_cmd_cmd_fifo.read(); 3056 p_vci_ini_config.contig = m_config_cmd_contig_fifo.read(); 3057 #if NEW_XRAM_VCI 3058 //TODO 3059 #else 3060 p_vci_ini_config.wdata = (vci_data_t_x)m_config_cmd_data_fifo.read(); // The first is in param_io 3061 // the second in param_d 3062 #endif 3063 p_vci_ini_config.eop = m_config_cmd_eop_fifo.read(); 3064 p_vci_ini_config.cons = m_config_cmd_cons_fifo.read(); 3065 p_vci_ini_config.plen = m_config_cmd_plen_fifo.read(); 3066 p_vci_ini_config.wrap = m_config_cmd_wrap_fifo.read(); 3067 p_vci_ini_config.cfixed = m_config_cmd_cfixed_fifo.read(); 3068 p_vci_ini_config.clen = m_config_cmd_clen_fifo.read(); 3069 p_vci_ini_config.trdid = m_config_cmd_trdid_fifo.read(); 3070 p_vci_ini_config.pktid = m_config_cmd_pktid_fifo.read(); 3071 } 3072 else 3073 { 3074 p_vci_ini_config.cmdval = false; 3075 p_vci_ini_config.address = 0; 3076 p_vci_ini_config.be = 0; 3077 p_vci_ini_config.cmd = vci_param_io::CMD_NOP; 3078 p_vci_ini_config.contig = false; 3079 p_vci_ini_config.wdata = 0; 3080 p_vci_ini_config.eop = false; 3081 p_vci_ini_config.cons = true; 3082 p_vci_ini_config.plen = 0; 3083 p_vci_ini_config.wrap = false; 3084 p_vci_ini_config.cfixed = false; 3085 p_vci_ini_config.clen = 0; 3086 p_vci_ini_config.trdid = 0; 3087 p_vci_ini_config.pktid = 0; 3088 } 1968 // VCI initiator response on IOX Network 1969 // it depends on the CONFIG_RSP FSM state 1970 1971 p_vci_ini_iox.rspack = m_config_rsp_data_fifo.wok() and 1972 (r_config_rsp_fsm.read() == CONFIG_RSP_FIFO_PUT) and 1973 not r_alloc_fifo_config_rsp_local.read(); 1974 1975 // VCI initiator command on INT network 1976 // it depends on the MISS_WTI_CMD FSM state 1977 1978 // default values 1979 p_vci_ini_int.srcid = m_int_srcid; 1980 p_vci_ini_int.trdid = 0; 1981 p_vci_ini_int.cfixed = false; 1982 p_vci_ini_int.eop = true; 1983 p_vci_ini_int.wrap = false; 1984 p_vci_ini_int.clen = 0; 1985 p_vci_ini_int.contig = false; 1986 p_vci_ini_int.cons = true; 1987 p_vci_ini_int.be = 0xFF; 3089 1988 3090 // VCI target command on the Direct network 3091 // it depends on the CONFIG_CMD FSM state 3092 3093 switch ( r_config_cmd_fsm.read() ) 3094 { 3095 case CONFIG_CMD_IDLE: 3096 case CONFIG_CMD_TRT_LOCK: 3097 case CONFIG_CMD_TRT_WAIT: 3098 case CONFIG_CMD_TRT_SET: 3099 case CONFIG_CMD_IT_ADDR_IOMMU_READ_1: 3100 case CONFIG_CMD_IT_ADDR_READ_1: 3101 case CONFIG_CMD_ERROR_RSP: 3102 case CONFIG_CMD_INVAL_REQ: 3103 p_vci_tgt_config.cmdack = false; 3104 break; 3105 case CONFIG_CMD_FIFO_PUT: 3106 case CONFIG_CMD_PTPR_WRITE: 3107 case CONFIG_CMD_PTPR_READ: 3108 case CONFIG_CMD_ACTIVE_WRITE: 3109 case CONFIG_CMD_ACTIVE_READ: 3110 case CONFIG_CMD_BVAR_READ: 3111 case CONFIG_CMD_ETR_READ: 3112 case CONFIG_CMD_BAD_ID_READ: 3113 case CONFIG_CMD_IT_ADDR_IOMMU_WRITE_2: 3114 case CONFIG_CMD_IT_ADDR_IOMMU_READ_2: 3115 case CONFIG_CMD_IT_ADDR_WRITE_2: 3116 case CONFIG_CMD_IT_ADDR_READ_2: 3117 case CONFIG_CMD_INVAL: 3118 p_vci_tgt_config.cmdack = m_config_cmd_addr_fifo.wok(); 3119 break; 3120 case CONFIG_CMD_IT_ADDR_IOMMU_WRITE_1: 3121 case CONFIG_CMD_IT_ADDR_WRITE_1: 3122 case CONFIG_CMD_ERROR_WAIT: 3123 p_vci_tgt_config.cmdack = true; 3124 break; 3125 default: 3126 p_vci_tgt_config.cmdack = false; 3127 break; 3128 }// end switch r_config_cmd_fsm 3129 3130 ///////////////////// 3131 // CONFIG Responses// 3132 ///////////////////// 1989 switch ( r_miss_wti_cmd_fsm.read() ) 1990 { 1991 case MISS_WTI_CMD_IDLE: 1992 p_vci_ini_int.cmdval = false; 1993 p_vci_ini_int.address = 0; 1994 p_vci_ini_int.cmd = vci_param_int::CMD_NOP; 1995 p_vci_ini_int.pktid = PKTID_READ; 1996 p_vci_ini_int.wdata = 0; 1997 p_vci_ini_int.plen = 0; 1998 break; 3133 1999 3134 // VCI target response on the Direct network 3135 if(r_config_rsp_fifo_local_priority) 3136 { 3137 if( m_config_local_data_fifo.rok() ) 3138 { 3139 p_vci_tgt_config.rspval = true; 3140 p_vci_tgt_config.rsrcid = m_config_local_rsrcid_fifo.read(); 3141 p_vci_tgt_config.rtrdid = m_config_local_rtrdid_fifo.read(); 3142 p_vci_tgt_config.rpktid = m_config_local_rpktid_fifo.read(); 3143 p_vci_tgt_config.rdata = (vci_data_t)m_config_local_data_fifo.read(); 3144 p_vci_tgt_config.rerror = m_config_local_rerror_fifo.read(); 3145 p_vci_tgt_config.reop = m_config_local_reop_fifo.read(); 3146 } 3147 else if(m_config_rsp_data_fifo.rok() ) 3148 { 3149 p_vci_tgt_config.rspval = true; 3150 p_vci_tgt_config.rsrcid = m_config_rsp_rsrcid_fifo.read(); 3151 p_vci_tgt_config.rtrdid = m_config_rsp_rtrdid_fifo.read(); 3152 3153 p_vci_tgt_config.rpktid = m_config_rsp_rpktid_fifo.read(); 2000 case MISS_WTI_CMD_WTI: 2001 p_vci_ini_int.cmdval = true; 2002 p_vci_ini_int.address = r_iommu_peri_wti[r_miss_wti_cmd_index.read()].read(); 2003 p_vci_ini_int.cmd = vci_param_int::CMD_WRITE; 2004 p_vci_ini_int.pktid = PKTID_WRITE; 2005 p_vci_ini_int.wdata = (int_data_t)r_irq_pending[r_miss_wti_cmd_index.read()].read(); 2006 p_vci_ini_int.plen = vci_param_int::B; 2007 break; 3154 2008 3155 p_vci_tgt_config.rdata = (vci_data_t)m_config_rsp_data_fifo.read(); // The first is in param_d 3156 // the second in param_io 3157 p_vci_tgt_config.rerror = m_config_rsp_rerror_fifo.read(); 3158 p_vci_tgt_config.reop = m_config_rsp_reop_fifo.read(); 3159 } 3160 else 3161 { 3162 p_vci_tgt_config.rspval = false; 3163 3164 p_vci_tgt_config.rsrcid = 0; 3165 p_vci_tgt_config.rdata = 0; 3166 p_vci_tgt_config.rpktid = 0; 3167 p_vci_tgt_config.rtrdid = 0; 3168 p_vci_tgt_config.rerror = 0; 3169 p_vci_tgt_config.reop = false; 3170 3171 } 3172 } 3173 else 3174 { 3175 if(m_config_rsp_data_fifo.rok() ) 3176 { 3177 p_vci_tgt_config.rspval = true; 3178 p_vci_tgt_config.rsrcid = m_config_rsp_rsrcid_fifo.read(); 3179 p_vci_tgt_config.rtrdid = m_config_rsp_rtrdid_fifo.read(); 3180 3181 p_vci_tgt_config.rpktid = m_config_rsp_rpktid_fifo.read(); 3182 3183 p_vci_tgt_config.rdata = (vci_data_t)m_config_rsp_data_fifo.read(); // The first is in param_d 3184 // the second in param_io 3185 p_vci_tgt_config.rerror = m_config_rsp_rerror_fifo.read(); 3186 p_vci_tgt_config.reop = m_config_rsp_reop_fifo.read(); 3187 } 3188 else if( m_config_local_data_fifo.rok() ) 3189 { 3190 p_vci_tgt_config.rspval = true; 3191 p_vci_tgt_config.rsrcid = m_config_local_rsrcid_fifo.read(); 3192 p_vci_tgt_config.rtrdid = m_config_local_rtrdid_fifo.read(); 3193 p_vci_tgt_config.rpktid = m_config_local_rpktid_fifo.read(); 3194 p_vci_tgt_config.rdata = (vci_data_t)m_config_local_data_fifo.read(); 3195 p_vci_tgt_config.rerror = m_config_local_rerror_fifo.read(); 3196 p_vci_tgt_config.reop = m_config_local_reop_fifo.read(); 3197 } 3198 else 3199 { 3200 p_vci_tgt_config.rspval = false; 3201 3202 p_vci_tgt_config.rsrcid = 0; 3203 p_vci_tgt_config.rdata = 0; 3204 p_vci_tgt_config.rpktid = 0; 3205 p_vci_tgt_config.rtrdid = 0; 3206 p_vci_tgt_config.rerror = 0; 3207 p_vci_tgt_config.reop = false; 3208 3209 } 3210 } 3211 3212 // VCI initiator response on the IO Network 3213 // it depends on the CONFIG_RSP FSM state 3214 switch ( r_config_rsp_fsm.read() ) 3215 { 3216 case CONFIG_RSP_IDLE: 3217 case CONFIG_RSP_TRT_LOCK: 3218 p_vci_ini_config.rspack = false; 3219 break; 3220 case CONFIG_RSP_FIFO_PUT: 3221 p_vci_ini_config.rspack = m_config_rsp_data_fifo.wok(); 3222 break; 3223 }// end switch r_config_rsp_fsm 3224 3225 //////////////////////////////////////////////////////////////// 3226 // VCI initiator command and response on from the Direct network 3227 // for Miss Transactions 3228 p_vci_ini_miss.srcid = m_srcid_miss; 3229 3230 switch ( r_miss_init_fsm.read() ) 3231 { 3232 case MISS_INIT_IDLE_MISS: 3233 case MISS_INIT_IDLE_IRQ: 3234 p_vci_ini_miss.cmdval = false; 3235 p_vci_ini_miss.address = 0; 3236 p_vci_ini_miss.be = 0; 3237 p_vci_ini_miss.cmd = vci_param_d::CMD_NOP; 3238 p_vci_ini_miss.contig = false; 3239 p_vci_ini_miss.wdata = 0; 3240 p_vci_ini_miss.eop = false; 3241 p_vci_ini_miss.cons = true; 3242 p_vci_ini_miss.plen = 0; 3243 p_vci_ini_miss.wrap = false; 3244 p_vci_ini_miss.cfixed = false; 3245 p_vci_ini_miss.clen = 0; 3246 p_vci_ini_miss.trdid = 0; 3247 p_vci_ini_miss.pktid = 0; 3248 3249 p_vci_ini_miss.rspack = false; 3250 break; 3251 3252 case MISS_INIT_IRQ_CMD: 3253 p_vci_ini_miss.cmdval = true; 3254 p_vci_ini_miss.address = (paddr_t)r_it_addr[r_irq_chosen.read()]; 3255 p_vci_ini_miss.wdata = 0; 3256 p_vci_ini_miss.plen = vci_param_d::B; 3257 p_vci_ini_miss.trdid = 0; 3258 p_vci_ini_miss.cmd = vci_param_d::CMD_READ; 3259 p_vci_ini_miss.eop = true; 3260 3261 p_vci_ini_miss.be = 0xF; 3262 p_vci_ini_miss.pktid = 0; 3263 p_vci_ini_miss.cons = false; 3264 p_vci_ini_miss.wrap = false; 3265 p_vci_ini_miss.contig = true; 3266 p_vci_ini_miss.clen = 0; 3267 p_vci_ini_miss.cfixed = false; 3268 break; 3269 3270 case MISS_INIT_IRQ_RSP: 3271 case MISS_INIT_TLB_MISS_RSP: 3272 p_vci_ini_miss.cmdval = false; 3273 p_vci_ini_miss.address = 0; 3274 p_vci_ini_miss.be = 0; 3275 p_vci_ini_miss.cmd = vci_param_d::CMD_NOP; 3276 p_vci_ini_miss.contig = false; 3277 p_vci_ini_miss.wdata = 0; 3278 p_vci_ini_miss.eop = false; 3279 p_vci_ini_miss.cons = true; 3280 p_vci_ini_miss.plen = 0; 3281 p_vci_ini_miss.wrap = false; 3282 p_vci_ini_miss.cfixed = false; 3283 p_vci_ini_miss.clen = 0; 3284 p_vci_ini_miss.trdid = 0; 3285 p_vci_ini_miss.pktid = 0; 3286 3287 p_vci_ini_miss.rspack = true; 3288 3289 break; 3290 3291 case MISS_INIT_TLB_MISS_CMD: 3292 p_vci_ini_miss.cmdval = true; 3293 p_vci_ini_miss.address = (paddr_t)((r_iotlb_paddr.read())& CACHE_LINE_MASK); 3294 p_vci_ini_miss.wdata = 0x00000000; 3295 p_vci_ini_miss.plen = m_words*(vci_param_d::B); 3296 p_vci_ini_miss.trdid = 0; //could be used as the index on a miss transaction table 3297 p_vci_ini_miss.cmd = vci_param_d::CMD_READ; 3298 p_vci_ini_miss.eop = true; 3299 3300 p_vci_ini_miss.be = 0xF; 3301 p_vci_ini_miss.pktid = 0; 3302 p_vci_ini_miss.cons = false; 3303 p_vci_ini_miss.wrap = false; 3304 p_vci_ini_miss.contig = true; 3305 p_vci_ini_miss.clen = 0; 3306 p_vci_ini_miss.cfixed = false; 3307 break; 3308 3309 } // end switch r_miss_init_fsm 2009 case MISS_WTI_CMD_MISS: 2010 p_vci_ini_int.cmdval = true; 2011 p_vci_ini_int.address = r_tlb_paddr.read() & CACHE_LINE_MASK; 2012 p_vci_ini_int.cmd = vci_param_int::CMD_READ; 2013 p_vci_ini_int.pktid = PKTID_READ; 2014 p_vci_ini_int.wdata = 0; 2015 p_vci_ini_int.plen = m_words*(vci_param_int::B); 2016 break; 2017 } 2018 2019 // VCI initiator response on INT network 2020 // It depends on the MISS_WTI_RSP FSM state 2021 2022 if ( r_miss_wti_rsp_fsm.read() == MISS_WTI_RSP_IDLE ) p_vci_ini_int.rspack = false; 2023 else p_vci_ini_int.rspack = true; 2024 3310 2025 } // end genMoore 3311 2026
Note: See TracChangeset
for help on using the changeset viewer.