Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / api / sam / src / SS_SamIo.h
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: SS_SamIo.h
5* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
6* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
7*
8* The above named program is free software; you can redistribute it and/or
9* modify it under the terms of the GNU General Public
10* License version 2 as published by the Free Software Foundation.
11*
12* The above named program is distributed in the hope that it will be
13* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15* General Public License for more details.
16*
17* You should have received a copy of the GNU General Public
18* License along with this work; if not, write to the Free Software
19* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20*
21* ========== Copyright Header End ============================================
22*/
23#ifndef __SS_SamIo_h__
24#define __SS_SamIo_h__
25
26#ifdef COMPILE_FOR_SAM
27
28#include "SS_Types.h"
29#include "SS_AddressMap.h"
30
31namespace Sam
32{
33#define bool_t bool
34
35#include "vcpu.h"
36};
37
38class SS_Io : public SS_AddressMap
39{
40 public:
41 SS_Io() : SS_AddressMap(), access_io(0) {}
42 ~SS_Io() {}
43
44 enum access_io_status
45 {
46 NOT_HANDLED=-1,
47 OK=0,
48 FOLLOWME=1,
49 NOP=2,
50 RSV_READ=3, // read from reserved range
51 RSV_WRITE=4 // write to reserved range
52 };
53
54
55 // Supported User Interface Operations
56
57 void poke8( uint_t sid, uint64_t addr, uint8_t data ) { st8(sid,addr,data); }
58 void poke16( uint_t sid, uint64_t addr, uint16_t data ) { st16(sid,addr,data); }
59 void poke32( uint_t sid, uint64_t addr, uint32_t data ) { st32(sid,addr,data); }
60 void poke64( uint_t sid, uint64_t addr, uint64_t data ) { st64(sid,addr,data); }
61 uint8_t peek8u( uint_t sid, uint64_t addr ) { return ld8u(sid,addr); }
62 int8_t peek8s( uint_t sid, uint64_t addr ) { return ld8s(sid,addr); }
63 uint16_t peek16u( uint_t sid, uint64_t addr ) { return ld16u(sid,addr); }
64 int16_t peek16s( uint_t sid, uint64_t addr ) { return ld16s(sid,addr); }
65 uint32_t peek32u( uint_t sid, uint64_t addr ) { return ld32u(sid,addr); }
66 int32_t peek32s( uint_t sid, uint64_t addr ) { return ld32s(sid,addr); }
67 uint64_t peek64( uint_t sid, uint64_t addr ) { return ld64(sid,addr); }
68
69 // Supported Fetch Operation (instruction fetch)
70
71 uint32_t fetch32( uint_t sid, uint64_t addr ) { return ld32u(sid,addr); }
72 void fetch256( uint_t sid, uint64_t addr, uint64_t data[4] ) { ld256(sid,addr,data); }
73 void fetch512( uint_t sid, uint64_t addr, uint64_t data[8] ) { ld512(sid,addr,data); }
74
75 void st8 ( uint_t sid, uint64_t addr, uint8_t data )
76 {
77 uint64_t _data = data;
78 SS_AddressMap::Range* range = find(addr);
79 if (range != SS_AddressMap::fail)
80 range->cpu(sid, SS_Access::STORE, addr, 1, &_data);
81 else
82 error[sid] = (access_io)(sid,Sam::VCPU_STORE_OP,addr,1,_data,~0);
83 }
84
85 void st16 ( uint_t sid, uint64_t addr, uint16_t data )
86 {
87 uint64_t _data = data;
88 SS_AddressMap::Range* range = find(addr);
89 if (range != SS_AddressMap::fail)
90 range->cpu(sid, SS_Access::STORE, addr, 2, &_data);
91 else
92 error[sid] = (access_io)(sid,Sam::VCPU_STORE_OP,addr,2,_data,~0);
93 }
94
95 void st32 ( uint_t sid, uint64_t addr, uint32_t data )
96 {
97 uint64_t _data = data;
98 SS_AddressMap::Range* range = find(addr);
99 if (range != SS_AddressMap::fail)
100 range->cpu(sid, SS_Access::STORE, addr, 4, &_data);
101 else
102 error[sid] = (access_io)(sid,Sam::VCPU_STORE_OP,addr,4,_data,~0);
103 }
104
105 void st64 ( uint_t sid, uint64_t addr, uint64_t data )
106 {
107 SS_AddressMap::Range* range = find(addr);
108 if (range != SS_AddressMap::fail)
109 range->cpu(sid, SS_Access::STORE, addr, 8, &data);
110 else
111 error[sid] = (access_io)(sid,Sam::VCPU_STORE_OP,addr,8,data,~0);
112 }
113
114 void st128( uint_t sid, uint64_t addr, uint64_t data[2] )
115 {
116 SS_AddressMap::Range* range = find(addr);
117 if (range != SS_AddressMap::fail)
118 range->cpu(sid, SS_Access::STORE, addr, 16, data);
119 else
120 io_error();
121 }
122
123 void st512( uint_t sid, uint64_t addr, uint64_t data[8] )
124 {
125 SS_AddressMap::Range* range = find(addr);
126 if (range != SS_AddressMap::fail)
127 range->cpu(sid, SS_Access::STORE, addr, 64, data);
128 else
129 io_error();
130 }
131
132 uint8_t ld8u ( uint_t sid, uint64_t addr )
133 {
134 return ld8s(sid, addr);
135 }
136
137 int8_t ld8s ( uint_t sid, uint64_t addr )
138 {
139 uint64_t _data;
140 SS_AddressMap::Range* range = find(addr);
141 if (range != SS_AddressMap::fail)
142 range->cpu(sid, SS_Access::LOAD, addr, 1, &_data);
143 else
144 error[sid] = (access_io)(sid,Sam::VCPU_LOAD_OP,addr,1,_data,~0);
145 return _data;
146 }
147
148 uint16_t ld16u( uint_t sid, uint64_t addr )
149 {
150 return ld16s(sid, addr);
151 }
152
153 int16_t ld16s( uint_t sid, uint64_t addr )
154 {
155 uint64_t _data;
156 SS_AddressMap::Range* range = find(addr);
157 if (range != SS_AddressMap::fail)
158 range->cpu(sid, SS_Access::LOAD, addr, 2, &_data);
159 else
160 error[sid] = (access_io)(sid,Sam::VCPU_LOAD_OP,addr,2,_data,~0);
161 return _data;
162 }
163
164 uint32_t ld32u( uint_t sid, uint64_t addr )
165 {
166 return ld32s(sid, addr);
167 }
168
169 int32_t ld32s( uint_t sid, uint64_t addr )
170 {
171 uint64_t _data;
172 SS_AddressMap::Range* range = find(addr);
173 if (range != SS_AddressMap::fail)
174 range->cpu(sid, SS_Access::LOAD, addr, 4, &_data);
175 else
176 error[sid] = (access_io)(sid,Sam::VCPU_LOAD_OP,addr,4,_data,~0);
177 return _data;
178 }
179
180 uint64_t ld64 ( uint_t sid, uint64_t addr )
181 {
182 uint64_t _data;
183 SS_AddressMap::Range* range = find(addr);
184 if (range != SS_AddressMap::fail)
185 range->cpu(sid, SS_Access::LOAD, addr, 8, &_data);
186 else
187 error[sid] = (access_io)(sid,Sam::VCPU_LOAD_OP,addr,8,_data,~0);
188 return _data;
189 }
190
191 void ld128( uint_t sid, uint64_t addr, uint64_t data[2] )
192 {
193 SS_AddressMap::Range* range = find(addr);
194 if (range != SS_AddressMap::fail)
195 range->cpu(sid, SS_Access::LOAD, addr, 16, data);
196 else
197 io_error();
198 }
199
200 void ld256( uint_t sid, uint64_t addr, uint64_t data[4] )
201 {
202 SS_AddressMap::Range* range = find(addr);
203 if (range != SS_AddressMap::fail)
204 range->cpu(sid, SS_Access::LOAD, addr, 32, data);
205 else
206 io_error();
207 }
208
209 void ld512( uint_t sid, uint64_t addr, uint64_t data[8] )
210 {
211 SS_AddressMap::Range* range = find(addr);
212 if (range != SS_AddressMap::fail)
213 range->cpu(sid, SS_Access::LOAD, addr, 64, data);
214 else
215 {
216 error[sid] = (access_io)(sid,Sam::VCPU_LOAD_OP,addr+0, 8,data[0],~0);
217 if (error[sid] == 0)
218 {
219 (access_io)(sid,Sam::VCPU_LOAD_OP,addr+8, 8,data[1],~0);
220 (access_io)(sid,Sam::VCPU_LOAD_OP,addr+16,8,data[2],~0);
221 (access_io)(sid,Sam::VCPU_LOAD_OP,addr+24,8,data[3],~0);
222 (access_io)(sid,Sam::VCPU_LOAD_OP,addr+32,8,data[4],~0);
223 (access_io)(sid,Sam::VCPU_LOAD_OP,addr+40,8,data[5],~0);
224 (access_io)(sid,Sam::VCPU_LOAD_OP,addr+48,8,data[6],~0);
225 (access_io)(sid,Sam::VCPU_LOAD_OP,addr+56,8,data[7],~0);
226 }
227 }
228 }
229
230 void st64partial( uint_t sid, uint64_t addr, uint64_t data, uint64_t mask )
231 {
232 SS_AddressMap::Range* range = find(addr);
233 if (range != SS_AddressMap::fail)
234 {
235 uint64_t _data[2];
236 _data[0] = data;
237 _data[1] = mask;
238 range->cpu(sid, SS_Access::STP, addr, 8, _data);
239 }
240 else
241 error[sid] = (access_io)(sid,Sam::VCPU_STORE_PARTIAL_OP,addr,8,data,mask);
242 }
243
244 void ld128atomic( uint_t sid, uint64_t addr, uint64_t data[2] )
245 {
246 SS_AddressMap::Range* range = find(addr);
247 if (range != SS_AddressMap::fail)
248 range->cpu(sid, SS_Access::LOAD, addr, 16, data);
249 else
250 io_error();
251 }
252
253 uint8_t ldstub( uint_t sid, uint64_t addr )
254 {
255 uint64_t data = 0xff;
256 SS_AddressMap::Range* range = find(addr);
257 if (range != SS_AddressMap::fail)
258 range->cpu(sid, SS_Access::LDST, addr, 1, &data);
259 else
260 io_error();
261 return data;
262 }
263
264 uint32_t swap( uint_t sid, uint64_t addr, uint32_t rd )
265 {
266 uint64_t data = rd;
267 SS_AddressMap::Range* range = find(addr);
268 if (range != SS_AddressMap::fail)
269 range->cpu(sid, SS_Access::SWAP, addr, 4, &data);
270 else
271 io_error();
272 return data;
273 }
274
275 uint64_t casx( uint_t sid, uint64_t addr, uint64_t rd, uint64_t rs2 )
276 {
277 uint64_t data[2];
278 data[0] = rd;
279 data[1] = rs2;
280 SS_AddressMap::Range* range = find(addr);
281 if (range != SS_AddressMap::fail)
282 range->cpu(sid, SS_Access::CAS, addr, 8, data);
283 else
284 io_error();
285 return data[0];
286 }
287
288 uint32_t cas( uint_t sid, uint64_t addr, uint32_t rd, uint32_t rs2 )
289 {
290 uint64_t data[2];
291 data[0] = rd;
292 data[1] = rs2;
293 SS_AddressMap::Range* range = find(addr);
294 if (range != SS_AddressMap::fail)
295 range->cpu(sid, SS_Access::CAS, addr, 4, data);
296 else
297 io_error();
298 return data[0];
299 }
300
301 void prefetch( uint_t sid, uint64_t addr, uint_t size )
302 {
303 uint64_t data;
304 SS_AddressMap::Range* range = find(addr);
305 if (range != SS_AddressMap::fail)
306 io_error();
307 else
308 (access_io)(sid,Sam::VCPU_PREFETCH_OP,addr,size,data,~0);
309 }
310
311 void flush( uint_t sid, uint64_t addr, uint_t size )
312 {
313 uint64_t data;
314 SS_AddressMap::Range* range = find(addr);
315 if (range != SS_AddressMap::fail)
316 io_error();
317 else
318 (access_io)(sid,Sam::VCPU_FLUSH_OP,addr,size,data,~0);
319 }
320
321 static SS_Io io;
322
323 typedef int (*AccessIO)( int sid, int type, uint64_t addr, uint32_t size, uint64_t &data, uint64_t mask );
324
325 void set_access_io( AccessIO _access_io ) { access_io = _access_io; }
326
327 int error[65536]; // 64K seems enough space for virtual strands
328
329 private:
330 void io_error();
331
332 AccessIO access_io;
333};
334
335#endif /* COMPILE_FOR_SAM */
336#endif /* __SS_SamIo_h__ */