Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / legion / src / devices / mem_bus / libpiu / piu.c
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: piu.c
5* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
6* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
7*
8* The above named program is free software; you can redistribute it and/or
9* modify it under the terms of the GNU General Public
10* License version 2 as published by the Free Software Foundation.
11*
12* The above named program is distributed in the hope that it will be
13* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15* General Public License for more details.
16*
17* You should have received a copy of the GNU General Public
18* License along with this work; if not, write to the Free Software
19* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20*
21* ========== Copyright Header End ============================================
22*/
23/*
24 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
26 */
27
28#pragma ident "@(#)piu.c 1.15 07/09/19 SMI"
29
30#include <stdio.h>
31#include <stdlib.h>
32#include <unistd.h>
33#include <fcntl.h>
34#include <sys/types.h>
35#include <sys/stat.h>
36#include <sys/mman.h>
37#include <errno.h>
38#include <fcntl.h>
39#include <sys/dkio.h>
40#include <sys/dklabel.h>
41#include <sys/vtoc.h>
42#include <strings.h>
43
44#include "basics.h"
45#include "allocate.h"
46#include "lexer.h"
47#include "simcore.h"
48#include "config.h"
49#include "dumpinfo.h"
50#include "strutil.h"
51#include "fatal.h"
52#include "tsparcv9internal.h"
53#include "sparcv9regs.h"
54#include "device.h"
55#include "pcie_device.h"
56#include "piu.h"
57
58static void piu_parse(config_dev_t *);
59static void piu_init(config_dev_t *);
60static void piu_dump(config_dev_t *);
61void piu_init_csr(pcie_model_t *piup);
62static bool_t piu_cpu_access(simcpu_t *, config_addr_t *,
63 tpaddr_t offset, maccess_t op, uint64_t * regp);
64static void parse_pcie_device(char *devname, config_dev_t *config_devp);
65
66extern dev_type_t *find_dev_type(char * devnamep);
67
68LIST_DEF(dev_child_cache, dev_child_type_t);
69
70#ifdef VFALLS /* { */
71#define PIU_NAME "piu_vf"
72#define PIU_TYPE dev_type_piu_vf
73
74#else
75
76#define PIU_NAME "piu"
77#define PIU_TYPE dev_type_piu
78
79#endif /* } VFALLS */
80
81/*
82 * PIU interfaces exported to legion
83 */
84
85dev_type_t PIU_TYPE={
86 PIU_NAME,
87 piu_parse,
88 piu_init,
89 piu_dump,
90 generic_device_non_cacheable,
91 piu_cpu_access,
92 DEV_MAGIC
93};
94
95/*
96 * Complete the creation and parsing of the PCI Express Interface Unit (PIU).
97 *
98 * The 'piu' directive specifies the address mappings of two noncacheable
99 * regions as below:
100 *
101 * - an 8 MB region for PIO access to the PCIE CSRs within PIU
102 *
103 * - an 64 GB region that maps to sub-regions for
104 *
105 * * PCIE Cfg/IO
106 * * PCIE MEM32
107 * * PCIE MEM64
108 *
109 * It also supports a 'pcie_device' directive which is used to define each PCIE
110 * device connected to piu.
111 *
112 * For Niagara2, the format in the conf file is as follows:
113 *
114 * device "piu"
115 * 0x8800000000 + 8M,
116 * 0xC000000000 + 64G
117 * {
118 * pcie_device "dev_name" <pcie device properties>;
119 * }
120 *
121 */
122void piu_parse(config_dev_t *config_devp)
123{
124 pcie_model_t *piup;
125 lexer_tok_t tok;
126 char *proc_type_namep;
127
128 DBGDEV( lprintf(-1, "piu_parse: parsing device %d\n", config_devp->device_id); );
129
130 piup = (void *)Xcalloc(1, pcie_model_t);
131
132 proc_type_namep = LIST_ENTRY(config_devp->domainp->procs, 0)->proc_typep->proc_type_namep;
133 piup->proc_type_namep = strdup(proc_type_namep);
134
135 config_devp->devp = (void *)piup;
136
137 /*
138 * For N2 case where the node id is zero, and is not parsed from the
139 * config file.
140 */
141 if (!(piup->config_procp))
142 piup->config_procp = LIST_ENTRY(config_devp->domainp->procs, 0);
143 /*
144 * Continue parsing the 'piu' directive
145 */
146 tok = lex_get_token();
147 switch(tok) {
148 case T_S_Colon:
149 return; /* nothing more to parse */
150 case T_L_Brace:
151 break; /* must be a pcie_device, so continue */
152 default:
153 lex_fatal("expecting either ; or Left Brace when parsing PIU");
154 }
155
156 /*
157 * We've found a Left Brace so lets continue the parsing - should find a
158 * pcie_device
159 */
160 do {
161 tok = lex_get_token();
162
163 if (tok == T_R_Brace) break; /* We're done */
164
165 if (tok != T_Token)
166 lex_fatal("expected pcie_device directive when parsing piu");
167#ifdef VFALLS /* { */
168 if (streq(lex.strp, "node_id")) {
169 int idx;
170
171 lex_get(T_Number);
172 NODE2IDX(lex.val, config_devp->domainp, idx);
173 piup->config_procp = LIST_ENTRY(config_devp->domainp->procs, idx);
174
175 DBGDEV(lprintf(-1, "PIU addresses %llx to %llx assigned to nodeid %d\n",
176 config_devp->addrp->baseaddr, config_devp->addrp->topaddr, lex.val););
177 lex_get(T_S_Colon);
178
179 } else
180 if (streq(lex.strp, "dmu_local")) {
181 tpaddr_t baseaddr, topaddr;
182 bool_t is_size;
183 static bool_t ins_once = false;
184
185 lex_get(T_Number);
186 baseaddr = lex.val;
187
188 is_size = false;
189 tok = lex_get_token();
190 if (tok == T_Plus) is_size = true; else lex_unget();
191
192 lex_get(T_Number);
193 topaddr = lex.val;
194 if (is_size)
195 topaddr += baseaddr;
196
197 if (topaddr <= baseaddr)
198 lex_fatal("top address <= base address with device %s",
199 config_devp->dev_typep->dev_type_namep);
200 if (!ins_once) {
201 /* only need to do this once since same local address for all nodes */
202 insert_domain_address(config_devp->domainp, config_devp, baseaddr, topaddr);
203 ins_once = true;
204 }
205 lex_get(T_S_Colon);
206
207 } else
208
209#endif /* } VFALLS */
210 /* Check if we've found a pcie_device */
211 if (streq(lex.strp, "pcie_device")) {
212 char *pcie_dev_name;
213
214 /*
215 * Now parse the name of the PCIE device
216 */
217 tok = lex_get_token();
218 switch (tok) {
219 case T_String:
220 pcie_dev_name = Xstrdup(lex.strp);
221 break;
222 default:
223 lex_fatal("Expected a pcie_device name directive");
224 }
225
226 /*
227 * We've found a PCIE device and we got it's name, so
228 * lets locate the library for that device and let it
229 * continue parsing.
230 */
231
232 DBGDEV( lprintf(-1, "piu_parse: found a [%s] device\n", pcie_dev_name); );
233
234 parse_pcie_device(pcie_dev_name, config_devp);
235
236 lex_get(T_S_Colon);
237 continue;
238 }
239
240 } while (1);
241}
242
243
244static struct pcie_upbound piu_up = {
245 piu_dma_access,
246 piu_assert_intx,
247 piu_deassert_intx
248};
249
250/*
251 * We've found a pcie_device within the 'piu' directive, so we need to
252 * locate the library for that device. The PCIE device is implemented by
253 * the use of a new device type, 'pcie_dev_type_t', which is an extended
254 * format from the existing DEV_TYPE.
255 */
256static void
257parse_pcie_device(char *devnamep, config_dev_t *config_devp)
258{
259 pcie_dev_type_t *pcie_dev_typep = NULL;
260 pcie_dev_inst_t *pcie_dev_instp = NULL;
261 pcie_dwbound_t *pcie_dp = NULL;
262 dev_child_type_t *childp = NULL;
263 pcie_model_t *piup;
264
265 piup = (pcie_model_t *)config_devp->devp;
266
267 /*
268 * Load PCIE end point device model
269 */
270 pcie_dev_typep = (pcie_dev_type_t*)find_dev_type(devnamep);
271 if (pcie_dev_typep == NULL) {
272 DBGDEV( lprintf(-1, "Error! Cannot find device for [%s]\n", devnamep); );
273 return;
274 }
275
276 pcie_dev_instp = xmalloc(sizeof(*pcie_dev_instp), __LINE__, __FILE__);
277 if (pcie_dev_instp == NULL) {
278 perror("couldn't allocate memory for pcie_dev_instp");
279 exit(-10);
280 }
281 pcie_dev_instp->pcie_modp = piup;
282
283 /*
284 * Export PIU internal functions through the pcie_access_t interface
285 * to support upbound transactions (from PCIE end device to PIU)
286 */
287 pcie_dev_instp->pcie_up = &piu_up;
288
289 /*
290 * Init this PCIE device
291 */
292 pcie_dev_typep->dev_init(pcie_dev_instp);
293
294 /*
295 * Call the device specific parse routine to continue parsing the conf file
296 */
297 pcie_dev_typep->dev_parse(pcie_dev_instp->hdl);
298
299 /*
300 * Register this PCIE device with the piu model
301 */
302 piu_register_pcie_device(piup, pcie_dev_instp);
303
304 /*
305 * Create a global list for dev_child_cache and each entry
306 * contains a pointer to the device_id of the PCIE end device
307 * connected to the PIU model.
308 */
309 childp = (dev_child_type_t *)xmalloc(sizeof(dev_child_type_t), __LINE__, __FILE__);
310 if (childp == NULL) {
311 perror("couldn't allocation memory for dev_child_type_t");
312 exit(-10);
313 }
314
315 childp->child_devicep = (void *)pcie_dev_instp;
316 childp->parent_device_id = config_devp->device_id;
317
318 LIST_ADD_PTR(dev_child_cache, dev_child_type_t, childp);
319}
320
321/*
322 * Initialize the PIU model after parsing is complete
323 */
324void piu_init(config_dev_t *config_devp)
325{
326 pcie_model_t *piup;
327
328 LIST_INIT(dev_child_cache, dev_child_type_t);
329
330 piup = (pcie_model_t *)config_devp->devp;
331 piup->config_devp = config_devp;
332
333 /*
334 * init PIU CSR with power on reset
335 */
336 piu_init_csr(piup);
337
338 /*
339 * init error lookup table
340 */
341 piu_init_error_list();
342}
343
344
345/*
346 * Piu configuration dump
347 */
348void piu_dump(config_dev_t * config_devp)
349{
350}
351
352
353/*
354 * Initialize PIU CSR with power on reset value
355 */
356void piu_init_csr(pcie_model_t *piup)
357{
358 piu_csr_t *csrs = &piup->csrs;
359 int i, nwords;
360
361 nwords = pcie_csrs[PIU_Event_Queue_State_Register].nwords;
362 for (i = 0; i < nwords; i++)
363 csrs->Event_Queue_State_Register[i] = EQ_IDLE;
364
365}
366
367
368/*
369 * Access PIU (downbound)
370 */
371bool_t piu_cpu_access(simcpu_t *sp, config_addr_t *cap, tpaddr_t offset, maccess_t memop, uint64_t *regp)
372{
373 pcie_model_t *piup;
374 bool_t cfgio,status;
375 piu_region_t region;
376 uint32_t count;
377 uint64_t addr, pa = cap->baseaddr + offset;
378 int node_id = 0;
379
380#ifdef VFALLS /* { */
381 domain_t *domainp;
382 int idx;
383
384 /*
385 * VF PIU ADDRESS MAP
386 * ------------------
387 *
388 * Single Node Config
389 * ------------------
390 *
391 * ACCESS DMU PCI-Express Space
392 * ---------------------------------------------------------------------
393 * Node 0 0x88.0000.0000 + 8M 0xC0.0000.0000 - 0xCF.FFFF.FFFF(64GB)
394 *
395 * Multinode config
396 * ---------------
397 *
398 * ACCESS DMU PCI-Express Space
399 * ---------------------------------------------------------------------
400 * Local 0x88.0000.0000 + 8M none
401 * Node 0 0xD2.0000.0000 + 8M 0xC0.0000.0000 - 0xC3.FFFF.FFFF(16GB)
402 * Node 1 0xD6.0000.0000 + 8M 0xC4.0000.0000 - 0xC7.FFFF.FFFF(16GB)
403 * Node 2 0xDA.0000.0000 + 8M 0xC8.0000.0000 - 0xCB.FFFF.FFFF(16GB)
404 * Node 3 0xDE.0000.0000 + 8M 0xCC.0000.0000 - 0xCF.FFFF.FFFF(16GB)
405 */
406
407 domainp = sp->config_procp->domainp;
408 if (domainp->procs.count > 1) {
409
410 /*
411 * If local DMU CSR access, need to convert to Node X(this node) DMU CSR
412 * address.
413 * Use the simcpu to get the correct node_id and then get the correct cap
414 */
415 if (cap->baseaddr == PHYS_ADDR_DMU) {
416 node_id = sp->config_procp->proc_id;
417 pa = PHYS_ADDR_DMU_REMOTE(node_id) + offset;
418 cap = find_domain_address(domainp, pa);
419 }
420 /*
421 * accessing 64GB region which may belong to a single node or divided
422 * into 16GB sections for each node
423 */
424 else if ((PHYS_ADDR_PIU_LB <= cap->baseaddr) && \
425 (((cap->topaddr-1) & PHYS_ADDR_MASK) <= PHYS_ADDR_PIU_UB)) {
426 domainp = cap->config_devp->domainp;
427 /* each node gets 16GB - case where there are multiple nodes */
428 for (idx = 0; idx<domainp->procs.count; idx++) {
429 node_id = LIST_ENTRY(domainp->procs, idx)->proc_id;
430 if (cap->baseaddr == PHYS_ADDR_PIU_REMOTE(node_id))
431 break;
432 }
433
434 /*
435 * to catch case where trying to access address space
436 * of a node that is not populated
437 */
438 if (idx == domainp->procs.count)
439 fatal("PIU access to pa %llx failed. Parent "
440 "node for this address not present.\n",pa);
441 }
442
443 /*
444 * If remote DMU CSR access, use cap to get at the node_id.
445 */
446 else {
447 domainp = cap->config_devp->domainp;
448 for (idx = 0; idx<domainp->procs.count ; idx++) {
449 node_id = LIST_ENTRY(domainp->procs, idx)->proc_id;
450 if (cap->baseaddr == PHYS_ADDR_DMU_REMOTE(node_id))
451 break;
452 }
453
454 /*
455 * to catch case where trying to access address space
456 * of a node that is not populated
457 */
458 if (idx == domainp->procs.count)
459 fatal("PIU Access to pa %llx failed. Parent "
460 "node for this address not present.\n");
461 }
462 }
463
464#endif /* } VFALLS */
465
466 piup = (pcie_model_t *) cap->config_devp->devp;
467
468 /*
469 * N2 PIU only supports 1,2,4 and 8-byte aligned PIO access the 64GB region
470 * and 8-byte to the CSRs in the 8MB region (section 16.3.2.1, N2 PRM Rev. 1.0)
471 */
472 switch(memop & MA_Size_Mask) {
473 case MA_Size8 :
474 count = 1;
475 break;
476 case MA_Size16 :
477 count = 2;
478 break;
479 case MA_Size32 :
480 count = 4;
481 break;
482 case MA_Size64 :
483 count = 8;
484 break;
485 default:
486 ASSERT(0);
487 }
488
489 region = piu_decode_region(sp, piup, pa, &addr);
490
491 switch (region) {
492 case PIU_REGION_CFGIO:
493 cfgio = GETMASK64(addr, 28, 28);
494
495 if (count == 8) {
496 DBGDEV( lprintf(sp->gid, "ERROR: illegal 8 byte access to PCI "
497 "Cfg/IO addr = 0x%llx\n on node %d", addr, node_id); );
498 return false;
499 }
500
501 if (cfgio) {
502 uint64_t ioaddr = addr & PCIE_IO_ADDR_MASK;
503
504 status = piu_io_access(piup, memop, ioaddr, count, regp);
505 } else {
506 status = piu_cfg_access(piup, memop, addr, count, regp);
507 }
508 break;
509 case PIU_REGION_MEM32:
510 status = piu_mem_access(piup, memop, addr, count, regp, PCIE_MEM32);
511 break;
512 case PIU_REGION_MEM64:
513 status = piu_mem_access(piup, memop, addr, count, regp, PCIE_MEM64);
514 break;
515 case PIU_REGION_8MB:
516 status = piu_csr_access(sp, piup, memop, addr, regp);
517 break;
518 default:
519 lprintf(sp->gid, "ERROR: out of range access to PCIE space: "
520 "pc=0x%llx pa=0x%llx on node %d\n", sp->pc, pa, node_id);
521 ASSERT(0);
522 }
523
524 return status;
525}
526
527
528/*
529 * Decode PCIE non-cachable regions
530 *
531 * - 8MB region for CSRs
532 *
533 * - 64GB region partitioned into three subregions as
534 *
535 * * PCIE-A Cfg/IO (512 MB)
536 * * PCIE-A MEM32 (16 MB - 2 GB)
537 * * PCIE-A MEM64 (16 MB - 32 GB)
538 */
539piu_region_t piu_decode_region(simcpu_t *sp, pcie_model_t *piup, uint64_t pa, uint64_t *offset)
540{
541 uint64_t reg_addr = pa & PHYS_ADDR_MASK;
542 int node_id=piup->config_procp->proc_id;
543
544#ifdef VFALLS /* { */
545
546 if ((reg_addr == (PHYS_ADDR_DMU_REMOTE(node_id))) || (reg_addr == (PHYS_ADDR_DMU))) {
547#else
548 if (reg_addr == (PHYS_ADDR_DMU)) {
549#endif /* } VFALLS */
550 if ((pa & DMU_8MB_GAP_MASK) == 0) {
551 *offset = pa & DMU_8MB_OFFSET_MASK;
552 return PIU_REGION_8MB;
553 } else {
554 /* should be a fatal() */
555 lprintf(sp->gid, "ERROR: illegal access to PIU CSRs: "
556 "pc=0x%llx pa=0x%llx on node %d\n",
557 sp->pc, pa, node_id);
558 ASSERT(0);
559 }
560 }
561
562 if ((reg_addr>=PHYS_ADDR_PIU_LB) && (reg_addr<=PHYS_ADDR_PIU_UB)) {
563
564 if (piu_decode_cfgio(piup, pa, offset)) {
565 return PIU_REGION_CFGIO;
566 } else if (piu_decode_mem32(piup, pa, offset)) {
567 return PIU_REGION_MEM32;
568 } else if (piu_decode_mem64(piup, pa, offset)) {
569 return PIU_REGION_MEM64;
570 } else
571 return PIU_REGION_UNMAPPED;
572 }
573}
574
575
576/*
577 * Decode PCIE Cfg/IO region
578 */
579bool_t piu_decode_cfgio(pcie_model_t *piup, uint64_t pa, uint64_t *offset)
580{
581 ncu_t *ncup;
582 map_info_t *map;
583
584 piup->config_procp->proc_typep->get_pseudo_dev(piup->config_procp, "ncu", (void *)&ncup);
585
586 map = &ncup->map[PIU_REGION_CFGIO];
587
588 if (map->enable && ((pa & map->mask) == map->base)) {
589 *offset = pa & PCIE_IOCON_ADDR_MASK;
590 return true;
591 }
592
593 return false;
594}
595
596
597/*
598 * Decode PCIE MEM32 region
599 */
600bool_t piu_decode_mem32(pcie_model_t *piup, uint64_t pa, uint64_t *offset)
601{
602 ncu_t *ncup;
603 map_info_t *map;
604
605 piup->config_procp->proc_typep->get_pseudo_dev(piup->config_procp, "ncu", (void *)&ncup);
606
607 map = &ncup->map[PIU_REGION_MEM32];
608
609 if (map->enable && ((pa & map->mask) == map->base)) {
610 *offset = pa & (map->size - 1);
611 return true;
612 }
613
614 return false;
615}
616
617
618/*
619 * Decode PCIE MEM64 region
620 */
621bool_t piu_decode_mem64(pcie_model_t *piup, uint64_t pa, uint64_t *offset)
622{
623 ncu_t *ncup;
624 map_info_t *map;
625 uint64_t pcie_offset;
626 piu_csr_t *csrs = &piup->csrs;
627
628 piup->config_procp->proc_typep->get_pseudo_dev(piup->config_procp, "ncu", (void *)&ncup);
629
630 map = &ncup->map[PIU_REGION_MEM64];
631
632 if (map->enable && ((pa & map->mask) == map->base)) {
633 uint64_t pcie_offset;
634
635 pcie_offset = csrs->Mem_64_PCIE_Offset_Register;
636
637 *offset = (pa & ~map->mask & PCIE_MEM64_ADDR_MASK) | pcie_offset;
638 return true;
639 }
640
641 return false;
642}
643
644
645/*
646 * Access PCIE CSRs (downbound)
647 */
648bool_t piu_csr_access(simcpu_t *sp, pcie_model_t *piup, maccess_t memop, uint64_t offset, uint64_t *regp)
649{
650 uint64_t old_value, value, new_error, *csrs = (uint64_t *)&piup->csrs;
651 pcie_csr_t index;
652 int size, regx, wordx;
653 char regname[BUFSIZ];
654 int node_id=piup->config_procp->proc_id;
655
656
657 /*
658 * PIU only supports 8-byte accesses to registers
659 */
660 size = memop & MA_Size_Mask;
661 if (size != MA_Size64) return false;
662
663 /*
664 * check illegal offset
665 */
666 index = piu_offset2reg(offset, &regx);
667
668 if (index == UND_PCIE_CSRS) {
669 DBGDEV(lprintf(sp->gid, "Access illegal PCIE register at offset "
670 "= 0x%llx on node %d\n", offset, node_id); );
671 return false;
672 }
673
674 /*
675 * read/write PCIE registers
676 */
677 wordx = regx - pcie_csrs[index].regx;
678
679 strcpy(regname, pcie_csrs[index].name);
680 if (pcie_csrs[index].nwords > 1)
681 sprintf(&regname[strlen(regname)], "[%d]", wordx);
682
683 switch (memop) {
684 case MA_st64:
685 value = *regp;
686 old_value = csrs[regx];
687 /*
688 * check on Read only registers
689 */
690 switch (index) {
691 case PIU_Interrupt_State_Status_Register_1:
692 case PIU_Interrupt_State_Status_Register_2:
693 case PIU_INTX_Status_Register:
694 case PIU_Event_Queue_State_Register:
695 case PIU_IMU_Interrupt_Status_Register:
696 case PIU_DMC_Core_and_Block_Error_Status_Register:
697 case PIU_MMU_Interrupt_Status_Register:
698 case PIU_ILU_Interrupt_Status_Register:
699 case PIU_Packet_Scoreboard_DMA_Register_Set:
700 case PIU_Packet_Scoreboard_PIO_Register_Set:
701 case PIU_Transaction_Scoreboard_Register_Set:
702 case PIU_Transaction_Scoreboard_Status_Register:
703 case PIU_PEU_Egress_Credits_Consumed_Register:
704 case PIU_PEU_Egress_Credit_Limit_Register:
705 case PIU_PEU_Egress_Retry_Buffer_Register:
706 case PIU_PEU_Ingress_Credits_Allocated_Register:
707 case PIU_PEU_Ingress_Credits_Received_Register:
708 case PIU_PEU_Other_Event_Interrupt_Status_Register:
709 case PIU_PEU_Device_Capabilities_Register:
710 case PIU_PEU_Device_Status_Register:
711 case PIU_PEU_Link_Capabilities_Register:
712 case PIU_PEU_Link_Status_Register:
713 case PIU_PEU_Uncorrectable_Error_Interrupt_Status_Register:
714 case PIU_PEU_Correctable_Error_Interrupt_Status_Register:
715 case PIU_PEU_CXPL_SERDES_Revision_Register:
716 case PIU_PEU_CXPL_AckNak_Latency_Timer_Register:
717 case PIU_PEU_CXPL_Replay_Timer_Register:
718 case PIU_PEU_CXPL_Core_Status_Register:
719 case PIU_PEU_CXPL_Event_Error_Interrupt_Status_Register:
720 case PIU_PEU_Link_Bit_Error_Counter_II_Register:
721 case PIU_PEU_SERDES_Receiver_Lane_Status_Register:
722 case PIU_PEU_SERDES_Transmitter_Status_Register:
723 DBGDEV(lprintf(sp->gid, "Error: Write Read-Only Register "
724 "'%s' offset=0x%llx value=0x%llx on node %d\n",
725 pcie_csrs[index].name, offset, *regp, node_id); );
726
727 return false; /* FIXME: should trap on the error */
728 }
729
730 csrs[regx] = *regp;
731
732 DBGDEV(lprintf(sp->gid, "Write PIU register '%s' at offset = "
733 "0x%llx value = 0x%llx on node %d\n",
734 pcie_csrs[index].name, offset, *regp, node_id); );
735 /*
736 * act upon write to reg
737 */
738 switch (index) {
739 case PIU_Interrupt_Clear_Registers:
740 piu_set_irq_state(piup, wordx+INO_INTA, (*regp & MASK64(1,0)));
741 break;
742 case PIU_INT_A_Clear_Register:
743 case PIU_INT_B_Clear_Register:
744 case PIU_INT_C_Clear_Register:
745 case PIU_INT_D_Clear_Register:
746 if (*regp & 1)
747 piu_set_intx_state(piup, index-PIU_INT_A_Clear_Register+INO_INTA, IRQ_IDLE);
748 break;
749 case PIU_Event_Queue_Control_Set_Register:
750 if (value & MASK64(57,57)) {
751 /*
752 * upon ENOVERR set, update the OVERR and STATE field
753 * of the EQ Tail and State register
754 */
755 piup->csrs.Event_Queue_Tail_Register[wordx] |= MASK64(57,57);
756 piup->csrs.Event_Queue_State_Register[wordx] = EQ_ERROR;
757 }
758 if (value & MASK64(44,44))
759 /*
760 * upon EN bit set, update the STATE bit of
761 * the EQ State register
762 */
763 piup->csrs.Event_Queue_State_Register[wordx] = EQ_ACTIVE;
764 break;
765 case PIU_Event_Queue_Control_Clear_Register:
766 if (value & MASK64(57,57))
767 /* COVERR */
768 piup->csrs.Event_Queue_Tail_Register[wordx] &= ~MASK64(57,57);
769 if (value & MASK64(47,47)) {
770 /* E2I */
771 if (piup->csrs.Event_Queue_State_Register[wordx] == EQ_ERROR)
772 piup->csrs.Event_Queue_State_Register[wordx] = EQ_IDLE;
773 }
774 if (value & MASK64(44,44))
775 /* DIS */
776 piup->csrs.Event_Queue_State_Register[wordx] = EQ_IDLE;
777 break;
778 case PIU_Event_Queue_Tail_Register:
779 case PIU_Event_Queue_Head_Register:
780 csrs[regx] = old_value;
781 WRITE_PIU_CSR(csrs[regx], value, MASK64(6,0));
782 break;
783 case PIU_MSI_Mapping_Register:
784 csrs[regx] = old_value;
785 WRITE_PIU_CSR(csrs[regx], value, MASK64(63,62)|MASK64(5,0));
786 break;
787 case PIU_MSI_Clear_Registers:
788 if (value & MASK64(62,62))
789 /* EQWR_N */
790 piup->csrs.MSI_Mapping_Register[wordx] &= ~MASK64(62,62);
791 csrs[regx] = 0;
792 break;
793 case PIU_MSI_32_bit_Address_Register:
794 csrs[regx] = old_value;
795 WRITE_PIU_CSR(csrs[regx], value, MASK64(31,16));
796 break;
797 case PIU_MSI_64_bit_Address_Register:
798 csrs[regx] = old_value;
799 WRITE_PIU_CSR(csrs[regx], value, MASK64(63,16));
800 break;
801 case PIU_IMU_Error_Status_Clear_Register:
802 /*
803 * W1C: clear IMU error
804 */
805 piup->csrs.IMU_Error_Status_Set_Register &= ~value;
806 break;
807 case PIU_IMU_Error_Status_Set_Register:
808 /*
809 * W1S to simulate actual IMU error occurence
810 */
811 new_error = value & ~old_value;
812 if (new_error) {
813 csrs[regx] = new_error | old_value;
814 piu_simulate_imu_error(piup, new_error);
815 }
816 break;
817 case PIU_MMU_Error_Status_Clear_Register:
818 /*
819 * W1C: clear MMU error
820 */
821 piup->csrs.MMU_Error_Status_Set_Register &= ~value;
822 break;
823 case PIU_MMU_Error_Status_Set_Register:
824 /*
825 * W1S to simulate actual MMU error occurence
826 */
827 new_error = value & ~old_value;
828 if (new_error) {
829 csrs[regx] = new_error | old_value;
830 piu_simulate_mmu_error(piup, new_error);
831 }
832 break;
833 default:
834 break;
835 }
836
837
838 break;
839 case MA_ldu64:
840 value = csrs[regx];
841
842 /*
843 * Check on Load-Only (write-only but reads always return 0) CSRs
844 */
845 switch (index) {
846 case PIU_Event_Queue_Control_Set_Register:
847 case PIU_Event_Queue_Control_Clear_Register:
848 value = 0;
849 break;
850 }
851
852 switch (index) {
853 case PIU_Interrupt_Clear_Registers:
854 value = piu_get_irq_state(piup, wordx+INO_INTA);
855 break;
856 case PIU_INT_A_Clear_Register:
857 case PIU_INT_B_Clear_Register:
858 case PIU_INT_C_Clear_Register:
859 case PIU_INT_D_Clear_Register:
860 value = piu_get_intx_state(piup, index-PIU_INT_A_Clear_Register+INO_INTA);
861 break;
862 case PIU_MSI_Clear_Registers:
863 /*
864 * return EQWR_N bit
865 */
866 value = piup->csrs.MSI_Clear_Registers[wordx] & MASK64(62, 62);
867 break;
868 case PIU_IMU_Error_Status_Clear_Register:
869 value = piup->csrs.IMU_Error_Status_Set_Register;
870 break;
871 case PIU_IMU_Interrupt_Status_Register:
872 value = piup->csrs.IMU_Error_Status_Set_Register &
873 piup->csrs.IMU_Interrupt_Enable_Register;
874 break;
875 case PIU_MMU_Error_Status_Clear_Register:
876 value = piup->csrs.MMU_Error_Status_Set_Register;
877 break;
878 case PIU_MMU_Interrupt_Status_Register:
879 value = piup->csrs.MMU_Error_Status_Set_Register &
880 piup->csrs.MMU_Interrupt_Enable_Register;
881 break;
882 }
883
884 DBGDEV(lprintf(sp->gid, "Read PCIE register '%s' at offset = "
885 "0x%llx value = 0x%llx on node %d\n",
886 pcie_csrs[index].name, offset, value, node_id); );
887
888 if (&(sp->intreg[Reg_sparcv9_g0]) != regp)
889 *regp = value;
890
891 break;
892 default:
893 lprintf(sp->gid, "ERROR: PIU only supports 8 byte CSR access, "
894 "node is %d\n", node_id);
895 ASSERT(0);
896 }
897
898 return true;
899}
900
901
902/*
903 * Access PCIE device's IO space (downbound)
904 */
905bool_t piu_io_access(pcie_model_t *piup, maccess_t memop, uint64_t ioaddr, uint32_t count, uint64_t *regp)
906{
907 pcie_dev_inst_t *pcie_devp;
908 pcie_dwbound_t *pcie_dp;
909 bool_t status;
910
911 /*
912 * find matching PCIE end device
913 */
914 pcie_devp = piu_find_pcie_dev(piup, (void *)&ioaddr, PCIE_IO);
915 if (pcie_devp == NULL) {
916 DBGDEV( lprintf(-1, "PCIE device with mapped pa = 0x%lx not found!\n", ioaddr); );
917 return false;
918 }
919
920 pcie_dp = pcie_devp->pcie_dp;
921
922 switch (memop & MA_Op_Mask) {
923 case MA_Ld:
924 case MA_LdSigned:
925 status = pcie_dp->mem_access(pcie_devp->hdl, ioaddr, regp, count, DA_Load, PCIE_IO);
926 break;
927 case MA_St:
928 status = pcie_dp->mem_access(pcie_devp->hdl, ioaddr, regp, count, DA_Store, PCIE_IO);
929 break;
930 default:
931 ASSERT(0);
932 }
933
934 return status;
935}
936
937
938/*
939 * Access PCIE device's Configuation space (downbound)
940 *
941 * The data is inverted between the big and little endian format
942 * because PCI cfg space is structured as little endian
943 */
944bool_t piu_cfg_access(pcie_model_t *piup, maccess_t memop, uint64_t ioaddr, uint32_t count, uint64_t *regp)
945{
946 pcie_dev_inst_t *pcie_devp;
947 pcie_dwbound_t *pcie_dp;
948 uint8_t bus_no, dev_no, fun_no, reg_no;
949 uint16_t req_id;
950 uint64_t data;
951 bool_t status;
952
953 /*
954 * determine request Id
955 */
956 bus_no = (ioaddr & PCIE_BUS_NO_MASK) >> PCIE_BUS_NO_SHIFT;
957 dev_no = (ioaddr & PCIE_DEV_NO_MASK) >> PCIE_DEV_NO_SHIFT;
958 fun_no = (ioaddr & PCIE_FUN_NO_MASK) >> PCIE_FUN_NO_SHIFT;
959 reg_no = ioaddr & PCIE_REG_NO_MASK;
960
961 req_id = PCIE_REQ_ID(bus_no, dev_no, fun_no);
962
963 /*
964 * find matching PCIE end device
965 */
966 pcie_devp = piu_find_pcie_dev(piup, (void *)&req_id, PCIE_CFG);
967 if (pcie_devp == NULL) {
968 DBGDEV( lprintf(-1, "PCIE device with bus_no=0x%x dev_no=0x%x fun_no=0x%x not found!\n",
969 PCIE_BUS_NO(req_id), PCIE_DEV_NO(req_id), PCIE_FUN_NO(req_id)); );
970 return false;
971 }
972
973 /*
974 * read or write access to PCIE Cfg space
975 */
976 pcie_dp = pcie_devp->pcie_dp;
977
978 switch (memop & MA_Op_Mask) {
979 case MA_Ld:
980 case MA_LdSigned:
981 status = pcie_dp->mem_access(pcie_devp->hdl, reg_no, regp, count, DA_Load, PCIE_CFG);
982 break;
983 case MA_St:
984 status = pcie_dp->mem_access(pcie_devp->hdl, reg_no, regp, count, DA_Store, PCIE_CFG);
985 break;
986 default:
987 ASSERT(0);
988 }
989
990 return status;
991}
992
993
994/*
995 * Access PCIE device's MEM32/MEM64 space (downbound)
996 */
997bool_t piu_mem_access(pcie_model_t *piup, maccess_t memop, uint64_t paddr, uint32_t count, uint64_t *regp,
998 pcie_space_t space_id)
999{
1000 pcie_dev_inst_t *pcie_devp;
1001 pcie_dwbound_t *pcie_dp;
1002 bool_t status;
1003
1004 /*
1005 * find matching PCIE end device
1006 */
1007 pcie_devp = piu_find_pcie_dev(piup, (void *)&paddr, space_id);
1008 if (pcie_devp == NULL) {
1009 DBGDEV( lprintf(-1, "PCIE device with mapped pa = 0x%lx not found!\n", paddr); );
1010 return false;
1011 }
1012
1013 pcie_dp = pcie_devp->pcie_dp;
1014
1015 switch (memop & MA_Op_Mask) {
1016 case MA_Ld:
1017 case MA_LdSigned:
1018 status = pcie_dp->mem_access(pcie_devp->hdl, paddr, regp, count, DA_Load, space_id);
1019 break;
1020 case MA_St:
1021 status = pcie_dp->mem_access(pcie_devp->hdl, paddr, regp, count, DA_Store, space_id);
1022 break;
1023 default:
1024 ASSERT(0);
1025 }
1026
1027 return status;
1028}
1029
1030
1031/*
1032 * DMA transactions (upbound)
1033 *
1034 * Arguments:
1035 * piup: handle to pcie_model structure
1036 * va: host virtual address accessed by the DMA transaction
1037 * datap: data read from/written to the host memory
1038 * count: data size counted in byte
1039 * req_id: 16 bit requester Id
1040 * type: access type (load vs. store)
1041 * mode: addressing mode, can be either 32 bit or 64 bit address
1042 */
1043bool_t piu_dma_access(pcie_model_t *piup, tvaddr_t va, uint8_t *datap, int count,
1044 uint16_t req_id, dev_access_t type, dev_mode_t mode)
1045{
1046 uint64_t msi_addr;
1047 bool_t is_msi = false, status;
1048 tpaddr_t pa;
1049
1050 /*
1051 * decode MSI access
1052 */
1053 if (mode == PCIE_IS32) {
1054 msi_addr = piup->csrs.MSI_32_bit_Address_Register & MASK64(31, 16);
1055 is_msi = ((va & MASK64(31,16)) == msi_addr);
1056 }
1057 if (mode == PCIE_IS64) {
1058 int sun4v, base, bit=63;
1059
1060 /*
1061 * In sun4v mode, if EQ_base_addr_reg.bit[63]=0, msi_addr_reg.bit[63]
1062 * is not used for comparison (see 16.3.9.8 of N2 PRM, rev 1.2)
1063 */
1064 sun4v = GETMASK64(piup->csrs.MMU_Control_and_Status_Register, 2, 2);
1065 base = GETMASK64(piup->csrs.Event_Queue_Base_Address_Register, 63,63);
1066
1067 if (sun4v)
1068 bit = (base == 0) ? 62 : 63;
1069
1070 msi_addr = piup->csrs.MSI_64_bit_Address_Register & MASK64(bit, 16);
1071 is_msi = ((va & MASK64(bit,16)) == msi_addr);
1072 }
1073
1074 if (is_msi && type == DA_Store) {
1075 status = piu_msi_write(piup, va, datap, count, req_id, mode);
1076 return (status);
1077 }
1078
1079 /*
1080 * perform IOMMU operation
1081 */
1082 status = piu_iommu(piup, va, req_id, type, mode, &pa);
1083
1084
1085 /*
1086 * VA -> PA translation is successful, do DMA transaction with pa
1087 */
1088 if (status) {
1089 config_proc_t *procp = piup->config_procp;
1090
1091 status = procp->proc_typep->dev_mem_access(procp, pa, datap, count, type);
1092 }
1093
1094 return (status);
1095}
1096
1097
1098/*
1099 * This function performs IOMMU operation upon each DMA request.
1100 */
1101bool_t piu_iommu(pcie_model_t *piup, tvaddr_t va, uint16_t req_id, dev_access_t type,
1102 dev_mode_t mode, tpaddr_t *pa)
1103{
1104 int te, be, sun4v;
1105 bool_t status = false;
1106
1107 te = GETMASK64(piup->csrs.MMU_Control_and_Status_Register, 0, 0);
1108 be = GETMASK64(piup->csrs.MMU_Control_and_Status_Register, 1, 1);
1109 sun4v = GETMASK64(piup->csrs.MMU_Control_and_Status_Register, 2, 2);
1110
1111 /*
1112 * check if it's MMU bypass opeartion (allowed in both SUN4V and SUN4U mode)
1113 */
1114 if (be && (mode == PCIE_IS64)) {
1115 if ((va & MASK64(63, 39)) == MASK64(63, 50)) {
1116 *pa = va & MASK64(38, 0);
1117
1118 DBGDEV(lprintf(-1, "piu_iommu: bypass va = 0x%llx pa = 0x%llx\n", va, *pa); );
1119 return true;
1120 } else {
1121 if (!sun4v) {
1122 /*
1123 * FIXME: should raise the MMU BYP_OOR error in sun4u mode
1124 */
1125 DBGDEV(lprintf(-1, "piu_iommu: IOMMU BYP_OOR error va = 0x%llx\n", va); );
1126 ASSERT(0);
1127 }
1128 }
1129 }
1130
1131 if (!be && (mode == PCIE_IS64)) {
1132 if (!sun4v) {
1133 /*
1134 * FIXME: should raise the MMU BYP_ERR error in sun4u mode
1135 */
1136 DBGDEV(lprintf(-1, "piu_iommu: IOMMU BYP_ERR error va = 0x%llx\n", va); );
1137 ASSERT(0);
1138 }
1139 }
1140
1141 /*
1142 * check whether MMU is disabled
1143 */
1144 if (!te) {
1145 /*
1146 * FIXME: raise MMU TRN_ERR for both sun4v and sun4u mode
1147 */
1148 DBGDEV(lprintf(-1, "piu_iommu: MMU is disabled, va = 0x%llx\n", va); );
1149 ASSERT(0);
1150 }
1151
1152 /*
1153 * perform IOMMU operation under SUN4U or SUN4V mode
1154 */
1155 if (sun4v) {
1156 status = piu_iommu_sun4v(piup, va, req_id, type, mode, pa);
1157 } else {
1158 status = piu_iommu_sun4u(piup, va, req_id, type, mode, pa);
1159 }
1160
1161 return (status);
1162}
1163
1164
1165/*
1166 * Translate VA -> PA, SUN4U mode
1167 */
1168bool_t piu_iommu_sun4u(pcie_model_t *piup, tvaddr_t va, uint16_t req_id, dev_access_t type,
1169 dev_mode_t mode, tpaddr_t *pa)
1170{
1171 config_proc_t *procp = piup->config_procp;
1172 int ts, ps, pg_bits, tsb_sz, tte_idx;
1173 uint64_t tb, vpn, tte_addr, tte, pg_mask;
1174 bool_t status;
1175
1176 ts = GETMASK64(piup->csrs.MMU_TSB_Control_Register, 3, 0);
1177 ps = GETMASK64(piup->csrs.MMU_TSB_Control_Register, 8, 8);
1178 tb = piup->csrs.MMU_TSB_Control_Register & MASK64(38, 13);
1179
1180 /*
1181 * determine the tte index in terms of
1182 *
1183 * - page size: 8K (ps=0) and 64K (ps=1)
1184 * - number of TSB entries (=1K*2^ts = 2^(10+ts))
1185 */
1186 pg_bits = 13 + 3*ps;
1187 vpn = (va & MASK64(31, pg_bits)) >> pg_bits;
1188 tsb_sz = 1 << (ts+10);
1189 tte_idx = (vpn & (tsb_sz-1)) << 3; /* each entry of 8 byte */
1190 tte_addr = tb + tte_idx;
1191
1192 /*
1193 * retrieve the tte entry
1194 */
1195 status = procp->proc_typep->dev_mem_access(procp, tte_addr, (uint8_t *)&tte, 8, DA_Load);
1196 if (!status) {
1197 DBGDEV(lprintf(-1, "piu_iommu_sun4u: illegal tte_addr: tte_addr = 0x%lx va = 0x%lx\n",
1198 tte_addr, va); );
1199 ASSERT(0);
1200 }
1201
1202 /*
1203 * finally do VA -> PA
1204 */
1205 piu_iommu_va2pa(tte, ps, va, req_id, type, mode, pa);
1206
1207 DBGDEV(lprintf(-1, "piu_iommu_sun4u: translate va = 0x%lx to pa = 0x%llx, tte_addr = 0x%lx tte = 0x%llx\n",
1208 va, *pa, tte_addr, tte); );
1209
1210 return true;
1211}
1212
1213
1214/*
1215 * Translate VA -> PA, SUN4V mode
1216 */
1217bool_t piu_iommu_sun4v(pcie_model_t *piup, tvaddr_t va, uint16_t req_id, dev_access_t type,
1218 dev_mode_t mode, tpaddr_t *pa)
1219{
1220 config_proc_t *procp = piup->config_procp;
1221 piu_csr_t *csrs = &piup->csrs;
1222 int i, busid_sel, busid, ps, ts, pg_bits, tsb_sz, tte_idx;
1223 uint8_t idx, iotsb_idx, iotsb_no;
1224 uint64_t dev2iotsb, offset, base_pa, vpn, tte_addr, tte;
1225 bool_t status;
1226
1227 /*
1228 * Form 7 bit index id into the DEV2IOTSB table, which is implemented
1229 * by a set of 16 x 64-bit registers, with each register containing
1230 * 8 x 5-bit values to index into the IOTSBDESC table.
1231 */
1232 busid = PCIE_BUS_NO(req_id);
1233 busid_sel = GETMASK64(csrs->MMU_Control_and_Status_Register, 3, 3);
1234
1235 idx = (va >> 63) << 6;
1236 idx |= busid_sel ? GETMASK64(busid, 5, 0) : GETMASK64(busid, 6, 1);
1237
1238 /*
1239 * Use the 7 bit index id to extract the 5-bit iotsb_no from the
1240 * DEV2IOTSB table (total of 128 index cells out of 16 regs).
1241 */
1242 dev2iotsb = csrs->MMU_DEV2IOTSB_Registers[idx>>3];
1243 iotsb_idx = GETMASK64(idx, 2, 0) << 3;
1244 iotsb_no = GETMASK64(dev2iotsb, iotsb_idx + 4, iotsb_idx);
1245
1246 /*
1247 * Use iotsb_no as index to retrieve IOTSB info from IOTSBDESC table
1248 * (implemented by a set of 32 x 64-bit registers)
1249 */
1250 base_pa = GETMASK64(csrs->MMU_IOTSBDESC_Registers[iotsb_no], 59, 34);
1251 offset = GETMASK64(csrs->MMU_IOTSBDESC_Registers[iotsb_no], 33, 7);
1252 ps = GETMASK64(csrs->MMU_IOTSBDESC_Registers[iotsb_no], 6, 4);
1253 ts = GETMASK64(csrs->MMU_IOTSBDESC_Registers[iotsb_no], 3, 0);
1254
1255 /*
1256 * validate VA
1257 */
1258 if ((va & MASK64(62, 40)) != 0) {
1259 uint64_t error_code, trans_type;
1260
1261 /*
1262 * log the error
1263 */
1264 csrs->MMU_Translation_Fault_Address_Register = va & MASK64(63, 2);
1265
1266 if (mode == PCIE_IS32)
1267 trans_type = (type == DA_Load) ? TLP_MRd_FMT_TYPE_IS32 : TLP_MWr_FMT_TYPE_IS32;
1268 else
1269 trans_type = (type == DA_Load) ? TLP_MRd_FMT_TYPE_IS64 : TLP_MWr_FMT_TYPE_IS64;
1270
1271 csrs->MMU_Translation_Fault_Status_Register = req_id | (trans_type << 16);
1272
1273 /*
1274 * raise mmu sun4v_va_oor error
1275 */
1276 error_code = 1ULL<<SUN4V_VA_OOR_P;
1277 csrs->MMU_Error_Status_Set_Register |= error_code;
1278
1279 piu_raise_mmu_error(piup, error_code);
1280
1281 return true;
1282 }
1283
1284 /*
1285 * determine adjusted page number using encoded ps value
1286 * and adjusted VA at a given offset
1287 *
1288 * FIXME: check underflow error on vpn (error = sun4v_va_adj_uf)
1289 */
1290 pg_bits = 13 + 3*ps;
1291 vpn = ((va & MASK64(39, pg_bits)) >> pg_bits) - offset;
1292
1293 /*
1294 * calculate tte index in terms of TSB size
1295 *
1296 * FIXME: check out of range error on vpn (error = TRN_OOR)
1297 */
1298 tsb_sz = 1 << (ts+10);
1299 tte_idx = (vpn & (tsb_sz-1)) << 3;
1300 tte_addr = (base_pa << 13) + tte_idx;
1301
1302 /*
1303 * retrieve the tte entry
1304 */
1305 status = procp->proc_typep->dev_mem_access(procp, tte_addr, (uint8_t *)&tte, 8, DA_Load);
1306 if (!status) {
1307 DBGDEV(lprintf(-1, "piu_iommu_sun4v: illegal tte_addr: tte_addr = 0x%lx va = 0x%lx\n",
1308 tte_addr, va); );
1309 ASSERT(0);
1310 }
1311
1312 /*
1313 * finally do VA -> PA
1314 */
1315 piu_iommu_va2pa(tte, ps, va, req_id, type, mode, pa);
1316
1317 DBGDEV(lprintf(-1, "piu_iommu_sun4v: translate va = 0x%lx to pa = 0x%llx, tte_addr = 0x%lx tte = 0x%llx\n",
1318 va, *pa, tte_addr, tte); );
1319
1320 return true;
1321}
1322
1323
1324bool_t piu_iommu_va2pa(uint64_t tte, int ps, tvaddr_t va, uint16_t req_id, dev_access_t type,
1325 dev_mode_t mode, tpaddr_t *pa)
1326{
1327 bool_t tte_key_valid, tte_data_w, tte_data_v;
1328 uint16_t tte_dev_key;
1329 int pg_bits;
1330 uint64_t pg_mask, tte_data_pa;
1331
1332 /*
1333 * validate tte
1334 */
1335 tte_data_v = GETMASK64(tte, 0, 0);
1336 tte_key_valid = GETMASK64(tte, 2, 2);
1337 tte_dev_key = GETMASK64(tte, 63, 48);
1338
1339 /*
1340 * assert on invalid tte entry
1341 */
1342 ASSERT(tte_data_v);
1343
1344#ifdef VFALLS /* { */
1345 /*
1346 * check the RO (Relaxed Ordering) bit
1347 */
1348 if (GETMASK64(tte, 6, 6))
1349 DBGDEV(lprintf(-1, "Relaxed Ordering is not supported"); );
1350#endif /* } VFALLS */
1351
1352 /*
1353 * compare tte's DEV_KEY field with req_id
1354 */
1355 if (tte_key_valid) {
1356 /*
1357 * According to N2 PIU PRM, the function number portion of
1358 * the tte_dev_key and the source req_id should be masked
1359 * with the FNM field of the tte.
1360 */
1361 uint16_t tte_fnm = MASK64(15,3) | GETMASK64(tte, 5, 3);
1362
1363 if ((tte_dev_key & tte_fnm) != (req_id & tte_fnm)) {
1364 DBGDEV(lprintf(-1, "piu_iommu_va2pa: req_id=0x%lx not matching tte dev_key=0x%lx\n",
1365 req_id, tte_dev_key); );
1366 ASSERT(0);
1367 }
1368 }
1369
1370 /*
1371 * check on DATA_W for the write request
1372 */
1373 tte_data_w = GETMASK64(tte, 1, 1);
1374 if ((tte_data_w == 0) && type == DA_Store) {
1375 DBGDEV(lprintf(-1, "piu_iommu_sun4u: write to non-writable page: va = 0x%lx tte = 0x%lx\n",
1376 va, tte); );
1377 ASSERT(0);
1378 }
1379
1380 /*
1381 * finally translate VA to PA
1382 */
1383 pg_bits = 13 + 3*ps;
1384 pg_mask = (1 << pg_bits) - 1;
1385 tte_data_pa = tte & MASK64(38, pg_bits);
1386 *pa = tte_data_pa | (va & pg_mask);
1387
1388 return true;
1389}
1390
1391
1392/*
1393 * Assert INTx interrupt
1394 */
1395bool_t piu_assert_intx(pcie_model_t *piup, uint8_t pin_no, uint8_t dev_no)
1396{
1397 uint8_t ino;
1398
1399 /*
1400 * FIXME: check if PIU supports more than 4 devices
1401 */
1402 ASSERT(pin_no < 4);
1403
1404 /*
1405 * generate mondo interrupt
1406 */
1407 ino = pin_no + INO_INTA;
1408
1409 piu_mondo_interrupt(piup, ino, IRQ_RECEIVED);
1410
1411 return true;
1412}
1413
1414
1415/*
1416 * Deassert INTx interrupt
1417 */
1418bool_t piu_deassert_intx(pcie_model_t *piup, uint8_t pin_no, uint8_t dev_no)
1419{
1420 uint8_t ino;
1421
1422 /*
1423 * FIXME: check if PIU supports more than 4 devices
1424 */
1425 ASSERT(pin_no < 4);
1426
1427 ino = pin_no + INO_INTA;
1428
1429 piu_mondo_interrupt(piup, ino, IRQ_IDLE);
1430
1431 return true;
1432}
1433
1434
1435/*
1436 * Generate IRQ mondo interrupt and update the interrupt state accordingly
1437 */
1438void piu_mondo_interrupt(pcie_model_t *piup, uint8_t ino, irq_state_t new)
1439{
1440 bool_t V;
1441 int regx;
1442 irq_state_t old;
1443
1444 DBGDEV( lprintf(-1, "piu_mondo_interrupt: ino = %d\n", ino); );
1445
1446 /*
1447 * get the current IRQ mondo state
1448 */
1449 regx = ino - INO_INTA;
1450 old = piu_get_irq_state(piup, ino);
1451
1452 V = GETMASK64(piup->csrs.Interrupt_Mapping_Registers[regx], 31, 31);
1453
1454 if ((old == IRQ_IDLE) && (new == IRQ_RECEIVED) && V) {
1455 bool_t mdo_mode;
1456 pcie_mondo_t *irq_mondo = (pcie_mondo_t *)Xcalloc(1, pcie_mondo_t);
1457
1458 irq_mondo->thread_id = GETMASK64(piup->csrs.Interrupt_Mapping_Registers[regx], 30, 25);
1459
1460 mdo_mode = GETMASK64(piup->csrs.Interrupt_Mapping_Registers[regx], 63, 63);
1461
1462 if (mdo_mode == 0) {
1463 irq_mondo->data[0] = (irq_mondo->thread_id << 6) | ino;
1464 irq_mondo->data[1] = 0;
1465 } else {
1466 uint64_t data0 = piup->csrs.Interrupt_Mondo_Data_0_Register;
1467 irq_mondo->data[0] = (data0 & MASK64(63, 12)) | (irq_mondo->thread_id << 6) | ino;
1468 irq_mondo->data[1] = piup->csrs.Interrupt_Mondo_Data_1_Register;
1469 }
1470
1471 /*
1472 * send IRQ mondo to target CPU
1473 */
1474 piup->config_procp->proc_typep->ext_signal(piup->config_procp, ES_PCIE, (void *)irq_mondo);
1475
1476 new = IRQ_PENDING;
1477 }
1478
1479 /*
1480 * update interrupt state
1481 */
1482 piu_set_irq_state(piup, ino, new);
1483
1484}
1485
1486
1487/*
1488 * Update INTx state
1489 */
1490void piu_set_intx_state(pcie_model_t *piup, uint8_t ino, irq_state_t new)
1491{
1492 int bit, val;
1493
1494 switch (ino) {
1495 case INO_INTA:
1496 case INO_INTB:
1497 case INO_INTC:
1498 case INO_INTD:
1499 bit = 3 - (ino - INO_INTA);
1500 val = 1 << bit;
1501 if (new == IRQ_IDLE)
1502 piup->csrs.INTX_Status_Register &= ~val;
1503 else
1504 piup->csrs.INTX_Status_Register |= val;
1505 }
1506}
1507
1508
1509/*
1510 * Get INTx state
1511 */
1512int piu_get_intx_state(pcie_model_t *piup, uint8_t ino)
1513{
1514 int val = 0, bit;
1515
1516 switch (ino) {
1517 case INO_INTA:
1518 case INO_INTB:
1519 case INO_INTC:
1520 case INO_INTD:
1521 bit = 3 - (ino - INO_INTA);
1522 val = (piup->csrs.INTX_Status_Register >> bit) & 1;
1523 }
1524 return val;
1525}
1526
1527
1528/*
1529 * Update Interrupt State Status Register with the new mondo state 'new'
1530 */
1531void piu_set_irq_state(pcie_model_t *piup, uint8_t ino, irq_state_t new)
1532{
1533 int bit;
1534 uint64_t *regp;
1535
1536 /*
1537 * determine which status register to use in terms of ino
1538 */
1539 regp = ino<32 ? &piup->csrs.Interrupt_State_Status_Register_1 : &piup->csrs.Interrupt_State_Status_Register_2;
1540
1541 /*
1542 * each mondo state is encoded via a 2 bit value:
1543 *
1544 * 00: IRQ_IDLE
1545 * 01: IRQ_RECEIVED
1546 * 10: IRQ_RESERVED
1547 * 11: IRQ_PENDING
1548 */
1549 bit = 2 * (ino&31);
1550
1551 /*
1552 * update the approriate bits of the register
1553 */
1554 *regp &= ~(IRQ_STATE_MASK << bit);
1555 *regp |= ((uint64_t)new << bit);
1556
1557 /*
1558 * update the INTx status register if ino = 20-23
1559 */
1560 piu_set_intx_state(piup, ino, new);
1561}
1562
1563
1564/*
1565 * Get mondo interrupt state
1566 */
1567int piu_get_irq_state(pcie_model_t *piup, uint8_t ino)
1568{
1569 int bit;
1570 uint64_t val;
1571 irq_state_t state;
1572
1573 bit = 2* (ino&31);
1574 val = ino<32 ? piup->csrs.Interrupt_State_Status_Register_1: piup->csrs.Interrupt_State_Status_Register_2;
1575 state = (val >> bit) & IRQ_STATE_MASK;
1576
1577 return state;
1578}
1579
1580
1581/*
1582 * This function handles memory write request for both MSI and MSI-X.
1583 *
1584 * Arguments:
1585 * piup: handle to pcie_model structure
1586 * msi_addr: host address for MSI/MSI-X write, can be either 32 bit or 64 bit
1587 * msi_datap: pointer to the MSI/MSI-X data of size 2 or 4 byte
1588 * count: can be either 2 byte or 4 byte to indicate MSI or MSI-X request
1589 * req_id: 16 bit requester Id
1590 * mode: addressing mode, can be either 32 bit or 64 bit address
1591 *
1592 */
1593bool_t piu_msi_write(pcie_model_t *piup, uint64_t msi_addr, uint8_t *msi_datap,
1594 int count, uint16_t req_id, dev_mode_t mode)
1595{
1596 uint64_t mapping;
1597 int map_idx, v, eqwr_n, eqnum;
1598 uint32_t msi_vector=0;
1599
1600
1601 /*
1602 * validate count to determin MSI vs. MSI-X
1603 */
1604 if ((count != 2) && (count != 4)) {
1605 DBGDEV( lprintf(-1, "piu_msi_write: invalid msi_data size = %d \n", count); );
1606 return false;
1607 }
1608
1609 /*
1610 * PIU implements a total of 256 MSI_Mapping_Registers as the mapping
1611 * table to allow SW to map each MSI/MSI-X request to an event queue.
1612 * The lower 8 bits of the MSI/MSI-X data field is used to index into
1613 * the mapping table.
1614 */
1615 memcpy((void *)&msi_vector, (void *)msi_datap, count);
1616 map_idx = (count == 2) ? *(uint16_t *)&msi_vector : msi_vector;
1617
1618 DBGDEV( lprintf(-1, "piu_msi_write: addr = 0x%lx data = %d\n", msi_addr, map_idx); );
1619
1620 mapping = piup->csrs.MSI_Mapping_Register[map_idx];
1621 v = GETMASK64(mapping, 63, 63);
1622 eqwr_n = GETMASK64(mapping, 62, 62);
1623 eqnum = GETMASK64(mapping, 5, 0);
1624
1625 if (v && !eqwr_n) {
1626 /*
1627 * assemble the event queue record
1628 */
1629 eq_record_t *record = (eq_record_t *)Xcalloc(1, eq_record_t);
1630
1631 record->fmt_type = mode ? TLP_MSI_FMT_TYPE_IS64 : TLP_MSI_FMT_TYPE_IS32;
1632
1633 /*
1634 * always one DW
1635 */
1636 record->length = 1;
1637 record->addr_15_2 = GETMASK64(msi_addr, 15, 2);
1638 record->rid = req_id;
1639 record->addr_hi = GETMASK64(msi_addr, 63, 16);
1640
1641 /*
1642 * Remove byte swapping here, as per MSI-X RFE P1584,
1643 * Fire 2.0 no longer loads MSI/MSI-X data into event
1644 * queue record in the Little-Endian format.
1645 *
1646 * Note: the current PRM for both Fire rev 2.1, and
1647 * N2 PIU rev 1.3 is not up-to-date with this
1648 * change yet.
1649 */
1650 if (count == 2)
1651 record->data0 = *(uint16_t *)&msi_vector;
1652 if (count == 4) {
1653 record->data0 = msi_vector & MASK64(15,0);
1654 record->data1 = (msi_vector & MASK64(31,16)) >> 16;
1655 }
1656
1657 piu_eq_write(piup, eqnum, record, req_id);
1658 }
1659
1660 return true;
1661}
1662
1663
1664/*
1665 * Write event queue records to the queue and update the tail pointer of the queue.
1666 */
1667bool_t piu_eq_write(pcie_model_t *piup, int eqnum, eq_record_t *record, uint16_t req_id)
1668{
1669 int overr, state = true;
1670 bool_t status;
1671
1672 overr = GETMASK64(piup->csrs.Event_Queue_Tail_Register[eqnum], 57, 57);
1673 state = GETMASK64(piup->csrs.Event_Queue_State_Register[eqnum], 2, 0);
1674
1675 DBGDEV( lprintf(-1, "piu_eq_write: eqnum = %d state = %d\n", eqnum, state); );
1676
1677 if ((state == EQ_ACTIVE) && !overr) {
1678 int head = GETMASK64(piup->csrs.Event_Queue_Head_Register[eqnum], 6, 0);
1679 int tail = GETMASK64(piup->csrs.Event_Queue_Tail_Register[eqnum], 6, 0);
1680 int next = (tail + 1) % EQ_NUM_ENTRIES;
1681 bool_t full = (next == head);
1682 bool_t empty = (head == tail);
1683
1684 if (full) {
1685 /*
1686 * set the overflow bit and generate a DMU internal interrupt (ino 62)
1687 */
1688 piup->csrs.Event_Queue_Tail_Register[eqnum] |= MASK64(57,57);
1689 piup->csrs.Event_Queue_State_Register[eqnum] = EQ_ERROR;
1690
1691 piu_mondo_interrupt(piup, INO_DMU, IRQ_RECEIVED);
1692 }
1693 else {
1694 /*
1695 * determine the EQ record address to write the event queue record
1696 */
1697 uint64_t base, offset, rec_va, pa;
1698 dev_mode_t mode = PCIE_IS64;
1699 int sun4v;
1700
1701 base = piup->csrs.Event_Queue_Base_Address_Register & MASK64(63,19);
1702 offset = (eqnum * EQ_NUM_ENTRIES + tail) * EQ_RECORD_SIZE;
1703 rec_va = base + offset;
1704
1705 DBGDEV( lprintf(-1, "piu_eq_write: EQ record va = 0x%llx\n", rec_va); );
1706
1707 /*
1708 * setup the access mode of the EQ record address in terms of the
1709 * IOMMU mode (see N2 PRM rev 1.2, section 16.3.4)
1710 */
1711 sun4v = GETMASK64(piup->csrs.MMU_Control_and_Status_Register, 2, 2);
1712 if ((!sun4v) && (rec_va & MASK64(63, 32) == 0))
1713 mode = PCIE_IS32;
1714
1715 /*
1716 * pass the EQ address to IOMMU for translation
1717 */
1718 status = piu_iommu(piup, rec_va, req_id, DA_Store, mode, &pa);
1719
1720 /*
1721 * write the record to the event queue
1722 */
1723 if (status) {
1724 config_proc_t *procp = piup->config_procp;
1725
1726 status = procp->proc_typep->dev_mem_access(procp, pa, (uint8_t *)record,
1727 sizeof(*record), DA_Store);
1728
1729 /*
1730 * update the tail pointer
1731 */
1732 piup->csrs.Event_Queue_Tail_Register[eqnum] = next & MASK64(6,0);
1733
1734 /*
1735 * if the queue is empty, generate a mondo interrupt depending on state
1736 */
1737 if (empty)
1738 piu_mondo_interrupt(piup, INO_EQLO+eqnum, IRQ_RECEIVED);
1739 }
1740 }
1741 }
1742
1743 return (status);
1744}
1745
1746
1747void piu_init_error_list()
1748{
1749 int i;
1750
1751 imu_error_entry_t imu_error_init_list[] = {
1752 { PIU_ERR ( MSI_NOT_EN_P, 0) },
1753 { PIU_ERR ( COR_MES_NOT_EN_P, 1) },
1754 { PIU_ERR ( NONFATAL_MES_NOT_EN_P, 2) },
1755 { PIU_ERR ( FATAL_MES_NOT_EN_P, 3) },
1756 { PIU_ERR ( PMPME_MES_NOT_EN_P, 4) },
1757 { PIU_ERR ( PMEACK_MES_NOT_EN_P, 5) },
1758 { PIU_ERR ( MSI_PAR_ERR_P, 6) },
1759 { PIU_ERR ( MSI_MAL_ERR_P, 7) },
1760 { PIU_ERR ( EQ_NOT_EN_P, 8) },
1761 { PIU_ERR ( EQ_OVER_P, 9) },
1762 { PIU_ERR ( MSI_NOT_EN_S, 32) },
1763 { PIU_ERR ( COR_MES_NOT_EN_S, 33) },
1764 { PIU_ERR ( NONFATAL_MES_NOT_EN_S, 34) },
1765 { PIU_ERR ( FATAL_MES_NOT_EN_S, 35) },
1766 { PIU_ERR ( PMPME_MES_NOT_EN_SEQ_OVER_S, 36) },
1767 { PIU_ERR ( PMEACK_MES_NOT_EN_S, 37) },
1768 { PIU_ERR ( MSI_PAR_ERR_S, 38) },
1769 { PIU_ERR ( MSI_MAL_ERR_S, 39) },
1770 { PIU_ERR ( EQ_NOT_EN_S, 40) },
1771 { PIU_ERR ( EQ_OVER_S, 41) },
1772 { -1, (char *)0 },
1773 };
1774
1775 mmu_error_entry_t mmu_error_init_list[] = {
1776 { PIU_ERR ( BYP_ERR_P, 0) },
1777 { PIU_ERR ( BYP_OOR_P, 1) },
1778 { PIU_ERR ( SUN4V_INV_PG_SZ_P, 2) },
1779 { PIU_ERR ( SPARE1_P, 3) },
1780 { PIU_ERR ( TRN_ERR_P, 4) },
1781 { PIU_ERR ( TRN_OOR_P, 5) },
1782 { PIU_ERR ( TTE_INV_P, 6) },
1783 { PIU_ERR ( TTE_PRT_P, 7) },
1784 { PIU_ERR ( TTC_DPE_P, 8) },
1785 { PIU_ERR ( TTC_CAE_P, 9) },
1786 { PIU_ERR ( SPARE2_P, 10) },
1787 { PIU_ERR ( SPARE3_P, 11) },
1788 { PIU_ERR ( TBW_DME_P, 12) },
1789 { PIU_ERR ( TBW_UDE_P, 13) },
1790 { PIU_ERR ( TBW_ERR_P, 14) },
1791 { PIU_ERR ( TBW_DPE_P, 15) },
1792 { PIU_ERR ( IOTSBDESC_INV_P, 16) },
1793 { PIU_ERR ( IOTSBDESC_DPE_P, 17) },
1794 { PIU_ERR ( SUN4V_VA_OOR_P, 18) },
1795 { PIU_ERR ( SUN4V_VA_ADJ_UF_P, 19) },
1796 { PIU_ERR ( SUN4V_KEY_ERR_P, 20) },
1797 { PIU_ERR ( BYP_ERR_S, 32) },
1798 { PIU_ERR ( BYP_OOR_S, 33) },
1799 { PIU_ERR ( SUN4V_INV_PG_SZ_S, 34) },
1800 { PIU_ERR ( SPARE1_S, 35) },
1801 { PIU_ERR ( TRN_ERR_S, 36) },
1802 { PIU_ERR ( TRN_OOR_S, 37) },
1803 { PIU_ERR ( TTE_INV_S, 38) },
1804 { PIU_ERR ( TTE_PRT_S, 39) },
1805 { PIU_ERR ( TTC_DPE_S, 40) },
1806 { PIU_ERR ( TTC_CAE_S, 41) },
1807 { PIU_ERR ( SPARE2_S, 42) },
1808 { PIU_ERR ( SPARE3_S, 43) },
1809 { PIU_ERR ( TBW_DME_S, 44) },
1810 { PIU_ERR ( TBW_UDE_S, 45) },
1811 { PIU_ERR ( TBW_ERR_S, 46) },
1812 { PIU_ERR ( TBW_DPE_S, 47) },
1813 { PIU_ERR ( IOTSBDESC_INV_S, 48) },
1814 { PIU_ERR ( IOTSBDESC_DPE_S, 49) },
1815 { PIU_ERR ( SUN4V_VA_OOR_S, 50) },
1816 { PIU_ERR ( SUN4V_VA_ADJ_UF_S, 51) },
1817 { PIU_ERR ( SUN4V_KEY_ERR_S, 52) },
1818 { -1, (char *)0 },
1819 };
1820
1821 for (i = 0; imu_error_init_list[i].error_type != -1; i ++)
1822 imu_error_list[imu_error_init_list[i].error_type] = imu_error_init_list[i];
1823
1824 for (i = 0; mmu_error_init_list[i].error_type != -1; i ++)
1825 mmu_error_list[mmu_error_init_list[i].error_type] = mmu_error_init_list[i];
1826
1827}
1828
1829
1830/*
1831 * imu error handler
1832 */
1833void piu_simulate_imu_error(pcie_model_t *piup, uint64_t imu_error)
1834{
1835 uint64_t error_code, intr_enable, imu_ie;
1836 int i;
1837
1838 /*
1839 * loop over the error bits and raise the error only if
1840 * the interrupt is enabled
1841 */
1842 imu_ie = piup->csrs.IMU_Interrupt_Enable_Register;
1843
1844 for (i=0; i<IMU_ERROR_MAXNUM; i++) {
1845 error_code = imu_error_list[i].error_code;
1846 intr_enable = imu_error_list[i].intr_enable;
1847
1848 if ((imu_error & error_code) && (imu_ie & intr_enable))
1849 piu_raise_imu_error(piup, error_code);
1850 }
1851}
1852
1853
1854void piu_raise_imu_error(pcie_model_t *piup, uint64_t error_code)
1855{
1856 piu_csr_t *csrs = &piup->csrs;
1857 uint64_t dmc_cbie;
1858 bool_t dmu, imu;
1859
1860 /*
1861 * update the error status register
1862 */
1863 csrs->IMU_Error_Status_Set_Register |= error_code;
1864
1865 /*
1866 * generate INO_DMU mondo interrupt
1867 */
1868 dmc_cbie = csrs->DMC_Core_and_Block_Interrupt_Enable_Register;
1869
1870 dmu = GETMASK64(dmc_cbie, 63, 63);
1871 imu = GETMASK64(dmc_cbie, 0, 0);
1872
1873 if (dmu && imu) {
1874 csrs->DMC_Core_and_Block_Error_Status_Register |= MASK64(0,0);
1875 piu_mondo_interrupt(piup, INO_DMU, IRQ_RECEIVED);
1876 }
1877}
1878
1879
1880/*
1881 * mmu error handler
1882 */
1883void piu_simulate_mmu_error(pcie_model_t *piup, uint64_t mmu_error)
1884{
1885 uint64_t error_code, intr_enable, mmu_ie;
1886 int i;
1887
1888 /*
1889 * loop over the error bits and raise the error only if
1890 * the interrupt is enabled
1891 */
1892 mmu_ie = piup->csrs.MMU_Interrupt_Enable_Register;
1893
1894 for (i=0; i<MMU_ERROR_MAXNUM; i++) {
1895 error_code = mmu_error_list[i].error_code;
1896 intr_enable = mmu_error_list[i].intr_enable;
1897
1898 if ((mmu_error & error_code) && (mmu_ie & intr_enable))
1899 piu_raise_mmu_error(piup, error_code);
1900 }
1901}
1902
1903
1904void piu_raise_mmu_error(pcie_model_t *piup, uint64_t error_code)
1905{
1906 piu_csr_t *csrs = &piup->csrs;
1907 uint64_t dmc_cbie;
1908 bool_t dmu, mmu;
1909
1910 /*
1911 * update the error status register
1912 */
1913 csrs->MMU_Error_Status_Set_Register |= error_code;
1914
1915 /*
1916 * generate INO_DMU mondo interrupt
1917 */
1918 dmc_cbie = csrs->DMC_Core_and_Block_Interrupt_Enable_Register;
1919
1920 dmu = GETMASK64(dmc_cbie, 63, 63);
1921 mmu = GETMASK64(dmc_cbie, 0, 0);
1922
1923 if (dmu && mmu) {
1924 csrs->DMC_Core_and_Block_Error_Status_Register |= MASK64(1,1);
1925 piu_mondo_interrupt(piup, INO_DMU, IRQ_RECEIVED);
1926 }
1927}
1928
1929
1930/*
1931 * Look up the PIU register type from its offset value
1932 */
1933pcie_csr_t piu_offset2reg(uint64_t offset, int *regx)
1934{
1935 int i;
1936
1937 /*
1938 * first to check the few interrupt registers
1939 * (PIU supports less number of these regs than the Fire for Niagara 1)
1940 */
1941 if ((offset > 0x6011D8) && (offset < 0x6011F0))
1942 return UND_PCIE_CSRS;
1943 if ((offset > 0x6015D8) && (offset < 0x6015F0))
1944 return UND_PCIE_CSRS;
1945
1946 for (i = 0; i < NUM_PCIE_CSRS; i++) {
1947 int nwords, diff = offset - pcie_csrs[i].offset;
1948
1949 if (diff == 0) {
1950 *regx = pcie_csrs[i].regx;
1951 return i;
1952 }
1953
1954 if (diff < 0)
1955 return UND_PCIE_CSRS;
1956
1957 if ((nwords = pcie_csrs[i].nwords) != 1) {
1958 int wordx = diff/8;
1959
1960 if (wordx < nwords) {
1961 *regx = pcie_csrs[i].regx + wordx;
1962 return i;
1963 }
1964 }
1965 }
1966
1967 return UND_PCIE_CSRS;
1968}
1969
1970
1971/*
1972 * Add the new PCIE device to the linked list
1973 */
1974void piu_register_pcie_device(pcie_model_t *piup, pcie_dev_inst_t *new)
1975{
1976 pcie_dev_inst_t *temp;
1977
1978 if (piup->pcie_devices_list_head == NULL) {
1979 piup->pcie_devices_list_head = new;
1980 return;
1981 }
1982
1983 temp = piup->pcie_devices_list_head;
1984 while (temp->next != NULL)
1985 temp = temp->next;
1986 temp->next = new;
1987}
1988
1989
1990/*
1991 * Get the PCIE end device with the given request ID
1992 */
1993pcie_dev_inst_t *
1994piu_find_pcie_dev(pcie_model_t *piup, void *dptr, pcie_space_t space_id)
1995{
1996 pcie_dev_inst_t *pcie_dev;
1997 int found = 0;
1998 config_dev_t *config_devp;
1999
2000 pcie_dev = piup->pcie_devices_list_head;
2001
2002 if (space_id == PCIE_CFG) {
2003 uint16_t req_id = *(uint16_t *)dptr;
2004
2005 while (pcie_dev != NULL) {
2006 if (pcie_dev->req_id == req_id) {
2007 found = 1;
2008 break;
2009 }
2010 pcie_dev = pcie_dev->next;
2011 }
2012 } else {
2013 while (pcie_dev != NULL) {
2014 uint64_t paddr = *(uint64_t *)dptr;
2015
2016 if (pcie_dev->pcie_dp->bar_test(pcie_dev->hdl, paddr, space_id)) {
2017 found = 1;
2018 break;
2019 }
2020 pcie_dev = pcie_dev->next;
2021 }
2022 }
2023
2024 if (!found)
2025 return(NULL);
2026
2027 return(pcie_dev);
2028}