Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | /* |
2 | * ========== Copyright Header Begin ========================================== | |
3 | * | |
4 | * OpenSPARC T2 Processor File: tsparcv9internal.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 | /* | |
24 | * Copyright 2007 Sun Microsystems, Inc. All rights reserved. | |
25 | * Use is subject to license terms. | |
26 | */ | |
27 | ||
28 | #ifndef _TSPARCV9INTERNAL_H_ | |
29 | #define _TSPARCV9INTERNAL_H_ | |
30 | ||
31 | #pragma ident "@(#)tsparcv9internal.h 1.47 07/02/15 SMI" | |
32 | ||
33 | #ifdef __cplusplus | |
34 | extern "C" { | |
35 | #endif | |
36 | ||
37 | /* | |
38 | * defines to support the values we stuff into the simcpu_t | |
39 | * misc registers | |
40 | */ | |
41 | ||
42 | #define v9_ccr miscreg[0] | |
43 | #define v9_asi miscreg[1] | |
44 | #define v9_y miscreg[2] | |
45 | #define v9_fsr_exc miscreg[3] | |
46 | #define v9_fsr_tem miscreg[4] | |
47 | #define v9_fsr_ctrl miscreg[5] | |
48 | #define v9_gsr miscreg[6] | |
49 | ||
50 | #define V9_FSR_RD_BIT 30 | |
51 | #define V9_FSR_RD_MASK MASK64(31,30) | |
52 | #define V9_FSR_TEM_BIT 23 | |
53 | #define V9_FSR_TEM_MASK MASK64(27,23) | |
54 | #define V9_FSR_NS_MASK MASK64(22,22) | |
55 | #define V9_FSR_FTT_SHIFT 14 | |
56 | #define V9_FSR_FTT_MASK MASK64(16,14) | |
57 | #define V9_FSR_FCC0_SHIFT 10 | |
58 | #define V9_FSR_FCC1_SHIFT 32 | |
59 | #define V9_FSR_FCC_BITS 2 | |
60 | #define V9_FSR_FCC_MASK MASK64((V9_FSR_FCC_BITS - 1),0) | |
61 | #define V9_FSR_AEXC_MASK MASK64(9,5) | |
62 | #define V9_FSR_CEXC_MASK MASK64(4,0) | |
63 | ||
64 | #define V9_FSR_ALL_FCC_MASK \ | |
65 | (MASK64((V9_FSR_FCC1_SHIFT+(V9_FSR_FCC_BITS*3)-1),V9_FSR_FCC1_SHIFT) | \ | |
66 | MASK64((V9_FSR_FCC0_SHIFT+V9_FSR_FCC_BITS-1),V9_FSR_FCC0_SHIFT)) | |
67 | ||
68 | /* ldfsr/ldxfsr mask - does not change reserved/readonly or ftt fields. */ | |
69 | #define V9_FSR_REG_MASK (V9_FSR_ALL_FCC_MASK | V9_FSR_RD_MASK | \ | |
70 | V9_FSR_TEM_MASK | \ | |
71 | V9_FSR_AEXC_MASK | V9_FSR_CEXC_MASK) | |
72 | ||
73 | #define V9_FSR_FCC0(_fsr) (((_fsr) >> V9_FSR_FCC0_SHIFT) & V9_FSR_FCC_MASK) | |
74 | /* _fccn can be 1, 2 or 3 */ | |
75 | #define V9_FSR_FCCN(_fsr, _fccn) (((_fsr) >> (V9_FSR_FCC1_SHIFT + (((_fccn) - 1) * V9_FSR_FCC_BITS))) & V9_FSR_FCC_MASK) | |
76 | ||
77 | /* Bits in CEXC, AEXC and TEM */ | |
78 | #define V9_FSR_NV_BIT 0x10 | |
79 | #define V9_FSR_OF_BIT 0x08 | |
80 | #define V9_FSR_UF_BIT 0x04 | |
81 | #define V9_FSR_DZ_BIT 0x02 | |
82 | #define V9_FSR_NX_BIT 0x01 | |
83 | ||
84 | /* GSR - General Status Register */ | |
85 | #define V9_GSR_MASK_MASK MASK64(63, 32) | |
86 | #define V9_GSR_IM_MASK MASK64(27, 27) | |
87 | #define V9_GSR_IRND_SHIFT 25 | |
88 | #define V9_GSR_IRND_MASK MASK64(26, 25) | |
89 | #define V9_GSR_SCALE_MASK MASK64(7, 3) | |
90 | #define V9_GSR_ALIGN_MASK MASK64(2, 0) | |
91 | ||
92 | #define V9_GSR_REG_MASK (V9_GSR_MASK_MASK | V9_GSR_IM_MASK | \ | |
93 | V9_GSR_IRND_MASK | V9_GSR_SCALE_MASK | \ | |
94 | V9_GSR_ALIGN_MASK) | |
95 | ||
96 | ||
97 | typedef enum { | |
98 | V9_UnInitialised, /* Not a legit state - tells us allocated but not inited */ | |
99 | V9_User, V9_Priv, V9_HyperPriv, V9_RED, V9_Error, | |
100 | V9_State_Max /* Not a legit state - used to let us know the max number of states */ | |
101 | } sparcv9_state_t; | |
102 | ||
103 | /* For useful debugging stuff: */ | |
104 | extern char * sparcv9_state_name[]; | |
105 | ||
106 | typedef enum { | |
107 | /* 0x0 Reserved */ | |
108 | Sparcv9_trap_power_on_reset = 0x1, | |
109 | Sparcv9_trap_watchdog_reset = 0x2, | |
110 | Sparcv9_trap_externally_initiated_reset = 0x3, | |
111 | Sparcv9_trap_software_initiated_reset = 0x4, | |
112 | Sparcv9_trap_RED_state_exception = 0x5, | |
113 | /* 0x6-0x7 Reserved */ | |
114 | Sparcv9_trap_instruction_access_exception = 0x8, | |
115 | Sparcv9_trap_instruction_access_MMU_miss = 0x9, | |
116 | Sparcv9_trap_instruction_access_error = 0xa, | |
117 | /* 0xb-0xf Reserved */ | |
118 | Sparcv9_trap_illegal_instruction = 0x10, | |
119 | Sparcv9_trap_privileged_opcode = 0x11, | |
120 | Sparcv9_trap_unimplemented_LDD = 0x12, | |
121 | Sparcv9_trap_unimplemented_STD = 0x13, | |
122 | /* 0x14-0x1f Reserved */ | |
123 | Sparcv9_trap_fp_disabled = 0x20, | |
124 | Sparcv9_trap_fp_exception_ieee_754 = 0x21, | |
125 | Sparcv9_trap_fp_exception_other = 0x22, | |
126 | Sparcv9_trap_tag_overflow = 0x23, | |
127 | Sparcv9_trap_clean_window = 0x24, | |
128 | /* 0x25-0x27 clean_window reserved */ | |
129 | Sparcv9_trap_division_by_zero = 0x28, | |
130 | Sparcv9_trap_internal_processor_error = 0x29, | |
131 | /* 0x2a-0x2f Reserved */ | |
132 | Sparcv9_trap_data_access_exception = 0x30, | |
133 | Sparcv9_trap_data_access_MMU_miss = 0x31, | |
134 | Sparcv9_trap_data_access_error = 0x32, | |
135 | Sparcv9_trap_data_access_protection = 0x33, | |
136 | Sparcv9_trap_mem_address_not_aligned = 0x34, | |
137 | Sparcv9_trap_LDDF_mem_address_not_aligned = 0x35, | |
138 | Sparcv9_trap_STDF_mem_address_not_aligned = 0x36, | |
139 | Sparcv9_trap_privileged_action = 0x37, | |
140 | Sparcv9_trap_LDQF_mem_address_not_aligned = 0x38, | |
141 | Sparcv9_trap_STQF_mem_address_not_aligned = 0x39, | |
142 | /* 0x3a-0x3f Reserved */ | |
143 | Sparcv9_trap_async_data_error = 0x40, | |
144 | Sparcv9_trap_interrupt_level_1 = 0x41, | |
145 | Sparcv9_trap_interrupt_level_2 = 0x42, | |
146 | Sparcv9_trap_interrupt_level_3 = 0x43, | |
147 | Sparcv9_trap_interrupt_level_4 = 0x44, | |
148 | Sparcv9_trap_interrupt_level_5 = 0x45, | |
149 | Sparcv9_trap_interrupt_level_6 = 0x46, | |
150 | Sparcv9_trap_interrupt_level_7 = 0x47, | |
151 | Sparcv9_trap_interrupt_level_8 = 0x48, | |
152 | Sparcv9_trap_interrupt_level_9 = 0x49, | |
153 | Sparcv9_trap_interrupt_level_a = 0x4a, | |
154 | Sparcv9_trap_interrupt_level_b = 0x4b, | |
155 | Sparcv9_trap_interrupt_level_c = 0x4c, | |
156 | Sparcv9_trap_interrupt_level_d = 0x4d, | |
157 | Sparcv9_trap_interrupt_level_e = 0x4e, | |
158 | Sparcv9_trap_interrupt_level_f = 0x4f, | |
159 | /* 0x50-0x5f Reserved */ | |
160 | /* 0x60-0x7f Impl Dep */ | |
161 | ||
162 | Sparcv9_trap_spill_0_normal = 0x80, | |
163 | Sparcv9_trap_spill_1_normal = 0x84, | |
164 | Sparcv9_trap_spill_2_normal = 0x88, | |
165 | Sparcv9_trap_spill_3_normal = 0x8c, | |
166 | Sparcv9_trap_spill_4_normal = 0x90, | |
167 | Sparcv9_trap_spill_5_normal = 0x94, | |
168 | Sparcv9_trap_spill_6_normal = 0x98, | |
169 | Sparcv9_trap_spill_7_normal = 0x9c, | |
170 | ||
171 | Sparcv9_trap_spill_0_other = 0xa0, | |
172 | Sparcv9_trap_spill_1_other = 0xa4, | |
173 | Sparcv9_trap_spill_2_other = 0xa8, | |
174 | Sparcv9_trap_spill_3_other = 0xac, | |
175 | Sparcv9_trap_spill_4_other = 0xb0, | |
176 | Sparcv9_trap_spill_5_other = 0xb4, | |
177 | Sparcv9_trap_spill_6_other = 0xb8, | |
178 | Sparcv9_trap_spill_7_other = 0xbc, | |
179 | ||
180 | Sparcv9_trap_fill_0_normal = 0xc0, | |
181 | Sparcv9_trap_fill_1_normal = 0xc4, | |
182 | Sparcv9_trap_fill_2_normal = 0xc8, | |
183 | Sparcv9_trap_fill_3_normal = 0xcc, | |
184 | Sparcv9_trap_fill_4_normal = 0xd0, | |
185 | Sparcv9_trap_fill_5_normal = 0xd4, | |
186 | Sparcv9_trap_fill_6_normal = 0xd8, | |
187 | Sparcv9_trap_fill_7_normal = 0xdc, | |
188 | ||
189 | Sparcv9_trap_fill_0_other = 0xe0, | |
190 | Sparcv9_trap_fill_1_other = 0xe4, | |
191 | Sparcv9_trap_fill_2_other = 0xe8, | |
192 | Sparcv9_trap_fill_3_other = 0xec, | |
193 | Sparcv9_trap_fill_4_other = 0xf0, | |
194 | Sparcv9_trap_fill_5_other = 0xf4, | |
195 | Sparcv9_trap_fill_6_other = 0xf8, | |
196 | Sparcv9_trap_fill_7_other = 0xfc, | |
197 | ||
198 | /* trap 0x100-0x17f, */ | |
199 | Sparcv9_trap_trap_instruction = 0x100, | |
200 | /* htrap 0x180-0x1ff, */ | |
201 | Sparcv9_trap_htrap_instruction = 0x180, | |
202 | Sparcv9_trap_illegal_value = 0x200 | |
203 | } sparcv9_trap_type_t; | |
204 | ||
205 | ||
206 | typedef enum { | |
207 | v9_mm_tso = 0x0, | |
208 | v9_mm_pso = 0x1, | |
209 | v9_mm_rmo = 0x2, | |
210 | v9_mm_illegal = 0x3 | |
211 | } v9_mm_t; | |
212 | ||
213 | ||
214 | typedef enum { | |
215 | SPARCv9_FTT_None = 0, | |
216 | SPARCv9_FTT_IEEE_754_exception = 1, | |
217 | SPARCv9_FTT_unfinished_FPop = 2, | |
218 | SPARCv9_FTT_unimplemented_FPop = 3, | |
219 | SPARCv9_FTT_sequence_error = 4, | |
220 | SPARCv9_FTT_hardware_error = 5, | |
221 | SPARCv9_FTT_invalid_fp_register = 6, | |
222 | SPARCv9_FTT_reserved = 7 | |
223 | } v9_fsr_ftt_t; | |
224 | ||
225 | ||
226 | enum V9_MACCESS { | |
227 | MA_V9_LdFSR = MA_Non_Gen_Base, | |
228 | MA_V9_LdXFSR = MA_V9_LdFSR + MA_Non_Gen_Skip, | |
229 | MA_V9_StFSR = MA_V9_LdXFSR + MA_Non_Gen_Skip, | |
230 | MA_V9_StXFSR = MA_V9_StFSR + MA_Non_Gen_Skip, | |
231 | MA_V9_Flush = MA_V9_StXFSR + MA_Non_Gen_Skip | |
232 | }; | |
233 | ||
234 | /* | |
235 | * These macros must be passed an op masked with MA_Op_Mask. | |
236 | */ | |
237 | #define IS_V9_MA_LOAD(_op) (_IS_MA_LOAD((_op)) || \ | |
238 | (maccess_t)MA_V9_LdFSR == (_op) || \ | |
239 | (maccess_t)MA_V9_LdXFSR == (_op)) | |
240 | #define IS_V9_MA_STORE(_op) (_IS_MA_STORE((_op)) || \ | |
241 | (maccess_t)MA_V9_StFSR == (_op) || \ | |
242 | (maccess_t)MA_V9_StXFSR == (_op) || \ | |
243 | (maccess_t)MA_V9_Flush == (_op)) | |
244 | #define IS_V9_MA_ATOMIC(_op) (_IS_MA_ATOMIC((_op))) | |
245 | ||
246 | ||
247 | typedef enum { | |
248 | USE_ASI_REG, | |
249 | NO_FLAG | |
250 | } asi_flag_t; | |
251 | ||
252 | ||
253 | /* | |
254 | * The actual definition of sparcv9_cpu_t: | |
255 | * private to this module | |
256 | */ | |
257 | ||
258 | ||
259 | #if WALL_TIME | |
260 | ||
261 | extern hrtime_t base_hrtime; | |
262 | ||
263 | #define RAW_HRTIME (gethrtime() - base_hrtime) | |
264 | #define HRT_TO_TICK(_hrt, _scale) ((uint64_t)((double)(_hrt) * (_scale))) | |
265 | #define TICK_TO_HRT(_tick, _scale_recip) ((hrtime_t)((double)(_tick) * \ | |
266 | (_scale_recip))) | |
267 | ||
268 | #define _RAW_TCOUNTER(_tcp) HRT_TO_TICK(RAW_HRTIME, (_tcp)->scale) | |
269 | #define RAW_TICK(_v9p) (options.walltime ? _RAW_TCOUNTER((_v9p)->tick) : \ | |
270 | ((_v9p)->simp->cycle)) | |
271 | #define RAW_STICK(_v9p) (options.walltime ? _RAW_TCOUNTER((_v9p)->stick) : \ | |
272 | ((_v9p)->simp->cycle)) | |
273 | ||
274 | #else /* WALL_TIME */ | |
275 | ||
276 | #define RAW_TICK(_v9p) ((_v9p)->simp->cycle) | |
277 | #define RAW_STICK(_v9p) ((_v9p)->simp->cycle) | |
278 | ||
279 | #endif /* WALL_TIME */ | |
280 | ||
281 | typedef struct { | |
282 | #if WALL_TIME | |
283 | double scale; | |
284 | double scale_recip; | |
285 | #endif /* WALL_TIME */ | |
286 | uint64_t offset; | |
287 | bool_t non_priv_trap; | |
288 | } tick_counter_t; | |
289 | ||
290 | /* ticktarg_t needs to be able to hold uint64_t and hrtime_t */ | |
291 | typedef uint64_t ticktarg_t; | |
292 | ||
293 | typedef struct { | |
294 | uint64_t compare; | |
295 | ticktarg_t target; | |
296 | bool_t interrupt_enabled; | |
297 | bool_t triggered; | |
298 | bool_t pending; | |
299 | tick_counter_t *counter; | |
300 | } tick_compare_t; | |
301 | ||
302 | /* | |
303 | * Legion debug features used by all sparcv9 processors | |
304 | * and parsed from config file. | |
305 | */ | |
306 | struct PROC_DEBUG { | |
307 | uint64_t exit_at; /* if set in conf file, exit when | |
308 | we reach this num of instns */ | |
309 | uint64_t perf_cycle_gap; /* Override PERF_CYCLE_GAP */ | |
310 | }; | |
311 | ||
312 | ||
313 | struct SPARCV9_CPU { | |
314 | /* Window registers */ | |
315 | uint_t cwp; | |
316 | uint_t cansave; | |
317 | uint_t canrestore; | |
318 | uint_t otherwin; | |
319 | uint_t cleanwin; | |
320 | uint_t wstate_other; | |
321 | uint_t wstate_normal; | |
322 | ||
323 | uint_t active_window; /* window currently in intreg file */ | |
324 | uint_t active_global; /* globals currently in intreg file */ | |
325 | /* -1 if intregs not active */ | |
326 | ||
327 | #define V9_WSTATE_NORMAL_BITS 0 | |
328 | #define V9_WSTATE_OTHER_BITS 3 | |
329 | #define V9_WSTATE_MASK 0x7 | |
330 | ||
331 | ||
332 | ||
333 | #define V9_REG_GROUP 8 /* 8 registers */ | |
334 | #define V9_IN_OFFSET 24 | |
335 | #define V9_LOCAL_OFFSET 16 | |
336 | #define V9_OUT_OFFSET 8 | |
337 | uint_t nwins; | |
338 | uint_t nwins_mask; /* set to nwins-1 */ | |
339 | uint64_t * winsp; | |
340 | ||
341 | #define V9_GLOBAL_GROUP 8 | |
342 | #define V9_GLOBAL_OFFSET 0 | |
343 | uint_t nglobals; | |
344 | uint64_t * globalsp; | |
345 | uint_t gl; | |
346 | #define Q_MAXPGL 2 /* Max GL for cpu obeying Q spec */ | |
347 | ||
348 | #define V9_PSTATE_IE_BIT 1 | |
349 | #define V9_PSTATE_PRIV_BIT 2 | |
350 | #define V9_PSTATE_AM_BIT 3 | |
351 | #define V9_PSTATE_PEF_BIT 4 | |
352 | #define V9_PSTATE_MM_BITS 6 | |
353 | #define V9_PSTATE_MM_MASK 0x3 | |
354 | #define V9_PSTATE_TLE_BIT 8 | |
355 | #define V9_PSTATE_CLE_BIT 9 | |
356 | #define V9_PSTATE_TCT_BIT 12 | |
357 | struct { | |
358 | bool_t priv; /* PRIV */ | |
359 | bool_t int_enabled; /* IE */ | |
360 | bool_t addr_mask; /* AM */ | |
361 | v9_mm_t mm; /* memory mode */ | |
362 | bool_t fpu_enabled; /* PEF */ | |
363 | bool_t cle; /* CLE */ | |
364 | bool_t tle; /* TLE */ | |
365 | bool_t tct; /* TCT */ | |
366 | } pstate; | |
367 | ||
368 | #define V9_HPSTATE_TLZ_BIT 0 | |
369 | #define V9_HPSTATE_HPRIV_BIT 2 | |
370 | #define V9_HPSTATE_RED_BIT 5 | |
371 | #define V9_HPSTATE_IBE_BIT 10 | |
372 | struct { | |
373 | bool_t hpriv; | |
374 | bool_t tlz; /* trap level zero */ | |
375 | bool_t red; /* RED */ | |
376 | bool_t ibe; /* instruction breakpoint enable */ | |
377 | } hpstate; | |
378 | ||
379 | /* Trap support registers */ | |
380 | uint_t tl; /* trap level reg */ | |
381 | uint_t maxtl; /* max supported (SPARCv9_TLSPACE-1) */ | |
382 | uint_t pil; /* processor interrupt level */ | |
383 | ||
384 | #define Q_MAXPTL 2 /* Max TL for cpu obeying Q spec */ | |
385 | ||
386 | #define SPARCv9_TLSPACE 8 | |
387 | tvaddr_t tpc[SPARCv9_TLSPACE]; /* tpc[0] = TPC1 etc. */ | |
388 | tvaddr_t tnpc[SPARCv9_TLSPACE]; | |
389 | uint64_t tstate[SPARCv9_TLSPACE]; | |
390 | uint16_t tt[SPARCv9_TLSPACE]; /* trap type */ | |
391 | #define N_TPC(_v9p, _tl) (_v9p)->tpc[ (_tl)-1 ] | |
392 | #define N_TNPC(_v9p, _tl) (_v9p)->tnpc[ (_tl)-1 ] | |
393 | #define N_TSTATE(_v9p, _tl) (_v9p)->tstate[ (_tl)-1 ] | |
394 | #define N_TT(_v9p, _tl) (_v9p)->tt[ (_tl)-1 ] | |
395 | ||
396 | #define V9_TT_MASK 0x1ff | |
397 | ||
398 | uint64_t htstate[SPARCv9_TLSPACE]; | |
399 | #define N_HTSTATE(_v9p, _tl) (_v9p)->htstate[ (_tl)-1 ] | |
400 | ||
401 | #define V9_TBA_MASK ((tvaddr_t)~((1LL<<15)-1)) | |
402 | tvaddr_t tba; /* trap base address */ | |
403 | #define V9_HTBA_MASK ((tvaddr_t)~((1LL<<14)-1)) | |
404 | tvaddr_t htba; /* hypervisor trap base address */ | |
405 | ||
406 | /* Other misc registers */ | |
407 | simcpu_t * simp; | |
408 | ||
409 | tick_counter_t *tick; | |
410 | tick_counter_t *stick; | |
411 | tick_counter_t _tick; | |
412 | tick_counter_t _stick; | |
413 | ||
414 | tick_compare_t tick_cmpr; | |
415 | tick_compare_t stick_cmpr; | |
416 | tick_compare_t hstick_cmpr; | |
417 | ||
418 | uint32_t softint; | |
419 | ||
420 | sparcv9_state_t state; | |
421 | uint64_t ver; | |
422 | ||
423 | PERFDEF(struct { | |
424 | simcycle_t enter_icount; | |
425 | simcycle_t icount[V9_State_Max]; | |
426 | } perf; ) | |
427 | ||
428 | /* | |
429 | * Floating point state | |
430 | * (NOTE: for efficiency, many fsr fields are implemented using | |
431 | * simcpu_t private registers) | |
432 | */ | |
433 | ||
434 | bool_t has_fpu; /* true if this v9 cpu is supposed to have an fpu */ | |
435 | bool_t fpu_on; /* true if is fully enabled (has_fpu, pstate.pef=1, fprs.fef=1) */ | |
436 | struct { | |
437 | bool_t fef; /* floating point enabled in FPRS register */ | |
438 | /* combine with pstate.pef to enable FPU */ | |
439 | bool_t du; | |
440 | bool_t dl; | |
441 | } fprs; | |
442 | #define V9_FPRS_FEF_BIT 2 | |
443 | #define V9_FPRS_DU_BIT 1 | |
444 | #define V9_FPRS_DL_BIT 0 | |
445 | ||
446 | bool_t had_RED_trap; | |
447 | ||
448 | /* | |
449 | * Specific callbacks for the type of sparc core we have | |
450 | */ | |
451 | ||
452 | void (*read_state_reg)(simcpu_t* sp, uint_t rdest, uint_t state_regnum); | |
453 | void (*write_state_reg)(simcpu_t* sp, uint_t state_regnum, uint64_t val); | |
454 | void (*read_priv_reg)(simcpu_t* sp, uint_t rdest, uint_t priv_regnum); | |
455 | void (*write_priv_reg)(simcpu_t* sp, uint_t priv_regnum, uint64_t val); | |
456 | void (*read_hyp_priv_reg)(simcpu_t* sp, uint_t rdest, uint_t hpriv_regnum); | |
457 | void (*write_hyp_priv_reg)(simcpu_t* sp, uint_t hpriv_regnum, uint64_t val); | |
458 | ||
459 | bool_t (*check_vahole)(simcpu_t* sp, tvaddr_t pc); | |
460 | void (*done_retry)(simcpu_t* sp, bool_t is_done); | |
461 | void (*jpriv)(simcpu_t* sp, tvaddr_t addr); | |
462 | void (*asi_access)(simcpu_t * sp, maccess_t op, uint_t regnum, uint_t asi, uint64_t reg1, uint64_t reg2, asi_flag_t asi_flag ); | |
463 | ||
464 | void (*post_precise_trap)(simcpu_t * sp, sparcv9_trap_type_t v9trap); | |
465 | ||
466 | /* Pointer to implementation specific v9 info - for use with callbacks */ | |
467 | void * impl_specificp; | |
468 | ||
469 | }; | |
470 | ||
471 | #if PERFORMANCE_CHECK /* { */ | |
472 | #define PERF_ACCUMULATE_ICOUNT(_v9p) do { \ | |
473 | simcycle_t _icount = ICOUNT(_v9p->simp); \ | |
474 | _v9p->perf.icount[_v9p->state] += (_icount - _v9p->perf.enter_icount); \ | |
475 | _v9p->perf.enter_icount = _icount; \ | |
476 | } while (0) | |
477 | #else /* } { */ | |
478 | #define PERF_ACCUMULATE_ICOUNT(_v9p) do { } while (0) | |
479 | #endif /* } */ | |
480 | ||
481 | ||
482 | ||
483 | ||
484 | #define NEXT_INSTN(_sp) do { (_sp)->pc = (_sp)->npc; (_sp)->npc += 4; } while (0) | |
485 | /* FIXME: may want to check for PC alignment with SET_PC_WITH_DS */ | |
486 | #define SET_PC_WITH_DS(_sp, _targ) do { (_sp)->pc = (_sp)->npc; (_sp)->npc = (_targ); } while (0) | |
487 | ||
488 | ||
489 | ||
490 | extern void sparcv9_save_instr(simcpu_t * sp, uint_t rdest_num, tvaddr_t newval); | |
491 | extern void sparcv9_restore_instr(simcpu_t * sp, uint_t rdest_num, tvaddr_t newval); | |
492 | extern void sparcv9_return_instr(simcpu_t * sp, tvaddr_t newval); | |
493 | ||
494 | extern void sparcv9_udiv64(simcpu_t * sp, uint_t rdest_num, uint64_t a, uint64_t b); | |
495 | ||
496 | /* | |
497 | * Other misc values | |
498 | */ | |
499 | ||
500 | ||
501 | typedef enum { | |
502 | cond_a = 0x8, | |
503 | cond_n = 0x0, | |
504 | cond_ne = 0x9, | |
505 | cond_e = 0x1, | |
506 | cond_g = 0xA, | |
507 | cond_le = 0x2, | |
508 | cond_ge = 0xB, | |
509 | cond_l = 0x3, | |
510 | cond_gu = 0xC, | |
511 | cond_leu = 0x4, | |
512 | cond_cc = 0xD, | |
513 | cond_cs = 0x5, | |
514 | cond_pos = 0xE, | |
515 | cond_neg = 0x6, | |
516 | cond_vc = 0xF, | |
517 | cond_vs = 0x7 | |
518 | } cond_type_t; | |
519 | ||
520 | extern void sparcv9_trapcc(simcpu_t * sp, uint64_t tnum, uint_t cc, cond_type_t cond); | |
521 | ||
522 | ||
523 | /* iflush */ | |
524 | ||
525 | extern void ss_iflush_by_pa(simcpu_t * sp, uint64_t pa, uint_t gran); | |
526 | ||
527 | /* FLUSH instruction granularity = 64 bytes */ | |
528 | #define SS_FLUSH_GRAN 0x40 | |
529 | ||
530 | typedef enum { | |
531 | cc_bit_c = 0x1, | |
532 | cc_bit_v = 0x2, | |
533 | cc_bit_z = 0x4, | |
534 | cc_bit_n = 0x8 | |
535 | } cc_bit_t; | |
536 | ||
537 | /* macros to help with the formation of cc values */ | |
538 | ||
539 | #define _V9_cc_n(_n) ((_n)<<3) | |
540 | #define _V9_cc_z(_z) ((_z)<<2) | |
541 | #define _V9_cc_v(_v) ((_v)<<1) | |
542 | #define _V9_cc_c(_c) (_c) | |
543 | ||
544 | #define _V9_cc(_n, _z, _v, _c) _V9_cc_n(_n)|_V9_cc_z(_z)|_V9_cc_v(_v)|_V9_cc_c(_c) | |
545 | #define V9_icc(_n, _z, _v, _c) _V9_cc(_n, _z, _v, _c) | |
546 | #define V9_xcc(_n, _z, _v, _c) (_V9_cc(_n, _z, _v, _c)<<4) | |
547 | ||
548 | #define V9_icc_n(_n) ((_n)<<3) | |
549 | #define V9_icc_z(_z) ((_z)<<2) | |
550 | #define V9_icc_v(_v) ((_v)<<1) | |
551 | #define V9_icc_c(_c) (_c) | |
552 | ||
553 | #define V9_xcc_n(_n) ((_n)<<7) | |
554 | #define V9_xcc_z(_z) ((_z)<<6) | |
555 | #define V9_xcc_v(_v) ((_v)<<5) | |
556 | #define V9_xcc_c(_c) ((_c)<<4) | |
557 | ||
558 | ||
559 | #define V9_icc_n_mask V9_icc_n(1ULL) | |
560 | #define V9_icc_z_mask V9_icc_z(1ULL) | |
561 | #define V9_icc_v_mask V9_icc_v(1ULL) | |
562 | #define V9_icc_c_mask V9_icc_c(1ULL) | |
563 | #define V9_xcc_n_mask V9_xcc_n(1ULL) | |
564 | #define V9_xcc_z_mask V9_xcc_z(1ULL) | |
565 | #define V9_xcc_v_mask V9_xcc_v(1ULL) | |
566 | #define V9_xcc_c_mask V9_xcc_c(1ULL) | |
567 | ||
568 | #define V9_icc_mask 0x0f | |
569 | #define V9_xcc_mask 0xf0 | |
570 | ||
571 | #define V9_ext_icc(_x) ((_x)&V9_icc_mask) | |
572 | #define V9_ext_xcc(_x) (((_x)&V9_xcc_mask)>>4) | |
573 | ||
574 | /* FPU condition codes */ | |
575 | ||
576 | #define V9_fcc_u 3 | |
577 | #define V9_fcc_g 2 | |
578 | #define V9_fcc_l 1 | |
579 | #define V9_fcc_e 0 | |
580 | ||
581 | ||
582 | uint64_t sparcv9_invert_endianess(uint64_t *regp, uint32_t count); | |
583 | ||
584 | /* | |
585 | * Support functions for debugging Legion's SPARC v9 modules | |
586 | */ | |
587 | #if !defined(NDEBUG) /* { */ | |
588 | ||
589 | extern void sparcv9_dump_intregs(simcpu_t *sp); | |
590 | extern void sparcv9_dump_state(simcpu_t *sp); | |
591 | ||
592 | #endif /* } */ | |
593 | ||
594 | #ifndef NDEBUG /* { */ | |
595 | #define DBG_FSR 0x1000000000LL | |
596 | #define DBG_FP 0x40000000000LL | |
597 | #define DBGFSR(s) do { if (debug_bits & DBG_FSR) { s } } while (0) /* floating point status register */ | |
598 | #define DBGFP(s) do { if (debug_bits & DBG_FP) { s } } while (0) /* floating point instructions */ | |
599 | #define DBG_FPRS 0x2000000000LL | |
600 | #define DBGFPRS(s) do { if (debug_bits & DBG_FPRS) { s } } while (0) /* floating point registers state */ | |
601 | #else /* } { */ | |
602 | #define DBGFSR(s) do { } while (0) | |
603 | #define DBGFPRS(s) do { } while (0) | |
604 | #endif /* } */ | |
605 | ||
606 | #ifndef FP_DECODE_DISABLED | |
607 | #define FP_EXEC_FPU_ON_CHECK \ | |
608 | sparcv9_cpu_t * v9p = (sparcv9_cpu_t*)(sp->specificp); \ | |
609 | if (!v9p->fpu_on) { \ | |
610 | v9p->post_precise_trap(sp, Sparcv9_trap_fp_disabled); \ | |
611 | return; \ | |
612 | } | |
613 | #else /* FP_DECODE_DISABLED */ | |
614 | #define FP_EXEC_FPU_ON_CHECK | |
615 | #endif /* FP_DECODE_DISABLED */ | |
616 | ||
617 | #ifdef __cplusplus | |
618 | } | |
619 | #endif | |
620 | ||
621 | #endif /* _TSPARCV9INTERNAL_H_ */ |