Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / devices / n2_piu / piu_dr.cc
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: piu_dr.cc
// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
//
// The above named program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License version 2 as published by the Free Software Foundation.
//
// The above named program is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this work; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
//
// ========== Copyright Header End ============================================
#include <sam_piu.h>
extern pcie_csr_desc_t pcie_csrs[];
bool samPiu::dump(FILE * fp){
const char * m1 = "-----PIU CSRs----\n";
fwrite(m1,strlen(m1),1,fp);
// dump the csrs
dump_piu_csrs(fp);
const char * m2 = "-----PIU pending interrupts----\n";
fwrite(m2,strlen(m2),1,fp);
// dump the intr lists
dump_intr(fp);
const char * m3 = "-----PIU nacked interrupt----\n";
fwrite(m3,strlen(m3),1,fp);
// dump the IRQ and time
dump_irq(fp);
return true;
}
void samPiu::dump_irq(FILE * fp){
fprintf(fp,"next_event_fire_time %llx\n",event_fire_time);
if(irql.empty()){
fprintf(fp,"no_nacked_irq\n");
return;
}
fprintf(fp,"Num Irq's %d\n",irql.size());
list <VCPU_InterruptRequest* >::iterator it;
for(it = irql.begin(); it != irql.end(); it++){
fprintf(fp,"itid %d\n",(*it)->itid);
fprintf(fp,"isid %d\n",(*it)->isid);
fprintf(fp,"data0 %llx\n",(*it)->data[0]);
fprintf(fp,"data1 %llx\n",(*it)->data[1]);
}
fflush(fp);
return;
}
void samPiu::dump_piu_csrs(FILE * fp){
const int bufsize = 64 * 1024;
char buf[bufsize];
uint64_t *csrs = (uint64_t *)&piuModel.csrs;
for(int i = 0; i < NUM_PCIE_CSRS; i++){
sprintf(buf,"%-80s0x%-16llx ",pcie_csrs[i].name,pcie_csrs[i].offset);
int index = pcie_csrs[i].regx;
for(int j = 0; j < pcie_csrs[i].nwords; j++){
char val[128];
sprintf(val,"0x%x 0x%016llx,",j,csrs[index+j]);
strcat(buf,val);
}
fwrite(buf,strlen(buf),1,fp);
fwrite("\n",strlen("\n"),1,fp);
}
fflush(fp);
return;
}
void samPiu::dump_intr(FILE * fp){
const int bufsize = 64 * 1024;
char buf[bufsize];
char tbuf[bufsize];
for(int i = 0; i < 4; i++){
sprintf(buf,"Int%c ",'A' + i);
list<int>::iterator listIt;
tbuf[0] = 0;
for(listIt = intLine[i].begin(); listIt != intLine[i].end(); listIt++){
sprintf(tbuf,"0x%x ",*listIt);
strcat(buf,tbuf);
}
fwrite(buf,strlen(buf),1,fp);
fwrite("\n",strlen("\n"),1,fp);
}
buf[0] = 0;
for(int i = 0; i < 64; i++){
sprintf(tbuf,"%d,",pendingIntr[i]);
strcat(buf,tbuf);
}
fwrite(buf,strlen(buf),1,fp);
fwrite("\n",strlen("\n"),1,fp);
fflush(fp);
return;
}
bool samPiu::restore(FILE *fp){
const int bufsize = 64 * 1024;
char buf[bufsize];
fgets(buf,bufsize,fp);
restore_piu_csrs(fp);
fgets(buf,bufsize,fp);
restore_intr(fp);
fgets(buf,bufsize,fp);
restore_irq(fp);
return true;
}
void samPiu::restore_irq(FILE * fp){
char buf[1024];
fgets(buf,1024,fp);
sscanf(buf,"next_event_fire_time %llx\n",&event_fire_time);
mmi_register_event(event_fire_time,samPiu_1ms_callback,(void*)this,0);
fgets(buf,1024,fp);
if(!strcmp("no_nacked_irq\n",buf))
return;
int size;
sscanf(buf,"Num Irq's %d\n",&size);
for(int i = 0 ; i < size; i++){
VCPU_InterruptRequest *ir = new VCPU_InterruptRequest;
fgets(buf,1024,fp);
sscanf(buf,"itid %d\n",&ir->itid);
fgets(buf,1024,fp);
sscanf(buf,"isid %d\n",&ir->isid);
fgets(buf,1024,fp);
sscanf(buf,"data0 %llx\n",&ir->data[0]);
fgets(buf,1024,fp);
sscanf(buf,"data1 %llx\n",&ir->data[1]);
irql.push_back(ir);
}
return;
}
void samPiu::restore_piu_csrs(FILE * fp){
const int bufsize = 64 * 1024;
char buf[bufsize];
uint64_t *csrs = (uint64_t *)&piuModel.csrs;
for(int i = 0; i < NUM_PCIE_CSRS; i++){
fgets(buf,bufsize,fp);
strtok(buf," "); // csr name, ignore
const char * csr_offset = strtok(0," "); // csr offset
uint64_t offset = strtoull(csr_offset,0,0);
int regx;
pcie_csr_t index = piu_offset2reg(offset, &regx);
for(int j = 0; j < pcie_csrs[index].nwords; j++){
strtok(0," "); // index, ignore
const char * csr_val = strtok(0,",");
uint64_t val = strtoull(csr_val,0,0);
csrs[regx] = val;
regx++;
}
}
// set the bus/device/function etc
int i;
piu_offset2reg( PIU_CSR_BASE + PIU_DMU_PCIE_CONFREG_OFFSET , &i);
secondary_bus_no = (csrs[i]) >> 24 & 0xff;
primary_bus_no = (csrs[i]) >> 8 & 0xff;
device = (csrs[i]) >> 3 & 0x1f;
function = (csrs[i]) & 0x7;
return;
}
void samPiu::restore_intr(FILE * fp){
const int bufsize = 64 * 1024;
char buf[bufsize];
for(int i = 0; i < 4; i++){
fgets(buf,bufsize,fp);
strtok(buf," "); // intr line number, ignore
const char * bus_val;
while( bus_val = strtok(0," ") ){
if(bus_val[0] == '\n')
break;
uint64_t val = strtoull(bus_val,0,0);
setIntx(val,i,true);
}
}
fgets(buf,bufsize,fp);
const char * intr_val = strtok(buf,",");
pendingIntr[0] = atoi(intr_val);
for(int i = 1; i < 64; i++){
intr_val = strtok(0,",");
pendingIntr[i] = atoi(intr_val);
}
return;
}