Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / api / sam / src / SS_VirtualCpu.cc
CommitLineData
920dae64
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: SS_VirtualCpu.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_VirtualCpu.h"
23
24uint_t SS_VirtualCpu::id = 0;
25SS_VirtualCpu* SS_VirtualCpu::list = 0;
26
27SS_VirtualCpu::SS_VirtualCpu( SS_Model* model )/*{{{*/
28 :
29 next(0),
30 cpu(model->cpu[id]),
31 strand(new SS_VirtualStrand[cpu->strand_cnt()])
32{
33 cpu->clr_stepping();
34
35 // The virtual cpu id (vid) numbers from 0 to N-1.
36 // The strand id associated with vid X is sid X
37 // if the id is not overwritten in the rc file.
38
39 for (int s=0; s < cpu->strand_cnt(); s++)
40 strand[s].strand = cpu->strand[s];
41
42 ++id;
43}
44/*}}}*/
45
46SS_VirtualStrand* SS_VirtualCpu::create( SS_Model* (*model)(), Sam::VCPU_Config* config, Sam::VCPU_ImpIntf* interface )/*{{{*/
47{
48 SS_VirtualCpu* pntr;
49 uint_t base_id = 0;
50
51 // Get the strand with strand_id() number config->id .
52 // Whilst locating the strand create any missing cpu instances.
53
54 if (list == 0)
55 {
56 SS_Model* ss = (model)();
57 ss->create_cpu(1);
58 list = new SS_VirtualCpu(ss);
59 }
60
61 for (pntr = list; config->id >= (pntr->cpu->strand_cnt() + base_id) ; pntr = pntr->next)
62 {
63 base_id += pntr->cpu->strand_cnt();
64
65 if (pntr->next == 0)
66 {
67 SS_Model* ss = (model)();
68 ss->create_cpu(1);
69 pntr->next = new SS_VirtualCpu(ss);
70 }
71 }
72
73 uint_t i = config->id - base_id;
74
75 // Connect the strand to the "outside" world
76
77 pntr->strand[i].strand->io->set_access_io(interface->access_io);
78 pntr->strand[i].strand->memory = interface->mem;
79 pntr->strand[i].strand->asi_ext_obj = &pntr->strand[i];
80 pntr->strand[i].strand->asi_ext_ld64_fp = ss_asi_ext_ld64;
81 pntr->strand[i].strand->asi_ext_st64_fp = ss_asi_ext_st64;
82 pntr->strand[i].config = *config;
83 pntr->strand[i].sys_intf = *interface;
84
85 // Make the strand active in step().
86
87 pntr->cpu->set_stepping(i);
88
89 // Return the virtual cpu instance.
90
91 return &pntr->strand[i];
92}
93/*}}}*/
94
95void SS_VirtualCpu::remove( SS_Model* ss )/*{{{*/
96{
97 while (list)
98 {
99 SS_VirtualCpu* hlp = list;
100 list = list->next;
101 delete hlp;
102 }
103
104 delete ss;
105}
106/*}}}*/
107
108int SS_VirtualCpu::snapshot( SS_Model* model, const char* dir_name, const char* file_name, bool load )/*{{{*/
109{
110 char name[1024];
111 name[0] = 0;
112 if (dir_name)
113 strcat(name,dir_name);
114 strcat(name,file_name);
115
116 FILE* file = fopen(name,load ? "r" : "w");
117 if (file == 0)
118 return -1;
119
120 SS_SnapShot ss(file,load);
121
122 model->snapshot(ss);
123
124 if (fclose(file) == 0)
125 return -1;
126
127 return 0;
128}
129/*}}}*/
130
131int SS_VirtualCpu::cycle( uint64_t nn )
132{
133 assert(nn==1);
134
135 SS_VirtualStrand *vcpu = SS_VirtualCpu::list ? SS_VirtualCpu::list->strand : NULL;
136 if ( vcpu && vcpu->config.trace_on && vcpu->config.execution_driven )
137 {
138 vcpu->sys_intf.vtrace->cycle();
139 }
140 return 0;
141}
142
143
144SS_AsiSpace::Error SS_VirtualCpu::ss_asi_ext_ld64( SS_Node*, void* asi_ptr, SS_Strand* s, SS_Vaddr va, uint64_t* data )/*{{{*/
145{
146 int sid = s->strand_id();
147 uint8_t asi = *((uint8_t *)asi_ptr);
148 SS_VirtualStrand *v = (SS_VirtualStrand *)s->asi_ext_obj;
149 int ok = v->sys_intf.access_asi(sid, Sam::VCPU_LOAD_OP, asi, va, 8, (*data));
150
151 return SS_AsiSpace::Error(ok);
152}
153/*}}}*/
154SS_AsiSpace::Error SS_VirtualCpu::ss_asi_ext_st64( SS_Node*, void* asi_ptr, SS_Strand* s, SS_Vaddr va, uint64_t data )/*{{{*/
155{
156 int sid = s->strand_id();
157 uint8_t asi = *((uint8_t *)asi_ptr);
158 SS_VirtualStrand *v = (SS_VirtualStrand *)s->asi_ext_obj;
159 int ok = v->sys_intf.access_asi(sid, Sam::VCPU_STORE_OP, asi, va, 8, data);
160 return SS_AsiSpace::Error(ok);
161}
162/*}}}*/