Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | /* |
2 | * ========== Copyright Header Begin ========================================== | |
3 | * | |
4 | * OpenSPARC T2 Processor File: SS_Io.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_Io_h__ | |
24 | #define __SS_Io_h__ | |
25 | ||
26 | #ifdef COMPILE_FOR_SAM | |
27 | ||
28 | #include "SS_SamIo.h" | |
29 | ||
30 | #else | |
31 | ||
32 | #ifndef MEMORY_MSYNC | |
33 | ||
34 | #include "SS_Types.h" | |
35 | #include "SS_AddressMap.h" | |
36 | ||
37 | class SS_Io : public SS_AddressMap/*{{{*/ | |
38 | { | |
39 | public: | |
40 | SS_Io(); | |
41 | ~SS_Io(); | |
42 | ||
43 | enum access_io_status { | |
44 | NOT_HANDLED=-1, | |
45 | OK=0, | |
46 | FOLLOWME=1, | |
47 | NOP=2, | |
48 | RSVD_READ=3, // read from reserved range | |
49 | RSVD_WRITE=4 // write to reserved range | |
50 | }; | |
51 | ||
52 | // Supported User Interface Operations | |
53 | ||
54 | void poke8 ( uint_t sid,uint64_t addr, uint8_t data ) { st8(sid,addr,data); } | |
55 | void poke16( uint_t sid, uint64_t addr, uint16_t data ) { st16(sid,addr,data); } | |
56 | void poke32( uint_t sid,uint64_t addr, uint32_t data ) { st32(sid,addr,data); } | |
57 | void poke64( uint_t sid,uint64_t addr, uint64_t data ) { st64(sid,addr,data); } | |
58 | uint8_t peek8u( uint_t sid,uint64_t addr ) { return ld8u(sid,addr); } | |
59 | int8_t peek8s( uint_t sid,uint64_t addr ) { return ld8s(sid,addr); } | |
60 | uint16_t peek16u( uint_t sid,uint64_t addr ) { return ld16u(sid,addr); } | |
61 | int16_t peek16s( uint_t sid,uint64_t addr ) { return ld16s(sid,addr); } | |
62 | uint32_t peek32u( uint_t sid,uint64_t addr ) { return ld32u(sid,addr); } | |
63 | int32_t peek32s( uint_t sid,uint64_t addr ) { return ld32s(sid,addr); } | |
64 | uint64_t peek64( uint_t sid,uint64_t addr ) { return ld64(sid,addr); } | |
65 | ||
66 | // Supported Fetch Operation (instruction fetch) | |
67 | ||
68 | uint32_t fetch32( uint_t sid, uint64_t addr ) { return ld32u(sid,addr); } | |
69 | void fetch256( uint_t sid, uint64_t addr, uint64_t data[4] ) { ld256(sid,addr,data); } | |
70 | void fetch512( uint_t sid, uint64_t addr, uint64_t data[8] ) { ld512(sid,addr,data); } | |
71 | ||
72 | // Supported Store Operations. st8(), st16(), st32() and st64() are gueranteed to be atomic. | |
73 | // st128() and st512() are atomic at the 64bit granularity. | |
74 | ||
75 | void st8 ( uint_t sid, uint64_t addr, uint8_t data ); | |
76 | void st16 ( uint_t sid, uint64_t addr, uint16_t data ); | |
77 | void st32 ( uint_t sid, uint64_t addr, uint32_t data ); | |
78 | void st64 ( uint_t sid, uint64_t addr, uint64_t data ); | |
79 | void st128( uint_t sid, uint64_t addr, uint64_t data[2] ); | |
80 | void st512( uint_t sid, uint64_t addr, uint64_t data[8] ); | |
81 | ||
82 | // Supported Load Operations. ld8[su]() to ld64() are quaranteed to be atomic. ld128() and | |
83 | // above are atomic at the 64 bit granularity. | |
84 | ||
85 | uint8_t ld8u ( uint_t sid, uint64_t addr ); | |
86 | int8_t ld8s ( uint_t sid, uint64_t addr ); | |
87 | uint16_t ld16u( uint_t sid, uint64_t addr ); | |
88 | int16_t ld16s( uint_t sid, uint64_t addr ); | |
89 | uint32_t ld32u( uint_t sid, uint64_t addr ); | |
90 | int32_t ld32s( uint_t sid, uint64_t addr ); | |
91 | uint64_t ld64 ( uint_t sid, uint64_t addr ); | |
92 | void ld128( uint_t sid, uint64_t addr, uint64_t data[2] ); | |
93 | void ld256( uint_t sid, uint64_t addr, uint64_t data[4] ); | |
94 | void ld512( uint_t sid, uint64_t addr, uint64_t data[8] ); | |
95 | ||
96 | // st64partial() performs 8 byte partial store. The bits to store are specified by mask. A 1 in bit N of | |
97 | // mask denotes that bit (data >> (N)) should be written. | |
98 | ||
99 | void st64partial( uint_t sid, uint64_t addr, uint64_t data, uint64_t mask ); | |
100 | ||
101 | // ld128atomic() (aka load twin double, load quad atomic) atomically loads two | |
102 | // 64bit values from memory at addr into rd. rd[0] is the value at addr, rd[1] | |
103 | // is the value at addr + 8. Note ld128 does() not guarantee atomicity. | |
104 | ||
105 | void ld128atomic( uint_t sid, uint64_t addr, uint64_t data[2] ); | |
106 | ||
107 | // ldstub() return a byte from memory at addr, and set the byte at addr | |
108 | // to 0xff. The ldstub() operation is atomic. | |
109 | ||
110 | uint8_t ldstub( uint_t sid, uint64_t addr ); | |
111 | ||
112 | // swap() stores the 32bit value rd with the 32bit value at addr. | |
113 | // The old 32bit value at addr is returned. The operation is atomic. | |
114 | ||
115 | uint32_t swap( uint_t sid, uint64_t addr, uint32_t rd ); | |
116 | ||
117 | // casx() compares the 64bit value rs2 with the 64bit value at addr. | |
118 | // If the two values are equal, the value rd is stored in the | |
119 | // 64bit value at addr. In both cases the old 64bit value at addr is | |
120 | // returned, that is the value at addr before the storei happened. | |
121 | // The casx() operation is atomic. | |
122 | ||
123 | uint64_t casx( uint_t sid, uint64_t addr, uint64_t rd, uint64_t rs2 ); | |
124 | ||
125 | // cas() is as casx, but for 32bit. | |
126 | ||
127 | uint32_t cas( uint_t sid, uint64_t addr, uint32_t rd, uint32_t rs2 ); | |
128 | ||
129 | // prefetch() prefetches data from memory into the cache hierarchy. | |
130 | ||
131 | void prefetch( uint_t sid, uint64_t addr, uint_t size ) {} | |
132 | ||
133 | // flush() writes dirty data in the cache back to memory | |
134 | ||
135 | void flush( uint_t sid, uint64_t addr, uint_t size ) {} // process does not provide data. | |
136 | ||
137 | static SS_Io io; | |
138 | }; | |
139 | /*}}}*/ | |
140 | ||
141 | #else | |
142 | ||
143 | #include <string.h> | |
144 | #include <sys/mman.h> | |
145 | #include "SS_Types.h" | |
146 | #include "SS_AddressMap.h" | |
147 | #include "SS_Memory.h" | |
148 | #include "MemoryTransaction.h" | |
149 | ||
150 | class SS_Io : public SS_AddressMap/*{{{*/ | |
151 | { | |
152 | public: | |
153 | SS_Io(); | |
154 | ~SS_Io(); | |
155 | ||
156 | enum access_io_status { | |
157 | NOT_HANDLED=-1, | |
158 | OK=0, | |
159 | FOLLOWME=1, | |
160 | NOP=2, | |
161 | RSVD_READ=3, // read from reserved range | |
162 | RSVD_WRITE=4 // write to reserved range | |
163 | }; | |
164 | ||
165 | ||
166 | // Supported User Interface Operations | |
167 | ||
168 | void poke8 ( int sid, uint64_t addr, uint8_t data ); | |
169 | void poke16( int sid, uint64_t addr, uint16_t data ); | |
170 | void poke32( int sid, uint64_t addr, uint32_t data ); | |
171 | void poke64( int sid, uint64_t addr, uint64_t data ); | |
172 | ||
173 | uint8_t peek8u( int sid, uint64_t addr ); | |
174 | int8_t peek8s( int sid, uint64_t addr ); | |
175 | uint16_t peek16u( int sid, uint64_t addr ); | |
176 | int16_t peek16s( int sid, uint64_t addr ); | |
177 | uint32_t peek32u( int sid, uint64_t addr ); | |
178 | int32_t peek32s( int sid, uint64_t addr ); | |
179 | uint64_t peek64( int sid, uint64_t addr ); | |
180 | ||
181 | // Supported Fetch Operation (instruction fetch) | |
182 | ||
183 | uint32_t fetch32( uint_t sid, uint64_t addr ); | |
184 | void fetch256( uint_t sid, uint64_t addr, uint64_t data[4] ); | |
185 | void fetch512( uint_t sid, uint64_t addr, uint64_t data[8] ); | |
186 | ||
187 | // Supported Store Operations. st8(), st16(), st32() and st64() are gueranteed to be atomic. | |
188 | // st128() and st512() are atomic per 64bit quantity. | |
189 | ||
190 | void st8( uint_t sid, uint64_t addr, uint8_t data ); | |
191 | void st16( uint_t sid, uint64_t addr, uint16_t data ); | |
192 | void st32( uint_t sid, uint64_t addr, uint32_t data ); | |
193 | void st64( uint_t sid, uint64_t addr, uint64_t data ); | |
194 | void st128( uint_t sid, uint64_t addr, uint64_t data[2] ); | |
195 | void st512( uint_t sid, uint64_t addr, uint64_t data[8] ); | |
196 | ||
197 | // Supported Load Operations. ld8[su]() to ld64() are quaranteed to be atomic. ld128() and | |
198 | // above are atomic at the 64 bit granularity. | |
199 | ||
200 | uint8_t ld8u ( uint_t sid, uint64_t addr ); | |
201 | int8_t ld8s( uint_t sid, uint64_t addr ); | |
202 | uint16_t ld16u( uint_t sid, uint64_t addr ); | |
203 | int16_t ld16s( uint_t sid, uint64_t addr ); | |
204 | uint32_t ld32u( uint_t sid, uint64_t addr ); | |
205 | int32_t ld32s( uint_t sid, uint64_t addr ); | |
206 | uint64_t ld64( uint_t sid, uint64_t addr ); | |
207 | void ld128( uint_t sid, uint64_t addr, uint64_t data[2] ); | |
208 | void ld256( uint_t sid, uint64_t addr, uint64_t data[4] ); | |
209 | void ld512( uint_t sid, uint64_t addr, uint64_t data[8] ); | |
210 | ||
211 | // st64partial() performs 8 byte partial store. The bytes to store are specified by mask. A 1 in bit N of | |
212 | // mask denotes that byte (data >> (8*N)) & 0xff should be written to memory | |
213 | ||
214 | void st64partial( uint_t sid, uint64_t addr, uint64_t data, uint64_t mask ); | |
215 | ||
216 | // ld128atomic() (aka load twin double, load quad atomic) atomically loads two | |
217 | // 64bit values from memory at addr into rd. rd[0] is the value at addr, rd[1] | |
218 | // is the value at addr + 8. Note ld128 does() not guarantee atomicity. | |
219 | ||
220 | void ld128atomic( uint_t sid, uint64_t addr, uint64_t data[2] ); | |
221 | ||
222 | // ldstub() return a byte from memory at addr, and set the byte at addr | |
223 | // to 0xff. The ldstub() operation is atomic. | |
224 | ||
225 | uint8_t ldstub( uint_t sid, uint64_t addr ); | |
226 | ||
227 | // swap() stores the 32bit value rd with the 32bit value at addr. | |
228 | // The old 32bit value at addr is returned. The operation is atomic. | |
229 | ||
230 | uint32_t swap( uint_t sid, uint64_t addr, uint32_t rd ); | |
231 | ||
232 | // casx() compares the 64bit value rs2 with the 64bit value at addr. | |
233 | // If the two values are equal, the value rd is stored in the | |
234 | // 64bit value at addr. In both cases the old 64bit value at addr is | |
235 | // returned, that is the value at addr before the storei happened. | |
236 | // The casx() operation is atomic. | |
237 | ||
238 | uint64_t casx( uint_t sid, uint64_t addr, uint64_t rd, uint64_t rs2 ); | |
239 | ||
240 | // cas() is as casx, but for 32bit. | |
241 | ||
242 | uint32_t cas( uint_t sid, uint64_t addr, uint32_t rd, uint32_t rs2 ); | |
243 | ||
244 | // prefetch() prefetches data from memory into the cache hierarchy. | |
245 | ||
246 | void prefetch( uint_t sid, uint64_t addr, uint_t size ) {} | |
247 | ||
248 | // flush() writes dirty data in the cache back to memory | |
249 | ||
250 | void flush( uint_t sid, uint64_t addr, uint_t size ) {} // process does not provide data. | |
251 | ||
252 | static SS_Io io; | |
253 | ||
254 | //---------------------------------------------------------------------------- | |
255 | // Memory Sync additional interface | |
256 | //---------------------------------------------------------------------------- | |
257 | ||
258 | void msync_info( uint_t strand_id, SS_Vaddr va, SS_Memory::Info info=SS_Memory::NONE ) | |
259 | { | |
260 | mem_xact.setStrand(strand_id); | |
261 | mem_xact.vaddr(va); | |
262 | msync_help = info; | |
263 | } | |
264 | ||
265 | void* msync_object; | |
266 | void (*msync_pre_access)( void* object, MemoryTransaction& ); | |
267 | void (*msync_post_access)( void* object, MemoryTransaction& ); | |
268 | ||
269 | typedef int (*AccessIO)( void* obj, int sid, int type, uint64_t addr, uint32_t size, uint64_t* data, uint64_t bitmask); | |
270 | ||
271 | void set_access_io( AccessIO _access_io ) { access_io = _access_io; } | |
272 | ||
273 | void set_access_io_obj( void* access_obj ) { access_io_obj = access_obj; } | |
274 | ||
275 | void peek128( int sid, uint64_t addr ,uint64_t data[2] ); | |
276 | void peek256( int sid, uint64_t addr ,uint64_t data[4] ); | |
277 | void peek512( int sid, uint64_t addr ,uint64_t data[8] ); | |
278 | void poke128( int sid, uint64_t addr, uint64_t data[2] ); | |
279 | void poke512( int sid, uint64_t addr, uint64_t data[8] ); | |
280 | ||
281 | private: | |
282 | SS_Memory* memory; | |
283 | MemoryTransaction mem_xact; | |
284 | SS_Memory::Info msync_help; | |
285 | AccessIO access_io; | |
286 | void *access_io_obj; | |
287 | ||
288 | uint64_t msync_ld( int sid, uint64_t addr, uint_t size ); | |
289 | void msync_ld( int sid, uint64_t addr, uint_t size, uint64_t* data ); | |
290 | void msync_st( int sid, uint64_t addr, uint_t size, uint64_t data ); | |
291 | void msync_st( int sid, uint64_t addr, uint_t size, uint64_t* data ); | |
292 | }; | |
293 | /*}}}*/ | |
294 | ||
295 | #endif /* MEMORY_MSYNC */ | |
296 | #endif /* COMPILE_FOR_SAM */ | |
297 | #endif /* __SS_Io_h__ */ | |
298 |