Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / devices / pcie_bridge / include / pcie_bridge.h
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: pcie_bridge.h
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#ifndef _PCIE_BRIDGE_
24#define _PCIE_BRIDGE_
25
26#include "pci.h"
27#include "pcie.h"
28#include "dr.h"
29#include "pci_common.h"
30#include "pci_bridge.h"
31#include "arg.h"
32#include <errno.h>
33#include <unistd.h>
34#include <list>
35
36#define BRIDGE_POWER_CAP_ADDR 0x40
37#define BRIDGE_MSI_CAP_ADDR 0x48
38#define BRIDGE_PCIE_CAP_ADDR 0x68
39
40#define BRIDGE_DEV_SERNUM_XCAP_ADDR 0x100
41#define SERNUM_VER_NXTPTR_OFFSET 2
42#define SERNUM_SN_LOW_OFFSET 4
43#define SERNUM_SN_HIGH_OFFSET 8
44
45#define BRIDGE_ADV_ERR_CAP_ADDR 0xfb4
46
47#define BRIDGE_PWRBGT_HDR_ADDR 0x138
48#define PWRBGT_DSEL_OFFSET 4
49#define PWRBGT_DATA_OFFSET 8
50#define PWRBGT_DATA_CAP_OFFSET 0xc
51
52
53class PcieBridge: public genericPcieDev, public Module{
54 // pcieBridgeIf is exported to the downstream pcie Bus.
55
56 pcieBusIf *secBusIf; // pcie bus intf on the secondary interface
57 const char * secBusName;
58
59 // pcie bus intf on the primary side is member of genericPcieDev
60
61 uint64_t mem64_base, mem64_limit;
62 uint32_t mem32_base, mem32_limit, io_base, io_limit;
63 bool upstream_port;
64
65 enum direction_t {downstream, upstream, peer};
66
67 direction_t direction(int BusNo, uint16_t reqId) {
68 uint16_t reqBus = reqId >> 8;
69 if (reqId == 0 || reqBus < BusNo)
70 return downstream;
71 else if (reqBus > BusNo)
72 return upstream;
73 else {
74 fprintf(stderr, "Peer request ID %x\n", reqId);
75 return peer;
76 }
77}
78 bridgeCommandReg * bCR;
79 bool io_mapped() {return bCR->io_mapped();}
80 bool mem_mapped() {return bCR->mem_mapped();}
81
82 bool pendingIntr[4];
83 typedef std::list<int > intxStatus;
84 intxStatus intLine[4]; // 4 lists of pending Intx interrupts,
85 // indexed with INT[A|B|C|D] type.
86 // For an upstream port -
87 // it holds the downstream port number of
88 // the asserting port.
89 // For a downstream port it holds the dev #
90 // An assert Intx message adds the port/dev
91 // # entry to this list, a deassert removes
92 // it. As long as there is an entry, an Intx
93 // message is pended to upstream bridge,
94 // otherwise a deassertIntx is send.
95 pthread_mutex_t intMutex;
96
97 // route the received Intx message to upstream bridge.
98 pcieCompleter assertIntx(pciExpMsgCode messageCode, uint16_t reqId,SAM_DeviceId *id){
99 uint16_t port_dev = reqId & 0xff;
100 // include both the dev and fun values
101
102 assert(messageCode >= MSG_Assert_INTA && messageCode <= MSG_Assert_INTD);
103
104 int line = upstream_port ? ( (port_dev >> 3 & 0x1f ) %4 + (messageCode - MSG_Assert_INTA)) % 4 : \
105 messageCode - MSG_Assert_INTA;
106
107 pthread_mutex_lock(&intMutex);
108 intLine[line].push_back(port_dev);
109 intLine[line].sort();
110 intLine[line].unique();
111
112 if(pendingIntr[line]){
113 debug_more("%s: asserting Intr%c from dev <%d> fun <%d> - Line already asserted\n",getName(),'A' + line, reqId >> 3 & 0x1f, reqId & 0x7 );
114
115 pthread_mutex_unlock(&intMutex);
116 return pcieCompleter(SC,getId());
117 }
118
119 pendingIntr[line] = true;
120 pthread_mutex_unlock(&intMutex);
121
122 debug_more("%s: asserting Intr%c from dev <%d> fun <%d>\n",getName(),'A' + line, reqId >> 3 & 0x1f, reqId & 0x7 );
123 uint8_t code = line + MSG_Assert_INTA;
124 msgRouting r = msgDB->msgCode2Routing((pciExpMsgCode)code);
125 return busIf->busif_msgAccess(code, r, getId(),id);
126
127 }
128
129 pcieCompleter deassertIntx(pciExpMsgCode messageCode, uint16_t reqId, SAM_DeviceId *id){
130 uint16_t port_dev = reqId & 0xff;
131 // include both the dev and fun values
132
133 assert(messageCode >= MSG_Deassert_INTA && messageCode <= MSG_Deassert_INTD);
134
135 int line = upstream_port ? ( (port_dev >> 3 & 0x1f ) %4 + (messageCode - MSG_Deassert_INTA)) % 4 : \
136 messageCode - MSG_Deassert_INTA;
137
138 pthread_mutex_lock(&intMutex);
139
140 intLine[line].remove(port_dev);
141 if(!intLine[line].empty()){
142 debug_more("%s: Deasserting Intr%c from dev <%d> fun <%d> - Line still asserted\n",getName(),'A' + line, reqId >> 3 & 0x1f, reqId & 0x7 );
143
144 pthread_mutex_unlock(&intMutex);
145 return pcieCompleter(SC,getId());
146 }
147
148 pendingIntr[line] = false;
149 pthread_mutex_unlock(&intMutex);
150 debug_more("%s: Deasserting Intr%c from dev <%d> fun <%d>\n",getName(),'A' + line, reqId >> 3 & 0x1f, reqId & 0x7 );
151
152 uint8_t code = line + MSG_Deassert_INTA;
153 msgRouting r = msgDB->msgCode2Routing((pciExpMsgCode)code);
154 return busIf->busif_msgAccess(code, r, getId(),id);
155 }
156
157 const char * dump_version1_0;
158 const char * current_dump_version;
159
160public:
161 bool devif_isBridge(){return true;}
162 PcieBridge(const char* modname, const char * instance_name);
163 ~PcieBridge();
164 void initPci();
165 void init_regs();
166 bool downstream_request(uint16_t reqId);
167
168 mmi_instance_t devif_getInstance() {return Module::instance;}
169 const char *devif_getName() {return Module::getName();}
170 void devif_confAccessCb(bool wr, uint64_t offset, uint8_t be=0xf);
171
172 // Module functions
173 const char *get_help();
174 bool parse_arg(const char *);
175 bool check_args();
176 void init_done();
177 void module_added(mmi_instance_t, const char*);
178 void module_deleted(mmi_instance_t, const char*);
179 void modinfo();
180 void *get_interface(const char*);
181 bool dump(FILE* fp);
182 bool restore(FILE* fp);
183
184 // genericPcieDev virtual/unimplemented functions
185 // or functions that need to be overridden eg
186 // devif_memAccess, devif_ioAccess, etc.
187 pcieCompleter devif_memAccess(bool wr, uint64_t addr, addrMd_xactnType mode, void * data,\
188 uint16_t length, uint8_t be, uint16_t reqId, tlp_X args,SAM_DeviceId *samId);
189
190 pcieCompleter devif_confAccess(bool wr, uint32_t offset, void * data, \
191 uint8_t be,uint16_t reqId, addrMd_xactnType tType, uint16_t length, tlp_X args,SAM_DeviceId *samId);
192
193 pcieCompleter devif_ioAccess(bool wr, uint64_t addr, void * data, uint8_t be, \
194 uint16_t reqId, uint16_t length, tlp_X args,SAM_DeviceId *samId);
195
196 pcieCompleter devif_msgAccess(uint8_t messageCode, msgRouting route, uint64_t tarIdOrAddr, uint16_t reqId, \
197 void * data, uint16_t length, uint16_t vendorId, uint32_t vendor_data, tlp_X args,SAM_DeviceId *samId);
198 int devif_getPriBusNo() {return (confSpace->readConf(PCI_BCNF_PRIBUS) & 0xff);}
199 int devif_getBusNo() {return (confSpace->readConf(PCI_BCNF_SECBUS) & 0xff);}
200 int devif_getSubBusNo() {return (confSpace->readConf(PCI_BCNF_SUBBUS) & 0xff);}
201
202
203 void handle_ui(int, char**);
204 void ui_cmd_usage(){
205 printf("ui format: %s <command> <command args> ... \n",getName());
206 printf("%s supports following UI commands\n",getName());
207 printf(" debug [<level>]\n\
208 set the debug level for debug prints to \'level\'\n\
209 if \'level\' not provided, print current debug level\n\
210 \'level\' = [0|1|2]\n");
211 printf(" dump [<filename>]\n \
212 dump the PCIE CSR contents to <filename>.pci in cwd\n \
213 default is stderr\n \
214 dump format is: <csr pciconf offset> <csr value> <csr r/w mask> <csr size> <csr name>\n");
215 printf(" restore <filename>\n\
216 restore the PCIE CSR contents from <filename>.pci in cwd \n\
217 restore file format is same as dump file format\n");
218 }
219
220
221};
222
223#endif