Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / devices / n2_ncu / ncu.cc
CommitLineData
920dae64
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: ncu.cc
4// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
5// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
6//
7// The above named program is free software; you can redistribute it and/or
8// modify it under the terms of the GNU General Public
9// License version 2 as published by the Free Software Foundation.
10//
11// The above named program is distributed in the hope that it will be
12// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14// General Public License for more details.
15//
16// You should have received a copy of the GNU General Public
17// License along with this work; if not, write to the Free Software
18// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
19//
20// ========== Copyright Header End ============================================
21#include "ncu.h"
22
23static const char *n2ncu_help = "SAM N2 NCU module\n\
24Sysconf format is :\n\
25sysconf n2_ncu <instance_name> \n\
26For UI help type <instance name> \n\
27For module specific info type \"modinfo <instance name>\"";
28
29static int access_ncu(uint32_t cpuid, void* obj, uint64_t paddr, mmi_bool_t wr, uint32_t size, uint64_t* buf, uint8_t bytemask){
30 n2Ncu * ncu = (n2Ncu*)obj;
31 return ncu->access_regs(cpuid,paddr,wr,size,buf,bytemask);
32}
33
34int n2ncu_ui_cmd(void * obj, int argc, char * argv[]){
35 n2Ncu * i = (n2Ncu *)obj;
36 i->handle_ui(argc, argv);
37 return 0;
38}
39
40
41const uint64_t n2Ncu::dumpRegsV1[25] = {
42 INT_MAN,
43 MONDO_INT_VEC,
44 SER_NUM,
45 EFU_STAT,
46 BANK_ENABLE,
47 BANK_ENABLE_STATUS,
48 L2_IDX_HASH_EN,
49 L2_IDX_HASH_EN_STATUS,
50 PCIE_A_MEM32_OFFSET_BASE,
51 PCIE_A_MEM32_OFFSET_MASK,
52 PCIE_A_MEM64_OFFSET_BASE,
53 PCIE_A_MEM64_OFFSET_MASK,
54 PCIE_A_IOCON_OFFSET_BASE,
55 PCIE_A_IOCON_OFFSET_MASK,
56 PCIE_A_FSH,
57 SOC_ESR,
58 SOC_LOG_ENABLE,
59 SOC_INTERRUPT_ENABLE,
60 SOC_ERROR_INJECTION,
61 SOC_FATAL_ERROR_ENABLE,
62 SOC_SII_ERROR_SYNDROME,
63 SOC_NCU_ERROR_SYNDROME,
64 MONDO_INT_DATA0,
65 MONDO_INT_DATA1,
66 MONDO_INT_BUSY,
67};
68
69const char * Module::get_help_string(){
70 return n2ncu_help;
71}
72
73Module * Module::create(const char *_modname, const char *_instance_name){
74 return new n2Ncu(_modname, _instance_name);
75}
76
77n2Ncu::n2Ncu(const char *_modname, const char *_instance_name)
78 : Module(_modname, _instance_name){
79
80 ncu_init();
81 mmi_register_instance_cmd(getInstance(),n2ncu_help,n2ncu_ui_cmd);
82 current_dump_version = strdup("v1.0");
83}
84
85
86void n2Ncu::ncu_init(){
87 uint64_t device;
88 int i;
89
90 //pthread_mutex_init(&ncu_lock, NULL);
91
92 /*
93 * setup init value (NCU spec, v0.99)
94 */
95 for (device=0; device < NCU_DEV_MAX; device++) {
96 regs.int_man[device] = 0x0;
97 }
98
99 regs.mondo_int_vec = 0x0;
100 regs.ser_num = 0xdeadbeef;
101 regs.efu_stat = MASK64(63,0);
102 regs.bank_enb = 0xff;
103 regs.bank_enb_stat = 0x3cf;
104 regs.l2_idx_hash_en_stat = false;
105 regs.pcie_a_mem32_offset_base = 0x0;
106 regs.pcie_a_mem32_offset_mask = MASK64(39,36);
107 regs.pcie_a_mem64_offset_base = 0x0;
108 regs.pcie_a_mem64_offset_mask = MASK64(39,36);
109 regs.pcie_a_iocon_offset_base = 0x0;
110 regs.pcie_a_iocon_offset_mask = MASK64(39,36);
111 regs.pcie_a_fsh = 0x0;
112 regs.soc_esr = 0x0;
113 regs.soc_log_enb = 0x1fffffff;
114 regs.soc_intr_enb = 0x0;
115 regs.soc_err_inject = 0x0;
116 regs.soc_fatal_enb = 0x0;
117 regs.soc_sii_err_syndrome = 0x0;
118 regs.soc_ncu_err_syndrome = 0x0;
119
120 for (i = 0; i < NCU_TARGETS; i++) {
121 regs.mondo_int_data0[i] = 0x0;
122 regs.mondo_int_data1[i] = 0x0;
123 regs.mondo_int_busy[i] = 0x0; //MASK64(6,6);
124 }
125 return;
126}
127
128
129
130// support 8 byte reads/writes of registers.
131int n2Ncu::access_regs(uint32_t cpuid, uint64_t paddr, mmi_bool_t wr, uint32_t size,\
132 uint64_t* buf, uint8_t bytemask){
133
134 if(size != 8){
135 debug_err("%s ERROR: %s access of size %d at addr %llx\n", \
136 getName(),wr?"WITE":"READ",size,paddr);
137 return -1;
138 }
139
140 if(paddr & 7){
141 debug_err("%s ERROR: unaligned %s access of size %d at addr %llx\n", \
142 getName(),wr?"WITE":"READ",size,paddr);
143 return -1;
144 }
145
146 uint64_t reg = paddr & NCU_REG_MASK;
147
148 if (reg < MONDO_INT_VEC)
149 reg = reg & NCU_INT_MAN_MASK;
150
151 if (reg >= MONDO_INT_DATA0) {
152 if (UINT64_RANGE_CHECK(MONDO_INT_DATA0, reg, MONDO_INT_DATA1))
153 reg = MONDO_INT_DATA0;
154 if (UINT64_RANGE_CHECK(MONDO_INT_DATA1, reg, MONDO_INT_ADATA0))
155 reg = MONDO_INT_DATA1;
156 if (UINT64_RANGE_CHECK(MONDO_INT_ADATA0, reg, MONDO_INT_ADATA1))
157 reg = MONDO_INT_ADATA0;
158 if (UINT64_RANGE_CHECK(MONDO_INT_ADATA1, reg, MONDO_INT_BUSY))
159 reg = MONDO_INT_ADATA1;
160 if (UINT64_RANGE_CHECK(MONDO_INT_BUSY, reg, MONDO_INT_ABUSY))
161 reg = MONDO_INT_BUSY;
162 }
163
164 //pthread_mutex_lock( &ncu_lock );
165
166 uint64_t val;
167 switch(wr){
168 case true: //8 byte write
169 val = *buf;
170
171 switch(reg){
172 case INT_MAN:
173 {
174 int idx;
175 idx = (paddr >> 3) & (NCU_DEV_MAX-1);
176 ASSIGN_NCU(regs.int_man[idx],MASK64(13,8)|MASK64(5,0),val,reg);
177 break;
178 }
179 case MONDO_INT_VEC:
180 ASSIGN_NCU(regs.mondo_int_vec, MASK64(5,0), val, reg);
181 break;
182 case SER_NUM:
183 case EFU_STAT:
184 case CORE_AVAIL:
185 case BANK_AVAIL:
186 case BANK_ENABLE_STATUS:
187 case L2_IDX_HASH_EN_STATUS:
188 case MONDO_INT_DATA0:
189 case MONDO_INT_DATA1:
190 case MONDO_INT_ADATA0:
191 case MONDO_INT_ADATA1:
192 debug_err("%s: attempted write to RO register\n \
193 Write 0x%llx to register %s (offset 0x%llx\n",\
194 getName(),val, ncu_reg_name(reg), reg);
195 break;
196 case PCIE_A_MEM32_OFFSET_BASE:
197 ASSIGN_NCU( regs.pcie_a_mem32_offset_base, MASK64(63,63)|MASK64(35,24), val, reg);
198 niagara2_pcie_mapping(PIU_REGION_MEM32);
199 break;
200 case PCIE_A_MEM32_OFFSET_MASK:
201 ASSIGN_NCU( regs.pcie_a_mem32_offset_mask, MASK64(39,24), val, reg);
202 niagara2_pcie_mapping(PIU_REGION_MEM32);
203 break;
204 case PCIE_A_MEM64_OFFSET_BASE:
205 ASSIGN_NCU( regs.pcie_a_mem64_offset_base, MASK64(63,63)|MASK64(35,24), val, reg);
206 niagara2_pcie_mapping(PIU_REGION_MEM64);
207 break;
208 case PCIE_A_MEM64_OFFSET_MASK:
209 ASSIGN_NCU( regs.pcie_a_mem64_offset_mask, MASK64(39,24), val, reg);
210 niagara2_pcie_mapping(PIU_REGION_MEM64);
211 break;
212 case PCIE_A_IOCON_OFFSET_BASE:
213 ASSIGN_NCU( regs.pcie_a_iocon_offset_base, MASK64(63,63)|MASK64(35,24), val, reg );
214 niagara2_pcie_mapping(PIU_REGION_CFGIO);
215 break;
216 case PCIE_A_IOCON_OFFSET_MASK:
217 ASSIGN_NCU( regs.pcie_a_iocon_offset_mask, MASK64(39,24) ,val, reg );
218 niagara2_pcie_mapping(PIU_REGION_CFGIO);
219 break;
220 case BANK_ENABLE:
221 case L2_IDX_HASH_EN:
222 debug_more("%s: register %s (offset 0x%llx) not implemented\n", \
223 getName(),ncu_reg_name(reg), reg);
224 break;
225 case PCIE_A_FSH:
226 ASSIGN_NCU( regs.pcie_a_fsh,~0ULL, val, reg);
227 break;
228 case SOC_ESR:
229 ASSIGN_NCU( regs.soc_esr, MASK64(63,63)|NCU_SOC_MASK, val, reg );
230 break;
231 case SOC_LOG_ENABLE:
232 ASSIGN_NCU( regs.soc_log_enb, MASK64(42,0) , val, reg );
233 break;
234 case SOC_INTERRUPT_ENABLE:
235 ASSIGN_NCU( regs.soc_intr_enb, MASK64(42,0), val, reg );
236 break;
237 case SOC_ERROR_INJECTION:
238 ASSIGN_NCU( regs.soc_err_inject, MASK64(42,0), val, reg );
239 break;
240 case SOC_FATAL_ERROR_ENABLE:
241 ASSIGN_NCU( regs.soc_fatal_enb, MASK64(42,0), val, reg );
242 break;
243 case SOC_PENDING_ERROR_STATUS:
244 /*
245 * same as SOC_ESR
246 */
247 ASSIGN_NCU( regs.soc_esr, MASK64(63,63)|NCU_SOC_MASK, val, reg );
248 break;
249 case SOC_SII_ERROR_SYNDROME:
250 ASSIGN_NCU( regs.soc_sii_err_syndrome, MASK64(63,63)|MASK64(58,0), val, reg );
251 break;
252 case SOC_NCU_ERROR_SYNDROME:
253 ASSIGN_NCU( regs.soc_ncu_err_syndrome, MASK64(63,58)|MASK64(55,0), val, reg );
254 break;
255 case MONDO_INT_BUSY:
256 {
257 int target;
258 target = (paddr >> 3) & (NCU_TARGETS-1);
259 ASSIGN_NCU( regs.mondo_int_busy[target], MASK64(6,6), val, reg );
260 break;
261 }
262 case MONDO_INT_ABUSY:
263 {
264 int target = cpuid;
265 ASSIGN_NCU( regs.mondo_int_busy[target], MASK64(6,6), val, reg );
266 break;
267 }
268 default:
269 debug_err("%s: ERROR unknow register access at offset %llx\n",getName(),reg);
270 //pthread_mutex_unlock( &ncu_lock );
271 return -1;
272 }
273
274 //debug_more("%s: write at register %s (offset %llx)\n", getName(), ncu_reg_name(reg), val);
275 //pthread_mutex_unlock( &ncu_lock );
276 return 0;
277
278 case false: // 8 byte read
279 switch(reg){
280 case INT_MAN:
281 {
282 int idx;
283 idx = (paddr >> 3) & (NCU_DEV_MAX-1);
284 val = regs.int_man[idx];
285 break;
286 }
287 case MONDO_INT_VEC:
288 val = regs.mondo_int_vec;
289 break;
290 case SER_NUM:
291 // XXX this ro register becomes a big bottleneck as the cpu
292 // idleloop continuously reads this register. Remove the
293 // locks to reduce contention
294 val = regs.ser_num;
295 // val = 0xdeadbeef;
296 break;
297 case CORE_AVAIL:
298 // XXX need to access the ASI register to provide access.
299 debug_err("%s: ERROR:unimplemented reg read at %s",getName(),ncu_reg_name(reg));
300 break;
301 case EFU_STAT:
302 val = regs.efu_stat;
303 break;
304 case BANK_AVAIL:
305 case BANK_ENABLE:
306 val = regs.bank_enb;
307 break;
308 case BANK_ENABLE_STATUS:
309 val = regs.bank_enb_stat;
310 break;
311 case PCIE_A_MEM32_OFFSET_BASE:
312 val = regs.pcie_a_mem32_offset_base;
313 break;
314 case PCIE_A_MEM32_OFFSET_MASK:
315 val = regs.pcie_a_mem32_offset_mask;
316 break;
317 case PCIE_A_MEM64_OFFSET_BASE:
318 val = regs.pcie_a_mem64_offset_base;
319 break;
320 case PCIE_A_MEM64_OFFSET_MASK:
321 val = regs.pcie_a_mem64_offset_mask;
322 break;
323 case PCIE_A_IOCON_OFFSET_BASE:
324 val = regs.pcie_a_iocon_offset_base;
325 break;
326 case PCIE_A_IOCON_OFFSET_MASK:
327 val = regs.pcie_a_iocon_offset_mask;
328 break;
329 case L2_IDX_HASH_EN:
330 case L2_IDX_HASH_EN_STATUS:
331 debug_more("%s:register %s (offset 0x%llx) not implemented\n",
332 getName(), ncu_reg_name(reg), reg );
333 val = 0;
334 break;
335 case PCIE_A_FSH:
336 val = regs.pcie_a_fsh;
337 break;
338 case SOC_ESR:
339 val = regs.soc_esr;
340 break;
341 case SOC_LOG_ENABLE:
342 val = regs.soc_log_enb;
343 break;
344 case SOC_INTERRUPT_ENABLE:
345 val = regs.soc_intr_enb;
346 break;
347 case SOC_ERROR_INJECTION:
348 val = regs.soc_err_inject;
349 break;
350 case SOC_FATAL_ERROR_ENABLE:
351 val = regs.soc_fatal_enb;
352 break;
353 case SOC_PENDING_ERROR_STATUS:
354 /*
355 * same as SOC_ESR
356 */
357 val = regs.soc_esr;
358 break;
359 case SOC_SII_ERROR_SYNDROME:
360 val = regs.soc_sii_err_syndrome;
361 break;
362 case SOC_NCU_ERROR_SYNDROME:
363 val = regs.soc_ncu_err_syndrome;
364 break;
365 case MONDO_INT_DATA0:
366 {
367 int target = (paddr >> 3) & (NCU_TARGETS-1);
368 val = regs.mondo_int_data0[target];
369 break;
370 }
371 case MONDO_INT_DATA1:
372 {
373 int target = (paddr >> 3) & (NCU_TARGETS-1);
374 val = regs.mondo_int_data1[target];
375 break;
376 }
377 case MONDO_INT_ADATA0:
378 {
379 int target = cpuid;
380 val = regs.mondo_int_data0[target];
381 break;
382 }
383 case MONDO_INT_ADATA1:
384 {
385 int target = cpuid;
386 val = regs.mondo_int_data1[target];
387 break;
388 }
389 case MONDO_INT_BUSY:
390 {
391 int target = (paddr >> 3) & (NCU_TARGETS-1);
392 val = regs.mondo_int_busy[target];
393 break;
394 }
395 case MONDO_INT_ABUSY:
396 {
397 int target = cpuid;
398 val = regs.mondo_int_busy[target];
399 break;
400 }
401 default:
402 *buf = 0;
403 debug_err("%s: ERROR unknow read register access at offset %llx\n",getName(),reg);
404 //pthread_mutex_unlock( &ncu_lock );
405 return -1;
406 }
407
408 *buf = val;
409 debug_more("%s: read register %s (value 0x%llx)\n", getName(), ncu_reg_name(reg), val);
410 //pthread_mutex_unlock( &ncu_lock );
411 return 0;
412
413 default:
414 *buf = 0;
415 //pthread_mutex_unlock( &ncu_lock );
416 return -1;
417 }
418}
419
420
421
422/*
423 * Create address mapping to access PCIE Cfg/IO, MEM32 and MEM64 space
424 */
425void n2Ncu::niagara2_pcie_mapping(piu_region_t region){
426 uint64_t base, mask, size;
427 bool enable;
428 const char *name[3] = {"Cfg/IO", "Mem32", "Mem64"};
429
430 switch(region){
431 case PIU_REGION_CFGIO:
432 base = regs.pcie_a_iocon_offset_base;
433 mask = regs.pcie_a_iocon_offset_mask;
434 break;
435 case PIU_REGION_MEM32:
436 base = regs.pcie_a_mem32_offset_base;
437 mask = regs.pcie_a_mem32_offset_mask;
438 break;
439 case PIU_REGION_MEM64:
440 base = regs.pcie_a_mem64_offset_base;
441 mask = regs.pcie_a_mem64_offset_mask;
442 break;
443 default:
444 assert(0);
445 }
446
447
448 enable = GETMASK64(base,63,63);
449 base &= PIU_REGION_OFFSET_MASK;
450 mask &= PIU_REGION_OFFSET_MASK;
451
452 if(enable){
453 size = ~(MASK64(63,36)|mask) + 1;
454 map[region].base = base;
455 map[region].mask = mask;
456 map[region].size = size;
457 map[region].enable = enable;
458
459 debug_more("%s:PCIE %s is mapped at 0x%llx - 0x%llx\n", \
460 getName(),name[region],base,base+size-1);
461 }
462}
463
464bool n2Ncu::dump_v1(FILE * fp){
465 const char * dump_version = "v1.0";
466 fwrite(dump_version,strlen(dump_version),1,fp);
467 fwrite("\n",strlen("\n"),1,fp);
468
469 for(int i = 0; i < (sizeof(dumpRegsV1)/sizeof(uint64_t)); i++ ){
470 char buf[64 * 1024], tcptr[64 * 1024];
471 sprintf(buf,"%-50s0x%-8llx ",ncu_reg_name(dumpRegsV1[i]),dumpRegsV1[i]);
472 uint64_t base = dumpRegsV1[i];
473 uint64_t val = 0;
474 switch(dumpRegsV1[i]){
475 case INT_MAN:
476 for(int j = 0; j < NCU_DEV_MAX; j++){
477 access_regs(0,base + j*8, mmi_false, 8, &val,0xff);
478 sprintf(tcptr, "0x%04x 0x%016llx,",j,val);
479 strcat(buf,tcptr);
480 }
481 break;
482 case MONDO_INT_DATA0:
483 case MONDO_INT_DATA1:
484 case MONDO_INT_BUSY:
485 for(int j = 0; j < NCU_TARGETS; j++){
486 access_regs(0,base + j*8, mmi_false, 8, &val,0xff);
487 sprintf(tcptr, "0x%04x 0x%016llx,",j,val);
488 strcat(buf,tcptr);
489 }
490 break;
491 default:
492 access_regs(0,base,mmi_false,8,&val,0xff);
493 sprintf(tcptr, "0x%016llx,",val);
494 strcat(buf,tcptr);
495 break;
496 }
497 fwrite(buf,strlen(buf),1,fp);
498 fwrite("\n",strlen("\n"),1,fp);
499 }
500 fflush(fp);
501 if(fp != stderr)
502 fclose(fp);
503 return true;
504}
505
506
507bool n2Ncu::dump(FILE * fp){
508
509 if(!strcmp(current_dump_version,"v1.0"))
510 return dump_v1(fp);
511 else {
512 assert(0);
513 }
514}
515
516bool n2Ncu::restore(FILE * fp){
517 const int bufsize = 64 * 1024;
518 char buf[bufsize];
519 fgets(buf,bufsize,fp);
520
521 buf[strlen(buf)-1] = 0;
522
523 if(!strcmp(buf,"v1.0")){
524 return restore_v1(fp);
525 }else{
526 printf("%s restore: dump version mismatch, restore failed\n",getName());
527 return false;
528 }
529}
530
531// if the CSR offsets change, this function may need change as well
532bool n2Ncu::restore_v1(FILE * fp){
533 const int bufsize = 64 * 1024;
534 char buf[bufsize];
535
536 while(fgets(buf,bufsize,fp)){
537 strtok(buf," "); // csr name, ignore
538 const char * csr_offset = strtok(0," "); // csr offset
539 uint64_t offset = strtoull(csr_offset,0,0);
540 switch(offset){
541 case INT_MAN:
542 for(int j = 0; j < NCU_DEV_MAX; j++){
543 const char * csr_index = strtok(0," ");
544 uint64_t index = strtoull(csr_index,0,0);
545 const char * csr_val = strtok(0,",");
546 uint64_t val = strtoull(csr_val,0,0);
547 regs.int_man[index] = val;
548 }
549 break;
550 case MONDO_INT_DATA0:
551 for(int j = 0; j < NCU_TARGETS; j++){
552 const char * csr_index = strtok(0," ");
553 uint64_t index = strtoull(csr_index,0,0);
554 const char * csr_val = strtok(0,",");
555 uint64_t val = strtoull(csr_val,0,0);
556 regs.mondo_int_data0[index] = val;
557 }
558 break;
559 case MONDO_INT_DATA1:
560 for(int j = 0; j < NCU_TARGETS; j++){
561 const char * csr_index = strtok(0," ");
562 uint64_t index = strtoull(csr_index,0,0);
563 const char * csr_val = strtok(0,",");
564 uint64_t val = strtoull(csr_val,0,0);
565 regs.mondo_int_data1[index] = val;
566 }
567 break;
568 case MONDO_INT_BUSY:
569 for(int j = 0; j < NCU_TARGETS; j++){
570 const char * csr_index = strtok(0," ");
571 uint64_t index = strtoull(csr_index,0,0);
572 const char * csr_val = strtok(0,",");
573 uint64_t val = strtoull(csr_val,0,0);
574 regs.mondo_int_busy[index] = val;
575 }
576 break;
577 case MONDO_INT_VEC:
578 case PCIE_A_MEM32_OFFSET_BASE:
579 case PCIE_A_MEM32_OFFSET_MASK:
580 case PCIE_A_MEM64_OFFSET_BASE:
581 case PCIE_A_MEM64_OFFSET_MASK:
582 case PCIE_A_IOCON_OFFSET_BASE:
583 case PCIE_A_IOCON_OFFSET_MASK:
584 case BANK_ENABLE:
585 case L2_IDX_HASH_EN:
586 case PCIE_A_FSH:
587 case SOC_ESR:
588 case SOC_LOG_ENABLE:
589 case SOC_INTERRUPT_ENABLE:
590 case SOC_ERROR_INJECTION:
591 case SOC_FATAL_ERROR_ENABLE:
592 case SOC_SII_ERROR_SYNDROME:
593 case SOC_NCU_ERROR_SYNDROME:
594 {
595 const char * csr_val = strtok(0,",");
596 uint64_t val = strtoull(csr_val,0,0);
597 access_regs(0,offset,mmi_true,8,&val,0xff);
598 }
599 break;
600 // r/o registers
601
602 case SER_NUM:
603 {
604 const char * csr_val = strtok(0,",");
605 uint64_t val = strtoull(csr_val,0,0);
606 regs.ser_num = val;
607 break;
608 }
609 case EFU_STAT:
610 {
611 const char * csr_val = strtok(0,",");
612 uint64_t val = strtoull(csr_val,0,0);
613 regs.efu_stat = val;
614 break;
615 }
616 case BANK_ENABLE_STATUS:
617 {
618 const char * csr_val = strtok(0,",");
619 uint64_t val = strtoull(csr_val,0,0);
620 regs.bank_enb_stat = val;
621 break;
622 }
623 case L2_IDX_HASH_EN_STATUS:
624 {
625 const char * csr_val = strtok(0,",");
626 uint64_t val = strtoull(csr_val,0,0);
627 regs.l2_idx_hash_en_stat = val;
628 break;
629 }
630 default:
631 assert(0);
632 }
633 }
634 return true;
635}
636
637void n2Ncu::handle_ui(int argc, char * argv[]){
638 if(argc == 1){
639 ui_cmd_usage();
640 return;
641 }else if(!strcmp(argv[1],"dump")){
642 FILE * fp = stderr;
643 if(argv[2]){
644 fp = fopen(argv[2],"w");
645 if(!fp){
646 printf("%s dump: error opening file <%s>\n",getName(),argv[2]);
647 fp = stderr;
648 }
649 }
650 dump(fp);
651 }else if(!strcmp(argv[1],"restore")){
652 FILE * fp;
653 if(argv[2]){
654 fp = fopen(argv[2],"r");
655 if(fp)
656 restore(fp);
657 else
658 printf("%s restore: error opening file <%s>\n",getName(),argv[2]);
659 }else
660 printf("%s restore: no restore filename specified\n",getName());
661 }else if(!strcmp(argv[1],"debug")){
662 if(argv[2]){
663 debug_level = atoi(argv[2]);
664 printf("%s: set debug level to %d\n",getName(),debug_level);
665 }else
666 printf("%s: current debug level %d\n",getName(),debug_level);
667 }else
668 debug_err("%s: unsupported UI command <%s>\n",getName(),argv[1]);
669 return;
670}
671
672const char *n2Ncu::ncu_reg_name(uint64_t reg){
673
674 switch (reg) {
675 case INT_MAN: return "int_man";
676 case MONDO_INT_VEC: return "mondo_int_vec";
677 case SER_NUM: return "ser_num";
678 case EFU_STAT: return "efu_stat";
679 case CORE_AVAIL: return "core_avail";
680 case BANK_AVAIL: return "bank_avail";
681 case BANK_ENABLE: return "bank_enable";
682 case BANK_ENABLE_STATUS: return "bank_enable_status";
683 case L2_IDX_HASH_EN: return "l2_idx_hash_en";
684 case L2_IDX_HASH_EN_STATUS: return "l2_idx_hash_en_status";
685 case PCIE_A_MEM32_OFFSET_BASE: return "pcie_a_mem32_offset_base";
686 case PCIE_A_MEM32_OFFSET_MASK: return "pcie_a_mem32_offset_mask";
687 case PCIE_A_MEM64_OFFSET_BASE: return "pcie_a_mem64_offset_base";
688 case PCIE_A_MEM64_OFFSET_MASK: return "pcie_a_mem64_offset_mask";
689 case PCIE_A_IOCON_OFFSET_BASE: return "pcie_a_iocon_offset_base";
690 case PCIE_A_IOCON_OFFSET_MASK: return "pcie_a_iocon_offset_mask";
691 case PCIE_A_FSH: return "pcie_a_fsh";
692 case SOC_ESR: return "soc_error_status";
693 case SOC_LOG_ENABLE: return "soc_error_log_enable";
694 case SOC_INTERRUPT_ENABLE: return "soc_error_interrupt_enable";
695 case SOC_FATAL_ERROR_ENABLE: return "soc_fatal_error_enable";
696 case SOC_PENDING_ERROR_STATUS: return "soc_pending_error_status";
697 case SOC_ERROR_INJECTION: return "soc_error_injection";
698 case SOC_SII_ERROR_SYNDROME: return "soc_sii_error_syndrome";
699 case SOC_NCU_ERROR_SYNDROME: return "soc_sii_error_syndrome";
700 case MONDO_INT_DATA0: return "mondo_int_data0";
701 case MONDO_INT_DATA1: return "mondo_int_data1";
702 case MONDO_INT_ADATA0: return "mondo_int_adata0";
703 case MONDO_INT_ADATA1: return "mondo_int_adata1";
704 case MONDO_INT_BUSY: return "mondo_int_busy";
705 case MONDO_INT_ABUSY: return "mondo_int_abusy";
706 default: return "Illegal NCU register";
707 }
708}
709
710