Changeset 712 for trunk/modules
- Timestamp:
- Jun 10, 2014, 11:32:32 AM (11 years ago)
- Location:
- trunk/modules/vci_io_bridge
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/modules/vci_io_bridge/caba/source/include/vci_io_bridge.h
r585 r712 37 37 // configuration or data transactions to peripherals. 38 38 // 39 // Regarding DMA transactions initiated by external peripherals, it provides 39 // It supports two types of transactions from peripherals: 40 // - DMA transactions to the RAM network, 41 // - WTI transactions to the INT network. 42 // Regarding transactions initiated by external peripherals, it provides 40 43 // an - optional - IOMMU service : the 32 bits virtual address is translated 41 44 // to a (up to) 40 bits physical address by a standard SoCLib generic TLB. 42 45 // In case of TLB MISS, the DMA transaction is stalled until the TLB is updated. 43 // In case of page fault (illegal access), a VCI error is returned to the44 // faulty peripheral.46 // In case of page fault or read_only violation (illegal access), a VCI error 47 // is returned to the faulty peripheral, and a IOMMU WTI is sent. 45 48 ///////////////////////////////////////////////////////////////////////////////// 46 49 // General Constraints: … … 63 66 // - Ne pas garder tous les champs WRITE CMD dans les FIFO a chaque flit 64 67 // (seulement 'data' et 'be') 65 // - Traiter complêtement les codes d'erreur en réponse à une transaction66 // WTI write67 68 /////////////////////////////////////////////////////////////////////////////// 68 69 … … 94 95 : public soclib::caba::BaseModule 95 96 { 96 // Data and be fields have different widths on INT and EXT networks97 // Data and be fields have different widths on INT and EXT/IOC networks 97 98 typedef typename vci_param_ext::data_t ext_data_t; 98 99 typedef typename vci_param_int::data_t int_data_t; 99 100 typedef typename vci_param_ext::be_t ext_be_t; 100 typedef typename vci_param_int::be_t ext_in_t;101 typedef typename vci_param_int::be_t int_be_t; 101 102 102 103 // Other fields must be equal … … 130 131 { 131 132 DMA_CMD_IDLE, 132 DMA_CMD_FIFO_PUT_CMD, 133 DMA_CMD_FIFO_PUT_RSP, 134 DMA_CMD_MISS_WAIT, 135 DMA_CMD_WAIT_EOP, 133 DMA_CMD_DMA_REQ, 134 DMA_CMD_WTI_IOX_REQ, 135 DMA_CMD_ERR_WAIT_EOP, 136 DMA_CMD_ERR_WTI_REQ, 137 DMA_CMD_ERR_RSP_REQ, 138 DMA_CMD_TLB_MISS_WAIT, 136 139 }; 137 140 138 // States for DMA_RSP FSM (from RAM to IOX)141 // States for DMA_RSP FSM 139 142 enum dma_rsp_fsm_state 140 143 { 141 DMA_RSP_IDLE, 142 DMA_RSP_FIFO_PUT, 144 DMA_RSP_IDLE_DMA, 145 DMA_RSP_IDLE_WTI, 146 DMA_RSP_IDLE_ERR, 147 DMA_RSP_PUT_DMA, 148 DMA_RSP_PUT_WTI, 149 DMA_RSP_PUT_ERR, 143 150 }; 144 151 … … 159 166 }; 160 167 161 // States for CONFIG_CMD FSM (from INT to IOX)168 // States for CONFIG_CMD FSM 162 169 enum config_cmd_fsm_state 163 170 { … … 168 175 }; 169 176 170 // states for CONFIG_RSP FSM (from IOX to INT)177 // states for CONFIG_RSP FSM 171 178 enum config_rsp_fsm_state 172 179 { 173 CONFIG_RSP_IDLE, 174 CONFIG_RSP_PUT_LO, 180 CONFIG_RSP_IDLE_IOX, 181 CONFIG_RSP_IDLE_LOC, 182 CONFIG_RSP_PUT_LOW, 175 183 CONFIG_RSP_PUT_HI, 176 184 CONFIG_RSP_PUT_UNC, 185 CONFIG_RSP_PUT_LOC, 186 177 187 }; 178 188 179 // States for MISS_WTI_CMD FSM (to INT network) 180 enum miss_wti_cmd_state 181 { 182 MISS_WTI_CMD_IDLE, 183 MISS_WTI_CMD_WTI, 184 MISS_WTI_CMD_MISS, 185 }; 186 187 // States for MISS_WTI_RSP FSM (from INT network) 189 // States for MISS_WTI_RSP FSM 188 190 enum miss_wti_rsp_state 189 191 { 190 192 MISS_WTI_RSP_IDLE, 191 MISS_WTI_RSP_WTI, 193 MISS_WTI_RSP_WTI_IOX, 194 MISS_WTI_RSP_WTI_MMU, 192 195 MISS_WTI_RSP_MISS, 193 196 }; … … 196 199 enum pktid_values_e 197 200 { 198 PKTID_READ = 0x0, // TSAR code for read data uncached 199 PKTID_WRITE = 0x4, // TSAR code for write 201 PKTID_MISS = 0x0, // TSAR code for read data uncached 202 PKTID_WTI_IOX = 0x4, // TSAR code for write 203 PKTID_WTI_MMU = 0xC, // TSAR code for write 200 204 }; 201 205 … … 210 214 sc_in<bool> p_clk; 211 215 sc_in<bool> p_resetn; 212 sc_in<bool>* p_irq[32]; // not always constructed213 216 214 217 soclib::caba::VciInitiator<vci_param_ext> p_vci_ini_ram; … … 222 225 private: 223 226 const size_t m_words; 224 const bool m_has_irqs;225 227 226 228 // INT & IOX Networks 227 229 std::list<soclib::common::Segment> m_int_seglist; 228 const vci_srcid_t m_int_srcid; // localSRCID on INT network230 const vci_srcid_t m_int_srcid; // SRCID on INT network 229 231 std::list<soclib::common::Segment> m_iox_seglist; 230 232 … … 241 243 // MEMORY MAPPED REGISTERS 242 244 /////////////////////////////// 243 sc_signal<uint32_t> r_iommu_ptpr; // page table pointer register245 sc_signal<uint32_t> r_iommu_ptpr; // page table pointer 244 246 sc_signal<bool> r_iommu_active; // iotlb mode 245 sc_signal<uint32_t> r_iommu_bvar; // iommu bad virtual address 246 sc_signal<uint32_t> r_iommu_etr; // iommu error type 247 sc_signal<uint32_t> r_iommu_bad_id; // SRCID of faulty peripheral 248 sc_signal<uint32_t> r_iommu_wti_enable; // enable WTI transactions 249 sc_signal<vci_addr_t> r_iommu_wti_paddr; // address of IOMMU WTI 250 sc_signal<vci_addr_t>* r_iommu_peri_wti; // array[32] WTI for peripherals 247 sc_signal<uint32_t> r_iommu_bvar; // bad vaddr 248 sc_signal<uint32_t> r_iommu_etr; // error type 249 sc_signal<uint32_t> r_iommu_bad_id; // faulty srcid 250 sc_signal<bool> r_iommu_wti_enable; // enable IOB WTI 251 sc_signal<uint32_t> r_iommu_wti_addr_lo; // IOMMU WTI paddr (32 lsb) 252 sc_signal<uint32_t> r_iommu_wti_addr_hi; // IOMMU WTI paddr (32 msb) 253 254 sc_signal<uint32_t> r_xicu_base; // XICU paddr base (cluster 0) 255 sc_signal<uint32_t> r_xicu_size; // XIXU paddr size (cluster 0) 251 256 252 257 /////////////////////////////////// … … 254 259 /////////////////////////////////// 255 260 sc_signal<int> r_dma_cmd_fsm; 256 sc_signal<uint32_t> r_dma_cmd_vaddr; // input virtual address 257 sc_signal<vci_addr_t> r_dma_cmd_paddr; // output physical address 261 sc_signal<vci_addr_t> r_dma_cmd_paddr; // output paddr 262 263 sc_signal<bool> r_dma_cmd_to_miss_wti_cmd_req; 264 sc_signal<vci_addr_t> r_dma_cmd_to_miss_wti_cmd_addr; 265 sc_signal<vci_cmd_t> r_dma_cmd_to_miss_wti_cmd_cmd; 266 sc_signal<vci_srcid_t> r_dma_cmd_to_miss_wti_cmd_srcid; 267 sc_signal<vci_trdid_t> r_dma_cmd_to_miss_wti_cmd_trdid; 268 sc_signal<vci_trdid_t> r_dma_cmd_to_miss_wti_cmd_pktid; 269 sc_signal<int_data_t> r_dma_cmd_to_miss_wti_cmd_wdata; 270 271 sc_signal<bool> r_dma_cmd_to_dma_rsp_req; 272 sc_signal<vci_srcid_t> r_dma_cmd_to_dma_rsp_rsrcid; 273 sc_signal<vci_trdid_t> r_dma_cmd_to_dma_rsp_rtrdid; 274 sc_signal<vci_pktid_t> r_dma_cmd_to_dma_rsp_rpktid; 275 sc_signal<vci_rerror_t> r_dma_cmd_to_dma_rsp_rerror; 276 sc_signal<ext_data_t> r_dma_cmd_to_dma_rsp_rdata; 277 278 sc_signal<bool> r_dma_cmd_to_tlb_req; 279 sc_signal<uint32_t> r_dma_cmd_to_tlb_vaddr; // input vaddr 258 280 259 281 /////////////////////////////////// … … 266 288 /////////////////////////////////// 267 289 sc_signal<int> r_config_cmd_fsm; 268 sc_signal<uint32_t> r_config_cmd_rdata; 269 sc_signal<bool> r_config_cmd_error; 270 sc_signal<uint32_t> r_config_cmd_inval_vaddr; 290 291 sc_signal<bool> r_config_cmd_to_tlb_req; 292 sc_signal<uint32_t> r_config_cmd_to_tlb_vaddr; 293 294 sc_signal<bool> r_config_cmd_to_config_rsp_req; 295 sc_signal<bool> r_config_cmd_to_config_rsp_rerror; 296 sc_signal<uint32_t> r_config_cmd_to_config_rsp_rdata; 271 297 272 298 sc_signal<ext_data_t> r_config_cmd_wdata; … … 293 319 // TLB FSM REGISTERS 294 320 /////////////////////////////////// 295 sc_signal<int> r_tlb_fsm; // state register296 sc_signal<bool> r_waiting_transaction; // Flag for returning from321 sc_signal<int> r_tlb_fsm; // state register 322 sc_signal<bool> r_waiting_transaction; // Flag for returning from 297 323 sc_signal<int> r_tlb_miss_type; 298 324 sc_signal<bool> r_tlb_miss_error; 299 325 300 sc_signal<vci_addr_t> r_tlb_paddr; // physical address of pte 301 sc_signal<uint32_t> r_tlb_pte_flags; // pte1 or first word of pte2 302 sc_signal<uint32_t> r_tlb_pte_ppn; // second word of pte2 303 sc_signal<size_t> r_tlb_way; // selected way in tlb 304 sc_signal<size_t> r_tlb_set; // selected set in tlb 305 306 uint32_t* r_tlb_buf_data; // prefetch buffer for PTEs 307 sc_signal<bool> r_tlb_buf_valid; // one valit flag for all PTEs 308 sc_signal<vci_addr_t> r_tlb_buf_tag; // cache line number 309 sc_signal<vci_addr_t> r_tlb_buf_vaddr; // virtual address first PTE 310 sc_signal<bool> r_tlb_buf_big_page; // ??? 311 312 /////////////////////////////////// 313 // MISS_WTI_CMD FSM REGISTERS 314 /////////////////////////////////// 315 sc_signal<int> r_miss_wti_cmd_fsm; 316 sc_signal<size_t> r_miss_wti_cmd_index; 326 sc_signal<vci_addr_t> r_tlb_paddr; // physical address of pte 327 sc_signal<uint32_t> r_tlb_pte_flags; // pte1 or first word of pte2 328 sc_signal<uint32_t> r_tlb_pte_ppn; // second word of pte2 329 sc_signal<size_t> r_tlb_way; // selected way in tlb 330 sc_signal<size_t> r_tlb_set; // selected set in tlb 331 332 uint32_t* r_tlb_buf_data; // prefetch buffer for PTEs 333 sc_signal<bool> r_tlb_buf_valid; // one valit flag for all PTEs 334 sc_signal<vci_addr_t> r_tlb_buf_tag; // cache line number 335 sc_signal<vci_addr_t> r_tlb_buf_vaddr; // vaddr for first PTE 336 sc_signal<bool> r_tlb_buf_big_page; // ??? 337 338 sc_signal<bool> r_tlb_to_miss_wti_cmd_req; 317 339 318 340 /////////////////////////////////// … … 320 342 /////////////////////////////////// 321 343 sc_signal<int> r_miss_wti_rsp_fsm; 322 sc_signal<bool> r_miss_wti_rsp_error; 323 sc_signal<size_t> r_miss_wti_rsp_count; 344 sc_signal<bool> r_miss_wti_rsp_error_wti; // VCI error on WTI 345 sc_signal<bool> r_miss_wti_rsp_error_miss; // VCI error on MISS 346 sc_signal<size_t> r_miss_wti_rsp_count; // flits counter 347 348 sc_signal<bool> r_miss_wti_rsp_to_dma_rsp_req; 349 sc_signal<vci_rerror_t> r_miss_wti_rsp_to_dma_rsp_rerror; 350 sc_signal<vci_srcid_t> r_miss_wti_rsp_to_dma_rsp_rsrcid; 351 sc_signal<vci_trdid_t> r_miss_wti_rsp_to_dma_rsp_rtrdid; 352 sc_signal<vci_pktid_t> r_miss_wti_rsp_to_dma_rsp_rpktid; 353 324 354 325 355 ///////////////////////////////////////////////////// … … 327 357 ///////////////////////////////////////////////////// 328 358 sc_signal<bool> r_alloc_fifo_config_rsp_local; 329 sc_signal<bool> r_alloc_fifo_dma_rsp_local; 330 331 ////////////////////////////////// 332 // IRQ FSM registers 333 ////////////////////////////////// 334 sc_signal<bool>* r_irq_pending; // array[32] 335 sc_signal<bool>* r_irq_request; // array[32] 359 336 360 337 361 ////////////////////////////////////////////////////////////////// … … 340 364 GenericTlb<vci_addr_t> r_iotlb; 341 365 342 //////////////////////////////////////////////////////////////////343 // Inter-FSM communications344 //////////////////////////////////////////////////////////////////345 346 // between DMA_CMD and TLB FSM347 sc_signal<bool> r_dma_tlb_req;348 349 // between CONFIG_CMD FSM and TLB FSM350 sc_signal<bool> r_config_tlb_req;351 352 // between TLB FSM and MISS_WTI FSM353 sc_signal<bool> r_tlb_miss_req;354 366 355 367 ///////////////////////// … … 405 417 GenericFifo<vci_rerror_t> m_config_rsp_rerror_fifo; 406 418 407 419 // output FIFO to VCI_INI port on INT network (VCI command) 420 GenericFifo<vci_addr_t> m_miss_wti_cmd_addr_fifo; 421 GenericFifo<vci_srcid_t> m_miss_wti_cmd_srcid_fifo; 422 GenericFifo<vci_trdid_t> m_miss_wti_cmd_trdid_fifo; 423 GenericFifo<vci_pktid_t> m_miss_wti_cmd_pktid_fifo; 424 GenericFifo<int_be_t> m_miss_wti_cmd_be_fifo; 425 GenericFifo<vci_cmd_t> m_miss_wti_cmd_cmd_fifo; 426 GenericFifo<vci_contig_t> m_miss_wti_cmd_contig_fifo; 427 GenericFifo<int_data_t> m_miss_wti_cmd_data_fifo; 428 GenericFifo<vci_eop_t> m_miss_wti_cmd_eop_fifo; 429 GenericFifo<vci_cons_t> m_miss_wti_cmd_cons_fifo; 430 GenericFifo<vci_plen_t> m_miss_wti_cmd_plen_fifo; 431 GenericFifo<vci_wrap_t> m_miss_wti_cmd_wrap_fifo; 432 GenericFifo<vci_cfixed_t> m_miss_wti_cmd_cfixed_fifo; 433 GenericFifo<vci_clen_t> m_miss_wti_cmd_clen_fifo; 434 408 435 //////////////////////////////// 409 436 // Activity counters … … 432 459 uint32_t m_cpt_fsm_config_cmd [32]; 433 460 uint32_t m_cpt_fsm_config_rsp [32]; 434 uint32_t m_cpt_fsm_miss_wti_cmd [32];435 461 uint32_t m_cpt_fsm_miss_wti_rsp [32]; 436 462 437 463 protected: 464 438 465 SC_HAS_PROCESS(VciIoBridge); 439 466 440 467 public: 468 441 469 VciIoBridge( 442 470 sc_module_name insname, … … 447 475 const soclib::common::IntTab &int_srcid, // INT network SRCID 448 476 const soclib::common::IntTab &iox_tgtid, // IOX network TGTID 449 const bool has_irqs, // component has irq ports450 477 const size_t dcache_words, 451 478 const size_t iotlb_ways, … … 462 489 463 490 private: 491 492 bool is_wti( vci_addr_t paddr ); 464 493 void transition(); 465 494 void genMoore(); -
trunk/modules/vci_io_bridge/caba/source/src/vci_io_bridge.cpp
r585 r712 43 43 #define DEBUG_CONFIG_CMD 1 44 44 #define DEBUG_CONFIG_RSP 1 45 #define DEBUG_MISS_WTI 145 #define DEBUG_MISS_WTI_CMD 1 46 46 47 47 namespace soclib { … … 53 53 { 54 54 "DMA_CMD_IDLE", 55 "DMA_CMD_FIFO_PUT_CMD", 56 "DMA_CMD_FIFO_PUT_RSP", 57 "DMA_CMD_MISS_WAIT", 58 "DMA_CMD_WAIT_EOP", 55 "DMA_CMD_DMA_REQ", 56 "DMA_CMD_WTI_IOX_REQ", 57 "DMA_CMD_ERR_WAIT_EOP", 58 "DMA_CMD_ERR_WTI_REQ", 59 "DMA_CMD_ERR_RSP_REQ", 60 "DMA_CMD_TLB_MISS_WAIT", 59 61 }; 60 62 61 63 const char *dma_rsp_fsm_state_str[] = 62 64 { 63 "DMA_RSP_IDLE", 64 "DMA_RSP_FIFO_PUT", 65 "DMA_RSP_IDLE_DMA", 66 "DMA_RSP_IDLE_WTI", 67 "DMA_RSP_IDLE_ERR", 68 "DMA_RSP_PUT_DMA", 69 "DMA_RSP_PUT_WTI", 70 "DMA_RSP_PUT_ERR", 65 71 }; 66 72 … … 90 96 const char *config_rsp_fsm_state_str[] = 91 97 { 92 "CONFIG_RSP_IDLE", 93 "CONFIG_RSP_PUT_LO", 98 "CONFIG_RSP_IDLE_IOX", 99 "CONFIG_RSP_IDLE_LOC", 100 "CONFIG_RSP_PUT_LOW", 94 101 "CONFIG_RSP_PUT_HI", 95 102 "CONFIG_RSP_PUT_UNC", 103 "CONFIG_RSP_PUT_LOC", 96 104 }; 97 105 98 const char *miss_wti_cmd_state_str[] =99 {100 "MISS_WTI_CMD_IDLE",101 "MISS_WTI_CMD_WTI",102 "MISS_WTI_CMD_MISS",103 };104 106 const char *miss_wti_rsp_state_str[] = 105 107 { 106 108 "MISS_WTI_RSP_IDLE", 107 "MISS_WTI_RSP_WTI", 109 "MISS_WTI_RSP_WTI_IOX", 110 "MISS_WTI_RSP_WTI_MMU", 108 111 "MISS_WTI_RSP_MISS", 109 112 }; … … 121 124 const soclib::common::IntTab &int_srcid, // INT network SRCID 122 125 const soclib::common::IntTab &iox_tgtid, // IOX network TGTID 123 const bool has_irqs,124 126 const size_t dcache_words, 125 127 const size_t iotlb_ways, … … 138 140 139 141 m_words( dcache_words ), 140 m_has_irqs( has_irqs ),141 142 142 143 // INT & IOX Network … … 157 158 r_iommu_etr("r_iommu_etr"), 158 159 r_iommu_bad_id("r_iommu_bad_id"), 159 r_iommu_wti_ paddr("r_iommu_wti_paddr"),160 r_iommu_ peri_wti(alloc_elems<sc_signal<vci_addr_t> >("r_peri_wti_paddr", 32)),160 r_iommu_wti_enable("r_iommu_wti_enable"), 161 r_iommu_wti_addr_lo("r_iommu_wti_addr_lo"), 161 162 162 163 // DMA_CMD FSM registers 163 164 r_dma_cmd_fsm("r_dma_cmd_fsm"), 164 r_dma_cmd_vaddr("r_dma_cmd_vaddr"),165 165 r_dma_cmd_paddr("r_dma_cmd_paddr"), 166 166 167 r_dma_cmd_to_miss_wti_cmd_req("r_dma_cmd_to_miss_wti_cmd_req"), 168 r_dma_cmd_to_miss_wti_cmd_addr("r_dma_cmd_to_miss_wti_cmd_addr"), 169 r_dma_cmd_to_miss_wti_cmd_srcid("r_dma_cmd_to_miss_wti_cmd_srcid"), 170 r_dma_cmd_to_miss_wti_cmd_trdid("r_dma_cmd_to_miss_wti_cmd_trdid"), 171 r_dma_cmd_to_miss_wti_cmd_pktid("r_dma_cmd_to_miss_wti_cmd_pktid"), 172 r_dma_cmd_to_miss_wti_cmd_wdata("r_dma_cmd_to_miss_wti_cmd_wdata"), 173 174 r_dma_cmd_to_dma_rsp_req("r_dma_cmd_to_dma_rsp_req"), 175 r_dma_cmd_to_dma_rsp_rsrcid("r_dma_cmd_to_dma_rsp_rsrcid"), 176 r_dma_cmd_to_dma_rsp_rtrdid("r_dma_cmd_to_dma_rsp_rtrdid"), 177 r_dma_cmd_to_dma_rsp_rpktid("r_dma_cmd_to_dma_rsp_rpktid"), 178 179 r_dma_cmd_to_tlb_req("r_dma_cmd_to_tlb_req"), 180 r_dma_cmd_to_tlb_vaddr("r_dma_cmd_to_tlb_vaddr"), 181 167 182 //DMA_RSP FSM registers 168 183 r_dma_rsp_fsm("r_dma_rsp_fsm"), … … 170 185 // CONFIG_CMD FSM registers 171 186 r_config_cmd_fsm("r_config_cmd_fsm"), 172 r_config_cmd_rdata("r_config_cmd_rdata"), 173 r_config_cmd_error("r_config_cmd_error"), 174 r_config_cmd_inval_vaddr("r_config_cmd_inval_vaddr"), 187 188 r_config_cmd_to_tlb_req("r_config_cmd_to_tlb_req"), 189 r_config_cmd_to_tlb_vaddr("r_config_cmd_to_tlb_vaddr"), 190 191 r_config_cmd_to_config_rsp_req("r_config_cmd_to_config_rsp_req"), 192 r_config_cmd_to_config_rsp_rerror("r_config_cmd_to_config_rsp_rerror"), 193 r_config_cmd_to_config_rsp_rdata("r_config_cmd_to_config_rsp_rdata"), 194 175 195 r_config_cmd_wdata("r_config_cmd_wdata"), 176 196 r_config_cmd_be("r_config_cmd_be"), … … 196 216 r_tlb_miss_type("r_tlb_miss_type"), 197 217 r_tlb_miss_error("r_tlb_miss_error"), 218 198 219 r_tlb_paddr("r_tlb_paddr"), 199 220 r_tlb_pte_flags("r_tlb_pte_flags"), 200 221 r_tlb_pte_ppn("r_tlb_pte_ppn"), 201 222 r_tlb_way("r_tlb_way"), 202 r_tlb_set("r_tlb_set"), 223 r_tlb_set("r_tlb_set"), 224 203 225 r_tlb_buf_valid("r_tlb_buf_valid"), 204 226 r_tlb_buf_tag("r_tlb_buf_tag"), … … 206 228 r_tlb_buf_big_page("r_tlb_buf_big_page"), 207 229 208 // MISS_WTI_CMD FSM registers 209 r_miss_wti_cmd_fsm("r_miss_wti_cmd_fsm"), 210 r_miss_wti_cmd_index("r_miss_wti_cmd_index"), 211 212 // MISS_WTI_CMD FSM registers 230 r_tlb_to_miss_wti_cmd_req("r_tlb_to_miss_wti_cmd_req"), 231 232 // MISS_WTI_RSP FSM registers 213 233 r_miss_wti_rsp_fsm("r_miss_wti_rsp_fsm"), 214 r_miss_wti_rsp_error ("r_miss_wti_rsp_error"),215 216 // allocator for CONFIG_RSP & DMA_RSP fifos217 r_alloc_fifo_config_rsp_local("r_alloc_fifo_config_rsp_local"), 218 r_ alloc_fifo_dma_rsp_local("r_alloc_fifo_dma_rsp_local"),219 220 // IRQs registers221 r_ irq_pending(alloc_elems<sc_signal<bool> >("r_irq_pending", 32)),222 r_ irq_request(alloc_elems<sc_signal<bool> >("r_irq_request", 32)),223 234 r_miss_wti_rsp_error_wti("r_miss_wti_rsp_error_wti"), 235 r_miss_wti_rsp_error_miss("r_miss_wti_rsp_error_miss"), 236 r_miss_wti_rsp_count("r_miss_wti_rsp_count"), 237 238 r_miss_wti_rsp_to_dma_rsp_req("r_miss_wti_rsp_to_dma_rsp_req"), 239 r_miss_wti_rsp_to_dma_rsp_rerror("r_miss_wti_rsp_to_dma_rsp_rerror"), 240 r_miss_wti_rsp_to_dma_rsp_rsrcid("r_miss_wti_rsp_to_dma_rsp_rsrcid"), 241 r_miss_wti_rsp_to_dma_rsp_rtrdid("r_miss_wti_rsp_to_dma_rsp_rtrdid"), 242 r_miss_wti_rsp_to_dma_rsp_rpktid("r_miss_wti_rsp_to_dma_rsp_rpktid"), 243 224 244 // TLB for IOMMU 225 245 r_iotlb("iotlb", 0, iotlb_ways, iotlb_sets, vci_param_int::N), 226 246 227 // Inter-FSM communications228 r_dma_tlb_req("r_dma_tlb_req"),229 r_config_tlb_req("r_config_tlb_req"),230 r_tlb_miss_req("r_tlb_miss_req"),231 232 247 // DMA_CMD FIFOs 233 248 m_dma_cmd_addr_fifo("m_dma_cmd_addr_fifo",2), … … 276 291 m_config_rsp_rpktid_fifo("m_config_rsp_rpktid_fifo",2), 277 292 m_config_rsp_reop_fifo("m_config_rsp_reop_fifo",2), 278 m_config_rsp_rerror_fifo("m_config_rsp_rerror_fifo",2) 293 m_config_rsp_rerror_fifo("m_config_rsp_rerror_fifo",2), 294 295 // MISS_WTI_CMD FIFOs 296 m_miss_wti_cmd_addr_fifo("m_miss_wti_cmd_addr_fifo",2), 297 m_miss_wti_cmd_srcid_fifo("m_miss_wti_cmd_srcid_fifo",2), 298 m_miss_wti_cmd_trdid_fifo("m_miss_wti_cmd_trdid_fifo",2), 299 m_miss_wti_cmd_pktid_fifo("m_miss_wti_cmd_pktid_fifo",2), 300 m_miss_wti_cmd_be_fifo("m_miss_wti_cmd_be_fifo",2), 301 m_miss_wti_cmd_cmd_fifo("m_miss_wti_cmd_cmd_fifo",2), 302 m_miss_wti_cmd_contig_fifo("m_miss_wti_cmd_contig_fifo",2), 303 m_miss_wti_cmd_data_fifo("m_miss_wti_cmd_data_fifo",2), 304 m_miss_wti_cmd_eop_fifo("m_miss_wti_cmd_eop_fifo",2), 305 m_miss_wti_cmd_cons_fifo("m_miss_wti_cmd_cons_fifo",2), 306 m_miss_wti_cmd_plen_fifo("m_miss_wti_cmd_plen_fifo",2), 307 m_miss_wti_cmd_wrap_fifo("m_miss_wti_cmd_wrap_fifo",2), 308 m_miss_wti_cmd_cfixed_fifo("m_miss_wti_cmd_cfixed_fifo",2), 309 m_miss_wti_cmd_clen_fifo("m_miss_wti_cmd_clen_fifo",2) 279 310 { 280 311 std::cout << " - Building VciIoBridge : " << name << std::endl; … … 320 351 "VCI_IO_BRIDGE ERROR: SRCID widths must be equal on the 3 networks"); 321 352 322 // contruct 32 IRQ ports if required323 if ( has_irqs )324 {325 for ( size_t n=0 ; n<32 ; n++ ) p_irq[n] = new sc_core::sc_in<bool>;326 }327 328 353 // Cache line buffer 329 354 r_tlb_buf_data = new uint32_t[dcache_words]; … … 343 368 ///////////////////////////////////// 344 369 { 345 delete [] r_iommu_peri_wti;346 370 delete [] r_tlb_buf_data; 347 soclib::common::dealloc_elems(p_irq, 32);348 soclib::common::dealloc_elems(r_irq_request, 32);349 soclib::common::dealloc_elems(r_irq_pending, 32);350 371 } 351 372 … … 363 384 << " | " << config_cmd_fsm_state_str[r_config_cmd_fsm.read()] 364 385 << " | " << config_rsp_fsm_state_str[r_config_rsp_fsm.read()] 365 << " | " << miss_wti_cmd_state_str[r_miss_wti_cmd_fsm.read()]366 386 << " | " << miss_wti_rsp_state_str[r_miss_wti_rsp_fsm.read()] 367 387 << std::endl; … … 396 416 } 397 417 418 //////////////////////////////////// 419 tmpl(bool)::is_wti(vci_addr_t paddr) 420 //////////////////////////////////// 421 { 422 uint32_t addr32 = (uint32_t)paddr; 423 uint32_t base = r_xicu_base.read(); 424 uint32_t size = r_xicu_size.read(); 425 return ( (addr32 >= base) and (addr32 < (base + size)) ); 426 } 427 398 428 ///////////////////////// 399 429 tmpl(void)::transition() … … 403 433 { 404 434 r_dma_cmd_fsm = DMA_CMD_IDLE; 405 r_dma_rsp_fsm = DMA_RSP_IDLE ;435 r_dma_rsp_fsm = DMA_RSP_IDLE_DMA; 406 436 r_tlb_fsm = TLB_IDLE; 407 437 r_config_cmd_fsm = CONFIG_CMD_IDLE; 408 r_config_rsp_fsm = CONFIG_RSP_IDLE; 409 r_miss_wti_cmd_fsm = MISS_WTI_CMD_IDLE; 438 r_config_rsp_fsm = CONFIG_RSP_IDLE_IOX; 410 439 r_miss_wti_rsp_fsm = MISS_WTI_RSP_IDLE; 411 412 r_alloc_fifo_config_rsp_local = true;413 r_alloc_fifo_dma_rsp_local = true;414 440 415 441 r_tlb_buf_valid = false; 416 442 r_iommu_active = false; 417 443 r_iommu_wti_enable = false; 418 444 445 r_xicu_size = 0; 446 r_xicu_base = 0; 447 419 448 // initializing FIFOs 420 449 m_dma_cmd_addr_fifo.init(); … … 455 484 m_config_cmd_clen_fifo.init(); 456 485 486 m_miss_wti_cmd_addr_fifo.init(); 487 m_miss_wti_cmd_srcid_fifo.init(); 488 m_miss_wti_cmd_trdid_fifo.init(); 489 m_miss_wti_cmd_pktid_fifo.init(); 490 m_miss_wti_cmd_be_fifo.init(); 491 m_miss_wti_cmd_cmd_fifo.init(); 492 m_miss_wti_cmd_contig_fifo.init(); 493 m_miss_wti_cmd_data_fifo.init(); 494 m_miss_wti_cmd_eop_fifo.init(); 495 m_miss_wti_cmd_cons_fifo.init(); 496 m_miss_wti_cmd_plen_fifo.init(); 497 m_miss_wti_cmd_wrap_fifo.init(); 498 m_miss_wti_cmd_cfixed_fifo.init(); 499 m_miss_wti_cmd_clen_fifo.init(); 500 457 501 m_config_rsp_rsrcid_fifo.init(); 458 502 m_config_rsp_rtrdid_fifo.init(); … … 463 507 464 508 // SET/RESET Communication flip-flops 465 r_dma_tlb_req = false; 466 r_config_tlb_req = false; 467 r_tlb_miss_req = false; 509 r_dma_cmd_to_miss_wti_cmd_req = false; 510 r_dma_cmd_to_dma_rsp_req = false; 511 r_dma_cmd_to_tlb_req = false; 512 r_config_cmd_to_tlb_req = false; 513 r_config_cmd_to_config_rsp_req = false; 514 r_tlb_to_miss_wti_cmd_req = false; 515 r_miss_wti_rsp_to_dma_rsp_req = false; 516 517 // error flip_flops 518 r_miss_wti_rsp_error_miss = false; 519 r_miss_wti_rsp_error_wti = false; 468 520 469 521 // Debug variable 470 m_debug_activated = false;522 m_debug_activated = false; 471 523 472 for ( size_t n=0 ; n<32 ; n++ )473 {474 r_irq_pending[n] = false;475 r_irq_request[n] = false;476 }477 478 524 // activity counters 479 m_cpt_total_cycles = 0;480 m_cpt_iotlb_read = 0;481 m_cpt_iotlb_miss = 0;482 m_cpt_iotlbmiss_transaction = 0;483 m_cost_iotlbmiss_transaction = 0;525 m_cpt_total_cycles = 0; 526 m_cpt_iotlb_read = 0; 527 m_cpt_iotlb_miss = 0; 528 m_cpt_iotlbmiss_transaction = 0; 529 m_cost_iotlbmiss_transaction = 0; 484 530 485 m_cpt_trt_dma_full = 0;486 m_cpt_trt_dma_full_cost = 0;487 m_cpt_trt_config_full = 0;488 m_cpt_trt_config_full_cost = 0;531 m_cpt_trt_dma_full = 0; 532 m_cpt_trt_dma_full_cost = 0; 533 m_cpt_trt_config_full = 0; 534 m_cpt_trt_config_full_cost = 0; 489 535 490 536 for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_dma_cmd [i] = 0; … … 493 539 for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_config_cmd [i] = 0; 494 540 for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_config_rsp [i] = 0; 495 for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_miss_wti_cmd [i] = 0;496 541 for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_miss_wti_rsp [i] = 0; 497 542 … … 499 544 } 500 545 501 // default values for FIFOs 502 bool dma_cmd_fifo_put = false; 503 bool dma_cmd_fifo_get = false; 504 505 bool dma_rsp_fifo_put = false; 506 bool dma_rsp_fifo_get = false; 546 // default values for the 5 FIFOs 547 bool dma_cmd_fifo_put = false; 548 bool dma_cmd_fifo_get = p_vci_ini_ram.cmdack.read(); 507 549 508 bool config_cmd_fifo_put = false; 509 bool config_cmd_fifo_get = false; 510 511 bool config_rsp_fifo_put = false; 512 bool config_rsp_fifo_get = false; 550 bool dma_rsp_fifo_put = false; 551 bool dma_rsp_fifo_get = p_vci_tgt_iox.rspack.read(); 552 vci_rerror_t dma_rsp_fifo_rerror = 0; 553 vci_srcid_t dma_rsp_fifo_rsrcid = 0; 554 vci_trdid_t dma_rsp_fifo_rtrdid = 0; 555 vci_pktid_t dma_rsp_fifo_rpktid = 0; 556 ext_data_t dma_rsp_fifo_rdata = 0; 557 bool dma_rsp_fifo_reop = false; 558 559 bool config_cmd_fifo_put = false; 560 bool config_cmd_fifo_get = p_vci_ini_iox.cmdack.read(); 561 562 bool config_rsp_fifo_put = false; 563 bool config_rsp_fifo_get = p_vci_tgt_int.rspack.read(); 564 vci_rerror_t config_rsp_fifo_rerror = 0; 565 vci_srcid_t config_rsp_fifo_rsrcid = 0; 566 vci_trdid_t config_rsp_fifo_rtrdid = 0; 567 vci_pktid_t config_rsp_fifo_rpktid = 0; 568 ext_data_t config_rsp_fifo_rdata = 0; 569 bool config_rsp_fifo_reop = false; 570 571 bool miss_wti_cmd_fifo_put = false; 572 bool miss_wti_cmd_fifo_get = p_vci_ini_int.cmdack.read(); 573 vci_addr_t miss_wti_cmd_fifo_address = 0; 574 vci_cmd_t miss_wti_cmd_fifo_cmd = 0; 575 vci_srcid_t miss_wti_cmd_fifo_srcid = 0; 576 vci_trdid_t miss_wti_cmd_fifo_trdid = 0; 577 vci_pktid_t miss_wti_cmd_fifo_pktid = 0; 578 int_data_t miss_wti_cmd_fifo_wdata = 0; 513 579 514 580 #ifdef INSTRUMENTATION … … 518 584 m_cpt_fsm_config_cmd [r_config_cmd_fsm.read() ] ++; 519 585 m_cpt_fsm_config_rsp [r_config_rsp_fsm.read() ] ++; 520 m_cpt_fsm_miss_wti_cmd [r_miss_wti_cmd_fsm.read() ] ++;521 586 m_cpt_fsm_miss_wti_rsp [r_miss_wti_rsp_fsm.read() ] ++; 522 587 #endif … … 527 592 528 593 ////////////////////////////////////////////////////////////////////////////// 529 // The DMA_CMD_FSM handles DMA transactions requested by peripherals 530 // It makes the address translation if IOMMU is activated. 594 // The DMA_CMD_FSM handles transactions requested by peripherals. 595 // - it can be DMA transactions to RAM network (DMA_REQ state). 596 // - it can be WTI transactions to INT network (EXT_WTI_REQ state). 597 // It makes the address translation if IOMMU is activated, requesting 598 // the TLB_MISS FSM in case of TLB miss (TLB_MISS_WAIT state). 599 // When the IOMMU is activated, a DMA request can fail in two cases: 600 // - write to a read-only address : detected in IDLE state 601 // - virtual address unmapped : detected in MISS_WAIT state 602 // In both cases of violation, the DMA_CMD FSM makes the following actions : 603 // 1. register the error in r_iommu_*** registers 604 // 2. wait the faulty command EOP (ERR_WAIT_EOP state) 605 // 3. request a IOMMU WTI to MISS_WTI FSM, (ERR_WTI_REQ state) 606 // 4. request a response error to DMA_RSP FSM (ERR_RSP_REQ state) 531 607 /////////////////////////////////////////////////////////////////////////////// 532 608 … … 534 610 { 535 611 ////////////////// 536 case DMA_CMD_IDLE: // waiting DMA VCI transaction 537 { 538 if ( p_vci_tgt_iox.cmdval.read() ) // compute physical address 612 case DMA_CMD_IDLE: // wait a DMA or WTI VCI transaction and route it 613 // after an IOMMU translation if IOMMU activated. 614 // no VCI flit is consumed in this state 615 { 616 if ( p_vci_tgt_iox.cmdval.read() ) 539 617 { 540 618 if ( not r_iommu_active.read() ) // tlb not activated 541 619 { 620 // save paddr address 621 r_dma_cmd_paddr = p_vci_tgt_iox.address.read(); 622 623 // analyse paddr for WTI/DMA routing 624 // WTI requests must be single flit (READ or WRITE) 625 if ( is_wti( p_vci_tgt_iox.address.read() ) ) 626 { 627 assert( p_vci_tgt_iox.eop.read() and 628 "ERROR in VCI_IOB illegal VCI WTI command from IOX network"); 629 630 r_dma_cmd_fsm = DMA_CMD_WTI_IOX_REQ; 631 } 632 else 633 { 634 r_dma_cmd_fsm = DMA_CMD_DMA_REQ; 635 } 636 542 637 #if DEBUG_DMA_CMD 543 638 if( m_debug_activated ) 544 std::cout << " <IOB DMA_CMD_IDLE> @@@ dmacommand" << std::endl545 << " address = " << std::hex << p_vci_tgt_iox.address.read()639 std::cout << " <IOB DMA_CMD_IDLE> DMA command" << std::endl 640 << " : address = " << std::hex << p_vci_tgt_iox.address.read() 546 641 << " / srcid = " << p_vci_tgt_iox.srcid.read() 547 << " / trdid = " << p_vci_tgt_iox.trdid.read()548 642 << " / wdata = " << std::hex << p_vci_tgt_iox.wdata.read() 549 << " / be = " << p_vci_tgt_iox.be.read()550 643 << " / plen = " << std::dec << p_vci_tgt_iox.plen.read() 551 644 << " / eop = " << p_vci_tgt_iox.eop.read() << std::endl; 552 553 #endif 554 // put DMA transaction into DMA_CMD fifo 555 r_dma_cmd_paddr = p_vci_tgt_iox.address.read(); 556 r_dma_cmd_fsm = DMA_CMD_FIFO_PUT_CMD; 645 #endif 557 646 } 558 647 else if (r_tlb_fsm.read() == TLB_IDLE || … … 581 670 (p_vci_tgt_iox.cmd.read() == vci_param_ext::CMD_WRITE) ) 582 671 { 583 // put DMA response error into DMA_RSP fifo672 // register error 584 673 r_iommu_etr = MMU_WRITE_ACCES_VIOLATION; 585 674 r_iommu_bvar = p_vci_tgt_iox.address.read(); 586 675 r_iommu_bad_id = p_vci_tgt_iox.srcid.read(); 587 r_dma_cmd_fsm = DMA_CMD_FIFO_PUT_RSP; 676 677 // prepare response error request to DMA_RSP FSM 678 r_dma_cmd_to_dma_rsp_rsrcid = p_vci_tgt_iox.srcid.read(); 679 r_dma_cmd_to_dma_rsp_rtrdid = p_vci_tgt_iox.trdid.read(); 680 r_dma_cmd_to_dma_rsp_rpktid = p_vci_tgt_iox.pktid.read(); 681 682 // jumps IOMMU error sequence 683 r_dma_cmd_fsm = DMA_CMD_ERR_WAIT_EOP; 588 684 #if DEBUG_DMA_CMD 589 685 if( m_debug_activated ) … … 597 693 std::cout << " <IOB DMA_CMD_IDLE> TLB HIT" << std::endl; 598 694 #endif 599 // put DMA transaction into DMA_CMD fifo 600 r_dma_cmd_paddr = iotlb_paddr; 601 r_dma_cmd_fsm = DMA_CMD_FIFO_PUT_CMD; 695 // save paddr address 696 r_dma_cmd_paddr = iotlb_paddr; 697 698 // analyse address for WTI/DMA routing 699 if ( is_wti( iotlb_paddr ) ) 700 { 701 assert( p_vci_tgt_iox.eop.read() and 702 (p_vci_tgt_iox.cmd == vci_param_int::CMD_WRITE) and 703 "ERROR in VCI_IOB illegal VCI WTI command from IOX network"); 704 705 r_dma_cmd_fsm = DMA_CMD_WTI_IOX_REQ; 706 } 707 else 708 { 709 r_dma_cmd_fsm = DMA_CMD_DMA_REQ; 710 } 602 711 } 603 712 } … … 608 717 m_cpt_iotlb_miss++; 609 718 #endif 610 611 r_dma_cmd_vaddr = p_vci_tgt_iox.address.read();612 r_dma_tlb_req = true;613 r_dma_cmd_fsm = DMA_CMD_MISS_WAIT;719 // register virtual address, and send request to TLB FSM 720 r_dma_cmd_to_tlb_vaddr = p_vci_tgt_iox.address.read(); 721 r_dma_cmd_to_tlb_req = true; 722 r_dma_cmd_fsm = DMA_CMD_TLB_MISS_WAIT; 614 723 #if DEBUG_DMA_CMD 615 724 if( m_debug_activated ) 616 725 std::cout << " <IOB DMA_CMD_IDLE> TLB MISS" << std::endl; 617 726 #endif 618 } // end !hit727 } // end tlb miss 619 728 } // end if tlb_activated 620 729 } // end if cmdval 621 730 break; 622 731 } 623 ////////////////////////// 624 case DMA_CMD_FIFO_PUT_CMD: // put a DMA transaction in DMA_CMD fifo 625 // if contig, VCI address must be incremented 732 ///////////////////// 733 case DMA_CMD_DMA_REQ: // put a flit in DMA_CMD FIFO 734 // if contig, VCI address must be incremented 735 // after initial translation by IOMMU. 736 // flit is consumed if DMA_CMD FIFO not full 626 737 { 627 738 if ( p_vci_tgt_iox.cmdval && m_dma_cmd_addr_fifo.wok() ) … … 639 750 << " address = " << std::hex << r_dma_cmd_paddr.read() 640 751 << " srcid = " << p_vci_tgt_iox.srcid.read() 641 << " trdid = " << p_vci_tgt_iox.trdid.read()642 752 << " wdata = " << p_vci_tgt_iox.wdata.read() 643 << " be = " << p_vci_tgt_iox.be.read() 644 << " contig = " << p_vci_tgt_iox.contig.read() 645 << " eop = " << std::dec << p_vci_tgt_iox.eop.read() 646 << " plen = " << std::dec << p_vci_tgt_iox.plen.read() << std::endl; 753 << " plen = " << std::dec << p_vci_tgt_iox.plen.read() 754 << " eop = " << std::dec << p_vci_tgt_iox.eop.read() << std::endl; 647 755 #endif 648 756 } 649 757 break; 650 758 } 651 ////////////////////// 652 case DMA_CMD_WAIT_EOP: // An error has been detected on the VCI DMA command 653 // consume the VCI packet before sending the error response 654 { 655 if ( p_vci_tgt_iox.eop.read() ) r_dma_cmd_fsm = DMA_CMD_FIFO_PUT_RSP; 656 break; 657 } 658 ////////////////////////// 659 case DMA_CMD_FIFO_PUT_RSP: // try to put a response error in DMA_RSP fifo 660 // The FIFO is shared with DMA_RSP FSM 661 // and we must we wait for allocation... 662 { 663 if ( r_alloc_fifo_dma_rsp_local.read() ) 759 ///////////////////////// 760 case DMA_CMD_WTI_IOX_REQ: // post a WTI_IOX request to MISS_WTI FSM 761 // if no prending previous request 762 // command arguments are stored in dedicated registers 763 // VCI flit is consumed if no previous request 764 { 765 if ( not r_dma_cmd_to_miss_wti_cmd_req.read() ) // no previous pending request 664 766 { 665 dma_rsp_fifo_put = true; 666 667 if( m_dma_rsp_data_fifo.wok() ) 668 { 669 767 r_dma_cmd_to_miss_wti_cmd_req = true; 768 r_dma_cmd_to_miss_wti_cmd_addr = p_vci_tgt_iox.address.read(); 769 r_dma_cmd_to_miss_wti_cmd_cmd = p_vci_tgt_iox.cmd.read(); 770 r_dma_cmd_to_miss_wti_cmd_wdata = (uint32_t)p_vci_tgt_iox.wdata.read(); 771 r_dma_cmd_to_miss_wti_cmd_srcid = p_vci_tgt_iox.srcid.read(); 772 r_dma_cmd_to_miss_wti_cmd_trdid = p_vci_tgt_iox.trdid.read(); 773 r_dma_cmd_to_miss_wti_cmd_pktid = PKTID_WTI_IOX; 774 775 r_dma_cmd_fsm = DMA_CMD_IDLE; 776 670 777 #if DEBUG_DMA_CMD 671 778 if( m_debug_activated ) 672 std::cout << " <IOB DMA_CMD_ FIFO_PUT_RSP> Put a response error to a DMA transaction."673 << std::endl;674 #endif 675 r_dma_cmd_fsm = DMA_CMD_IDLE;676 } 779 std::cout << " <IOB DMA_CMD_WTI_IOX_REQ> request WTI transaction from ext peripheral" 780 << " : address = " << std::hex << r_dma_cmd_paddr.read() 781 << " / srcid = " << p_vci_tgt_iox.srcid.read() 782 << " / wdata = " << p_vci_tgt_iox.wdata.read() << std::endl; 783 #endif 677 784 } 678 785 break; 679 786 } 680 /////////////////////// 681 case DMA_CMD_MISS_WAIT: // waiting completion of a TLB miss 682 // we must test a possible page fault error... 683 { 684 if ( not r_dma_tlb_req.read() ) // TLB miss completed 787 ////////////////////////// 788 case DMA_CMD_ERR_WAIT_EOP: // wait EOP before requesting WTI & error response 789 // VCI flit is always consumed 790 { 791 if ( p_vci_tgt_iox.eop.read() ) r_dma_cmd_fsm = DMA_CMD_ERR_WTI_REQ; 792 793 #if DEBUG_DMA_CMD 794 if( m_debug_activated ) 795 std::cout << " <IOB DMA_CMD_WAIT_EOP> wait EOP for faulty DMA command" << std::endl; 796 #endif 797 break; 798 } 799 800 ///////////////////////// 801 case DMA_CMD_ERR_WTI_REQ: // post a WTI_MMU request to MISS_WTI_CMD FSM 802 // if no prending previous request 803 // response arguments are stored in dedicated registers 804 // no VCI flit is consumed 805 { 806 if ( not r_dma_cmd_to_miss_wti_cmd_req.read() ) // no pending previous request 807 { 808 r_dma_cmd_to_miss_wti_cmd_req = true; 809 r_dma_cmd_to_miss_wti_cmd_addr = (vci_addr_t)r_iommu_wti_addr_lo.read() | 810 (((vci_addr_t)r_iommu_wti_addr_hi.read())<<32); 811 r_dma_cmd_to_miss_wti_cmd_wdata = 0; 812 r_dma_cmd_to_miss_wti_cmd_srcid = m_int_srcid; 813 r_dma_cmd_to_miss_wti_cmd_trdid = 0; 814 r_dma_cmd_to_miss_wti_cmd_pktid = PKTID_WTI_MMU; 815 816 r_dma_cmd_fsm = DMA_CMD_ERR_RSP_REQ; 817 818 #if DEBUG_DMA_CMD 819 if( m_debug_activated ) 820 std::cout << " <IOB DMA_CMD_ERR_WTI_REQ> request an IOMMU WTI" << std::endl; 821 #endif 822 } 823 break; 824 } 825 ///////////////////////// 826 case DMA_CMD_ERR_RSP_REQ: // post an error response request to DMA_RSP FSM 827 // if no prending previous request 828 // response arguments are stored in dedicated registers 829 // no VCI flit is consumed 830 { 831 if ( not r_dma_cmd_to_dma_rsp_req.read() ) // no pending previous request 832 { 833 r_dma_cmd_to_dma_rsp_req = true; 834 r_dma_cmd_to_dma_rsp_rerror = 0x1; 835 r_dma_cmd_to_dma_rsp_rdata = 0; 836 } 837 break; 838 } 839 /////////////////////////// 840 case DMA_CMD_TLB_MISS_WAIT: // waiting completion of a TLB miss 841 // we must test a possible page fault error... 842 { 843 if ( not r_dma_cmd_to_tlb_req.read() ) // TLB miss completed 685 844 { 686 845 if ( r_tlb_miss_error.read() ) // Error reported by TLB FSM 687 846 { 688 847 r_iommu_etr = MMU_READ_PT2_UNMAPPED; 689 r_iommu_bvar = r_dma_cmd_ vaddr.read();848 r_iommu_bvar = r_dma_cmd_to_tlb_vaddr.read(); 690 849 r_iommu_bad_id = p_vci_tgt_iox.srcid.read(); 691 r_dma_cmd_fsm = DMA_CMD_ FIFO_PUT_RSP;850 r_dma_cmd_fsm = DMA_CMD_ERR_WAIT_EOP; 692 851 } 693 852 else // No error … … 700 859 } // end switch DMA_CMD FSM 701 860 702 ////////////////////////////////////////////////////////////////////////////// 703 // The DMA_RSP_FSM handles the RAM responses to peripherals DMA transactions. 704 ////////////////////////////////////////////////////////////////////////////// 705 706 switch( r_dma_rsp_fsm.read() ) 707 { 708 ////////////////// 709 case DMA_RSP_IDLE: // waiting a response from RAM betwork 710 { 711 if ( p_vci_ini_ram.rspval.read() ) 712 { 713 r_dma_rsp_fsm = DMA_RSP_FIFO_PUT; 714 } 715 break; 716 } 717 ////////////////////// 718 case DMA_RSP_FIFO_PUT: 719 { 720 if(p_vci_ini_ram.rspval.read() and not r_alloc_fifo_dma_rsp_local.read() ) 721 { 722 dma_rsp_fifo_put = true; 723 724 if(p_vci_ini_ram.reop.read()) r_dma_rsp_fsm = DMA_RSP_IDLE; 861 //////////////////////////////////////////////////////////////////////////////// 862 // The DMA_RSP_FSM controls access to the DMA_RSP FIFO to the IOX network. 863 // There exist 3 "clients" to send VCI responses on the IOX network: 864 // - request from p_vci_ini_ram : normal DMA response from RAM network, 865 // - request from MISS_WTI_RSP FSM : normal WTI response from INT network, 866 // - request from DMA_CMD FSM : bad address error response 867 // This FSM implements a round robin priority, with a "dead cycle" between 868 // two transactions. It could be optimized if throughput is critical... 869 //////////////////////////////////////////////////////////////////////////////// 870 871 // does nothing if FIFO is full 872 if ( m_dma_rsp_rerror_fifo.wok() ) 873 { 874 switch( r_dma_rsp_fsm.read() ) 875 { 876 ////////////////////// 877 case DMA_RSP_IDLE_DMA: // normal DMA response has highest priority 878 { 879 if (p_vci_ini_ram.rspval.read()) r_dma_rsp_fsm = DMA_RSP_PUT_DMA; 880 else if(r_miss_wti_rsp_to_dma_rsp_req.read()) r_dma_rsp_fsm = DMA_RSP_PUT_WTI; 881 else if(r_dma_cmd_to_dma_rsp_req.read()) r_dma_rsp_fsm = DMA_RSP_PUT_ERR; 882 break; 883 } 884 ////////////////////// 885 case DMA_RSP_IDLE_WTI: // normal WTI response has highest priority 886 { 887 if (r_miss_wti_rsp_to_dma_rsp_req.read()) r_dma_rsp_fsm = DMA_RSP_PUT_WTI; 888 else if(r_dma_cmd_to_dma_rsp_req.read()) r_dma_rsp_fsm = DMA_RSP_PUT_ERR; 889 else if(p_vci_ini_ram.rspval.read()) r_dma_rsp_fsm = DMA_RSP_PUT_DMA; 890 break; 891 } 892 ////////////////////// 893 case DMA_RSP_IDLE_ERR: // error response has highest priority 894 { 895 if (r_dma_cmd_to_dma_rsp_req.read()) r_dma_rsp_fsm = DMA_RSP_PUT_ERR; 896 else if(p_vci_ini_ram.rspval.read()) r_dma_rsp_fsm = DMA_RSP_PUT_DMA; 897 else if(r_miss_wti_rsp_to_dma_rsp_req.read()) r_dma_rsp_fsm = DMA_RSP_PUT_WTI; 898 break; 899 } 900 /////////////////////// 901 case DMA_RSP_PUT_DMA: // put one flit of the DMA response into FIFO 902 { 903 dma_rsp_fifo_put = true; 904 dma_rsp_fifo_rerror = p_vci_ini_ram.rerror.read(); 905 dma_rsp_fifo_rdata = p_vci_ini_ram.rdata.read(); 906 dma_rsp_fifo_rsrcid = p_vci_ini_ram.rsrcid.read(); 907 dma_rsp_fifo_rtrdid = p_vci_ini_ram.rtrdid.read(); 908 dma_rsp_fifo_rpktid = p_vci_ini_ram.rpktid.read(); 909 dma_rsp_fifo_reop = p_vci_ini_ram.reop.read(); 910 911 // update priority 912 if ( p_vci_ini_ram.reop.read() ) r_dma_rsp_fsm = DMA_RSP_IDLE_WTI; 725 913 726 914 #if DEBUG_DMA_RSP 727 915 if( m_debug_activated ) 728 std::cout << " <IOB DMA_RSP_ FIFO_PUT> Push response into DMA_RSP fifo:"729 << " /rsrcid = " << std::hex << p_vci_ini_ram.rsrcid.read()916 std::cout << " <IOB DMA_RSP_PUT_DMA> Push DMA response into DMA_RSP FIFO" 917 << " : rsrcid = " << std::hex << p_vci_ini_ram.rsrcid.read() 730 918 << " / rtrdid = " << p_vci_ini_ram.rtrdid.read() 731 << " / rdata = " << std::hex << p_vci_ini_ram.rdata.read() 919 << " / rpktid = " << p_vci_ini_ram.rpktid.read() 920 << " / rdata = " << p_vci_ini_ram.rdata.read() 732 921 << " / rerror = " << p_vci_ini_ram.rerror.read() 733 << " / reop = " << p_vci_ini_ram.reop.read() << std::endl; 734 #endif 735 } 736 break; 737 } 738 } // end switch DMA_RSP_FSM 922 << " / reop = " << p_vci_ini_ram.reop.read() << std::endl; 923 #endif 924 break; 925 } 926 /////////////////////// 927 case DMA_RSP_PUT_WTI: // put single flit WTI response into FIFO 928 { 929 dma_rsp_fifo_put = true; 930 dma_rsp_fifo_rerror = r_miss_wti_rsp_to_dma_rsp_rerror.read(); 931 dma_rsp_fifo_rdata = 0; 932 dma_rsp_fifo_rsrcid = r_miss_wti_rsp_to_dma_rsp_rsrcid.read(); 933 dma_rsp_fifo_rtrdid = r_miss_wti_rsp_to_dma_rsp_rtrdid.read(); 934 dma_rsp_fifo_rpktid = r_miss_wti_rsp_to_dma_rsp_rpktid.read(); 935 dma_rsp_fifo_reop = true; 936 937 // acknowledge request 938 r_miss_wti_rsp_to_dma_rsp_req = false; 939 940 // update priority 941 r_dma_rsp_fsm = DMA_RSP_IDLE_ERR; 942 943 #if DEBUG_DMA_RSP 944 if( m_debug_activated ) 945 std::cout << " <IOB DMA_RSP_PUT_WTI> Push WTI response into DMA_RSP FIFO" 946 << " : rsrcid = " << std::hex << r_miss_wti_rsp_to_dma_rsp_rsrcid.read() 947 << " / rtrdid = " << r_miss_wti_rsp_to_dma_rsp_rtrdid.read() 948 << " / rpktid = " << r_miss_wti_rsp_to_dma_rsp_rpktid.read() 949 << " / rdata = " << 0 950 << " / rerror = " << r_miss_wti_rsp_to_dma_rsp_rerror.read() 951 << " / reop = " << true << std::endl; 952 #endif 953 break; 954 } 955 /////////////////////// 956 case DMA_RSP_PUT_ERR: // put sinfle flit error response into FIFO 957 { 958 dma_rsp_fifo_put = true; 959 dma_rsp_fifo_rerror = 0x1; 960 dma_rsp_fifo_rdata = 0; 961 dma_rsp_fifo_rsrcid = r_dma_cmd_to_dma_rsp_rsrcid.read(); 962 dma_rsp_fifo_rtrdid = r_dma_cmd_to_dma_rsp_rtrdid.read(); 963 dma_rsp_fifo_rpktid = r_dma_cmd_to_dma_rsp_rpktid.read(); 964 dma_rsp_fifo_reop = true; 965 966 // acknowledge request 967 r_dma_cmd_to_dma_rsp_req = false; 968 969 // update priority 970 r_dma_rsp_fsm = DMA_RSP_PUT_DMA; 971 972 #if DEBUG_DMA_RSP 973 if( m_debug_activated ) 974 std::cout << " <IOB DMA_RSP_PUT_DMA> Push IOMMU ERROR response into DMA_RSP FIFO" 975 << " : rsrcid = " << std::hex << r_dma_cmd_to_dma_rsp_rsrcid.read() 976 << " / rtrdid = " << r_dma_cmd_to_dma_rsp_rtrdid.read() 977 << " / rpktid = " << r_dma_cmd_to_dma_rsp_rpktid.read() 978 << " / rdata = " << 0 979 << " / rerror = " << r_dma_cmd_to_dma_rsp_rerror.read() 980 << " / reop = " << true << std::endl; 981 #endif 982 break; 983 } 984 } // end switch DMA_RSP FSM 985 } // end if FIFO full 986 739 987 740 988 ////////////////////////////////////////////////////////////////////////////////// 741 // The TLB FSM handles TLB miss request (from DMA_CMD FSM),989 // The TLB FSM handles the TLB miss requests from DMA_CMD FSM, 742 990 // and the PTE inval request (from CONFIG_CMD FSM). 743 991 // PTE inval request have highest priority. In case of TLB miss, … … 745 993 // In case of buffer miss, it request the MISS_WTI FSM to access the memory. 746 994 // It bypass the first level page table access if possible. 747 // It reset the r_dma_ tlb_req flip-flop to signal TLB miss completion.995 // It reset the r_dma_cmd_to_tlb_req flip-flop to signal TLB miss completion. 748 996 // An unexpected, but possible page fault is signaled in r_tlb_miss_error flip_flop. 749 997 //////////////////////////////////////////////////////////////////////////////////// … … 755 1003 // PTE inval request are handled as unmaskable interrupts 756 1004 { 757 if ( r_config_ tlb_req ) // Request from CONFIG FSMfor a PTE invalidation1005 if ( r_config_cmd_to_tlb_req.read() ) // Request for a PTE invalidation 758 1006 { 759 r_config_ tlb_req= false;760 r_waiting_transaction = false;761 r_tlb_fsm = TLB_INVAL_CHECK;1007 r_config_cmd_to_tlb_req = false; 1008 r_waiting_transaction = false; 1009 r_tlb_fsm = TLB_INVAL_CHECK; 762 1010 } 763 1011 764 else if ( r_dma_ tlb_req.read() ) // request from DMA_CMDfor a TLB Miss1012 else if ( r_dma_cmd_to_tlb_req.read() ) // request for a TLB Miss 765 1013 { 766 1014 // Checking prefetch buffer … … 769 1017 if( r_tlb_buf_valid && // Hit on prefetch buffer 770 1018 (r_tlb_buf_vaddr.read() == 771 (r_dma_cmd_ vaddr.read()& ~PTE2_LINE_OFFSET & ~K_PAGE_OFFSET_MASK)))772 { 773 size_t pte_offset = (r_dma_cmd_ vaddr.read()& PTE2_LINE_OFFSET)>>12;1019 (r_dma_cmd_to_tlb_vaddr.read()& ~PTE2_LINE_OFFSET & ~K_PAGE_OFFSET_MASK))) 1020 { 1021 size_t pte_offset = (r_dma_cmd_to_tlb_vaddr.read()& PTE2_LINE_OFFSET)>>12; 774 1022 uint32_t pte_flags = r_tlb_buf_data[2*pte_offset]; 775 1023 uint32_t pte_ppn = r_tlb_buf_data[2*pte_offset+1]; … … 782 1030 783 1031 r_tlb_miss_error = true; 784 r_dma_ tlb_req = false;1032 r_dma_cmd_to_tlb_req = false; 785 1033 #if DEBUG_TLB_MISS 786 1034 if ( m_debug_activated ) … … 810 1058 if( r_tlb_buf_valid && // Hit on prefetch buffer 811 1059 (r_tlb_buf_vaddr.read() == 812 (r_dma_cmd_ vaddr.read()& ~PTE1_LINE_OFFSET & ~M_PAGE_OFFSET_MASK )))813 { 814 size_t pte_offset = (r_dma_cmd_ vaddr.read()& PTE1_LINE_OFFSET)>>21;1060 (r_dma_cmd_to_tlb_vaddr.read()& ~PTE1_LINE_OFFSET & ~M_PAGE_OFFSET_MASK ))) 1061 { 1062 size_t pte_offset = (r_dma_cmd_to_tlb_vaddr.read()& PTE1_LINE_OFFSET)>>21; 815 1063 uint32_t pte_flags = r_tlb_buf_data[pte_offset]; 816 1064 … … 822 1070 823 1071 r_tlb_miss_error = true; 824 r_dma_ tlb_req = false;1072 r_dma_cmd_to_tlb_req = false; 825 1073 #if DEBUG_TLB_MISS 826 1074 if ( m_debug_activated ) … … 851 1099 if ( m_debug_activated ) 852 1100 std::cout << " <IOB TLB_IDLE> Miss on prefetch buffer" 853 << std::hex << " / vaddr = " << r_dma_cmd_ vaddr.read() << std::endl;1101 << std::hex << " / vaddr = " << r_dma_cmd_to_tlb_vaddr.read() << std::endl; 854 1102 #endif 855 1103 } … … 867 1115 #endif 868 1116 // evaluate bypass in order to skip first level page table access 869 bypass = r_iotlb.get_bypass(r_dma_cmd_ vaddr.read(), &ptba);1117 bypass = r_iotlb.get_bypass(r_dma_cmd_to_tlb_vaddr.read(), &ptba); 870 1118 871 1119 // Request MISS_WTI_FSM a transaction on INT Network … … 878 1126 #endif 879 1127 pte_paddr = (vci_addr_t)((r_iommu_ptpr.read()) << (INDEX1_NBITS+2)) | 880 (vci_addr_t)((r_dma_cmd_ vaddr.read() >> PAGE_M_NBITS) << 2);1128 (vci_addr_t)((r_dma_cmd_to_tlb_vaddr.read() >> PAGE_M_NBITS) << 2); 881 1129 r_tlb_paddr = pte_paddr; 882 1130 883 r_tlb_ miss_req= true;884 r_tlb_miss_type = PTE1_MISS;885 r_tlb_fsm = TLB_WAIT;1131 r_tlb_to_miss_wti_cmd_req = true; 1132 r_tlb_miss_type = PTE1_MISS; 1133 r_tlb_fsm = TLB_WAIT; 886 1134 } 887 1135 else // Read PTE2 in XRAM … … 894 1142 //&PTE2 = PTBA + IX2 * 8 895 1143 pte_paddr = (vci_addr_t)ptba << PAGE_K_NBITS | 896 (vci_addr_t)(r_dma_cmd_ vaddr.read()&PTD_ID2_MASK)>>(PAGE_K_NBITS-3);1144 (vci_addr_t)(r_dma_cmd_to_tlb_vaddr.read()&PTD_ID2_MASK)>>(PAGE_K_NBITS-3); 897 1145 898 1146 r_tlb_paddr = pte_paddr; 899 1147 900 r_tlb_ miss_req= true;901 r_tlb_miss_type = PTE2_MISS;902 r_tlb_fsm = TLB_WAIT;1148 r_tlb_to_miss_wti_cmd_req = true; 1149 r_tlb_miss_type = PTE2_MISS; 1150 r_tlb_fsm = TLB_WAIT; 903 1151 } 904 1152 … … 929 1177 930 1178 r_tlb_miss_error = true; 931 r_dma_ tlb_req= false;932 r_tlb_fsm = TLB_IDLE;1179 r_dma_cmd_to_tlb_req = false; 1180 r_tlb_fsm = TLB_IDLE; 933 1181 934 1182 #if DEBUG_TLB_MISS … … 946 1194 { 947 1195 // register bypass 948 r_iotlb.set_bypass( r_dma_cmd_ vaddr.read(),1196 r_iotlb.set_bypass( r_dma_cmd_to_tlb_vaddr.read(), 949 1197 entry & ((1 << (vci_param_int::N-PAGE_K_NBITS)) - 1), 950 1198 0); //nline, unused 951 1199 952 // &PTE2 = PTBA + IX2 * 81200 // &PTE2 = PTBA + IX2 * 8 953 1201 // ps: PAGE_K_NBITS corresponds also to the size of a second level page table 954 1202 r_tlb_paddr = (vci_addr_t)(entry & ((1<<(vci_param_int::N-PAGE_K_NBITS))-1)) << PAGE_K_NBITS | 955 (vci_addr_t)(((r_dma_cmd_vaddr.read() & PTD_ID2_MASK) >> PAGE_K_NBITS) << 3); 956 r_tlb_miss_req = true; 957 r_tlb_miss_type = PTE2_MISS; 958 r_tlb_fsm = TLB_WAIT; 1203 (vci_addr_t)(((r_dma_cmd_to_tlb_vaddr.read() & PTD_ID2_MASK) >> PAGE_K_NBITS) << 3); 1204 1205 r_tlb_to_miss_wti_cmd_req = true; 1206 r_tlb_miss_type = PTE2_MISS; 1207 r_tlb_fsm = TLB_WAIT; 959 1208 960 1209 #ifdef INSTRUMENTATION … … 990 1239 size_t set; 991 1240 992 r_iotlb.select( r_dma_cmd_ vaddr.read(),1241 r_iotlb.select( r_dma_cmd_to_tlb_vaddr.read(), 993 1242 true, // PTE1 994 1243 &way, … … 1016 1265 1017 1266 r_tlb_paddr = (vci_addr_t)( ((r_tlb_pte_flags.read() & PPN1_MASK) << 21) 1018 | (r_dma_cmd_ vaddr.read()& M_PAGE_OFFSET_MASK) );1267 | (r_dma_cmd_to_tlb_vaddr.read()& M_PAGE_OFFSET_MASK) ); 1019 1268 1020 1269 // update TLB … … 1022 1271 pte, 1023 1272 0, // argument unused for a PTE1 1024 r_dma_cmd_ vaddr.read(),1273 r_dma_cmd_to_tlb_vaddr.read(), 1025 1274 r_tlb_way.read(), 1026 1275 r_tlb_set.read(), 1027 1276 0 ); //we set nline = 0 1277 1028 1278 #ifdef INSTRUMENTATION 1029 1279 m_cpt_iotlb_write++; … … 1066 1316 1067 1317 r_tlb_miss_error = true; 1068 r_dma_ tlb_req = false;1318 r_dma_cmd_to_tlb_req = false; 1069 1319 r_tlb_fsm = TLB_IDLE; 1070 1320 … … 1096 1346 size_t set; 1097 1347 1098 r_iotlb.select( r_dma_cmd_ vaddr.read(),1348 r_iotlb.select( r_dma_cmd_to_tlb_vaddr.read(), 1099 1349 false, // PTE2 1100 1350 &way, … … 1106 1356 #if DEBUG_TLB_MISS 1107 1357 if ( m_debug_activated ) 1108 { 1109 std::cout << " <IOB TLB_PTE2_SELECT> Select a slot in IOTLB:"; 1110 std::cout << " way = " << std::dec << way 1111 << " / set = " << set << std::endl; 1112 } 1358 std::cout << " <IOB TLB_PTE2_SELECT> Select a slot in IOTLB:" 1359 << " way = " << std::dec << way 1360 << " / set = " << set << std::endl; 1113 1361 #endif 1114 1362 r_tlb_way = way; … … 1125 1373 1126 1374 r_tlb_paddr = (vci_addr_t)( ((r_tlb_pte_ppn.read() & PPN2_MASK) << 12) 1127 | (r_dma_cmd_ vaddr.read()& K_PAGE_OFFSET_MASK) );1375 | (r_dma_cmd_to_tlb_vaddr.read()& K_PAGE_OFFSET_MASK) ); 1128 1376 1129 1377 // update TLB for a PTE2 … … 1131 1379 pte_flags, 1132 1380 pte_ppn, 1133 r_dma_cmd_ vaddr.read(),1381 r_dma_cmd_to_tlb_vaddr.read(), 1134 1382 r_tlb_way.read(), 1135 1383 r_tlb_set.read(), … … 1142 1390 if ( m_debug_activated ) 1143 1391 { 1144 std::cout << " <IOB TLB_PTE2_UPDT> write PTE2 in IOTLB"; 1145 std::cout<< " / set = " << std::dec << r_tlb_set.read()1146 1147 1392 std::cout << " <IOB TLB_PTE2_UPDT> write PTE2 in IOTLB" 1393 << " / set = " << std::dec << r_tlb_set.read() 1394 << " / way = " << r_tlb_way.read() << std::endl; 1395 r_iotlb.printTrace(); 1148 1396 } 1149 1397 #endif … … 1156 1404 // PTE inval request are handled as unmaskable interrupts 1157 1405 { 1158 if ( r_config_ tlb_req ) // Request from CONFIG FSMfor a PTE invalidation1406 if ( r_config_cmd_to_tlb_req.read() ) // Request for a PTE invalidation 1159 1407 { 1160 r_config_ tlb_req = false;1161 r_waiting_transaction = true;1162 r_tlb_fsm = TLB_INVAL_CHECK;1408 r_config_cmd_to_tlb_req = false; 1409 r_waiting_transaction = true; 1410 r_tlb_fsm = TLB_INVAL_CHECK; 1163 1411 } 1164 1412 … … 1166 1414 m_cost_iotlbmiss_transaction++; 1167 1415 #endif 1168 if ( not r_tlb_ miss_req ) // Miss transaction is done1416 if ( not r_tlb_to_miss_wti_cmd_req.read() ) // Miss transaction completed 1169 1417 { 1170 if ( r_miss_wti_rsp_error .read() ) // bus error1418 if ( r_miss_wti_rsp_error_miss.read() ) // bus error reported 1171 1419 { 1172 r_miss_wti_rsp_error = false;1173 r_tlb_miss_error = true;1174 r_dma_ tlb_req= false;1175 r_tlb_fsm = TLB_IDLE;1420 r_miss_wti_rsp_error_miss = false; 1421 r_tlb_miss_error = true; 1422 r_dma_cmd_to_tlb_req = false; 1423 r_tlb_fsm = TLB_IDLE; 1176 1424 } 1177 1425 else if(r_tlb_miss_type == PTE1_MISS) … … 1187 1435 } 1188 1436 //////////////// 1189 case TLB_RETURN: // reset r_dma_tlb_req flip-flopto signal TLB miss completion1190 1437 case TLB_RETURN: // reset r_dma_cmd_to_tlb_req to signal TLB miss completion 1438 // possible errors are signaled through r_tlb_miss_error 1191 1439 { 1192 1440 #if DEBUG_TLB_MISS … … 1194 1442 std::cout << " <IOB TLB_RETURN> IOTLB MISS completed" << std::endl; 1195 1443 #endif 1196 r_dma_ tlb_req = false;1444 r_dma_cmd_to_tlb_req = false; 1197 1445 r_tlb_fsm = TLB_IDLE; 1198 1446 break; … … 1210 1458 { 1211 1459 if( r_tlb_buf_vaddr.read() == 1212 (r_config_cmd_ inval_vaddr.read()& ~PTE2_LINE_OFFSET) )1460 (r_config_cmd_to_tlb_vaddr.read()& ~PTE2_LINE_OFFSET) ) 1213 1461 // The virtual address corresponds to one entry on the buffer line 1214 1462 { … … 1219 1467 { 1220 1468 if( r_tlb_buf_vaddr.read() == 1221 (r_config_cmd_ inval_vaddr.read()& ~PTE1_LINE_OFFSET) )1469 (r_config_cmd_to_tlb_vaddr.read()& ~PTE1_LINE_OFFSET) ) 1222 1470 // The virtual address corresponds to one entry on the buffer line 1223 1471 { … … 1229 1477 // Invalidation on IOTLB 1230 1478 bool ok; 1231 ok = r_iotlb.inval(r_config_cmd_ inval_vaddr.read());1479 ok = r_iotlb.inval(r_config_cmd_to_tlb_vaddr.read()); 1232 1480 1233 1481 if(r_waiting_transaction.read()) r_tlb_fsm =TLB_WAIT; … … 1239 1487 //////////////////////////////////////////////////////////////////////////////// 1240 1488 // The CONFIG_CMD_FSM handles the VCI commands from the INT network. 1241 // This FSM can handle single flit config transactions, but it can also handle1242 // software driven,multi-flits data transactions to ROM (read) or FBF (write).1489 // - it can be single flit config transactions 1490 // - it can be multi-flits data transactions to ROM (read) or FBF (write). 1243 1491 // The write burst transactions must be serialised from 32 to 64 bits width. 1244 1492 // The configuration requests can be local (IO_BRIDGE config registers) 1245 1493 // or remote (config registers of peripherals on IOX network). 1246 // - The local configuration segment is identified by the "special" atribute. 1494 // - The local configuration segment is identified by the "special" atribute 1495 // in the mapping table. 1247 1496 // - All configuration requests are checkeg against segmentation violation. 1248 1497 // - In case of local config request, or in case of segmentation violation, 1249 // the FSM put a VCI response request in CONFIG_RSP fifo.1498 // the FSM send a response request to CONFIG_RSP FSM. 1250 1499 // - In case of remote transaction, it put the VCI command in CONFIG_CMD fifo, 1251 1500 // and this require two cycles per IOX flit in case of write burst. … … 1296 1545 1297 1546 assert( (p_vci_tgt_int.be.read() == 0xF) and 1298 "ERROR in vci_io_bridge : BE !=0xF for a config access");1547 "ERROR in vci_io_bridge : BE must be 0xF for a config access"); 1299 1548 1300 1549 assert( ( eop ) and … … 1307 1556 else if ( read && (cell == IOB_IOMMU_PTPR) ) // READ PTPR 1308 1557 { 1309 r_config_cmd_ rdata = r_iommu_ptpr.read();1558 r_config_cmd_to_config_rsp_rdata = r_iommu_ptpr.read(); 1310 1559 } 1311 1560 else if( not read && (cell == IOB_WTI_ENABLE)) // WRITE WTI_ENABLE … … 1315 1564 else if( read && (cell == IOB_WTI_ENABLE)) // READ WTI ENABLE 1316 1565 { 1317 r_config_cmd_ rdata = r_iommu_wti_enable.read();1566 r_config_cmd_to_config_rsp_rdata = r_iommu_wti_enable.read(); 1318 1567 } 1319 1568 else if( read && (cell == IOB_IOMMU_BVAR)) // READ BVAR 1320 1569 { 1321 r_config_cmd_ rdata = r_iommu_bvar.read();1570 r_config_cmd_to_config_rsp_rdata = r_iommu_bvar.read(); 1322 1571 } 1323 1572 else if( read && (cell == IOB_IOMMU_ETR)) // READ ETR 1324 1573 { 1325 r_config_cmd_ rdata = r_iommu_etr.read();1574 r_config_cmd_to_config_rsp_rdata = r_iommu_etr.read(); 1326 1575 } 1327 1576 else if( read && (cell == IOB_IOMMU_BAD_ID)) // READ BAD_ID 1328 1577 { 1329 r_config_cmd_ rdata = r_iommu_bad_id.read();1578 r_config_cmd_to_config_rsp_rdata = r_iommu_bad_id.read(); 1330 1579 } 1331 1580 else if( not read && (cell == IOB_INVAL_PTE)) // WRITE INVAL_PTE 1332 1581 { 1333 r_config_ tlb_req= true;1334 r_config_cmd_ inval_vaddr = (uint32_t)p_vci_tgt_int.wdata.read();1582 r_config_cmd_to_tlb_req = true; 1583 r_config_cmd_to_tlb_vaddr = (uint32_t)p_vci_tgt_int.wdata.read(); 1335 1584 } 1336 1585 else if( not read && (cell == IOB_WTI_ADDR_LO)) // WRITE WTI_PADDR_LO 1337 1586 { 1338 r_iommu_wti_ paddr= (vci_addr_t)p_vci_tgt_int.wdata.read();1587 r_iommu_wti_addr_lo = (vci_addr_t)p_vci_tgt_int.wdata.read(); 1339 1588 } 1340 1589 else if( read && (cell == IOB_WTI_ADDR_LO)) // READ WTI_PADDR_LO 1341 1590 { 1342 r_config_cmd_ rdata = (uint32_t)r_iommu_wti_paddr.read();1591 r_config_cmd_to_config_rsp_rdata = r_iommu_wti_addr_lo.read(); 1343 1592 } 1344 1593 else if( not read && (cell == IOB_WTI_ADDR_HI)) // WRITE WTI_PADDR_HI 1345 1594 { 1346 r_iommu_wti_paddr = (r_iommu_wti_paddr.read() & 0x00000000FFFFFFFFLL) | 1347 ((vci_addr_t)p_vci_tgt_int.wdata.read())<<32; 1595 r_iommu_wti_addr_hi = (vci_addr_t)p_vci_tgt_int.wdata.read(); 1348 1596 } 1349 1597 else if( read && (cell == IOB_WTI_ADDR_HI)) // READ WTI_PADDR_HI 1350 1598 { 1351 r_config_cmd_rdata = (uint32_t)(r_iommu_wti_paddr.read()>>32); 1352 } 1353 else if( not read && ((cell >= IOB_PERI_WTI_BEGIN) // WRITE PERI WTI 1354 && (cell< (IOB_PERI_WTI_BEGIN + 64))) ) 1355 { 1356 size_t index = (cell - IOB_PERI_WTI_BEGIN)/2; 1357 bool high = (cell - IOB_PERI_WTI_BEGIN)%2; 1358 if ( high ) r_iommu_peri_wti[index] = // set 32 MSB bits 1359 (r_iommu_peri_wti[index].read() & 0x00000000FFFFFFFFLL) | 1360 ((vci_addr_t)p_vci_tgt_int.wdata.read())<<32; 1361 else r_iommu_peri_wti[index] = // set 32 LSB bits 1362 (vci_addr_t)p_vci_tgt_int.wdata.read(); 1363 } 1364 else if( read && ((cell >= IOB_PERI_WTI_BEGIN) // READ PERI WTI 1365 && (cell< (IOB_PERI_WTI_BEGIN + 64))) ) 1366 { 1367 size_t index = (cell - IOB_PERI_WTI_BEGIN)/2; 1368 bool high = (cell - IOB_PERI_WTI_BEGIN)%2; 1369 if ( high ) r_config_cmd_rdata = 1370 (uint32_t)(r_iommu_peri_wti[index].read()>>32); 1371 else r_config_cmd_rdata = 1372 (uint32_t)(r_iommu_peri_wti[index].read()); 1599 r_config_cmd_to_config_rsp_rdata = r_iommu_wti_addr_hi.read(); 1600 } 1601 else if( not read && (cell == IOB_XICU_BASE)) // WRITE XICU_BASE 1602 { 1603 r_xicu_base = (vci_addr_t)p_vci_tgt_int.wdata.read(); 1604 } 1605 else if( read && (cell == IOB_XICU_BASE)) // READ XICU_BASE 1606 { 1607 r_config_cmd_to_config_rsp_rdata = r_xicu_base.read(); 1608 } 1609 else if( not read && (cell == IOB_XICU_SIZE)) // WRITE XICU_SIZE 1610 { 1611 r_xicu_size = (vci_addr_t)p_vci_tgt_int.wdata.read(); 1612 } 1613 else if( read && (cell == IOB_XICU_SIZE)) // READ XICU_SIZE 1614 { 1615 r_config_cmd_to_config_rsp_rdata = r_xicu_size.read(); 1373 1616 } 1374 1617 else // Error: Wrong address, or invalid operation. … … 1376 1619 rerror = true; 1377 1620 } 1378 r_config_cmd_ error = rerror;1379 r_config_cmd_fsm = CONFIG_CMD_RSP;1621 r_config_cmd_to_config_rsp_rerror = rerror; 1622 r_config_cmd_fsm = CONFIG_CMD_RSP; 1380 1623 } 1381 1624 else if ( found ) // remote peripheral … … 1431 1674 else // out of segment address 1432 1675 { 1433 r_config_cmd_ rdata = 0;1434 r_config_cmd_ error = true;1435 if( eop ) r_config_cmd_fsm = CONFIG_CMD_RSP;1676 r_config_cmd_to_config_rsp_rdata = 0; 1677 r_config_cmd_to_config_rsp_rerror = true; 1678 if( eop ) r_config_cmd_fsm = CONFIG_CMD_RSP; 1436 1679 } 1437 1680 } // end if cmdval … … 1460 1703 } 1461 1704 //////////////////// 1462 case CONFIG_CMD_PUT: // try topost a command to CONFIG_CMD fifo (to IOX network)1705 case CONFIG_CMD_PUT: // post a command to CONFIG_CMD fifo (to IOX network) 1463 1706 { 1464 1707 config_cmd_fifo_put = true; … … 1480 1723 } 1481 1724 //////////////////// 1482 case CONFIG_CMD_RSP: // Try to put a response in CONFIG_RSP fifo, for1483 // a local configuration transaction or a segment error.1484 // The FIFO is shared with CONFIG_RSP FSM1485 // and must we wait for allocation...1486 { 1487 if ( r_alloc_fifo_config_rsp_local.read() )1725 case CONFIG_CMD_RSP: // Post a request to CONFIG_RSP FSM, 1726 // if no previous pending request. 1727 // r_config_cmd_to_config_rsp_rerror 1728 // has been set in IDLE state. 1729 { 1730 if ( not r_config_cmd_to_config_rsp_req.read() ) 1488 1731 { 1489 config_rsp_fifo_put = true; 1490 1491 if ( m_config_rsp_data_fifo.wok() ) 1492 { 1732 r_config_cmd_to_config_rsp_req = true; 1493 1733 1494 1734 #if DEBUG_CONFIG_CMD 1495 1735 if( m_debug_activated ) 1496 std::cout << " <IOB CONFIG_CMD_RSP> Response to a local configuration request" 1497 << std::endl; 1498 #endif 1499 r_config_cmd_fsm = CONFIG_CMD_IDLE; 1500 } 1736 std::cout << " <IOB CONFIG_CMD_RSP> Request a response to CONFIG_RSP FSM" 1737 << " / error = " << r_config_cmd_to_config_rsp_rerror.read() << std::endl; 1738 #endif 1739 r_config_cmd_fsm = CONFIG_CMD_IDLE; 1501 1740 } 1502 1741 break; … … 1505 1744 1506 1745 ////////////////////////////////////////////////////////////////////////////// 1507 // The CONFIG_RSP_FSM handles the 64 bits VCI responses from the periherals 1508 // on the IOX network and writes the responses in the CONFIG_RSP fifo. 1509 // This FSM handle both single flit config responses, and multi-flits 1510 // read responses (ROM), where data must be serialised (64 bits -> 32 bits). 1746 // The CONFIG_RSP_FSM controls access to the CONFIG_RSP FIFO to INT network. 1747 // It implements a round robin priority between 2 clients FSMs : 1748 // - CONFIG_CMD : response to a local config command. 1749 // - CONFIG_RSP : responses from peripherals on IOX network 1750 // Regarding the responses from IOX network it handles both single flit 1751 // config responses, and multi-flits read responses (ROM), where data must 1752 // be serialised (64 bits -> 32 bits). 1511 1753 // Note: We use the VCI RPKTID field to distinguish between read cached 1512 1754 // (multi-flits response) and others (single flit response). … … 1514 1756 ////////////////////////////////////////////////////////////////////////////// 1515 1757 1516 switch( r_config_rsp_fsm.read() ) 1517 { 1518 ///////////////////// 1519 case CONFIG_RSP_IDLE: // waiting a VCI response from IOX network 1520 // flit on IOX network is not consumed 1521 { 1522 if ( p_vci_ini_iox.rspval.read() ) 1523 { 1524 if ( (p_vci_ini_iox.rpktid.read() & 0x5) == 0x1 ) // multi-flits response 1758 // does nothing if FIFO full 1759 if ( m_config_rsp_rerror_fifo.wok() ) 1760 { 1761 switch( r_config_rsp_fsm.read() ) 1762 { 1763 ///////////////////////// 1764 case CONFIG_RSP_IDLE_IOX: // IOX requests have highest priority 1765 // no flit on IOX network is consumed 1766 { 1767 if ( p_vci_ini_iox.rspval.read() ) // IOX request 1768 { 1769 if ( (p_vci_ini_iox.rpktid.read() & 0x5) == 0x1 ) // multi-flits 1770 { 1771 r_config_rsp_fsm = CONFIG_RSP_PUT_LOW; 1772 } 1773 else // single flit 1774 { 1775 r_config_rsp_fsm = CONFIG_RSP_PUT_UNC; 1776 } 1777 } 1778 else if ( r_config_cmd_to_config_rsp_req.read() ) // LOC request 1779 { 1780 r_config_rsp_fsm = CONFIG_RSP_PUT_LOC; 1781 } 1782 break; 1783 } 1784 ///////////////////////// 1785 case CONFIG_RSP_IDLE_LOC: // LOC requests have highest priority 1786 // no flit on IOX network is consumed 1787 { 1788 if ( r_config_cmd_to_config_rsp_req.read() ) // LOC request 1789 { 1790 r_config_rsp_fsm = CONFIG_RSP_PUT_LOC; 1791 } 1792 else if ( p_vci_ini_iox.rspval.read() ) // IOX request 1793 { 1794 if ( (p_vci_ini_iox.rpktid.read() & 0x5) == 0x1 ) // multi-flits 1795 { 1796 r_config_rsp_fsm = CONFIG_RSP_PUT_LOW; 1797 } 1798 else // single flit 1799 { 1800 r_config_rsp_fsm = CONFIG_RSP_PUT_UNC; 1801 } 1802 } 1803 break; 1804 } 1805 //////////////////////// 1806 case CONFIG_RSP_PUT_LOW: // put 32 low bits into CONFIG_RSP fifo 1807 // no flit on IOX network is consumed 1525 1808 { 1526 r_config_rsp_fsm = CONFIG_RSP_PUT_LO; 1527 } 1528 else // single flit response 1529 { 1530 r_config_rsp_fsm = CONFIG_RSP_PUT_UNC; 1531 1532 assert( p_vci_ini_iox.reop.read() and 1533 "ERROR in vci_io_bridge : a remote config response should be one flit"); 1534 } 1535 } 1536 break; 1537 } 1538 /////////////////////// 1539 case CONFIG_RSP_PUT_LO: // try to write 32 low bits into CONFIG_RSP fifo 1540 // flit on IOX network is not consumed 1541 { 1542 if ( not r_alloc_fifo_config_rsp_local.read() and m_config_rsp_data_fifo.wok() ) 1543 { 1544 r_config_rsp_fsm = CONFIG_RSP_PUT_HI; 1809 config_rsp_fifo_put = true; 1810 config_rsp_fifo_rerror = p_vci_ini_iox.rerror.read(); 1811 config_rsp_fifo_rdata = (uint32_t)p_vci_ini_iox.rdata.read(); 1812 config_rsp_fifo_rsrcid = p_vci_ini_iox.rsrcid.read(); 1813 config_rsp_fifo_rtrdid = p_vci_ini_iox.rtrdid.read(); 1814 config_rsp_fifo_rpktid = p_vci_ini_iox.rpktid.read(); 1815 config_rsp_fifo_reop = false; 1816 1817 r_config_rsp_fsm = CONFIG_RSP_PUT_HI; 1545 1818 1546 1819 #if DEBUG_CONFIG_RSP 1547 1820 if( m_debug_activated ) 1548 std::cout << " <IOB CONFIG_RSP_PUT_LO > Push multi-flit response into CONFIG_RSP fifo:"1821 std::cout << " <IOB CONFIG_RSP_PUT_LOW> Push multi-flit response into CONFIG_RSP FIFO" 1549 1822 << " / rsrcid = " << std::hex << p_vci_ini_iox.rsrcid.read() 1550 1823 << " / rtrdid = " << p_vci_ini_iox.rtrdid.read() … … 1554 1827 << " / rerror = " << p_vci_ini_iox.rerror.read() << std::endl; 1555 1828 #endif 1556 } 1557 break; 1558 } 1559 /////////////////////// 1560 case CONFIG_RSP_PUT_HI: // try to write 32 high bits into CONFIG_RSP fifo 1561 // flit on IOX network is consumed if success 1562 { 1563 if ( not r_alloc_fifo_config_rsp_local.read() and m_config_rsp_data_fifo.wok() ) 1564 { 1565 if( p_vci_ini_iox.reop.read() ) r_config_rsp_fsm = CONFIG_RSP_IDLE; 1566 else r_config_rsp_fsm = CONFIG_RSP_PUT_LO; 1829 break; 1830 } 1831 /////////////////////// 1832 case CONFIG_RSP_PUT_HI: // put 32 high bits into CONFIG_RSP fifo 1833 // flit on IOX network is consumed 1834 { 1835 config_rsp_fifo_put = true; 1836 config_rsp_fifo_rerror = p_vci_ini_iox.rerror.read(); 1837 config_rsp_fifo_rdata = (uint32_t)(p_vci_ini_iox.rdata.read() >> 32); 1838 config_rsp_fifo_rsrcid = p_vci_ini_iox.rsrcid.read(); 1839 config_rsp_fifo_rtrdid = p_vci_ini_iox.rtrdid.read(); 1840 config_rsp_fifo_rpktid = p_vci_ini_iox.rpktid.read(); 1841 config_rsp_fifo_reop = p_vci_ini_iox.reop.read(); 1842 1843 if( p_vci_ini_iox.reop.read() ) r_config_rsp_fsm = CONFIG_RSP_IDLE_LOC; 1844 else r_config_rsp_fsm = CONFIG_RSP_PUT_LOW; 1567 1845 1568 1846 #if DEBUG_CONFIG_RSP 1569 1847 if( m_debug_activated ) 1570 std::cout << " <IOB CONFIG_RSP_PUT_HI> Push multi-flit response into CONFIG_RSP fifo:"1848 std::cout << " <IOB CONFIG_RSP_PUT_HI> Push multi-flit response into CONFIG_RSP FIFO" 1571 1849 << " / rsrcid = " << std::hex << p_vci_ini_iox.rsrcid.read() 1572 1850 << " / rtrdid = " << p_vci_ini_iox.rtrdid.read() 1573 1851 << " / rpktid = " << p_vci_ini_iox.rpktid.read() 1574 << " / rdata = " << (uint32_t)(p_vci_ini_iox.rdata.read() >>32)1852 << " / rdata = " << (uint32_t)(p_vci_ini_iox.rdata.read() >> 32) 1575 1853 << " / reop = " << p_vci_ini_iox.reop.read() 1576 1854 << " / rerror = " << p_vci_ini_iox.rerror.read() << std::endl; 1577 1855 #endif 1578 } 1579 break; 1580 } 1581 //////////////////////// 1582 case CONFIG_RSP_PUT_UNC: // try to write single flit into CONFIG_RSP fifo 1583 // flit on IOX network is consumed if success 1584 { 1585 if ( not r_alloc_fifo_config_rsp_local.read() and m_config_rsp_data_fifo.wok() ) 1586 { 1587 r_config_rsp_fsm = CONFIG_RSP_IDLE; 1856 break; 1857 } 1858 //////////////////////// 1859 case CONFIG_RSP_PUT_UNC: // put single flit into CONFIG_RSP fifo 1860 // flit on IOX network is consumed 1861 { 1862 assert( p_vci_ini_iox.reop.read() and 1863 "ERROR in vci_io_bridge : a remote config response should be one flit"); 1864 1865 config_rsp_fifo_put = true; 1866 config_rsp_fifo_rerror = p_vci_ini_iox.rerror.read(); 1867 config_rsp_fifo_rdata = (uint32_t)p_vci_ini_iox.rdata.read(); 1868 config_rsp_fifo_rsrcid = p_vci_ini_iox.rsrcid.read(); 1869 config_rsp_fifo_rtrdid = p_vci_ini_iox.rtrdid.read(); 1870 config_rsp_fifo_rpktid = p_vci_ini_iox.rpktid.read(); 1871 config_rsp_fifo_reop = true; 1872 1873 // update priority 1874 r_config_rsp_fsm = CONFIG_RSP_IDLE_LOC; 1588 1875 1589 1876 #if DEBUG_CONFIG_RSP 1590 1877 if( m_debug_activated ) 1591 std::cout << " <IOB CONFIG_RSP_PUT_UNC> Push single flit response into CONFIG_RSP fifo:"1878 std::cout << " <IOB CONFIG_RSP_PUT_UNC> Push single flit response into CONFIG_RSP FIFO" 1592 1879 << " / rsrcid = " << std::hex << p_vci_ini_iox.rsrcid.read() 1593 1880 << " / rtrdid = " << p_vci_ini_iox.rtrdid.read() … … 1597 1884 << " / rerror = " << p_vci_ini_iox.rerror.read() << std::endl; 1598 1885 #endif 1599 } 1600 break; 1601 } 1602 } // end switch CONFIG_RSP FSM 1603 1604 ///////////////////////////////////////////////////////////////////////////////// 1605 // If the IOB component has IRQ ports, the IRQ FSM detects all changes 1606 // on the 32 p_irq[i] ports and request a VCI write transaction to the 1607 // MISS_INIT FSM, using the 64 r_irq_request[i] and r_irq_pending[i] flip-flops. 1608 ///////////////////////////////////////////////////////////////////////////////// 1609 1610 if ( m_has_irqs ) 1611 { 1612 for ( size_t i = 0; i<32; ++i ) 1613 { 1614 r_irq_request[i] = ( p_irq[i]->read() == not r_irq_pending[i].read() ); 1615 r_irq_pending[i] = p_irq[i]->read(); 1616 } 1617 } 1618 1886 break; 1887 } 1888 //////////////////////// 1889 case CONFIG_RSP_PUT_LOC: // put single flit into CONFIG_RSP fifo 1890 // no flit on IOX network is consumed 1891 { 1892 config_rsp_fifo_put = true; 1893 config_rsp_fifo_rerror = r_config_cmd_to_config_rsp_rerror.read(); 1894 config_rsp_fifo_rdata = r_config_cmd_to_config_rsp_rdata.read(); 1895 config_rsp_fifo_rsrcid = r_config_cmd_srcid.read(); 1896 config_rsp_fifo_rtrdid = r_config_cmd_trdid.read(); 1897 config_rsp_fifo_rpktid = r_config_cmd_pktid.read(); 1898 config_rsp_fifo_reop = true; 1899 1900 // acknowledge request 1901 r_config_cmd_to_config_rsp_req = false; 1902 1903 // update priority 1904 r_config_rsp_fsm = CONFIG_RSP_IDLE_IOX; 1905 1906 #if DEBUG_CONFIG_RSP 1907 if( m_debug_activated ) 1908 std::cout << " <IOB CONFIG_RSP_PUT_UNC> Push single flit response into CONFIG_RSP FIFO" 1909 << " / rsrcid = " << std::hex << r_config_cmd_srcid.read() 1910 << " / rtrdid = " << r_config_cmd_trdid.read() 1911 << " / rpktid = " << r_config_cmd_pktid.read() 1912 << " / rdata = " << r_config_cmd_to_config_rsp_rdata.read() 1913 << " / reop = " << true 1914 << " / rerror = " << r_config_cmd_to_config_rsp_rerror.read() << std::endl; 1915 #endif 1916 break; 1917 } 1918 } // end switch CONFIG_RSP FSM 1919 } // end if FIFO full 1920 1619 1921 /////////////////////////////////////////////////////////////////////////////////// 1620 // The MISS_WTI_CMD FSM send VCI commands on the Internal Network. 1621 // It handles PTE MISS requests from TLB_MISS FSM and software IRQs. 1622 // It supports several simultaneous VCI transactions. 1922 // The MISS_WTI_CMD component is a combinational switch that push one single flit 1923 // VCI command in the MISS_WTI FIFO to INT Network, depending on two clients : 1924 // 1. MISS requests from TLB_MISS FSM : 1925 // These requests have highest priority because a TLB MISS is a blocking event 1926 // for the DMA FSM. The r_tlb_to_miss_wti_cmd_req flip-flop is reset by the 1927 // MISS_WTI_RSP FSM only when the response is received. 1928 // 2. WTI requests from DMA_CMD FSM : 1929 // These requestsare non blocking events, and the r_dma_cmd_to_miss_wti_cmd_req 1930 // flip-flop is reset as soon as the WTI command has been sent. 1931 // There is two types of WTI requests: 1932 // - external WTI from peripherals on IOX network. 1933 // - internal WTI caused by illegal DMA requests. 1623 1934 //////////////////////////////////////////////////////////////////////////////////// 1624 1935 1625 switch ( r_miss_wti_cmd_fsm.read() ) 1936 if ( r_tlb_to_miss_wti_cmd_req.read() and 1937 m_miss_wti_cmd_addr_fifo.wok() ) // put MISS READ 1938 { 1939 miss_wti_cmd_fifo_put = true; 1940 miss_wti_cmd_fifo_address = r_tlb_paddr.read(); 1941 miss_wti_cmd_fifo_wdata = 0; 1942 miss_wti_cmd_fifo_cmd = vci_param_int::CMD_READ; 1943 miss_wti_cmd_fifo_pktid = PKTID_MISS; 1944 miss_wti_cmd_fifo_srcid = m_int_srcid; 1945 miss_wti_cmd_fifo_trdid = 0; 1946 1947 #if DEBUG_MISS_WTI_CMD 1948 if( m_debug_activated ) 1949 std::cout << " <IOB MISS_WTI_CMD_WTI> push MISS TLB command into MISS_WTI FIFO" 1950 << " / PADDR = " << miss_wti_cmd_fifo_address << std::endl; 1951 #endif 1952 1953 } 1954 else if ( r_dma_cmd_to_miss_wti_cmd_req.read() and 1955 m_miss_wti_cmd_addr_fifo.wok() ) // put WTI READ / WRITE 1956 { 1957 r_dma_cmd_to_miss_wti_cmd_req = false; 1958 1959 miss_wti_cmd_fifo_put = true; 1960 miss_wti_cmd_fifo_cmd = r_dma_cmd_to_miss_wti_cmd_cmd.read(); 1961 miss_wti_cmd_fifo_address = r_dma_cmd_to_miss_wti_cmd_addr.read(); 1962 miss_wti_cmd_fifo_wdata = r_dma_cmd_to_miss_wti_cmd_wdata.read(); 1963 miss_wti_cmd_fifo_srcid = r_dma_cmd_to_miss_wti_cmd_srcid.read(); 1964 miss_wti_cmd_fifo_trdid = r_dma_cmd_to_miss_wti_cmd_trdid.read(); 1965 miss_wti_cmd_fifo_pktid = r_dma_cmd_to_miss_wti_cmd_pktid.read(); 1966 1967 #if DEBUG_MISS_WTI_CMD 1968 if( m_debug_activated ) 1969 std::cout << " <IOB MISS_WTI_CMD_WTI> push WTI command into MISS_WTI FIFO" 1970 << " / CMD = " << miss_wti_cmd_fifo_cmd 1971 << " / PADDR = " << miss_wti_cmd_fifo_address << std::endl; 1972 #endif 1973 1974 } 1975 1976 /////////////////////////////////////////////////////////////////////////////////// 1977 // The MISS_WTI_RSP FSM handles VCI responses from the INT network: 1978 // - for a TLB MISS (multi-flits read transaction), the cache line 1979 // is written in r_tlb_buf_data[], and r_tlb_to_miss_wti_cmd_req flip-flop is reset. 1980 // - for a WTI_IOX (single flit write transaction), the response must be 1981 // forwarded to the source peripheral on the INT network 1982 // - for a WTI_MMU (single flit write transaction), there is nothing to do. 1983 // 1984 // TODO VCI addressing errors for TLB MISS or for WTI_MMU (i.e. kernel errors...) 1985 // are registered in the r_miss_wti_rsp_error_miss & r_miss_wti_rsp_error_wti 1986 // flip-flops, and simulation stops... They could be signaled to OS by a WTI. 1987 //////////////////////////////////////////////////////////////////////////////////// 1988 1989 switch ( r_miss_wti_rsp_fsm.read() ) 1626 1990 { 1627 1991 /////////////////////// 1628 case MISS_WTI_CMD_IDLE: // TLB MISS have highest priority 1992 case MISS_WTI_RSP_IDLE: // waiting a VCI response 1993 // no VCI flit is consumed 1629 1994 { 1630 if ( r_tlb_miss_req.read() )1995 if ( p_vci_ini_int.rspval.read() ) 1631 1996 { 1632 r_miss_wti_cmd_fsm = MISS_WTI_CMD_MISS; 1633 } 1634 else if ( r_iommu_wti_enable.read() ) 1997 if ( p_vci_ini_int.rpktid.read() == PKTID_WTI_IOX ) 1998 { 1999 r_miss_wti_rsp_fsm = MISS_WTI_RSP_WTI_IOX; 2000 } 2001 else if ( p_vci_ini_int.rpktid.read() == PKTID_WTI_MMU ) 2002 { 2003 r_miss_wti_rsp_fsm = MISS_WTI_RSP_WTI_MMU; 2004 } 2005 else if ( p_vci_ini_int.rpktid.read() == PKTID_MISS ) 2006 { 2007 r_miss_wti_rsp_fsm = MISS_WTI_RSP_MISS; 2008 r_miss_wti_rsp_count = 0; 2009 } 2010 else 2011 { 2012 assert ( false and 2013 "VCI_IO_BRIDGE ERROR : illegal response type on INT network"); 2014 } 2015 } 2016 break; 2017 } 2018 ////////////////////////// 2019 case MISS_WTI_RSP_WTI_IOX: // Handling response to a peripheral WTI 2020 // consume VCI flit and transfer response 2021 // to DMA_RSP FSM in dedicated registers 2022 // if no pending previous request. 2023 { 2024 assert( p_vci_ini_int.reop.read() and 2025 "VCI_IO_BRIDGE ERROR: WTI_IOX response should have one single flit" ); 2026 2027 if ( not r_miss_wti_rsp_to_dma_rsp_req.read() ) // no previous pending request 1635 2028 { 1636 // checking if there is a new pending interrupt1637 bool found = false;1638 size_t n;1639 for ( n = 0 ; (n < 32) and not found ; n++ )1640 {1641 if ( r_irq_request[n] ) found = true; 1642 }1643 if ( found ) 1644 { 1645 r_miss_wti_cmd_index = n; 1646 r_miss_wti_cmd_fsm = MISS_WTI_CMD_WTI;1647 } 1648 } 1649 2029 r_miss_wti_rsp_to_dma_rsp_req = true; 2030 r_miss_wti_rsp_to_dma_rsp_rerror = p_vci_ini_int.rerror.read(); 2031 r_miss_wti_rsp_to_dma_rsp_rsrcid = p_vci_ini_int.rsrcid.read(); 2032 r_miss_wti_rsp_to_dma_rsp_rtrdid = p_vci_ini_int.rtrdid.read(); 2033 r_miss_wti_rsp_to_dma_rsp_rpktid = p_vci_ini_int.rpktid.read(); 2034 2035 r_miss_wti_rsp_fsm = MISS_WTI_RSP_IDLE; 2036 2037 #if DEBUG_MISS_WTI_RSP 2038 if( m_debug_activated ) 2039 std::cout << " <IOB MISS_WTI_RSP_WTI_IOX> Transfer response to a WTI_IOX" << std::endl; 2040 #endif 2041 } 2042 break; 1650 2043 } 1651 ////////////////////// 1652 case MISS_WTI_CMD_WTI: // send a single flit IRQ WRITE on INT Network 1653 // address is defined by IRQ_VECTOR[r_miss_wti_index] 1654 // data is defined by r_irq_pending[r_miss_wti_index] 2044 ////////////////////////// 2045 case MISS_WTI_RSP_WTI_MMU: // Handling response to an iommu WTI 2046 // consume VCI flit and test VCI error. 1655 2047 { 1656 if ( p_vci_ini_int.cmdack ) 2048 assert( p_vci_ini_int.reop.read() and 2049 "VCI_IO_BRIDGE ERROR: WTI_MMU response should have one single flit" ); 2050 2051 if ( (p_vci_ini_int.rerror.read()&0x1) != 0 ) // error reported 1657 2052 { 1658 // reset the request1659 r_ irq_request[r_miss_wti_cmd_index.read()] = false;1660 r_miss_wti_cmd_fsm = MISS_WTI_RSP_WTI;1661 1662 #if DEBUG_MISS_WTI 1663 if( m_debug_activated ) 1664 std::cout << " <IOB MISS_WTI_CMD_WTI> Send WTI write command on Internal Network" 1665 << " / IRQID = " << std::dec << r_miss_wti_cmd_index.read() << std::endl; 1666 #endif 1667 } 2053 // set the specific error flip-flop 2054 r_miss_wti_rsp_error_wti = true; 2055 assert( false and 2056 "VCI_IO_BRIDGE ERROR: VCI error response for a WTI_MMU transaction"); 2057 } 2058 2059 #if DEBUG_MISS_WTI_RSP 2060 if( m_debug_activated ) 2061 std::cout << " <IOB MISS_WTI_RSP_WTI_MMU> Receive response to a WTI_MMU" << std::endl; 2062 #endif 1668 2063 break; 1669 2064 } 1670 2065 /////////////////////// 1671 case MISS_WTI_CMD_MISS: // send a TLB MISS request on INT Network 1672 { 1673 if ( p_vci_ini_int.cmdack ) 1674 { 1675 r_tlb_buf_tag = ( (r_tlb_paddr.read()) & CACHE_LINE_MASK ); 1676 r_tlb_buf_valid = true; 1677 1678 if( r_tlb_miss_type.read() == PTE1_MISS ) 1679 r_tlb_buf_vaddr = (r_dma_cmd_vaddr.read() & 1680 ~M_PAGE_OFFSET_MASK & ~PTE1_LINE_OFFSET); 1681 else 1682 r_tlb_buf_vaddr = (r_dma_cmd_vaddr.read() & 1683 ~K_PAGE_OFFSET_MASK & ~PTE2_LINE_OFFSET); 1684 1685 r_miss_wti_cmd_fsm = MISS_WTI_RSP_MISS; 1686 1687 #if DEBUG_MISS_WTI 1688 if( m_debug_activated ) 1689 std::cout << " <IOB MISS_WTI_CMD_MISS> Send TLB MISS command on Internal Network" << std::hex 1690 << " / address = " <<(vci_addr_t)((r_tlb_paddr.read())& CACHE_LINE_MASK) << std::endl; 1691 #endif 1692 } 1693 break; 1694 } 1695 } // end switch r_miss_wti_cmd_fsm 1696 1697 /////////////////////////////////////////////////////////////////////////////////// 1698 // The MISS_WTI_RSP FSM handles VCI responses on the Internal Network. 1699 // it can be response to TLB MISS (read transaction) or WTI (write transaction). 1700 // It supports several simultaneous VCI transactions. 1701 //////////////////////////////////////////////////////////////////////////////////// 1702 1703 switch ( r_miss_wti_rsp_fsm.read() ) 1704 { 1705 case MISS_WTI_RSP_IDLE: // waiting a VCI response 1706 { 1707 if ( p_vci_ini_int.rspval.read() ) 1708 { 1709 if ( p_vci_ini_int.rpktid.read() == PKTID_READ ) // it's a TLB MISS response 1710 { 1711 r_miss_wti_rsp_fsm = MISS_WTI_RSP_MISS; 1712 r_miss_wti_rsp_count = 0; 1713 } 1714 else // it's a WTI WRITE response 1715 { 1716 r_miss_wti_rsp_fsm = MISS_WTI_RSP_WTI; 1717 1718 } 1719 } 1720 break; 1721 } 1722 ////////////////////// 1723 case MISS_WTI_RSP_WTI: // Handling response to a WTI transaction 1724 { 1725 assert( p_vci_ini_int.reop.read() and 1726 "VCI_IO_BRIDGE ERROR: IRQ Write response should have one single flit" ); 1727 1728 assert( ( (p_vci_ini_int.rerror.read()&0x1) == 0 ) and 1729 "VCI_IO_BRIDGE ERROR: IRQ Write response error !!!" ); 1730 // TODO handling error when using the IOMMU IRQ 1731 1732 #if DEBUG_MISS_WTI 1733 if( m_debug_activated ) 1734 std::cout << " <IOB MISS_WTI_RSP_WTI> Response to WTI write" << std::endl; 1735 #endif 1736 r_miss_wti_rsp_fsm = MISS_WTI_RSP_IDLE; 1737 break; 1738 } 1739 /////////////////////// 1740 case MISS_WTI_RSP_MISS: // Handling response to a TLB MISS transaction 2066 case MISS_WTI_RSP_MISS: // Handling response to a TLB MISS 2067 // write cache line in r_tlb_buf buffer 2068 // and analyse possible VCI error 2069 // VCI flit is consumed. 1741 2070 { 1742 2071 if ( p_vci_ini_int.rspval.read() ) … … 1744 2073 if ( (p_vci_ini_int.rerror.read()&0x1) != 0 ) // error reported 1745 2074 { 1746 r_miss_wti_rsp_error = true; 1747 if ( p_vci_ini_int.reop.read() ) 1748 { 1749 r_miss_wti_cmd_fsm = MISS_WTI_RSP_IDLE; 1750 r_tlb_miss_req = false; 1751 } 1752 #if DEBUG_MISS_WTI 2075 // set the specific error flip-flop 2076 r_miss_wti_rsp_error_miss = true; 2077 assert( false and 2078 "VCI_IO_BRIDGE ERROR: VCI error response for a TLB MISS transaction"); 2079 2080 } 2081 else // no error 2082 { 2083 2084 #if DEBUG_MISS_WTI_CMD 1753 2085 if( m_debug_activated ) 1754 std::cout << " <IOB MISS_WTI_RSP_MISS> ERROR " << std::endl; 1755 #endif 1756 } 1757 else // no error 1758 { 1759 bool eop = p_vci_ini_int.reop.read(); 1760 1761 #if DEBUG_MISS_WTI 1762 if( m_debug_activated ) 1763 std::cout << " <IOB MISS_WTI_RSP_MISS> Response to a tlb miss transaction" 2086 std::cout << " <IOB MISS_WTI_RSP_MISS> Receive response to a TLB MISS" 1764 2087 << " / Count = " << r_miss_wti_rsp_count.read() 1765 2088 << " / Data = " << std::hex << p_vci_ini_int.rdata.read() << std::endl; 1766 2089 #endif 2090 r_tlb_buf_data[r_miss_wti_rsp_count.read()] = p_vci_ini_int.rdata.read(); 2091 } 2092 2093 if ( p_vci_ini_int.reop.read() ) // last flit 2094 { 2095 bool eop = p_vci_ini_int.eop.read(); 1767 2096 assert(((eop == (r_miss_wti_rsp_count.read() == (m_words-1)))) and 1768 2097 "VCI_IO_BRIDGE ERROR: invalid length for a TLB MISS response"); 1769 2098 1770 r_tlb_buf_data[r_miss_wti_rsp_count.read()] = p_vci_ini_int.rdata.read(); 2099 r_miss_wti_rsp_count = 0; 2100 r_miss_wti_rsp_fsm = MISS_WTI_RSP_IDLE; 2101 r_tlb_to_miss_wti_cmd_req = false; 2102 } 2103 else // not the last flit 2104 { 1771 2105 r_miss_wti_rsp_count = r_miss_wti_rsp_count.read() + 1; 1772 1773 if ( eop )1774 {1775 r_tlb_miss_req = false; //reset the request flip-flop1776 r_miss_wti_cmd_fsm = MISS_WTI_RSP_IDLE;1777 }1778 2106 } 1779 2107 } … … 1782 2110 } // end switch r_miss_wti_rsp_fsm 1783 2111 1784 /////////////////////////////////////////////////////////////////////////1785 // This flip-flop allocates the access to the CONFIG_RSP fifo1786 // with a round robin priority between 2 clients FSMs :1787 // - CONFIG_CMD : to put a response to a local config command.1788 // - CONFIG_RSP : to put a response to a peripheral config command.1789 // The ressource is always allocated.1790 // A new allocation occurs when the owner FSM is not using it,1791 // and the other FSM is requiring it.1792 /////////////////////////////////////////////////////////////////////////1793 1794 if ( r_alloc_fifo_config_rsp_local.read() )1795 {1796 if ( (r_config_rsp_fsm.read() != CONFIG_RSP_IDLE) and // config_rsp_fsm requiring1797 (r_config_cmd_fsm.read() != CONFIG_CMD_RSP) ) // config_cmd_fsm not requiring1798 r_alloc_fifo_config_rsp_local = false;1799 }1800 else1801 {1802 if ( (r_config_cmd_fsm.read() == CONFIG_CMD_RSP) and // config_cmd_fsm requiring1803 (r_config_rsp_fsm.read() == CONFIG_RSP_IDLE) ) // config_rsp_fsm not requiring1804 r_alloc_fifo_config_rsp_local = true;1805 }1806 1807 /////////////////////////////////////////////////////////////////////////1808 // This flip-flop allocates the access to the DMA_RSP fifo1809 // with a round robin priority between 2 clients FSMs :1810 // - DMA_CMD : to put a error response in case of bad address translation1811 // - DMA_RSP : to put a normal response to a DMA transaction.1812 // The ressource is always allocated.1813 // A new allocation occurs when the owner FSM is not using it,1814 // and the other FSM is requiring it.1815 /////////////////////////////////////////////////////////////////////////1816 1817 if ( r_alloc_fifo_dma_rsp_local.read() )1818 {1819 if ( (r_dma_rsp_fsm.read() == DMA_RSP_FIFO_PUT) and1820 (r_dma_cmd_fsm.read() != DMA_CMD_FIFO_PUT_RSP) )1821 r_alloc_fifo_dma_rsp_local = false;1822 }1823 else1824 {1825 if ( (r_dma_cmd_fsm.read() == DMA_CMD_FIFO_PUT_RSP) and1826 (r_dma_rsp_fsm.read() != DMA_RSP_FIFO_PUT) )1827 r_alloc_fifo_dma_rsp_local = true;1828 }1829 1830 // Define GET signals for all output FIFOs1831 dma_cmd_fifo_get = p_vci_ini_ram.cmdack.read();1832 dma_rsp_fifo_get = p_vci_tgt_iox.rspack.read();1833 config_cmd_fifo_get = p_vci_ini_iox.cmdack.read();1834 config_rsp_fifo_get = p_vci_tgt_int.rspack.read();1835 2112 1836 2113 /////////////////////////////////////////////////////////// 1837 2114 // DMA_CMD fifo update 1838 // Onewriter : DMA_CMD FSM2115 // writer : DMA_CMD FSM 1839 2116 /////////////////////////////////////////////////////////// 1840 2117 … … 1884 2161 ////////////////////////////////////////////////////////////// 1885 2162 // DMA_RSP fifo update 1886 // Two writers : DMA_CMD FSM &DMA_RSP FSM2163 // writer : DMA_RSP FSM 1887 2164 ////////////////////////////////////////////////////////////// 1888 2165 1889 if (r_alloc_fifo_dma_rsp_local.read() ) // owner is DMA_CMD FSM 1890 // local response for a translation error 1891 { 1892 m_dma_rsp_data_fifo.update( dma_rsp_fifo_get, 1893 dma_rsp_fifo_put, 1894 0 ); // no data if error 1895 m_dma_rsp_rsrcid_fifo.update( dma_rsp_fifo_get, 1896 dma_rsp_fifo_put, 1897 p_vci_tgt_iox.rsrcid.read() ); 1898 m_dma_rsp_rtrdid_fifo.update( dma_rsp_fifo_get, 1899 dma_rsp_fifo_put, 1900 p_vci_tgt_iox.rtrdid.read() ); 1901 m_dma_rsp_rpktid_fifo.update( dma_rsp_fifo_get, 1902 dma_rsp_fifo_put, 1903 p_vci_tgt_iox.rpktid.read() ); 1904 m_dma_rsp_reop_fifo.update( dma_rsp_fifo_get, 1905 dma_rsp_fifo_put, 1906 true ); // single flit response 1907 m_dma_rsp_rerror_fifo.update( dma_rsp_fifo_get, 1908 dma_rsp_fifo_put, 1909 1 ); // error 1910 } 1911 else // owner is DMA_RSP FSM 1912 // normal response to a DMA transaction 1913 { 1914 m_dma_rsp_data_fifo.update( dma_rsp_fifo_get, 1915 dma_rsp_fifo_put, 1916 p_vci_ini_ram.rdata.read() ); 1917 m_dma_rsp_rsrcid_fifo.update( dma_rsp_fifo_get, 1918 dma_rsp_fifo_put, 1919 p_vci_ini_ram.rsrcid.read() ); 1920 m_dma_rsp_rtrdid_fifo.update( dma_rsp_fifo_get, 1921 dma_rsp_fifo_put, 1922 p_vci_ini_ram.rtrdid.read() ); 1923 m_dma_rsp_rpktid_fifo.update( dma_rsp_fifo_get, 1924 dma_rsp_fifo_put, 1925 p_vci_ini_ram.rpktid.read() ); 1926 m_dma_rsp_reop_fifo.update( dma_rsp_fifo_get, 1927 dma_rsp_fifo_put, 1928 p_vci_ini_ram.reop.read() ); 1929 m_dma_rsp_rerror_fifo.update( dma_rsp_fifo_get, 1930 dma_rsp_fifo_put, 1931 p_vci_ini_ram.rerror.read() ); 1932 } 2166 m_dma_rsp_data_fifo.update( dma_rsp_fifo_get, 2167 dma_rsp_fifo_put, 2168 dma_rsp_fifo_rdata ); 2169 m_dma_rsp_rsrcid_fifo.update( dma_rsp_fifo_get, 2170 dma_rsp_fifo_put, 2171 dma_rsp_fifo_rsrcid ); 2172 m_dma_rsp_rtrdid_fifo.update( dma_rsp_fifo_get, 2173 dma_rsp_fifo_put, 2174 dma_rsp_fifo_rtrdid ); 2175 m_dma_rsp_rpktid_fifo.update( dma_rsp_fifo_get, 2176 dma_rsp_fifo_put, 2177 dma_rsp_fifo_rpktid ); 2178 m_dma_rsp_reop_fifo.update( dma_rsp_fifo_get, 2179 dma_rsp_fifo_put, 2180 dma_rsp_fifo_reop ); 2181 m_dma_rsp_rerror_fifo.update( dma_rsp_fifo_get, 2182 dma_rsp_fifo_put, 2183 dma_rsp_fifo_rerror ); 1933 2184 1934 2185 //////////////////////////////////////////////////////////////// 1935 2186 // CONFIG_CMD fifo update 1936 // Onewriter : CONFIG_CMD FSM2187 // writer : CONFIG_CMD FSM 1937 2188 //////////////////////////////////////////////////////////////// 1938 2189 … … 1982 2233 ////////////////////////////////////////////////////////////////////////// 1983 2234 // CONFIG_RSP fifo update 1984 // There is two writers : CONFIG_CMD FSM &CONFIG_RSP FSM2235 // writer : CONFIG_RSP FSM 1985 2236 ////////////////////////////////////////////////////////////////////////// 1986 2237 1987 if ( r_alloc_fifo_config_rsp_local.read() ) // owner is CONFIG_CMD FSM 1988 // response for a local config transaction 1989 { 1990 m_config_rsp_data_fifo.update( config_rsp_fifo_get, 1991 config_rsp_fifo_put, 1992 r_config_cmd_rdata.read() ); 1993 m_config_rsp_rsrcid_fifo.update( config_rsp_fifo_get, 1994 config_rsp_fifo_put, 1995 p_vci_tgt_int.srcid.read() ); 1996 m_config_rsp_rtrdid_fifo.update( config_rsp_fifo_get, 1997 config_rsp_fifo_put, 1998 p_vci_tgt_int.trdid.read() ); 1999 m_config_rsp_rpktid_fifo.update( config_rsp_fifo_get, 2000 config_rsp_fifo_put, 2001 p_vci_tgt_int.pktid.read() ); 2002 m_config_rsp_reop_fifo.update( config_rsp_fifo_get, 2003 config_rsp_fifo_put, 2004 true ); // local config are one flit 2005 m_config_rsp_rerror_fifo.update( config_rsp_fifo_get, 2006 config_rsp_fifo_put, 2007 r_config_cmd_error.read() ); 2008 } 2009 else // owner is CONFIG_RSP FSM 2010 // response for a remote transaction 2011 { 2012 // PUT depends on CONFIG_RSP FSM state 2013 uint32_t rdata; 2014 bool reop; 2015 if ( r_config_rsp_fsm.read() == CONFIG_RSP_PUT_HI ) 2016 { 2017 config_rsp_fifo_put = true; 2018 rdata = (uint32_t)(p_vci_ini_iox.rdata.read()>>32); 2019 reop = p_vci_ini_iox.reop.read(); 2020 } 2021 else if ( r_config_rsp_fsm.read() == CONFIG_RSP_PUT_LO ) 2022 { 2023 config_rsp_fifo_put = true; 2024 rdata = (uint32_t)(p_vci_ini_iox.rdata.read()); 2025 reop = false; 2026 } 2027 else if ( r_config_rsp_fsm.read() == CONFIG_RSP_PUT_UNC ) 2028 { 2029 config_rsp_fifo_put = true; 2030 rdata = (uint32_t)(p_vci_ini_iox.rdata.read()); 2031 reop = true; 2032 } 2033 else 2034 { 2035 config_rsp_fifo_put = false; 2036 rdata = 0; 2037 reop = false;; 2038 } 2039 2040 m_config_rsp_data_fifo.update( config_rsp_fifo_get, 2041 config_rsp_fifo_put, 2042 rdata ); 2043 m_config_rsp_rsrcid_fifo.update( config_rsp_fifo_get, 2044 config_rsp_fifo_put, 2045 p_vci_ini_iox.rsrcid.read() ); 2046 m_config_rsp_rtrdid_fifo.update( config_rsp_fifo_get, 2047 config_rsp_fifo_put, 2048 p_vci_ini_iox.rtrdid.read() ); 2049 m_config_rsp_rpktid_fifo.update( config_rsp_fifo_get, 2050 config_rsp_fifo_put, 2051 p_vci_ini_iox.rpktid.read() ); 2052 m_config_rsp_reop_fifo.update( config_rsp_fifo_get, 2053 config_rsp_fifo_put, 2054 reop ); 2055 m_config_rsp_rerror_fifo.update( config_rsp_fifo_get, 2056 config_rsp_fifo_put, 2057 p_vci_ini_iox.rerror.read() ); 2058 } 2238 m_config_rsp_data_fifo.update( config_rsp_fifo_get, 2239 config_rsp_fifo_put, 2240 config_rsp_fifo_rdata ); 2241 m_config_rsp_rsrcid_fifo.update( config_rsp_fifo_get, 2242 config_rsp_fifo_put, 2243 config_rsp_fifo_rsrcid ); 2244 m_config_rsp_rtrdid_fifo.update( config_rsp_fifo_get, 2245 config_rsp_fifo_put, 2246 config_rsp_fifo_rtrdid ); 2247 m_config_rsp_rpktid_fifo.update( config_rsp_fifo_get, 2248 config_rsp_fifo_put, 2249 config_rsp_fifo_rpktid ); 2250 m_config_rsp_reop_fifo.update( config_rsp_fifo_get, 2251 config_rsp_fifo_put, 2252 config_rsp_fifo_reop ); 2253 m_config_rsp_rerror_fifo.update( config_rsp_fifo_get, 2254 config_rsp_fifo_put, 2255 config_rsp_fifo_rerror ); 2256 2257 //////////////////////////////////////////////////////////////// 2258 // MISS_WTI_CMD fifo update 2259 // One writer : MISS_WTI switch 2260 //////////////////////////////////////////////////////////////// 2261 2262 m_miss_wti_cmd_addr_fifo.update( miss_wti_cmd_fifo_get, 2263 miss_wti_cmd_fifo_put, 2264 miss_wti_cmd_fifo_address ); 2265 m_miss_wti_cmd_cmd_fifo.update( miss_wti_cmd_fifo_get, 2266 miss_wti_cmd_fifo_put, 2267 miss_wti_cmd_fifo_cmd ); 2268 m_miss_wti_cmd_contig_fifo.update( config_cmd_fifo_get, 2269 miss_wti_cmd_fifo_put, 2270 true ); 2271 m_miss_wti_cmd_cons_fifo.update( miss_wti_cmd_fifo_get, 2272 miss_wti_cmd_fifo_put, 2273 false ); 2274 m_miss_wti_cmd_plen_fifo.update( miss_wti_cmd_fifo_get, 2275 miss_wti_cmd_fifo_put, 2276 4 ); 2277 m_miss_wti_cmd_wrap_fifo.update( miss_wti_cmd_fifo_get, 2278 miss_wti_cmd_fifo_put, 2279 false ); 2280 m_miss_wti_cmd_cfixed_fifo.update( config_cmd_fifo_get, 2281 miss_wti_cmd_fifo_put, 2282 false ); 2283 m_miss_wti_cmd_clen_fifo.update( miss_wti_cmd_fifo_get, 2284 miss_wti_cmd_fifo_put, 2285 0 ); 2286 m_miss_wti_cmd_srcid_fifo.update( miss_wti_cmd_fifo_get, 2287 miss_wti_cmd_fifo_put, 2288 miss_wti_cmd_fifo_srcid ); 2289 m_miss_wti_cmd_trdid_fifo.update( miss_wti_cmd_fifo_get, 2290 miss_wti_cmd_fifo_put, 2291 miss_wti_cmd_fifo_trdid ); 2292 m_miss_wti_cmd_pktid_fifo.update( miss_wti_cmd_fifo_get, 2293 miss_wti_cmd_fifo_put, 2294 miss_wti_cmd_fifo_pktid ); 2295 m_miss_wti_cmd_data_fifo.update( miss_wti_cmd_fifo_get, 2296 miss_wti_cmd_fifo_put, 2297 miss_wti_cmd_fifo_wdata ); 2298 m_miss_wti_cmd_be_fifo.update( miss_wti_cmd_fifo_get, 2299 miss_wti_cmd_fifo_put, 2300 0xF ); 2301 m_miss_wti_cmd_eop_fifo.update( miss_wti_cmd_fifo_get, 2302 miss_wti_cmd_fifo_put, 2303 true ); 2059 2304 2060 2305 } // end transition() 2061 2306 2062 /////////////////////// 2307 ////////////////////////////////////////////////////////////////////////// 2063 2308 tmpl(void)::genMoore() 2064 /////////////////////// 2309 ////////////////////////////////////////////////////////////////////////// 2065 2310 { 2311 ///////////////// p_vci_ini_ram ///////////////////////////// 2312 2066 2313 // VCI initiator command on RAM network 2067 2314 // directly the content of the dma_cmd FIFO 2068 2069 2315 p_vci_ini_ram.cmdval = m_dma_cmd_addr_fifo.rok(); 2070 2316 p_vci_ini_ram.address = m_dma_cmd_addr_fifo.read(); … … 2083 2329 p_vci_ini_ram.srcid = m_dma_cmd_srcid_fifo.read(); 2084 2330 2085 // VCI target command ack on IOX network 2086 // depends on the DMA_CMD FSM state 2087 2088 switch ( r_dma_cmd_fsm.read() ) 2089 { 2090 case DMA_CMD_IDLE: 2091 case DMA_CMD_MISS_WAIT: 2092 p_vci_tgt_iox.cmdack = false; 2093 break; 2094 case DMA_CMD_WAIT_EOP: 2095 p_vci_tgt_iox.cmdack = true; 2096 break; 2097 case DMA_CMD_FIFO_PUT_CMD: 2098 p_vci_tgt_iox.cmdack = m_dma_cmd_addr_fifo.wok(); 2099 break; 2100 case DMA_CMD_FIFO_PUT_RSP: 2101 p_vci_tgt_iox.cmdack = m_dma_rsp_data_fifo.wok(); 2102 break; 2103 } 2104 2105 // VCI target response on IOX network 2331 // VCI initiator response on the RAM Network 2332 // depends on the DMA_RSP FSM state 2333 p_vci_ini_ram.rspack = m_dma_rsp_data_fifo.wok() and 2334 (r_dma_rsp_fsm.read() == DMA_RSP_PUT_DMA); 2335 2336 ///////////////// p_vci_tgt_iox ///////////////////////////// 2337 2338 // VCI target response on IOX network is 2106 2339 // directly the content of the DMA_RSP FIFO 2107 2108 2340 p_vci_tgt_iox.rspval = m_dma_rsp_data_fifo.rok(); 2109 2341 p_vci_tgt_iox.rsrcid = m_dma_rsp_rsrcid_fifo.read(); … … 2114 2346 p_vci_tgt_iox.reop = m_dma_rsp_reop_fifo.read(); 2115 2347 2116 // VCI initiator response on the RAM Network 2117 // depends on the DMA_RSP FSM state 2118 2119 p_vci_ini_ram.rspack = m_dma_rsp_data_fifo.wok() and 2120 (r_dma_rsp_fsm.read() == DMA_RSP_FIFO_PUT) and 2121 not r_alloc_fifo_dma_rsp_local.read(); 2122 2123 // VCI initiator command on IOX network 2348 // VCI target command ack on IOX network 2349 // depends on the DMA_CMD FSM state 2350 switch ( r_dma_cmd_fsm.read() ) 2351 { 2352 case DMA_CMD_IDLE: 2353 p_vci_tgt_iox.cmdack = false; 2354 break; 2355 case DMA_CMD_DMA_REQ: 2356 p_vci_tgt_iox.cmdack = m_dma_cmd_addr_fifo.wok(); 2357 break; 2358 case DMA_CMD_WTI_IOX_REQ: 2359 p_vci_tgt_iox.cmdack = not r_dma_cmd_to_miss_wti_cmd_req.read(); 2360 break; 2361 case DMA_CMD_ERR_WTI_REQ: 2362 p_vci_tgt_iox.cmdack = false; 2363 break; 2364 case DMA_CMD_ERR_WAIT_EOP: 2365 p_vci_tgt_iox.cmdack = true; 2366 break; 2367 case DMA_CMD_ERR_RSP_REQ: 2368 p_vci_tgt_iox.cmdack = false; 2369 break; 2370 case DMA_CMD_TLB_MISS_WAIT: 2371 p_vci_tgt_iox.cmdack = false; 2372 break; 2373 } 2374 2375 ////////////////// p_vci_ini_iox ///////////////////////////// 2376 2377 // VCI initiator command on IOX network is 2124 2378 // directly the content of the CONFIG_CMD FIFO 2125 2126 2379 p_vci_ini_iox.cmdval = m_config_cmd_addr_fifo.rok(); 2127 2380 p_vci_ini_iox.address = m_config_cmd_addr_fifo.read(); … … 2140 2393 p_vci_ini_iox.srcid = m_config_cmd_srcid_fifo.read(); 2141 2394 2395 // VCI initiator response on IOX Network 2396 // it depends on the CONFIG_RSP FSM state 2397 p_vci_ini_iox.rspack = m_config_rsp_data_fifo.wok() and 2398 ( (r_config_rsp_fsm.read() == CONFIG_RSP_PUT_UNC) or 2399 (r_config_rsp_fsm.read() == CONFIG_RSP_PUT_HI) ); 2400 2401 ///////////////// p_vci_tgt_int //////////////////////////////// 2402 2403 // VCI target response on INT network 2404 // directly the content of the CONFIG_RSP FIFO 2405 p_vci_tgt_int.rspval = m_config_rsp_data_fifo.rok(); 2406 p_vci_tgt_int.rsrcid = m_config_rsp_rsrcid_fifo.read(); 2407 p_vci_tgt_int.rtrdid = m_config_rsp_rtrdid_fifo.read(); 2408 p_vci_tgt_int.rpktid = m_config_rsp_rpktid_fifo.read(); 2409 p_vci_tgt_int.rdata = m_config_rsp_data_fifo.read(); 2410 p_vci_tgt_int.rerror = m_config_rsp_rerror_fifo.read(); 2411 p_vci_tgt_int.reop = m_config_rsp_reop_fifo.read(); 2412 2142 2413 // VCI target command ack on INT network 2143 2414 // it depends on the CONFIG_CMD FSM state 2144 2145 2415 switch ( r_config_cmd_fsm.read() ) 2146 2416 { … … 2159 2429 } 2160 2430 2161 // VCI target response on INT network 2162 // directly the content of the CONFIG_RSP FIFO 2163 2164 p_vci_tgt_int.rspval = m_config_rsp_data_fifo.rok(); 2165 p_vci_tgt_int.rsrcid = m_config_rsp_rsrcid_fifo.read(); 2166 p_vci_tgt_int.rtrdid = m_config_rsp_rtrdid_fifo.read(); 2167 p_vci_tgt_int.rpktid = m_config_rsp_rpktid_fifo.read(); 2168 p_vci_tgt_int.rdata = m_config_rsp_data_fifo.read(); 2169 p_vci_tgt_int.rerror = m_config_rsp_rerror_fifo.read(); 2170 p_vci_tgt_int.reop = m_config_rsp_reop_fifo.read(); 2171 2172 // VCI initiator response on IOX Network 2173 // it depends on the CONFIG_RSP FSM state 2174 2175 p_vci_ini_iox.rspack = m_config_rsp_data_fifo.wok() and 2176 not r_alloc_fifo_config_rsp_local.read() and 2177 ( (r_config_rsp_fsm.read() == CONFIG_RSP_PUT_UNC) or 2178 (r_config_rsp_fsm.read() == CONFIG_RSP_PUT_HI) ); 2431 ///////////////// p_vci_ini_int //////////////////////////////// 2179 2432 2180 2433 // VCI initiator command on INT network 2181 // it depends on the MISS_WTI_CMD FSM state 2182 // - WTI : single flit WRITE 2183 // - MISS TLB : multi-flit READ for a complete cache line 2184 2185 // default values 2186 p_vci_ini_int.srcid = m_int_srcid; 2187 p_vci_ini_int.trdid = 0; 2188 p_vci_ini_int.cfixed = false; 2189 p_vci_ini_int.eop = true; 2190 p_vci_ini_int.wrap = false; 2191 p_vci_ini_int.clen = 0; 2192 p_vci_ini_int.contig = true; 2193 p_vci_ini_int.cons = false; 2194 p_vci_ini_int.be = 0xF; 2195 2196 switch ( r_miss_wti_cmd_fsm.read() ) 2197 { 2198 case MISS_WTI_CMD_IDLE: 2199 p_vci_ini_int.cmdval = false; 2200 p_vci_ini_int.address = 0; 2201 p_vci_ini_int.cmd = vci_param_int::CMD_NOP; 2202 p_vci_ini_int.pktid = PKTID_READ; 2203 p_vci_ini_int.wdata = 0; 2204 p_vci_ini_int.plen = 0; 2205 break; 2206 2207 case MISS_WTI_CMD_WTI: 2208 p_vci_ini_int.cmdval = true; 2209 p_vci_ini_int.address = r_iommu_peri_wti[r_miss_wti_cmd_index.read()].read(); 2210 p_vci_ini_int.cmd = vci_param_int::CMD_WRITE; 2211 p_vci_ini_int.pktid = PKTID_WRITE; 2212 p_vci_ini_int.wdata = (int_data_t)r_irq_pending[r_miss_wti_cmd_index.read()].read(); 2213 p_vci_ini_int.plen = vci_param_int::B; 2214 break; 2215 2216 case MISS_WTI_CMD_MISS: 2217 p_vci_ini_int.cmdval = true; 2218 p_vci_ini_int.address = r_tlb_paddr.read() & CACHE_LINE_MASK; 2219 p_vci_ini_int.cmd = vci_param_int::CMD_READ; 2220 p_vci_ini_int.pktid = PKTID_READ; 2221 p_vci_ini_int.wdata = 0; 2222 p_vci_ini_int.plen = m_words*(vci_param_int::B); 2223 break; 2224 } 2434 // directly the content of the MISS_WTI_CMD FIFO 2435 p_vci_ini_int.cmdval = m_miss_wti_cmd_addr_fifo.rok(); 2436 p_vci_ini_int.address = m_miss_wti_cmd_addr_fifo.read(); 2437 p_vci_ini_int.be = m_miss_wti_cmd_be_fifo.read(); 2438 p_vci_ini_int.cmd = m_miss_wti_cmd_cmd_fifo.read(); 2439 p_vci_ini_int.contig = m_miss_wti_cmd_contig_fifo.read(); 2440 p_vci_ini_int.wdata = m_miss_wti_cmd_data_fifo.read(); 2441 p_vci_ini_int.eop = m_miss_wti_cmd_eop_fifo.read(); 2442 p_vci_ini_int.cons = m_miss_wti_cmd_cons_fifo.read(); 2443 p_vci_ini_int.plen = m_miss_wti_cmd_plen_fifo.read(); 2444 p_vci_ini_int.wrap = m_miss_wti_cmd_wrap_fifo.read(); 2445 p_vci_ini_int.cfixed = m_miss_wti_cmd_cfixed_fifo.read(); 2446 p_vci_ini_int.clen = m_miss_wti_cmd_clen_fifo.read(); 2447 p_vci_ini_int.trdid = m_miss_wti_cmd_trdid_fifo.read(); 2448 p_vci_ini_int.pktid = m_miss_wti_cmd_pktid_fifo.read(); 2449 p_vci_ini_int.srcid = m_miss_wti_cmd_srcid_fifo.read(); 2225 2450 2226 2451 // VCI initiator response on INT network 2227 2452 // It depends on the MISS_WTI_RSP FSM state 2228 2453 2229 if ( r_miss_wti_rsp_fsm.read() == MISS_WTI_RSP_IDLE ) p_vci_ini_int.rspack = false; 2230 else p_vci_ini_int.rspack = true; 2454 if ( r_miss_wti_rsp_fsm.read() == MISS_WTI_RSP_IDLE ) 2455 { 2456 p_vci_ini_int.rspack = false; 2457 } 2458 else if ( r_miss_wti_rsp_fsm.read() == MISS_WTI_RSP_WTI_IOX ) 2459 { 2460 p_vci_ini_int.rspack = not r_miss_wti_rsp_to_dma_rsp_req.read(); 2461 } 2462 else // MISS_WTI_RSP_MISS or MISS_WTI_RESP_WTI_MMU 2463 { 2464 p_vci_ini_int.rspack = true; 2465 } 2231 2466 2232 2467 } // end genMoore -
trunk/modules/vci_io_bridge/include/soclib/io_bridge.h
r434 r712 29 29 30 30 // IOB Configuration registers 31 // Minimal required segment size = 512 bytes (128words)31 // Minimal required segment size = 64 bytes (16 words) 32 32 enum 33 33 { … … 39 39 IOB_INVAL_PTE = 5, // W : Invalidate PTE (using virtual address) 40 40 IOB_WTI_ENABLE = 6, // R/W : Enable WTI (both IOB and external IRQs) 41 IOB_WTI_ADDR_LO = 7, // R/W : WTI for IOB itself (32 LSB address bits) 42 IOB_WTI_ADDR_HI = 8, // R/W : WTI for IOB itself (32 MSB address bits) 43 IOB_PERI_WTI_BEGIN = 64, // R/W : two 32 bits words per IRQ 41 IOB_WTI_ADDR_LO = 7, // R/W : IOB WTI address (32 LSB bits) 42 IOB_WTI_ADDR_HI = 8, // R/W : IOB WTI address (32 MSB bits) 43 IOB_XICU_BASE = 9, // R/W : XICU pbase address in cluster 0 44 IOB_XICU_SIZE = 10, // R/W : XICU segment size 44 45 /**/ 45 IOB_SPAN = 1 28,46 IOB_SPAN = 16, 46 47 }; 47 48 … … 51 52 { 52 53 MMU_NONE = 0x0000, // None 53 MMU_WRITE_ACCES_VIOLATION = 0x0008, // Write access to anon writable page54 MMU_WRITE_PT1_ILLEGAL_ACCESS = 0x0040, // Write Bus Error accessing Table 1 55 MMU_READ_PT1_UNMAPPED = 0x1001, // Read Page fault on Page Table 1 56 MMU_READ_PT2_UNMAPPED = 0x1002, // Read Page fault on Page Table 2 57 MMU_READ_PT1_ILLEGAL_ACCESS = 0x1040, // Read Bus Error in Table1 access 58 MMU_READ_PT2_ILLEGAL_ACCESS = 0x1080, // Read Bus Error in Table2 access 54 MMU_WRITE_ACCES_VIOLATION = 0x0008, // Write access to non writable page 55 MMU_WRITE_PT1_ILLEGAL_ACCESS = 0x0040, // Write Bus Error accessing Table 1 56 MMU_READ_PT1_UNMAPPED = 0x1001, // Read Page fault on Page Table 1 57 MMU_READ_PT2_UNMAPPED = 0x1002, // Read Page fault on Page Table 2 58 MMU_READ_PT1_ILLEGAL_ACCESS = 0x1040, // Read Bus Error in Table1 access 59 MMU_READ_PT2_ILLEGAL_ACCESS = 0x1080, // Read Bus Error in Table2 access 59 60 MMU_READ_DATA_ILLEGAL_ACCESS = 0x1100, // Read Bus Error in cache access 60 61 };
Note: See TracChangeset
for help on using the changeset viewer.