Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | /* |
2 | * ========== Copyright Header Begin ========================================== | |
3 | * | |
4 | * OpenSPARC T2 Processor File: sam_piu.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 | /* | |
24 | * This is a port from Legions PIU library to SAM, with the intention | |
25 | * of making as minimal changes as possible to the legion library sources, | |
26 | * while making it mmi compliant as much as possible. | |
27 | * Code that is not needed from SAM perspective is deleted. | |
28 | */ | |
29 | ||
30 | ||
31 | #include "module.h" | |
32 | #include "arg.h" | |
33 | #include "ncu.h" | |
34 | #include "piu.h" | |
35 | #include "dr.h" | |
36 | #include <list> | |
37 | ||
38 | using namespace std; | |
39 | ||
40 | extern "C"{ | |
41 | static int access_piu(uint32_t cpuid, void* obj, uint64_t paddr, mmi_bool_t wr, uint32_t size, uint64_t* buf, uint8_t bytemask); | |
42 | int n2piu_ui_cmd(void*, int argc, char * argv[]); | |
43 | void samPiu_1ms_callback(void * piuobj, void * ); | |
44 | ||
45 | } | |
46 | ||
47 | class samPiu:public Module, genericPcieDevIf{ | |
48 | private: | |
49 | int primary_bus_no; | |
50 | int secondary_bus_no; | |
51 | int subordinate_bus_no; | |
52 | int device; | |
53 | int function; | |
54 | ||
55 | const char *bus; // pcie bus name on the downstream | |
56 | mmi_instance_t busMod; // pcie bus instance | |
57 | ||
58 | const char * ncu; | |
59 | mmi_instance_t ncuMod; | |
60 | ||
61 | pcie_model_t piuModel; | |
62 | const char * N2_PIU_VERSION; | |
63 | ||
64 | public: | |
65 | pcieBusIf *busIf; // pcie bus interface | |
66 | n2Ncu * ncuIf; | |
67 | ||
68 | static const uint64_t PIU_CSR_BASE = 0x8800000000; | |
69 | static const uint64_t PIU_CSR_SIZE = 0x800000; // 8 MB | |
70 | ||
71 | // this region maps the pcie conf/io/mem32/mem64 regions of | |
72 | // downstream devices | |
73 | static const uint64_t PIU_PCIE_BASE = 0xc000000000; | |
74 | static const uint64_t PIU_PCIE_SIZE = 0x1000000000; // 64 GB | |
75 | ||
76 | /* | |
77 | * PIU CSR space allows only r/w's of 8 bytes. | |
78 | * pcie config/io space allows r/w' s of 1,2,4 bytes. | |
79 | * pcie mem32/mem64 allows r/w's of 1,2,4,8 bytes along with | |
80 | * partial writes, which specify a bytemask. | |
81 | */ | |
82 | ||
83 | // some useful offsets into PIU_CSR_BASE | |
84 | static const uint64_t PIU_DMU_PCIE_CONFREG_OFFSET = 0x653100; | |
85 | ||
86 | ||
87 | ||
88 | public: // genericPcieDevIf | |
89 | bool devif_isBridge(){ return false; } | |
90 | bool devif_isRootCmplx(){return true; } | |
91 | ||
92 | // piu does not support CONFIG access as a target | |
93 | pcieCompleter devif_confAccess(bool wr, uint32_t offset, void * data, \ | |
94 | uint8_t be, uint16_t reqId, addrMd_xactnType, uint16_t, tlp_X,SAM_DeviceId *id){ | |
95 | return pcieCompleter(CA); | |
96 | } | |
97 | ||
98 | // piu does not support IO access as a target | |
99 | pcieCompleter devif_ioAccess(bool wr, uint32_t addr, void * data, | |
100 | uint8_t be, uint16_t reqId, uint16_t length , tlp_X args,SAM_DeviceId *id){ | |
101 | return pcieCompleter(CA); | |
102 | } | |
103 | ||
104 | int devif_getBusNo(){ return secondary_bus_no; } | |
105 | int devif_getPriBusNo(){ return primary_bus_no; } | |
106 | int devif_getSubBusNo() { return subordinate_bus_no; } | |
107 | int devif_getDevice(){ return device; } | |
108 | int devif_getFunction(){ return function; } | |
109 | const char *devif_getName(){ return Module::getName(); } | |
110 | const char *devif_getBusName(){ return "N2 PIU internal bus"; } | |
111 | mmi_instance_t devif_getInstance(){ return Module::getInstance(); } | |
112 | ||
113 | void devif_confAccessCb(bool wr, uint64_t offset, uint8_t be){} | |
114 | ||
115 | pcieCompleter devif_memAccess(bool wr, uint64_t addr, addrMd_xactnType mode,\ | |
116 | void * data, uint16_t length, uint8_t be, uint16_t reqId, tlp_X args,SAM_DeviceId *id); | |
117 | ||
118 | pcieCompleter devif_msgAccess(uint8_t messageCode, msgRouting route, \ | |
119 | uint64_t tarIdOrAddr, uint16_t reqId, \ | |
120 | void * data, uint16_t length, \ | |
121 | uint16_t vendorId, uint32_t vendor_data, tlp_X args,SAM_DeviceId *id); | |
122 | ||
123 | ||
124 | // intr 0-19 are reserved, 20-23 intx, 24-59 ev q, 62 dmu, 63 peu | |
125 | bool pendingIntr[64]; | |
126 | typedef list<int > intxStatus; | |
127 | intxStatus intLine[4]; // 4 lists of pending interrupts, 1 for every device from a bus | |
128 | pthread_mutex_t intxMutex; | |
129 | pthread_mutex_t pendIntMutex; | |
130 | pthread_mutex_t piuMutex; | |
131 | pthread_mutex_t msiMutex[36]; // 36 event queues in total | |
132 | static const int MONDO_INTA = 20; | |
133 | ||
134 | ||
135 | pthread_mutex_t ncuMutex; | |
136 | typedef list<VCPU_InterruptRequest* > irqList; | |
137 | irqList irql; | |
138 | ||
139 | uint64_t event_fire_time; | |
140 | ||
141 | public: // Module interface | |
142 | const char *get_help(); | |
143 | bool parse_arg(const char *); | |
144 | bool check_args(); | |
145 | void init_done(); | |
146 | void module_added(mmi_instance_t, const char*); | |
147 | void module_deleted(mmi_instance_t, const char*); | |
148 | void modinfo(); | |
149 | void *get_interface(const char*); | |
150 | const char *get_version(); | |
151 | ||
152 | public: // others | |
153 | samPiu(const char *modname, const char *instance_name); | |
154 | n2Ncu * getNcu(){ return ncuIf; } | |
155 | uint16_t getReqId(){ return PCIE_REQUESTER_ID(primary_bus_no,device,function); } | |
156 | void sendMondo(pcie_mondo_t *); | |
157 | int handlePio(uint32_t cpuid,uint64_t paddr, mmi_bool_t wr, \ | |
158 | uint32_t size, uint64_t* buf, uint8_t bytemask); | |
159 | ||
160 | bool setPending(int ino, bool set){ | |
161 | pthread_mutex_lock(&pendIntMutex); | |
162 | bool ret = pendingIntr[ino]; | |
163 | pendingIntr[ino] = set; | |
164 | pthread_mutex_unlock(&pendIntMutex); | |
165 | return ret; | |
166 | } | |
167 | ||
168 | bool getPending(int ino){ | |
169 | return pendingIntr[ino]; | |
170 | } | |
171 | ||
172 | ||
173 | void setIntx(int devid,int line, bool set){ | |
174 | ||
175 | //printf("piu intx line %d set to %d\n",line,set); | |
176 | ||
177 | if(line < 0 || line > 3) | |
178 | assert(0); | |
179 | pthread_mutex_lock(&intxMutex); | |
180 | if(set){ | |
181 | intLine[line].push_back(devid); | |
182 | intLine[line].sort(); | |
183 | intLine[line].unique(); | |
184 | setPending(line + MONDO_INTA, true); | |
185 | }else{ | |
186 | intLine[line].remove(devid); | |
187 | if(intLine[line].empty()) | |
188 | setPending(line + MONDO_INTA, false); | |
189 | } | |
190 | pthread_mutex_unlock(&intxMutex); | |
191 | } | |
192 | ||
193 | void handle_ui(int argc, char * argv[]); | |
194 | void ui_cmd_usage(){ | |
195 | printf("ui format: %s <command> <command args> ... \n",getName()); | |
196 | printf("%s supports following UI commands\n",getName()); | |
197 | printf(" dump [<filename>]\n \ | |
198 | dump the CSR contents to \'filename\' \n \ | |
199 | default is stderr\n \ | |
200 | dump format is: <csr name> <csr physical offset> [<csr index> <csr value>,]+\n \ | |
201 | : pending interrupts (msi event q, intx)\n"); | |
202 | printf(" restore <filename>\n\ | |
203 | restore the CSR contents from \'filename\' \n\ | |
204 | restore file format is same as dump file format\n"); | |
205 | printf(" debug [<level>]\n\ | |
206 | set the debug level for debug prints to \'level\'\n\ | |
207 | if \'level\' not provided, print current debug level\n\ | |
208 | \'level\' = [0|1|2]\n"); | |
209 | } | |
210 | ||
211 | void samPiu::timer_callback(); | |
212 | ||
213 | bool dump(FILE *fp); | |
214 | bool restore(FILE *fp); | |
215 | void dump_piu_csrs(FILE * fp); | |
216 | void dump_intr(FILE * fp); | |
217 | void dump_irq(FILE * fp); | |
218 | void restore_piu_csrs(FILE * fp); | |
219 | void restore_intr(FILE * fp); | |
220 | void restore_irq(FILE * fp); | |
221 | ||
222 | ~samPiu(){} | |
223 | }; |