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