Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / devices / n2_piu / include / sam_piu.h
CommitLineData
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
38using namespace std;
39
40extern "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
47class samPiu:public Module, genericPcieDevIf{
48private:
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
64public:
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
88public: // 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
141public: // 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
152public: // 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};