Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | // ========== Copyright Header Begin ========================================== |
2 | // | |
3 | // OpenSPARC T2 Processor File: N2fcXactionProbe.vr | |
4 | // Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved | |
5 | // 4150 Network Circle, Santa Clara, California 95054, U.S.A. | |
6 | // | |
7 | // * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
8 | // | |
9 | // This program is free software; you can redistribute it and/or modify | |
10 | // it under the terms of the GNU General Public License as published by | |
11 | // the Free Software Foundation; version 2 of the License. | |
12 | // | |
13 | // This program is distributed in the hope that it will be useful, | |
14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | // GNU General Public License for more details. | |
17 | // | |
18 | // You should have received a copy of the GNU General Public License | |
19 | // along with this program; if not, write to the Free Software | |
20 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
21 | // | |
22 | // For the avoidance of doubt, and except that if any non-GPL license | |
23 | // choice is available it will apply instead, Sun elects to use only | |
24 | // the General Public License version 2 (GPLv2) at this time for any | |
25 | // software where a choice of GPL license versions is made | |
26 | // available with the language indicating that GPLv2 or any later version | |
27 | // may be used, or where a choice of which version of the GPL is applied is | |
28 | // otherwise unspecified. | |
29 | // | |
30 | // Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
31 | // CA 95054 USA or visit www.sun.com if you need additional information or | |
32 | // have any questions. | |
33 | // | |
34 | // ========== Copyright Header End ============================================ | |
35 | #include <vera_defines.vrh> | |
36 | ||
37 | #include "ccx_ncu.port_bind.vri" | |
38 | ||
39 | ||
40 | #define PCX_NCU_RQTYP_DW 5 | |
41 | #define PCX_NCU_SIZE_DW 8 | |
42 | #define PCX_NCU_ADDR_DW 40 | |
43 | #define PCX_NCU_DATA_DW 64 | |
44 | ||
45 | #define PCX_NCU_RQTYP_FLD 128:124 | |
46 | #define PCX_NCU_TID_FLD 122:117 | |
47 | #define PCX_NCU_SIZE_FLD 111:104 | |
48 | #define PCX_NCU_ADDR_FLD 103:64 | |
49 | #define PCX_NCU_DATA_FLD 63:0 | |
50 | ||
51 | // NCU register Addresses | |
52 | #define NCU_PCIE_MEM32_BASE_ADDR 16'h2000 | |
53 | #define NCU_PCIE_MEM32_MASK_ADDR 16'h2008 | |
54 | #define NCU_PCIE_MEM64_BASE_ADDR 16'h2010 | |
55 | #define NCU_PCIE_MEM64_MASK_ADDR 16'h2018 | |
56 | #define NCU_PCIE_IOCON_BASE_ADDR 16'h2020 | |
57 | #define NCU_PCIE_IOCON_MASK_ADDR 16'h2028 | |
58 | ||
59 | // NCU register Base fields | |
60 | #define NCU_BASE_EN_FLD 63 | |
61 | #define NCU_PCIE_MEMADDR_CMP_FLD 35:24 | |
62 | #define NCU_PCIE_CFGADDR_CMP_FLD 35:29 | |
63 | #define NCU_ADDR_IOCMD_FLD 28 | |
64 | ||
65 | #define NCU_BASE_ADDR_IOCFG_FLD 0 | |
66 | #define NCU_BASE_ADDR_MEM32_FLD 1 | |
67 | #define NCU_BASE_ADDR_MEM64_FLD 2 | |
68 | ||
69 | // PIU register Addresses | |
70 | #define PIU_EQ_BASE_ADDRESS_REG_ADDR 24'h610000 | |
71 | #define PIU_EQ_TAIL_REG_ADDR 24'h611600 | |
72 | #define PIU_EQ_HEAD_REG_ADDR 24'h611800 | |
73 | #define PIU_MSI_MAPPING_REG_ADDR 24'h620000 | |
74 | #define PIU_MSI_MAPPING_REG_ADDR 24'h620000 | |
75 | #define PIU_MSI_CLEAR_REG_ADDR 24'h628000 | |
76 | ||
77 | #define PIU_MSI_32_ADDRESS_REG_ADDR 24'h634000 | |
78 | #define PIU_MSI_64_ADDRESS_REG_ADDR 24'h634008 | |
79 | #define PIU_PCIE_64_OFFSET_REGISTER_ADDR 24'h634018 | |
80 | ||
81 | #define PIU_IOMMU_CONTROL_REGISTER_ADDR 24'h640000 | |
82 | #define PIU_IOMMU_TSB_CNTRL_REGISTER_ADDR 24'h640008 | |
83 | #define PIU_IOMMU_DEV2IOTSB_REGISTER_ADDR 24'h649000 | |
84 | #define PIU_IOMMU_IOTSBDESC_REGISTER_ADDR 24'h649100 | |
85 | ||
86 | #define PIU_DMU_PCIE_CONFIG_REGISTER_ADDR 24'h653100 | |
87 | ||
88 | #define PIU_PEU_PME_TURN_OFF_REGISTER_ADDR 24'h680010 | |
89 | #define PIU_PEU_INGRESS_INITIAL_CREDITS_REGISTER_ADDR 24'h680018 | |
90 | ||
91 | #define PIU_PEU_DEV_CNTRL_REGISTER_ADDR 24'h690008 | |
92 | #define PIU_PEU_SLOT_CAPABILITIES_REG_ADDR 24'h690030 | |
93 | ||
94 | ||
95 | // PIU register fields | |
96 | #define PCIE_64_OFFSET__FLD 63:24 | |
97 | #define MPS__FLD 7:5 | |
98 | ||
99 | ||
100 | extern integer asm2peu_mbox; | |
101 | ||
102 | ||
103 | class N2fcXactionProbe { | |
104 | PEUTestEnv env; | |
105 | ||
106 | ilupeuScenario Scenario; | |
107 | ||
108 | bit [63:0] ncuMem32Base; | |
109 | bit [63:0] ncuMem32Mask; | |
110 | ||
111 | bit [63:0] ncuMem64Base; | |
112 | bit [63:0] ncuMem64Mask; | |
113 | ||
114 | bit [63:0] ncuIoconBase; | |
115 | bit [63:0] ncuIoconMask; | |
116 | ||
117 | bit DtmMode; | |
118 | bit IgnorePMETurnOff; | |
119 | ||
120 | task new (ilupeuScenario a_Scenario); | |
121 | task setenv (PEUTestEnv a_env); | |
122 | task monitorNcuPioVld (); | |
123 | task monitorCcuSerdesDtm (); | |
124 | task monitorWarmReset (); | |
125 | ||
126 | task ncuAccess (bit [129:0] dat); | |
127 | task capturePioParams (bit [129:0] dat); | |
128 | task piuAccess (bit [129:0] dat); | |
129 | } | |
130 | ||
131 | ||
132 | task N2fcXactionProbe::new (ilupeuScenario a_Scenario) { | |
133 | ||
134 | Scenario = a_Scenario; | |
135 | DtmMode = 0; | |
136 | IgnorePMETurnOff = 0; | |
137 | ||
138 | fork | |
139 | monitorNcuPioVld(); | |
140 | monitorCcuSerdesDtm(); | |
141 | monitorWarmReset(); | |
142 | join none | |
143 | } | |
144 | ||
145 | ||
146 | task N2fcXactionProbe::setenv (PEUTestEnv a_env) { | |
147 | env = a_env; | |
148 | } | |
149 | ||
150 | ||
151 | task N2fcXactionProbe::monitorNcuPioVld () { | |
152 | bit [129:0] dat; | |
153 | ||
154 | while (1) { | |
155 | if (pcx_ncu_bind.$vld == 1'b1) { | |
156 | repeat (1) @ (posedge pcx_ncu_bind.$clk); // data rdy 1 clock later | |
157 | dat = pcx_ncu_bind.$dat; | |
158 | ||
159 | if (dat[103:100] == 4'hc) capturePioParams (dat); | |
160 | else if (dat[103: 96] == 8'h80) ncuAccess (dat); | |
161 | else if (dat[103: 96] == 8'h88) piuAccess (dat); | |
162 | } | |
163 | else { | |
164 | repeat (1) @ (posedge pcx_ncu_bind.$clk); | |
165 | } | |
166 | } | |
167 | } | |
168 | ||
169 | ||
170 | task N2fcXactionProbe::monitorCcuSerdesDtm () { | |
171 | integer WaitClocks = 16; | |
172 | ||
173 | N2fcPEUparams params = new (); | |
174 | ||
175 | if(probe_if.start_dtm_at_ccu_serdes_dtm) { | |
176 | // wait for ccu_serdes_dtm to be asserted | |
177 | @ (posedge probe_if.ccu_serdes_dtm); | |
178 | ||
179 | // wait for rst_ncu_unpark_thread to be asserted | |
180 | @ (posedge probe_if.rst_ncu_unpark_thread); | |
181 | ||
182 | ||
183 | if (get_plus_arg(CHECK, "pcie_dtm_clocks=")) { | |
184 | WaitClocks = get_plus_arg(NUM, "pcie_dtm_clocks="); | |
185 | } | |
186 | repeat (WaitClocks) @ (posedge random_rst_if.clk); // driven by tb_top.SYSCLK | |
187 | } else { | |
188 | @ (posedge probe_if.start_peu_dtm_training); | |
189 | } | |
190 | ||
191 | printf ("-%0d-UDEBUG:monitorCcuSerdesDtm : sending STARTDTM message\n", get_time(LO)); | |
192 | ||
193 | params.cmdType = "STARTDTM"; | |
194 | mailbox_put(asm2peu_mbox, params); | |
195 | ||
196 | DtmMode = 1; | |
197 | ||
198 | // SLAM_VECTORS no longer forces the bypass enable bit on | |
199 | //if (get_plus_arg(CHECK, "SLAM_VECTORS")) { | |
200 | // PiuCsrs.IoMmuControl = 2; | |
201 | // printf ("\nN2fcXactionProbe : PIU MMU CONTROL updated to %0h\n\n", PiuCsrs.IoMmuControl); | |
202 | //} | |
203 | } | |
204 | ||
205 | ||
206 | task N2fcXactionProbe::monitorWarmReset () { | |
207 | N2fcPEUparams params = new (); | |
208 | ||
209 | sync (ALL, e_StartPEUTest); | |
210 | printf("-%0d-UDEBUG:monitorWarmReset : Done Waiting for assembly to enable peutest", get_time(LO)); | |
211 | ||
212 | while (1) { | |
213 | // wait for initial flush reset to complete | |
214 | if (probe_if.flush_reset_complete !== 1) @(posedge probe_if.flush_reset_complete); | |
215 | ||
216 | // wait for warm reset to be asserted | |
217 | printf ("-%0d-UDEBUG:monitorWarmReset : waiting for warm reset\n", get_time(LO)); | |
218 | @ (negedge if_ILU_PEU.j2d_rst_l); | |
219 | ||
220 | printf ("-%0d-UDEBUG:monitorWarmReset : sending SOFTRESET message\n", get_time(LO)); | |
221 | ||
222 | params.cmdType = "SOFTRESET"; | |
223 | mailbox_put(asm2peu_mbox, params); | |
224 | ||
225 | // wait for warm reset to finish | |
226 | @ (posedge if_ILU_PEU.j2d_rst_l); | |
227 | } | |
228 | } | |
229 | ||
230 | ||
231 | //---------------------------------------------------------------- | |
232 | // Enable PCIe endpoint to expect a request from N2. | |
233 | // This routine, called from the Assembly via a user event, | |
234 | // triggers 1 Egress Command from N2. | |
235 | // Since the Denali end-point errors on un-expected packets, | |
236 | // it must be notified everytime N2 sends it a packet. | |
237 | // | |
238 | // cmdType: Type of command to transmit | |
239 | // CFGRD0 = Config Read Type 0 | |
240 | // CFGRD1 = Config Read Type 1 | |
241 | // CFGWR0 = Config Write Type 0 | |
242 | // CFGWR1 = Config Write Type 1 | |
243 | // IORD = I/O Read | |
244 | // IOWR = I/O Write | |
245 | // MRD = Memory Read | |
246 | // MWR = Memory Write | |
247 | // | |
248 | // addr: Request Address | |
249 | // | |
250 | // txLen: Request length in bytes. | |
251 | // | |
252 | //---------------------------------------------------------------- | |
253 | ||
254 | task N2fcXactionProbe::capturePioParams (bit [129:0] dat) { | |
255 | ||
256 | string cmdType = ""; | |
257 | bit [63:0] addr = 64'b0; | |
258 | bit [7:0] txLen = 8'b0; | |
259 | bit rdCmd = 1'b0; | |
260 | bit [1:0] cmd; | |
261 | bit [5:0] tid = 6'b0; | |
262 | ||
263 | ||
264 | N2fcPEUparams PEUparams = new (); | |
265 | ||
266 | ||
267 | // is this a read or write command ? | |
268 | // | |
269 | rdCmd = dat[PCX_NCU_RQTYP_FLD] == 5'b00000; | |
270 | ||
271 | addr = dat[PCX_NCU_ADDR_FLD]; | |
272 | ||
273 | if (rdCmd === 1'b1) | |
274 | case (dat[PCX_NCU_SIZE_FLD]) { | |
275 | 8'h00 : txLen = 8'd1; | |
276 | 8'h01 : txLen = 8'd2; | |
277 | 8'h02 : txLen = 8'd4; | |
278 | 8'h03 : txLen = 8'd8; | |
279 | 8'h04 : txLen = 8'd16; | |
280 | } | |
281 | else | |
282 | txLen = dat[PCX_NCU_SIZE_FLD]; | |
283 | ||
284 | tid = dat[PCX_NCU_TID_FLD]; | |
285 | ||
286 | // now determine if this is CFG, IO, or Mem32/64 command | |
287 | // match the base and mask address written into NCU registers | |
288 | // check if the access is enabled | |
289 | // | |
290 | if (ncuIoconBase[NCU_BASE_EN_FLD] === 1'b1) { | |
291 | ||
292 | if ( (ncuIoconMask[NCU_PCIE_CFGADDR_CMP_FLD] & addr[NCU_PCIE_CFGADDR_CMP_FLD]) === | |
293 | ncuIoconBase[NCU_PCIE_CFGADDR_CMP_FLD]) { | |
294 | cmd = (addr[NCU_ADDR_IOCMD_FLD] === 1'b1) ? 2'b01 : 2'b00; | |
295 | printf ("\n-%0d-UDEBUG:capturePioParams : address %0h matched CFGIO region, %s %h Tid %h\n\n", get_time(LO), addr, rdCmd ? "Rd Len":"Wr Bmsk", txLen, tid); | |
296 | PEUparams.BaseAddr = PiuCsrs.ncuBaseAddr[NCU_BASE_ADDR_IOCFG_FLD]; | |
297 | } | |
298 | } | |
299 | if (ncuMem32Base[NCU_BASE_EN_FLD] === 1'b1) { | |
300 | if ( (ncuMem32Mask[NCU_PCIE_MEMADDR_CMP_FLD] & addr[NCU_PCIE_MEMADDR_CMP_FLD]) === | |
301 | ncuMem32Base[NCU_PCIE_MEMADDR_CMP_FLD]) { | |
302 | cmd = 2'b10; | |
303 | printf ("\n-%0d-UDEBUG:capturePioParams : address %0h matched MEM32 region, %s %h Tid %h\n\n", get_time(LO), addr, rdCmd ? "Rd Len":"Wr Bmsk", txLen, tid); | |
304 | PEUparams.BaseAddr = PiuCsrs.ncuBaseAddr[NCU_BASE_ADDR_MEM32_FLD]; | |
305 | } | |
306 | } | |
307 | if (ncuMem64Base[NCU_BASE_EN_FLD] === 1'b1) { | |
308 | if ( (ncuMem64Mask[NCU_PCIE_MEMADDR_CMP_FLD] & addr[NCU_PCIE_MEMADDR_CMP_FLD]) === | |
309 | ncuMem64Base[NCU_PCIE_MEMADDR_CMP_FLD]) { | |
310 | cmd = 2'b11; | |
311 | printf ("\n-%0d-UDEBUG:capturePioParams : address %0h matched MEM64 region, %s %h Tid %h\n\n", get_time(LO), addr, rdCmd ? "Rd Len":"Wr Bmsk", txLen, tid); | |
312 | PEUparams.BaseAddr = PiuCsrs.ncuBaseAddr[NCU_BASE_ADDR_MEM64_FLD]; | |
313 | } | |
314 | } | |
315 | ||
316 | PEUparams.Pcie64Offset = PiuCsrs.piuPcie64Offset; // needed for MEM64 rd/wr | |
317 | ||
318 | case (cmd) { | |
319 | 2'b00 : { | |
320 | if (addr[27:20] == 8'h00) cmdType = rdCmd ? "CFGRD0" : "CFGWR0"; | |
321 | else cmdType = rdCmd ? "CFGRD1" : "CFGWR1"; | |
322 | } | |
323 | 2'b01 : cmdType = rdCmd ? "IORD" : "IOWR"; | |
324 | 2'b10 : cmdType = rdCmd ? "MRD" : "MWR"; | |
325 | 2'b11 : cmdType = rdCmd ? "MEM64RD" : "MEM64WR"; | |
326 | ||
327 | default : { | |
328 | printf ("N2fcXactionProbe::capturePioParams unknown cmd = %0h, A = %0h, D = %0h, en %b %b %b\n\n", | |
329 | cmd, addr[35:0], dat[PCX_NCU_DATA_FLD], ncuIoconBase[NCU_BASE_EN_FLD], ncuMem32Base[NCU_BASE_EN_FLD], ncuMem64Base[NCU_BASE_EN_FLD]); | |
330 | return; | |
331 | } | |
332 | } | |
333 | ||
334 | PEUparams.cmdType = cmdType; | |
335 | PEUparams.addr = addr; | |
336 | PEUparams.txLen = txLen; | |
337 | PEUparams.startData = dat[PCX_NCU_DATA_FLD]; | |
338 | PEUparams.err = ""; | |
339 | ||
340 | mailbox_put (asm2peu_mbox, PEUparams); | |
341 | } | |
342 | ||
343 | ||
344 | ||
345 | ||
346 | //---------------------------------------------------------------- | |
347 | ||
348 | task N2fcXactionProbe::ncuAccess (bit [129:0] dat) { | |
349 | ||
350 | bit [63:0] addr = 64'b0; | |
351 | bit rdCmd = 1'b0; | |
352 | ||
353 | ||
354 | rdCmd = dat[PCX_NCU_RQTYP_FLD] == 5'b00000; | |
355 | addr = dat[PCX_NCU_ADDR_FLD]; | |
356 | ||
357 | if (rdCmd === 1'b0) { | |
358 | case (addr[15:0]) { | |
359 | NCU_PCIE_MEM32_BASE_ADDR : { | |
360 | ncuMem32Base = dat[PCX_NCU_DATA_FLD]; | |
361 | PiuCsrs.ncuBaseAddr[NCU_BASE_ADDR_MEM32_FLD] = {1'b0, ncuMem32Base[62:0]}; // do not store EN bit | |
362 | printf ("\nN2fcXactionProbe : NCU MEM32 BASE updated to %0h\n\n", ncuMem32Base); | |
363 | } | |
364 | NCU_PCIE_MEM32_MASK_ADDR : { | |
365 | ncuMem32Mask = dat[PCX_NCU_DATA_FLD]; | |
366 | printf ("\nN2fcXactionProbe : NCU MEM32 MASK updated to %0h\n\n", ncuMem32Mask); | |
367 | } | |
368 | NCU_PCIE_MEM64_BASE_ADDR : { | |
369 | ncuMem64Base = dat[PCX_NCU_DATA_FLD]; | |
370 | PiuCsrs.ncuBaseAddr[NCU_BASE_ADDR_MEM64_FLD] = {1'b0, ncuMem64Base[62:0]}; // do not store EN bit | |
371 | printf ("\nN2fcXactionProbe : NCU MEM64 BASE updated to %0h\n\n", ncuMem64Base); | |
372 | } | |
373 | NCU_PCIE_MEM64_MASK_ADDR : { | |
374 | ncuMem64Mask = dat[PCX_NCU_DATA_FLD]; | |
375 | printf ("\nN2fcXactionProbe : NCU MEM64 MASK updated to %0h\n\n", ncuMem64Mask); | |
376 | } | |
377 | NCU_PCIE_IOCON_BASE_ADDR : { | |
378 | ncuIoconBase = dat[PCX_NCU_DATA_FLD]; | |
379 | PiuCsrs.ncuBaseAddr[NCU_BASE_ADDR_IOCFG_FLD] = {1'b0, ncuIoconBase[62:0]}; // do not store EN bit | |
380 | printf ("\nN2fcXactionProbe : NCU IOCON BASE updated to %0h\n\n", ncuIoconBase); | |
381 | } | |
382 | NCU_PCIE_IOCON_MASK_ADDR : { | |
383 | ncuIoconMask = dat[PCX_NCU_DATA_FLD]; | |
384 | printf ("\nN2fcXactionProbe : NCU IOCON MASK updated to %0h\n\n", ncuIoconMask); | |
385 | } | |
386 | default : { /* empty */ } | |
387 | } | |
388 | } | |
389 | } | |
390 | ||
391 | ||
392 | ||
393 | //---------------------------------------------------------------- | |
394 | ||
395 | task N2fcXactionProbe::piuAccess (bit [129:0] dat) { | |
396 | ||
397 | bit [63:0] addr = 64'b0; | |
398 | bit [63:0] data = 64'b0; | |
399 | bit rdCmd = 1'b0; | |
400 | ||
401 | bit [ FNX_PCIE_XTR_REG_DEN_WIDTH-1:0 ] denRegTmpData; | |
402 | bit [1:0] D3 = 3; | |
403 | bit [23:0] RegAddr; | |
404 | bit [11:0] RegIndex; | |
405 | ||
406 | rdCmd = dat[PCX_NCU_RQTYP_FLD] == 5'b00000; | |
407 | addr = dat[PCX_NCU_ADDR_FLD]; | |
408 | ||
409 | if (rdCmd === 1'b0) { | |
410 | case (addr[23:0]) { | |
411 | PIU_EQ_BASE_ADDRESS_REG_ADDR : { | |
412 | PiuCsrs.EQBaseAddr = dat[PCX_NCU_DATA_FLD]; | |
413 | PiuCsrs.EQBaseAddr[18:0] = 0; // zero out lower bits | |
414 | printf ("\nN2fcXactionProbe : PIU EQ BASE ADDR updated to %0h\n\n", PiuCsrs.EQBaseAddr ); | |
415 | } | |
416 | PIU_PCIE_64_OFFSET_REGISTER_ADDR : { | |
417 | data = dat[PCX_NCU_DATA_FLD]; | |
418 | PiuCsrs.piuPcie64Offset = {data[PCIE_64_OFFSET__FLD], 24'b0}; | |
419 | printf ("\nN2fcXactionProbe : PIU PCIE 64 OFFSET updated to %0h, piomode bits %h\n\n", PiuCsrs.piuPcie64Offset, data[1:0]); | |
420 | } | |
421 | PIU_MSI_32_ADDRESS_REG_ADDR : { | |
422 | PiuCsrs.piuMsi32Address = dat[PCX_NCU_DATA_FLD]; | |
423 | printf ("\nN2fcXactionProbe : PIU MSI 32 ADDRESS updated to %0h\n\n", PiuCsrs.piuMsi32Address); | |
424 | } | |
425 | PIU_MSI_64_ADDRESS_REG_ADDR: { | |
426 | PiuCsrs.piuMsi64Address = dat[PCX_NCU_DATA_FLD]; | |
427 | printf ("\nN2fcXactionProbe : PIU MSI 64 ADDRESS updated to %0h\n\n", PiuCsrs.piuMsi64Address); | |
428 | } | |
429 | PIU_IOMMU_CONTROL_REGISTER_ADDR: { | |
430 | PiuCsrs.IoMmuControl = dat[PCX_NCU_DATA_FLD]; | |
431 | printf ("\nN2fcXactionProbe : PIU MMU CONTROL updated to %0h\n\n", PiuCsrs.IoMmuControl); | |
432 | } | |
433 | ||
434 | PIU_IOMMU_TSB_CNTRL_REGISTER_ADDR: { | |
435 | PiuCsrs.IoMmuTsbControl = dat[PCX_NCU_DATA_FLD]; | |
436 | printf ("\nN2fcXactionProbe : PIU MMU TSB CONTROL updated to %0h\n\n", PiuCsrs.IoMmuTsbControl); | |
437 | } | |
438 | ||
439 | PIU_PEU_DEV_CNTRL_REGISTER_ADDR: { | |
440 | data = dat[PCX_NCU_DATA_FLD]; | |
441 | case( data[MPS__FLD] ) { | |
442 | 0: PiuCsrs.piuMaxPayloadSize = 128; | |
443 | 1: PiuCsrs.piuMaxPayloadSize = 256; | |
444 | 2: PiuCsrs.piuMaxPayloadSize = 512; | |
445 | default: printf ("\nN2fcXactionProbe : unsupported/reserved PIU Max Payload Size field(%0h) in PIU_PEU_DEV_CNTRL_REGISTER\n\n", dat[MPS__FLD]); | |
446 | } | |
447 | printf ("\nN2fcXactionProbe : PIU Max Payload Size is %0d\n\n", PiuCsrs.piuMaxPayloadSize); | |
448 | } | |
449 | ||
450 | PIU_DMU_PCIE_CONFIG_REGISTER_ADDR : { | |
451 | data = dat[PCX_NCU_DATA_FLD]; | |
452 | PiuCsrs.piuREQ_ID = data[15:0]; | |
453 | printf ("\nN2fcXactionProbe : PCIE REQ ID updated to 0x%0h\n\n", PiuCsrs.piuREQ_ID); | |
454 | } | |
455 | PIU_PEU_SLOT_CAPABILITIES_REG_ADDR: { | |
456 | printf ("\nN2fcXactionProbe : write to PEU SLOT CAPABILITIES register detected\n\n"); | |
457 | data = dat[PCX_NCU_DATA_FLD]; | |
458 | env.expectEgressMsg( PEC_PCI__MSG_CODE_SET_SLOT_POWER_LIMIT, { 22'b0, data[16:7] } ); | |
459 | } | |
460 | PIU_PEU_PME_TURN_OFF_REGISTER_ADDR: { | |
461 | printf ("\nN2fcXactionProbe : write to PEU PME TURN OFF register detected\n\n"); | |
462 | ||
463 | if( !IgnorePMETurnOff ) { | |
464 | // direct Denali Endpoint to enter D3 state (otherwise test will fail) | |
465 | denRegTmpData = env.Pod.FNXPCIEEnableTrans.ReadDenaliReg( PCIE_REG_PM_ST_CTRL ); | |
466 | denRegTmpData[1:0] = D3; | |
467 | env.Pod.FNXPCIEEnableTrans.WriteDenaliReg(PCIE_REG_PM_ST_CTRL, denRegTmpData); | |
468 | ||
469 | env.expectEgressMsg( PEC_PCI__MSG_CODE_PM_TURN_OFF, 0 ); | |
470 | } | |
471 | } | |
472 | ||
473 | PIU_PEU_INGRESS_INITIAL_CREDITS_REGISTER_ADDR: { | |
474 | data = dat[PCX_NCU_DATA_FLD]; | |
475 | printf ("\nN2fcXactionProbe : write to PEU INGRESS INITIAL CREDITS register detected: %h\n\n", data); | |
476 | ||
477 | Scenario.ilupeuInitialNonPostedHeaderCredit = data[39:32]; | |
478 | Scenario.ilupeuInitialPostedHeaderCredit = data[19:12]; | |
479 | Scenario.ilupeuInitialPostedDataCredit = data[11:0]; | |
480 | ||
481 | printf("N2fcXactionProbe: Scenario.ilupeuInitialPostedHeaderCredit = %d \n", Scenario.ilupeuInitialPostedHeaderCredit); | |
482 | printf("N2fcXactionProbe: Scenario.ilupeuInitialNonPostedHeaderCredit = %d \n", Scenario.ilupeuInitialNonPostedHeaderCredit); | |
483 | printf("N2fcXactionProbe: Scenario.ilupeuInitialPostedDataCredit = %d \n", Scenario.ilupeuInitialPostedDataCredit); | |
484 | ||
485 | if ((Scenario.ilupeuInitialNonPostedHeaderCredit + Scenario.ilupeuInitialPostedHeaderCredit) > 8'h30) { | |
486 | printf("WARNING: NonPostedHeaderCredit+PostedHeaderCredit exceeds 8'h30\n"); | |
487 | } | |
488 | if (Scenario.ilupeuInitialPostedDataCredit > 8'hc0) { | |
489 | printf("WARNING: PostedDataCredit exceeds 8'hc0\n"); | |
490 | } | |
491 | } | |
492 | ||
493 | default : { | |
494 | RegAddr = PIU_EQ_TAIL_REG_ADDR; | |
495 | if (addr[23:9] == RegAddr[23:9]) { | |
496 | RegIndex = addr[8:3]; | |
497 | data = dat[PCX_NCU_DATA_FLD]; | |
498 | PiuCsrs.EQTail[RegIndex] = data[6:0]; | |
499 | printf ("\nN2fcXactionProbe : write to EQ TAIL[%d] register detected, data=%h\n\n", RegIndex, PiuCsrs.EQTail[RegIndex]); | |
500 | } | |
501 | else { | |
502 | RegAddr = PIU_EQ_HEAD_REG_ADDR; | |
503 | if (addr[23:9] == RegAddr[23:9]) { | |
504 | RegIndex = addr[8:3]; | |
505 | data = dat[PCX_NCU_DATA_FLD]; | |
506 | PiuCsrs.EQHead[RegIndex] = data[6:0]; | |
507 | printf ("\nN2fcXactionProbe : write to EQ HEAD[%d] register detected, data=%h\n\n", RegIndex, PiuCsrs.EQHead[RegIndex]); | |
508 | } | |
509 | else { | |
510 | RegAddr = PIU_MSI_MAPPING_REG_ADDR; | |
511 | if (addr[23:11] == RegAddr[23:11]) { | |
512 | RegIndex = addr[10:3]; | |
513 | PiuCsrs.MSIMapping[RegIndex] = dat[PCX_NCU_DATA_FLD]; | |
514 | printf ("\nN2fcXactionProbe : write to MSI MAPPING[%d] register detected, data=%h\n\n", RegIndex, PiuCsrs.MSIMapping[RegIndex]); | |
515 | } | |
516 | else { | |
517 | RegAddr = PIU_MSI_CLEAR_REG_ADDR; | |
518 | if (addr[23:11] == RegAddr[23:11]) { | |
519 | RegIndex = addr[10:3]; | |
520 | data = dat[PCX_NCU_DATA_FLD]; | |
521 | printf ("\nN2fcXactionProbe : write to MSI CLEAR[%d] register detected, data=%h\n\n", RegIndex, data); | |
522 | if(data[62]) { | |
523 | PiuCsrs.ClearMsiEqWr(RegIndex); | |
524 | } | |
525 | } | |
526 | else { | |
527 | RegAddr = PIU_IOMMU_DEV2IOTSB_REGISTER_ADDR; | |
528 | if (addr[23:7] == RegAddr[23:7]) { | |
529 | RegIndex = addr[6:3]; | |
530 | data = dat[PCX_NCU_DATA_FLD]; | |
531 | printf ("\nN2fcXactionProbe : write to DEV2IOTSB[%d] register detected, data=%h\n\n", RegIndex, data); | |
532 | PiuCsrs.IoMmuDev2Iotsb[RegIndex] = data; | |
533 | } | |
534 | else { | |
535 | RegAddr = PIU_IOMMU_IOTSBDESC_REGISTER_ADDR; | |
536 | if (addr[23:8] == RegAddr[23:8]) { | |
537 | RegIndex = addr[7:3]; | |
538 | data = dat[PCX_NCU_DATA_FLD]; | |
539 | printf ("\nN2fcXactionProbe : write to IOTSBDESC[%d] register detected, data=%h\n\n", RegIndex, data); | |
540 | PiuCsrs.IoMmuIoTsbDesc[RegIndex] = data; | |
541 | } | |
542 | } | |
543 | } | |
544 | } | |
545 | } | |
546 | } | |
547 | } | |
548 | } | |
549 | } | |
550 | } |