// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: SS_VirtualStrand.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 "SS_VirtualStrand.h"
SS_VirtualStrand::SS_VirtualStrand()
int SS_VirtualStrand ::interrupt( Sam::VCPU_InterruptRequest
* p
)
bool raise
= p
->isid
& 1; // uses this, N2 ignores it ...
(*strand
->external_interrupt
)(strand
,p
->data
,raise
);
int SS_VirtualStrand ::read_mem ( uint64_t addr
, uint64_t *value
, int size
, int asi
, int is_physical
)
paddr
= strand
->va2pa(addr
);
*value
= this->sys_intf
.mem
->ld64(paddr
);
int SS_VirtualStrand ::write_mem ( uint64_t addr
, uint64_t value
, int size
, int asi
, int is_physical
)
paddr
= strand
->va2pa(addr
);
this->sys_intf
.mem
->st64 ( paddr
, value
);
int SS_VirtualStrand ::set_breakpoint ( int *bp_id
, Sam::VCPU_BpType type
, uint64_t value
, Sam::VCPU_BpActionFn action
, uint64_t mask
)
case Sam::VCPU_BP_INSTR_ADDR
:
*bp_id
= strand
->break_on_inst_va( value
);
*bp_id
= strand
->break_on_trap( value
);
*bp_id
= strand
->break_on_red_mode();
// remove breakpoint bp_id
int SS_VirtualStrand ::delete_breakpoint ( int bp_id
)
SS_BreakPoint
* bp
= strand
->break_points
;
return 1; // there is no breakpoint set
// remove all breakpoints
strand
->break_delete(id
);
return strand
->break_delete(bp_id
);
int SS_VirtualStrand ::print_breakpoints ( FILE *fp
)
SS_BreakPoint
* bp
= strand
->break_points
;
fprintf(fp
, "No breakpoints set for cpu[%i] \n", strand
->strand_id());
else for (; bp
; bp
= bp
->next
)
fprintf(fp
, "cpu[%i] : bp_id = %i : value = 0x%llx : type = %i \n",
strand
->strand_id(), bp
->id
, bp
->va
, bp
->type
);
// output all valid tlb entries
int SS_VirtualStrand ::print_tlbs (FILE *fp
)
SS_Tlb
* itlb
= strand
->inst_tlb
;
SS_Tlb
* dtlb
= strand
->data_tlb
;
fprintf(fp
,"%s entries\n", itlb
==dtlb
? "UTLB" : "ITLB");
fprintf(fp
,"DTLB entries\n");
int SS_VirtualStrand::get_tlb_entries(Sam::VCPU_TLB
* &return_array
)
SS_Tlb
* itlb
= strand
->inst_tlb
;
SS_Tlb
* dtlb
= strand
->data_tlb
;
int count
= itlb
->size();
return_array
= new Sam::VCPU_TLB
[count
];
memset(return_array
, 0, count
*sizeof(Sam::VCPU_TLB
));
for (i
=0; i
<itlb
->size(); i
++) {
SS_Tte
* tte
= itlb
->get(i
);
Sam::VCPU_TLB
& tlb_rec
= return_array
[idx
];
tlb_rec
.format
= 1; // sun4u
// IMPORTANT: the caller must fill in the tlb_rec.cpuid field before tracing
tlb_rec
.tlb_type
= (itlb
==dtlb
)? 2: 0; // itlb/unified
tlb_rec
.tlb_no
= itlb
->tlb_id();
tlb_rec
.tte_tag
= tte
->tag();
// data: v:63 nfo:62 taddr: 55-13 ie:12 e:11 cp:10 cv:9 p:8 ep:7 w:6 sz:3-0
tlb_rec
.tte_data
= tte
->taddr() & (0x7ffffffffull
<< 13);
if (tte
->valid_bit()) tlb_rec
.tte_data
|= (1ull<<63);
if (tte
->nfo()) tlb_rec
.tte_data
|= (1ull << 62);
if (tte
->ie()) tlb_rec
.tte_data
|= (1ull << 12);
if (tte
->e()) tlb_rec
.tte_data
|= (1ull << 11);
if (tte
->cp()) tlb_rec
.tte_data
|= (1ull << 10);
if (tte
->cv()) tlb_rec
.tte_data
|= (1ull << 9);
if (tte
->p()) tlb_rec
.tte_data
|= (1ull << 8);
if (tte
->x()) tlb_rec
.tte_data
|= (1ull << 7);
if (tte
->w()) tlb_rec
.tte_data
|= (1ull << 6);
tlb_rec
.tte_data
|= tte
->page_size();
tlb_rec
.is_real
= tte
->real_bit();
tlb_rec
.partid
= tte
->pid();
tlb_rec
.tte_page_size
= tte
->page_size();
tlb_rec
.tte_context
= tte
->context();
for (i
=0; i
<dtlb
->size(); i
++) {
SS_Tte
* tte
= dtlb
->get(i
);
Sam::VCPU_TLB
& tlb_rec
= return_array
[idx
];
tlb_rec
.format
= 1; // sun4u
// IMPORTANT: the caller fills in the cpuid field before tracing
tlb_rec
.tlb_type
= 1; // dtlb
tlb_rec
.tlb_no
= dtlb
->tlb_id();
tlb_rec
.tte_tag
= tte
->tag();
// data: v:63 nfo:62 taddr: 55-13 ie:12 e:11 cp:10 cv:9 p:8 ep:7 w:6 sz:3-0
tlb_rec
.tte_data
= tte
->taddr() & (0x7ffffffffull
<< 13);
if (tte
->valid_bit()) tlb_rec
.tte_data
|= (1ull<<63);
if (tte
->nfo()) tlb_rec
.tte_data
|= (1ull << 62);
if (tte
->ie()) tlb_rec
.tte_data
|= (1ull << 12);
if (tte
->e()) tlb_rec
.tte_data
|= (1ull << 11);
if (tte
->cp()) tlb_rec
.tte_data
|= (1ull << 10);
if (tte
->cv()) tlb_rec
.tte_data
|= (1ull << 9);
if (tte
->p()) tlb_rec
.tte_data
|= (1ull << 8);
if (tte
->x()) tlb_rec
.tte_data
|= (1ull << 7);
if (tte
->w()) tlb_rec
.tte_data
|= (1ull << 6);
tlb_rec
.tte_data
|= tte
->page_size();
tlb_rec
.is_real
= tte
->real_bit();
tlb_rec
.partid
= tte
->pid();
tlb_rec
.tte_page_size
= tte
->page_size();
tlb_rec
.tte_context
= tte
->context();