Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / api / sam / src / SS_VirtualStrand.cc
CommitLineData
920dae64
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: SS_VirtualStrand.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
22#include "SS_VirtualStrand.h"
23#include "SS_Tlb.h"
24
25
26SS_VirtualStrand::SS_VirtualStrand()
27 :
28 strand(0),
29 tracer(this)
30{}
31
32int SS_VirtualStrand ::interrupt( Sam::VCPU_InterruptRequest* p)
33{
34 bool raise = p->isid & 1; // uses this, N2 ignores it ...
35 (*strand->external_interrupt)(strand,p->data,raise);
36 return 0;
37}
38
39
40
41int SS_VirtualStrand ::read_mem ( uint64_t addr, uint64_t *value, int size, int asi, int is_physical )
42{
43 uint64_t paddr = addr;
44
45 if ( !is_physical )
46 {
47 paddr = strand->va2pa(addr);
48
49 if (paddr == 0)
50 return 1;
51 }
52
53 *value = this->sys_intf.mem->ld64(paddr);
54 return 0;
55}
56
57int SS_VirtualStrand ::write_mem ( uint64_t addr, uint64_t value, int size, int asi, int is_physical )
58{
59 uint64_t paddr = addr;
60
61 if ( !is_physical )
62 {
63 paddr = strand->va2pa(addr);
64
65 if (paddr == 0)
66 return 1;
67 }
68
69 this->sys_intf.mem->st64 ( paddr, value);
70 return 0;
71}
72
73
74int SS_VirtualStrand ::set_breakpoint ( int *bp_id, Sam::VCPU_BpType type, uint64_t value, Sam::VCPU_BpActionFn action, uint64_t mask)
75{
76 switch (type)
77 {
78 case Sam::VCPU_BP_INSTR_ADDR:
79 *bp_id = strand->break_on_inst_va( value );
80 return 0;
81 case Sam::VCPU_BP_TRAP:
82 *bp_id = strand->break_on_trap( value );
83 return 0;
84 case Sam::VCPU_BP_RED:
85 *bp_id = strand->break_on_red_mode();
86 return 0;
87 default:
88 return 1;
89 }
90}
91
92
93// remove breakpoint bp_id
94int SS_VirtualStrand ::delete_breakpoint ( int bp_id )
95{
96 SS_BreakPoint* bp = strand->break_points;
97
98 if (bp==NULL)
99 return 1; // there is no breakpoint set
100
101 if(bp_id == ~(0))
102 {
103 // remove all breakpoints
104 while (bp)
105 {
106 int id = bp->id;
107 bp = bp->next;
108 strand->break_delete(id);
109 }
110 return 0;
111 }
112 else // remove bp_id
113 {
114 return strand->break_delete(bp_id);
115 }
116}
117
118
119// print breakpoint list
120int SS_VirtualStrand ::print_breakpoints ( FILE *fp )
121{
122 SS_BreakPoint* bp = strand->break_points;
123
124 if (bp==NULL)
125 {
126 fprintf(fp, "No breakpoints set for cpu[%i] \n", strand->strand_id());
127 }
128 else for (; bp; bp = bp->next)
129 {
130 fprintf(fp, "cpu[%i] : bp_id = %i : value = 0x%llx : type = %i \n",
131 strand->strand_id(), bp->id, bp->va, bp->type);
132 }
133
134 return 0;
135}
136
137
138// output all valid tlb entries
139int SS_VirtualStrand ::print_tlbs (FILE *fp)
140{
141 SS_Tlb* itlb = strand->inst_tlb;
142 SS_Tlb* dtlb = strand->data_tlb;
143
144 fprintf(fp,"%s entries\n", itlb==dtlb ? "UTLB" : "ITLB");
145 itlb->dump(fp);
146
147 if (dtlb != itlb)
148 {
149 fprintf(fp,"DTLB entries\n");
150 dtlb->dump(fp);
151 }
152
153 return 0;
154}
155
156
157
158int SS_VirtualStrand::get_tlb_entries(Sam::VCPU_TLB * &return_array)
159{
160 SS_Tlb * itlb = strand->inst_tlb;
161 SS_Tlb * dtlb = strand->data_tlb;
162
163 int count = itlb->size();
164 if (itlb != dtlb) {
165 count += dtlb->size();
166 }
167 return_array = new Sam::VCPU_TLB [count];
168 memset(return_array, 0, count*sizeof(Sam::VCPU_TLB));
169
170 int idx = 0;
171 int i;
172 for (i=0; i<itlb->size(); i++) {
173 SS_Tte * tte = itlb->get(i);
174 Sam::VCPU_TLB & tlb_rec = return_array[idx];
175
176 tlb_rec.format = 1; // sun4u
177 // IMPORTANT: the caller must fill in the tlb_rec.cpuid field before tracing
178 tlb_rec.demap = 0;
179 tlb_rec.tlb_type = (itlb==dtlb)? 2: 0; // itlb/unified
180 tlb_rec.tlb_index = i;
181 tlb_rec.tlb_no = itlb->tlb_id();
182
183 tlb_rec.tte_tag = tte->tag();
184
185 // 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
186 tlb_rec.tte_data = tte->taddr() & (0x7ffffffffull << 13);
187 if (tte->valid_bit()) tlb_rec.tte_data |= (1ull<<63);
188 if (tte->nfo()) tlb_rec.tte_data |= (1ull << 62);
189 if (tte->ie()) tlb_rec.tte_data |= (1ull << 12);
190 if (tte->e()) tlb_rec.tte_data |= (1ull << 11);
191 if (tte->cp()) tlb_rec.tte_data |= (1ull << 10);
192 if (tte->cv()) tlb_rec.tte_data |= (1ull << 9);
193 if (tte->p()) tlb_rec.tte_data |= (1ull << 8);
194 if (tte->x()) tlb_rec.tte_data |= (1ull << 7);
195 if (tte->w()) tlb_rec.tte_data |= (1ull << 6);
196 tlb_rec.tte_data |= tte->page_size();
197
198 tlb_rec.is_real = tte->real_bit();
199 tlb_rec.partid = tte->pid();
200
201 tlb_rec.tte_page_size = tte->page_size();
202 tlb_rec.tte_context = tte->context();
203
204 idx++;
205 }
206
207 if (itlb != dtlb) {
208 for (i=0; i<dtlb->size(); i++) {
209 SS_Tte * tte = dtlb->get(i);
210 Sam::VCPU_TLB & tlb_rec = return_array[idx];
211
212 tlb_rec.format = 1; // sun4u
213 // IMPORTANT: the caller fills in the cpuid field before tracing
214 tlb_rec.demap = 0;
215 tlb_rec.tlb_type = 1; // dtlb
216 tlb_rec.tlb_index = i;
217 tlb_rec.tlb_no = dtlb->tlb_id();
218
219 tlb_rec.tte_tag = tte->tag();
220
221 // 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
222 tlb_rec.tte_data = tte->taddr() & (0x7ffffffffull << 13);
223 if (tte->valid_bit()) tlb_rec.tte_data |= (1ull<<63);
224 if (tte->nfo()) tlb_rec.tte_data |= (1ull << 62);
225 if (tte->ie()) tlb_rec.tte_data |= (1ull << 12);
226 if (tte->e()) tlb_rec.tte_data |= (1ull << 11);
227 if (tte->cp()) tlb_rec.tte_data |= (1ull << 10);
228 if (tte->cv()) tlb_rec.tte_data |= (1ull << 9);
229 if (tte->p()) tlb_rec.tte_data |= (1ull << 8);
230 if (tte->x()) tlb_rec.tte_data |= (1ull << 7);
231 if (tte->w()) tlb_rec.tte_data |= (1ull << 6);
232 tlb_rec.tte_data |= tte->page_size();
233
234 tlb_rec.is_real = tte->real_bit();
235 tlb_rec.partid = tte->pid();
236
237 tlb_rec.tte_page_size = tte->page_size();
238 tlb_rec.tte_context = tte->context();
239
240 idx++;
241 }
242 }
243
244 assert (idx==count);
245 return count;
246
247}
248