Commit | Line | Data |
---|---|---|
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 | ||
24 | uint_t SS_VirtualCpu::id = 0; | |
25 | SS_VirtualCpu* SS_VirtualCpu::list = 0; | |
26 | ||
27 | SS_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 | ||
46 | SS_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 | ||
95 | void 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 | ||
108 | int 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 | ||
131 | int 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 | ||
144 | SS_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 | /*}}}*/ | |
154 | SS_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 | /*}}}*/ |