Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / devices / n2_ncu / include / ncu.h
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: ncu.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 __NCU_H__
24#define __NCU_H__
25
26
27/*
28 * this is the niagara2 ncu module. the original source is taken from legion
29 * with minor/cosmetic modifications. The name of the relevent functions is
30 * kept same as in legion so as to allow easy updates.
31 *
32 * The original source has related CSRs, which are not needed for this
33 * module, but are still added(though incomplete in certain instances) in case
34 * we need it in future.
35 */
36#include "pthread.h"
37#include <assert.h>
38#include "module.h"
39#include "types.h"
40#include "vcpu.h"
41#include "cpu_interface.h"
42
43static const char* piu_regions[] = {"cfgio","mem32","mem64","piu_8mb","unknown"};
44extern "C"{
45 static int access_ncu(uint32_t cpuid, void* obj, uint64_t paddr, mmi_bool_t wr, uint32_t size, uint64_t* buf, uint8_t bytemask);
46 int n2ncu_ui_cmd(void*, int argc, char * argv[]);
47}
48
49
50class n2Ncu:public Module{
51public:
52
53 #define MASK64( _high, _low ) ( ( (uint64_t)((~(uint64_t)0)>>(63-(_high))) ) & ( (uint64_t)( (~(uint64_t)0)<<(_low)) ) )
54 #define GETMASK64(x, hi, lo) (((uint64_t)(x) & MASK64((hi), (lo)))>>(lo))
55 /* src/procs/sunsparc/libniagara2/include/niagara2_device.h */
56
57 static const uint64_t NCU_CSR_BASE = 0x8000000000;
58 static const uint64_t NCU_CSR_SIZE = 0x100000000;
59 static const uint64_t PIU_MAX_REGION = 4;
60 static const uint64_t NCU_REG_MASK = 0x4ffff;
61 static const uint64_t NCU_TARGETS = 64; /* number of virtual cores */
62 static const uint64_t NCU_DEV_MAX = 128; /* max number of device Ids */
63 static const uint64_t NCU_DEV_ERR = 1; /* device Id for ECC error */
64 static const uint64_t NCU_DEV_SSI = 2; /* device Id for SSI interrupt */
65 static const uint64_t NCU_DEV_NIU_LB = 64; /* device Id range for NIU interrupt */
66 static const uint64_t NCU_DEV_NIU_UB = NCU_DEV_MAX-1;
67 static const uint64_t NCU_MONDO_INT_MASK = 0x40fff;
68 static const uint64_t NCU_MONDO_INT_BUSY = MASK64(6,6);
69 static const uint64_t NCU_SOC_MASK = MASK64(42,40)|MASK64(38,37)|MASK64(35,34)|MASK64(32,31)|MASK64(29,0);
70 static const uint64_t NCU_INT_MAN_MASK = NCU_DEV_MAX*8;
71
72 uint64_t NCU_INT_MAN_CPUID(uint64_t n){ return ((n&MASK64(13,8))>>8); }
73 static const uint64_t NCU_INT_ACK = 0;
74 static const uint64_t NCU_INT_NACK = -1;
75
76 static const uint64_t PIU_REGION_OFFSET_MASK = MASK64(35,24);
77 static const uint64_t PIU_REGION_OFFSET_MASK_HI = MASK64(39,36);
78
79 struct ncu_reg_t{
80 uint64_t int_man[NCU_DEV_MAX];
81 uint64_t mondo_int_vec;
82 uint64_t ser_num;
83 uint64_t efu_stat;
84 uint64_t bank_enb;
85 uint64_t bank_enb_stat;
86 uint64_t l2_idx_hash_en;
87 uint64_t l2_idx_hash_en_stat;
88 uint64_t pcie_a_mem32_offset_base;
89 uint64_t pcie_a_mem32_offset_mask;
90 uint64_t pcie_a_mem64_offset_base;
91 uint64_t pcie_a_mem64_offset_mask;
92 uint64_t pcie_a_iocon_offset_base;
93 uint64_t pcie_a_iocon_offset_mask;
94 uint64_t pcie_a_fsh;
95 uint64_t soc_esr;
96 uint64_t soc_log_enb;
97 uint64_t soc_intr_enb;
98 uint64_t soc_err_inject;
99 uint64_t soc_fatal_enb;
100 uint64_t soc_sii_err_syndrome;
101 uint64_t soc_ncu_err_syndrome;
102 uint64_t mondo_int_data0[NCU_TARGETS];
103 uint64_t mondo_int_data1[NCU_TARGETS];
104 uint64_t mondo_int_busy[NCU_TARGETS];
105 };
106
107 struct map_info_t{
108 uint64_t base;
109 uint64_t mask;
110 uint64_t size;
111 int func;
112 bool enable;
113 uint8_t priority;
114 int align_size;
115 int reverse_endian;
116
117 void info(){
118 printf("base<%llx>size<%llx>mask<%llx>en<%d>\n",base,size,mask,enable);
119 }
120
121 };
122
123 enum piu_region_t{
124 PIU_REGION_CFGIO = 0,
125 PIU_REGION_MEM32 = 1,
126 PIU_REGION_MEM64 = 2,
127 PIU_REGION_8MB = 3,
128 PIU_REGION_UNMAPPED
129 };
130
131 enum ncu_reg_offset_t{
132 INT_MAN = 0x00000,
133 MONDO_INT_VEC = 0x00a00,
134 SER_NUM = 0x01000,
135 EFU_STAT = 0x01008,
136 CORE_AVAIL = 0x01010,/* same as ASI_CORE_AVAILABLE */
137 BANK_AVAIL = 0x01018,
138 BANK_ENABLE = 0x01020,
139 BANK_ENABLE_STATUS = 0x01028,
140 L2_IDX_HASH_EN = 0x01030,
141 L2_IDX_HASH_EN_STATUS = 0x01038,
142 PCIE_A_MEM32_OFFSET_BASE = 0x02000,
143 PCIE_A_MEM32_OFFSET_MASK = 0x02008,
144 PCIE_A_MEM64_OFFSET_BASE = 0x02010,
145 PCIE_A_MEM64_OFFSET_MASK = 0x02018,
146 PCIE_A_IOCON_OFFSET_BASE = 0x02020,
147 PCIE_A_IOCON_OFFSET_MASK = 0x02028,
148 PCIE_A_FSH = 0x02030,
149 SOC_ESR = 0x03000,
150 SOC_LOG_ENABLE = 0x03008,
151 SOC_INTERRUPT_ENABLE = 0x03010,
152 SOC_ERROR_INJECTION = 0x03018,
153 SOC_FATAL_ERROR_ENABLE = 0x03020,
154 SOC_PENDING_ERROR_STATUS = 0x03028,/* same as SOC_ESR */
155 SOC_SII_ERROR_SYNDROME = 0x03030,
156 SOC_NCU_ERROR_SYNDROME = 0x03038,
157 MONDO_INT_DATA0 = 0x40000,
158 MONDO_INT_DATA1 = 0x40200,
159 MONDO_INT_ADATA0 = 0x40400,
160 MONDO_INT_ADATA1 = 0x40600,
161 MONDO_INT_BUSY = 0x40800,
162 MONDO_INT_ABUSY = 0x40a00
163 };
164
165 /*
166 * XXX need an interface to read asi registers from vonk to add support for
167 * ASI registers available through NCU
168 */
169
170
171 /*
172 * a list of registers that will be dumped and restored by this module.
173 * in case more registers are added, or some offsets change or any
174 * incompatible change happens, and there exist dumps with old format that need to be
175 * supported, then create a new dumpRegsV2[]. The restore
176 * function should be able to differtiate and handle correctly the
177 * different versions. Otherwise just modify the V1 array and dump/restore
178 * functions as needed.
179 */
180 static const uint64_t dumpRegsV1[25];
181
182private:
183
184 const char * current_dump_version;
185
186 bool UINT64_RANGE_CHECK(uint64_t _low, uint64_t _val, uint64_t _high){
187 return ((_val - _low) < (_high - _low));
188 }
189
190 void ASSIGN_NCU(uint64_t& _n,uint64_t _m,uint64_t val, uint64_t offset){
191 _n = val;
192 if(0LL != (val & ~(_m)))
193 debug_err("%s: WARNING: attempt to write to reserved field in NCU\n"
194 " Write 0x%llx to register %s (offset %llx)\n",
195 getName(), val, ncu_reg_name(offset),offset);
196 debug_more("%s: assigned %llx to register %s\n",getName(),val,ncu_reg_name(offset));
197
198 }
199 const char *ncu_reg_name(uint64_t reg);
200 void niagara2_pcie_mapping(piu_region_t region);
201
202
203
204
205public: // external interface fns. that can be called by other modules/system
206 int access_regs(uint32_t cpuid, uint64_t paddr, mmi_bool_t wr, uint32_t size,\
207 uint64_t* buf, uint8_t bytemask);
208 const map_info_t* getMap(piu_region_t region){ return &map[region]; }
209
210 // send mondo to target strand. return either ACK = 0, or NACK = -1
211 int sendPiuMondo(VCPU_InterruptRequest * r){
212 extern Vcpu *g_vcpu[NCPU_MAX];
213 debug_more("%s:sending interrupt to strand %x\n",getName(),r->itid);
214
215 int vector = regs.mondo_int_vec & 0x3f;
216 int target = r->itid;
217 int busy = regs.mondo_int_busy[target] >> 6 & 0x1;
218
219 if(busy)
220 return NCU_INT_NACK;
221
222 regs.mondo_int_data0[target] = r->data[0];
223 regs.mondo_int_data1[target] = r->data[1];
224 regs.mondo_int_busy[target] = 1 << 6;
225
226 r->data[7] = vector;
227 Vcpu *vcpu = get_vcpu(target);
228 if (!vcpu)
229 return NCU_INT_NACK;
230 vcpu->interrupt(r);
231 return NCU_INT_ACK;
232 }
233
234 int sendNiuMondo(VCPU_InterruptRequest * r){
235 extern Vcpu *g_vcpu[NCPU_MAX];
236
237 int vector = regs.int_man[r->isid] & 0x3f;
238 int target = r->itid;
239
240 r->data[7] = vector;
241
242 debug_more("%s:sending NIU interrupt tid:%x sid/ldg:%x vector:0x%x\n",getName(),r->itid, r->isid, vector);
243
244 Vcpu *vcpu = get_vcpu(target);
245 if (!vcpu)
246 return NCU_INT_NACK;
247 vcpu->interrupt(r);
248 return NCU_INT_ACK;
249 }
250
251 void handle_ui(int argc, char * argv[]);
252 void ui_cmd_usage(){
253 printf("ui format: %s <command> <command args> ... \n",getName());
254 printf("%s supports following UI commands\n",getName());
255 printf(" dump [<filename>]\n\
256 dump the CSR contents to \'filename\' \n\
257 default is stderr\n\
258 dump format is: <csr name> <csr offset> <csr value>\n");
259 printf(" restore <filename>\n\
260 restore the CSR contents from \'filename\' \n\
261 restore file format is same as dump file format\n");
262 printf(" debug [<level>]\n\
263 set the debug level for debug prints to \'level\'\n\
264 if \'level\' not provided, print current debug level\n\
265 \'level\' = [0|1|2]\n");
266 }
267
268public: // module interface
269
270 const char *get_help(){ return Module::get_help_string(); }
271 bool parse_arg(const char *){ return true; }
272 bool check_args(){return true; }
273 void init_done(){
274 mmi_map_physio(NCU_CSR_BASE,NCU_CSR_SIZE,(void*)this,access_ncu);
275 return;
276 }
277 void module_added(mmi_instance_t, const char*){ return; }
278 void module_deleted(mmi_instance_t, const char*){ return; }
279 void modinfo(){
280 printf("%s: N2 NCU module\n"
281 "iomap base<%llx size<%llx>\n",getName(), NCU_CSR_BASE,NCU_CSR_SIZE);
282 printf("PCIE MAP -->\n");
283 for(int i = 0; i < 3; i++){
284 printf("%s",piu_regions[i]);
285 map[i].info();
286 }
287 }
288 void *get_interface(const char*){ return (void*)this; }
289 const char *get_version(){ return "1.0"; }
290
291 bool dump(FILE *fp);
292 bool dump_v1(FILE *fp);
293 bool restore(FILE *fp);
294 bool restore_v1(FILE *fp);
295
296 n2Ncu(const char *_modname, const char *_instance_name);
297 ~n2Ncu(){}
298private:
299
300 ncu_reg_t regs;
301 map_info_t map[PIU_MAX_REGION];
302 int node_id;
303 pthread_mutex_t ncu_lock;
304
305 void ncu_init();
306
307};
308
309#endif // __NCU_H__
310
311