|
|
1.1 root 1: #include "exec.h"
2:
3: //#define DEBUG_PCALL
4: //#define DEBUG_MMU
5:
6: void raise_exception(int tt)
7: {
8: env->exception_index = tt;
9: cpu_loop_exit();
10: }
11:
12: #ifdef USE_INT_TO_FLOAT_HELPERS
13: void do_fitos(void)
14: {
1.1.1.3 ! root 15: FT0 = int32_to_float32(*((int32_t *)&FT1));
1.1 root 16: }
17:
18: void do_fitod(void)
19: {
1.1.1.3 ! root 20: DT0 = int32_to_float64(*((int32_t *)&FT1));
1.1 root 21: }
22: #endif
23:
24: void do_fabss(void)
25: {
26: FT0 = float32_abs(FT1);
27: }
28:
29: #ifdef TARGET_SPARC64
30: void do_fabsd(void)
31: {
32: DT0 = float64_abs(DT1);
33: }
34: #endif
35:
36: void do_fsqrts(void)
37: {
38: FT0 = float32_sqrt(FT1, &env->fp_status);
39: }
40:
41: void do_fsqrtd(void)
42: {
43: DT0 = float64_sqrt(DT1, &env->fp_status);
44: }
45:
1.1.1.3 ! root 46: #define GEN_FCMP(name, size, reg1, reg2, FS) \
! 47: void glue(do_, name) (void) \
! 48: { \
! 49: env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \
! 50: switch (glue(size, _compare) (reg1, reg2, &env->fp_status)) { \
! 51: case float_relation_unordered: \
! 52: T0 = (FSR_FCC1 | FSR_FCC0) << FS; \
! 53: if (env->fsr & FSR_NVM) { \
! 54: env->fsr |= T0; \
! 55: raise_exception(TT_FP_EXCP); \
! 56: } else { \
! 57: env->fsr |= FSR_NVA; \
! 58: } \
! 59: break; \
! 60: case float_relation_less: \
! 61: T0 = FSR_FCC0 << FS; \
! 62: break; \
! 63: case float_relation_greater: \
! 64: T0 = FSR_FCC1 << FS; \
! 65: break; \
! 66: default: \
! 67: T0 = 0; \
! 68: break; \
! 69: } \
! 70: env->fsr |= T0; \
1.1 root 71: }
72:
1.1.1.3 ! root 73: GEN_FCMP(fcmps, float32, FT0, FT1, 0);
! 74: GEN_FCMP(fcmpd, float64, DT0, DT1, 0);
1.1 root 75:
76: #ifdef TARGET_SPARC64
1.1.1.3 ! root 77: GEN_FCMP(fcmps_fcc1, float32, FT0, FT1, 22);
! 78: GEN_FCMP(fcmpd_fcc1, float64, DT0, DT1, 22);
1.1 root 79:
1.1.1.3 ! root 80: GEN_FCMP(fcmps_fcc2, float32, FT0, FT1, 24);
! 81: GEN_FCMP(fcmpd_fcc2, float64, DT0, DT1, 24);
1.1 root 82:
1.1.1.3 ! root 83: GEN_FCMP(fcmps_fcc3, float32, FT0, FT1, 26);
! 84: GEN_FCMP(fcmpd_fcc3, float64, DT0, DT1, 26);
1.1 root 85: #endif
86:
1.1.1.2 root 87: #if defined(CONFIG_USER_ONLY)
88: void helper_ld_asi(int asi, int size, int sign)
89: {
90: }
91:
92: void helper_st_asi(int asi, int size, int sign)
93: {
94: }
95: #else
1.1 root 96: #ifndef TARGET_SPARC64
97: void helper_ld_asi(int asi, int size, int sign)
98: {
99: uint32_t ret = 0;
100:
101: switch (asi) {
102: case 3: /* MMU probe */
103: {
104: int mmulev;
105:
106: mmulev = (T0 >> 8) & 15;
107: if (mmulev > 4)
108: ret = 0;
109: else {
110: ret = mmu_probe(env, T0, mmulev);
111: //bswap32s(&ret);
112: }
113: #ifdef DEBUG_MMU
114: printf("mmu_probe: 0x%08x (lev %d) -> 0x%08x\n", T0, mmulev, ret);
115: #endif
116: }
117: break;
118: case 4: /* read MMU regs */
119: {
120: int reg = (T0 >> 8) & 0xf;
121:
122: ret = env->mmuregs[reg];
123: if (reg == 3) /* Fault status cleared on read */
124: env->mmuregs[reg] = 0;
125: #ifdef DEBUG_MMU
126: printf("mmu_read: reg[%d] = 0x%08x\n", reg, ret);
127: #endif
128: }
129: break;
130: case 0x20 ... 0x2f: /* MMU passthrough */
1.1.1.2 root 131: switch(size) {
132: case 1:
133: ret = ldub_phys(T0);
134: break;
135: case 2:
136: ret = lduw_phys(T0 & ~1);
137: break;
138: default:
139: case 4:
140: ret = ldl_phys(T0 & ~3);
141: break;
142: case 8:
143: ret = ldl_phys(T0 & ~3);
144: T0 = ldl_phys((T0 + 4) & ~3);
145: break;
146: }
1.1 root 147: break;
148: default:
149: ret = 0;
150: break;
151: }
152: T1 = ret;
153: }
154:
155: void helper_st_asi(int asi, int size, int sign)
156: {
157: switch(asi) {
158: case 3: /* MMU flush */
159: {
160: int mmulev;
161:
162: mmulev = (T0 >> 8) & 15;
163: #ifdef DEBUG_MMU
164: printf("mmu flush level %d\n", mmulev);
165: #endif
166: switch (mmulev) {
167: case 0: // flush page
168: tlb_flush_page(env, T0 & 0xfffff000);
169: break;
170: case 1: // flush segment (256k)
171: case 2: // flush region (16M)
172: case 3: // flush context (4G)
173: case 4: // flush entire
174: tlb_flush(env, 1);
175: break;
176: default:
177: break;
178: }
179: #ifdef DEBUG_MMU
180: dump_mmu(env);
181: #endif
182: return;
183: }
184: case 4: /* write MMU regs */
185: {
186: int reg = (T0 >> 8) & 0xf;
187: uint32_t oldreg;
188:
189: oldreg = env->mmuregs[reg];
190: switch(reg) {
191: case 0:
192: env->mmuregs[reg] &= ~(MMU_E | MMU_NF);
193: env->mmuregs[reg] |= T1 & (MMU_E | MMU_NF);
194: // Mappings generated during no-fault mode or MMU
195: // disabled mode are invalid in normal mode
196: if (oldreg != env->mmuregs[reg])
197: tlb_flush(env, 1);
198: break;
199: case 2:
200: env->mmuregs[reg] = T1;
201: if (oldreg != env->mmuregs[reg]) {
202: /* we flush when the MMU context changes because
203: QEMU has no MMU context support */
204: tlb_flush(env, 1);
205: }
206: break;
207: case 3:
208: case 4:
209: break;
210: default:
211: env->mmuregs[reg] = T1;
212: break;
213: }
214: #ifdef DEBUG_MMU
215: if (oldreg != env->mmuregs[reg]) {
216: printf("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg, oldreg, env->mmuregs[reg]);
217: }
218: dump_mmu(env);
219: #endif
220: return;
221: }
222: case 0x17: /* Block copy, sta access */
223: {
224: // value (T1) = src
225: // address (T0) = dst
226: // copy 32 bytes
227: uint32_t src = T1, dst = T0;
228: uint8_t temp[32];
229:
230: tswap32s(&src);
231:
232: cpu_physical_memory_read(src, (void *) &temp, 32);
233: cpu_physical_memory_write(dst, (void *) &temp, 32);
234: }
235: return;
236: case 0x1f: /* Block fill, stda access */
237: {
238: // value (T1, T2)
239: // address (T0) = dst
240: // fill 32 bytes
241: int i;
242: uint32_t dst = T0;
243: uint64_t val;
244:
245: val = (((uint64_t)T1) << 32) | T2;
246: tswap64s(&val);
247:
248: for (i = 0; i < 32; i += 8, dst += 8) {
249: cpu_physical_memory_write(dst, (void *) &val, 8);
250: }
251: }
252: return;
253: case 0x20 ... 0x2f: /* MMU passthrough */
254: {
1.1.1.2 root 255: switch(size) {
256: case 1:
257: stb_phys(T0, T1);
258: break;
259: case 2:
260: stw_phys(T0 & ~1, T1);
261: break;
262: case 4:
263: default:
264: stl_phys(T0 & ~3, T1);
265: break;
266: case 8:
267: stl_phys(T0 & ~3, T1);
268: stl_phys((T0 + 4) & ~3, T2);
269: break;
270: }
1.1 root 271: }
272: return;
273: default:
274: return;
275: }
276: }
277:
278: #else
279:
280: void helper_ld_asi(int asi, int size, int sign)
281: {
282: uint64_t ret = 0;
283:
284: if (asi < 0x80 && (env->pstate & PS_PRIV) == 0)
285: raise_exception(TT_PRIV_ACT);
286:
287: switch (asi) {
288: case 0x14: // Bypass
289: case 0x15: // Bypass, non-cacheable
290: {
1.1.1.2 root 291: switch(size) {
292: case 1:
293: ret = ldub_phys(T0);
294: break;
295: case 2:
296: ret = lduw_phys(T0 & ~1);
297: break;
298: case 4:
299: ret = ldl_phys(T0 & ~3);
300: break;
301: default:
302: case 8:
303: ret = ldq_phys(T0 & ~7);
304: break;
305: }
1.1 root 306: break;
307: }
308: case 0x04: // Nucleus
309: case 0x0c: // Nucleus Little Endian (LE)
310: case 0x10: // As if user primary
311: case 0x11: // As if user secondary
312: case 0x18: // As if user primary LE
313: case 0x19: // As if user secondary LE
314: case 0x1c: // Bypass LE
315: case 0x1d: // Bypass, non-cacheable LE
316: case 0x24: // Nucleus quad LDD 128 bit atomic
317: case 0x2c: // Nucleus quad LDD 128 bit atomic
318: case 0x4a: // UPA config
319: case 0x82: // Primary no-fault
320: case 0x83: // Secondary no-fault
321: case 0x88: // Primary LE
322: case 0x89: // Secondary LE
323: case 0x8a: // Primary no-fault LE
324: case 0x8b: // Secondary no-fault LE
325: // XXX
326: break;
327: case 0x45: // LSU
328: ret = env->lsu;
329: break;
330: case 0x50: // I-MMU regs
331: {
332: int reg = (T0 >> 3) & 0xf;
333:
334: ret = env->immuregs[reg];
335: break;
336: }
337: case 0x51: // I-MMU 8k TSB pointer
338: case 0x52: // I-MMU 64k TSB pointer
339: case 0x55: // I-MMU data access
340: // XXX
341: break;
342: case 0x56: // I-MMU tag read
343: {
344: unsigned int i;
345:
346: for (i = 0; i < 64; i++) {
347: // Valid, ctx match, vaddr match
348: if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0 &&
349: env->itlb_tag[i] == T0) {
350: ret = env->itlb_tag[i];
351: break;
352: }
353: }
354: break;
355: }
356: case 0x58: // D-MMU regs
357: {
358: int reg = (T0 >> 3) & 0xf;
359:
360: ret = env->dmmuregs[reg];
361: break;
362: }
363: case 0x5e: // D-MMU tag read
364: {
365: unsigned int i;
366:
367: for (i = 0; i < 64; i++) {
368: // Valid, ctx match, vaddr match
369: if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0 &&
370: env->dtlb_tag[i] == T0) {
371: ret = env->dtlb_tag[i];
372: break;
373: }
374: }
375: break;
376: }
377: case 0x59: // D-MMU 8k TSB pointer
378: case 0x5a: // D-MMU 64k TSB pointer
379: case 0x5b: // D-MMU data pointer
380: case 0x5d: // D-MMU data access
381: case 0x48: // Interrupt dispatch, RO
382: case 0x49: // Interrupt data receive
383: case 0x7f: // Incoming interrupt vector, RO
384: // XXX
385: break;
386: case 0x54: // I-MMU data in, WO
387: case 0x57: // I-MMU demap, WO
388: case 0x5c: // D-MMU data in, WO
389: case 0x5f: // D-MMU demap, WO
390: case 0x77: // Interrupt vector, WO
391: default:
392: ret = 0;
393: break;
394: }
395: T1 = ret;
396: }
397:
398: void helper_st_asi(int asi, int size, int sign)
399: {
400: if (asi < 0x80 && (env->pstate & PS_PRIV) == 0)
401: raise_exception(TT_PRIV_ACT);
402:
403: switch(asi) {
404: case 0x14: // Bypass
405: case 0x15: // Bypass, non-cacheable
406: {
1.1.1.2 root 407: switch(size) {
408: case 1:
409: stb_phys(T0, T1);
410: break;
411: case 2:
412: stw_phys(T0 & ~1, T1);
413: break;
414: case 4:
415: stl_phys(T0 & ~3, T1);
416: break;
417: case 8:
418: default:
419: stq_phys(T0 & ~7, T1);
420: break;
421: }
1.1 root 422: }
423: return;
424: case 0x04: // Nucleus
425: case 0x0c: // Nucleus Little Endian (LE)
426: case 0x10: // As if user primary
427: case 0x11: // As if user secondary
428: case 0x18: // As if user primary LE
429: case 0x19: // As if user secondary LE
430: case 0x1c: // Bypass LE
431: case 0x1d: // Bypass, non-cacheable LE
432: case 0x24: // Nucleus quad LDD 128 bit atomic
433: case 0x2c: // Nucleus quad LDD 128 bit atomic
434: case 0x4a: // UPA config
435: case 0x88: // Primary LE
436: case 0x89: // Secondary LE
437: // XXX
438: return;
439: case 0x45: // LSU
440: {
441: uint64_t oldreg;
442:
443: oldreg = env->lsu;
444: env->lsu = T1 & (DMMU_E | IMMU_E);
445: // Mappings generated during D/I MMU disabled mode are
446: // invalid in normal mode
447: if (oldreg != env->lsu) {
448: #ifdef DEBUG_MMU
1.1.1.3 ! root 449: printf("LSU change: 0x%" PRIx64 " -> 0x%" PRIx64 "\n", oldreg, env->lsu);
1.1 root 450: dump_mmu(env);
451: #endif
452: tlb_flush(env, 1);
453: }
454: return;
455: }
456: case 0x50: // I-MMU regs
457: {
458: int reg = (T0 >> 3) & 0xf;
459: uint64_t oldreg;
460:
461: oldreg = env->immuregs[reg];
462: switch(reg) {
463: case 0: // RO
464: case 4:
465: return;
466: case 1: // Not in I-MMU
467: case 2:
468: case 7:
469: case 8:
470: return;
471: case 3: // SFSR
472: if ((T1 & 1) == 0)
473: T1 = 0; // Clear SFSR
474: break;
475: case 5: // TSB access
476: case 6: // Tag access
477: default:
478: break;
479: }
480: env->immuregs[reg] = T1;
481: #ifdef DEBUG_MMU
482: if (oldreg != env->immuregs[reg]) {
1.1.1.3 ! root 483: printf("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, oldreg, env->immuregs[reg]);
1.1 root 484: }
485: dump_mmu(env);
486: #endif
487: return;
488: }
489: case 0x54: // I-MMU data in
490: {
491: unsigned int i;
492:
493: // Try finding an invalid entry
494: for (i = 0; i < 64; i++) {
495: if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0) {
496: env->itlb_tag[i] = env->immuregs[6];
497: env->itlb_tte[i] = T1;
498: return;
499: }
500: }
501: // Try finding an unlocked entry
502: for (i = 0; i < 64; i++) {
503: if ((env->itlb_tte[i] & 0x40) == 0) {
504: env->itlb_tag[i] = env->immuregs[6];
505: env->itlb_tte[i] = T1;
506: return;
507: }
508: }
509: // error state?
510: return;
511: }
512: case 0x55: // I-MMU data access
513: {
514: unsigned int i = (T0 >> 3) & 0x3f;
515:
516: env->itlb_tag[i] = env->immuregs[6];
517: env->itlb_tte[i] = T1;
518: return;
519: }
520: case 0x57: // I-MMU demap
521: // XXX
522: return;
523: case 0x58: // D-MMU regs
524: {
525: int reg = (T0 >> 3) & 0xf;
526: uint64_t oldreg;
527:
528: oldreg = env->dmmuregs[reg];
529: switch(reg) {
530: case 0: // RO
531: case 4:
532: return;
533: case 3: // SFSR
534: if ((T1 & 1) == 0) {
535: T1 = 0; // Clear SFSR, Fault address
536: env->dmmuregs[4] = 0;
537: }
538: env->dmmuregs[reg] = T1;
539: break;
540: case 1: // Primary context
541: case 2: // Secondary context
542: case 5: // TSB access
543: case 6: // Tag access
544: case 7: // Virtual Watchpoint
545: case 8: // Physical Watchpoint
546: default:
547: break;
548: }
549: env->dmmuregs[reg] = T1;
550: #ifdef DEBUG_MMU
551: if (oldreg != env->dmmuregs[reg]) {
1.1.1.3 ! root 552: printf("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, oldreg, env->dmmuregs[reg]);
1.1 root 553: }
554: dump_mmu(env);
555: #endif
556: return;
557: }
558: case 0x5c: // D-MMU data in
559: {
560: unsigned int i;
561:
562: // Try finding an invalid entry
563: for (i = 0; i < 64; i++) {
564: if ((env->dtlb_tte[i] & 0x8000000000000000ULL) == 0) {
565: env->dtlb_tag[i] = env->dmmuregs[6];
566: env->dtlb_tte[i] = T1;
567: return;
568: }
569: }
570: // Try finding an unlocked entry
571: for (i = 0; i < 64; i++) {
572: if ((env->dtlb_tte[i] & 0x40) == 0) {
573: env->dtlb_tag[i] = env->dmmuregs[6];
574: env->dtlb_tte[i] = T1;
575: return;
576: }
577: }
578: // error state?
579: return;
580: }
581: case 0x5d: // D-MMU data access
582: {
583: unsigned int i = (T0 >> 3) & 0x3f;
584:
585: env->dtlb_tag[i] = env->dmmuregs[6];
586: env->dtlb_tte[i] = T1;
587: return;
588: }
589: case 0x5f: // D-MMU demap
590: case 0x49: // Interrupt data receive
591: // XXX
592: return;
593: case 0x51: // I-MMU 8k TSB pointer, RO
594: case 0x52: // I-MMU 64k TSB pointer, RO
595: case 0x56: // I-MMU tag read, RO
596: case 0x59: // D-MMU 8k TSB pointer, RO
597: case 0x5a: // D-MMU 64k TSB pointer, RO
598: case 0x5b: // D-MMU data pointer, RO
599: case 0x5e: // D-MMU tag read, RO
600: case 0x48: // Interrupt dispatch, RO
601: case 0x7f: // Incoming interrupt vector, RO
602: case 0x82: // Primary no-fault, RO
603: case 0x83: // Secondary no-fault, RO
604: case 0x8a: // Primary no-fault LE, RO
605: case 0x8b: // Secondary no-fault LE, RO
606: default:
607: return;
608: }
609: }
610: #endif
1.1.1.2 root 611: #endif /* !CONFIG_USER_ONLY */
1.1 root 612:
613: #ifndef TARGET_SPARC64
614: void helper_rett()
615: {
616: unsigned int cwp;
617:
618: env->psret = 1;
619: cwp = (env->cwp + 1) & (NWINDOWS - 1);
620: if (env->wim & (1 << cwp)) {
621: raise_exception(TT_WIN_UNF);
622: }
623: set_cwp(cwp);
624: env->psrs = env->psrps;
625: }
626: #endif
627:
628: void helper_ldfsr(void)
629: {
630: int rnd_mode;
631: switch (env->fsr & FSR_RD_MASK) {
632: case FSR_RD_NEAREST:
633: rnd_mode = float_round_nearest_even;
634: break;
635: default:
636: case FSR_RD_ZERO:
637: rnd_mode = float_round_to_zero;
638: break;
639: case FSR_RD_POS:
640: rnd_mode = float_round_up;
641: break;
642: case FSR_RD_NEG:
643: rnd_mode = float_round_down;
644: break;
645: }
646: set_float_rounding_mode(rnd_mode, &env->fp_status);
647: }
648:
649: void helper_debug()
650: {
651: env->exception_index = EXCP_DEBUG;
652: cpu_loop_exit();
653: }
654:
655: #ifndef TARGET_SPARC64
656: void do_wrpsr()
657: {
658: PUT_PSR(env, T0);
659: }
660:
661: void do_rdpsr()
662: {
663: T0 = GET_PSR(env);
664: }
665:
666: #else
667:
668: void do_popc()
669: {
670: T0 = (T1 & 0x5555555555555555ULL) + ((T1 >> 1) & 0x5555555555555555ULL);
671: T0 = (T0 & 0x3333333333333333ULL) + ((T0 >> 2) & 0x3333333333333333ULL);
672: T0 = (T0 & 0x0f0f0f0f0f0f0f0fULL) + ((T0 >> 4) & 0x0f0f0f0f0f0f0f0fULL);
673: T0 = (T0 & 0x00ff00ff00ff00ffULL) + ((T0 >> 8) & 0x00ff00ff00ff00ffULL);
674: T0 = (T0 & 0x0000ffff0000ffffULL) + ((T0 >> 16) & 0x0000ffff0000ffffULL);
675: T0 = (T0 & 0x00000000ffffffffULL) + ((T0 >> 32) & 0x00000000ffffffffULL);
676: }
677:
678: static inline uint64_t *get_gregset(uint64_t pstate)
679: {
680: switch (pstate) {
681: default:
682: case 0:
683: return env->bgregs;
684: case PS_AG:
685: return env->agregs;
686: case PS_MG:
687: return env->mgregs;
688: case PS_IG:
689: return env->igregs;
690: }
691: }
692:
693: void do_wrpstate()
694: {
695: uint64_t new_pstate, pstate_regs, new_pstate_regs;
696: uint64_t *src, *dst;
697:
698: new_pstate = T0 & 0xf3f;
699: pstate_regs = env->pstate & 0xc01;
700: new_pstate_regs = new_pstate & 0xc01;
701: if (new_pstate_regs != pstate_regs) {
702: // Switch global register bank
703: src = get_gregset(new_pstate_regs);
704: dst = get_gregset(pstate_regs);
705: memcpy32(dst, env->gregs);
706: memcpy32(env->gregs, src);
707: }
708: env->pstate = new_pstate;
709: }
710:
711: void do_done(void)
712: {
713: env->tl--;
714: env->pc = env->tnpc[env->tl];
715: env->npc = env->tnpc[env->tl] + 4;
716: PUT_CCR(env, env->tstate[env->tl] >> 32);
717: env->asi = (env->tstate[env->tl] >> 24) & 0xff;
718: env->pstate = (env->tstate[env->tl] >> 8) & 0xfff;
719: set_cwp(env->tstate[env->tl] & 0xff);
720: }
721:
722: void do_retry(void)
723: {
724: env->tl--;
725: env->pc = env->tpc[env->tl];
726: env->npc = env->tnpc[env->tl];
727: PUT_CCR(env, env->tstate[env->tl] >> 32);
728: env->asi = (env->tstate[env->tl] >> 24) & 0xff;
729: env->pstate = (env->tstate[env->tl] >> 8) & 0xfff;
730: set_cwp(env->tstate[env->tl] & 0xff);
731: }
732: #endif
733:
734: void set_cwp(int new_cwp)
735: {
736: /* put the modified wrap registers at their proper location */
737: if (env->cwp == (NWINDOWS - 1))
738: memcpy32(env->regbase, env->regbase + NWINDOWS * 16);
739: env->cwp = new_cwp;
740: /* put the wrap registers at their temporary location */
741: if (new_cwp == (NWINDOWS - 1))
742: memcpy32(env->regbase + NWINDOWS * 16, env->regbase);
743: env->regwptr = env->regbase + (new_cwp * 16);
744: REGWPTR = env->regwptr;
745: }
746:
747: void cpu_set_cwp(CPUState *env1, int new_cwp)
748: {
749: CPUState *saved_env;
750: #ifdef reg_REGWPTR
751: target_ulong *saved_regwptr;
752: #endif
753:
754: saved_env = env;
755: #ifdef reg_REGWPTR
756: saved_regwptr = REGWPTR;
757: #endif
758: env = env1;
759: set_cwp(new_cwp);
760: env = saved_env;
761: #ifdef reg_REGWPTR
762: REGWPTR = saved_regwptr;
763: #endif
764: }
765:
766: #ifdef TARGET_SPARC64
767: void do_interrupt(int intno)
768: {
769: #ifdef DEBUG_PCALL
770: if (loglevel & CPU_LOG_INT) {
771: static int count;
1.1.1.3 ! root 772: fprintf(logfile, "%6d: v=%04x pc=%016" PRIx64 " npc=%016" PRIx64 " SP=%016" PRIx64 "\n",
1.1 root 773: count, intno,
774: env->pc,
775: env->npc, env->regwptr[6]);
776: cpu_dump_state(env, logfile, fprintf, 0);
777: #if 0
778: {
779: int i;
780: uint8_t *ptr;
781:
782: fprintf(logfile, " code=");
783: ptr = (uint8_t *)env->pc;
784: for(i = 0; i < 16; i++) {
785: fprintf(logfile, " %02x", ldub(ptr + i));
786: }
787: fprintf(logfile, "\n");
788: }
789: #endif
790: count++;
791: }
792: #endif
793: #if !defined(CONFIG_USER_ONLY)
794: if (env->tl == MAXTL) {
1.1.1.2 root 795: cpu_abort(env, "Trap 0x%04x while trap level is MAXTL, Error state", env->exception_index);
1.1 root 796: return;
797: }
798: #endif
799: env->tstate[env->tl] = ((uint64_t)GET_CCR(env) << 32) | ((env->asi & 0xff) << 24) |
800: ((env->pstate & 0xfff) << 8) | (env->cwp & 0xff);
801: env->tpc[env->tl] = env->pc;
802: env->tnpc[env->tl] = env->npc;
803: env->tt[env->tl] = intno;
804: env->pstate = PS_PEF | PS_PRIV | PS_AG;
805: env->tbr &= ~0x7fffULL;
806: env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
807: if (env->tl < MAXTL - 1) {
808: env->tl++;
809: } else {
810: env->pstate |= PS_RED;
811: if (env->tl != MAXTL)
812: env->tl++;
813: }
814: env->pc = env->tbr;
815: env->npc = env->pc + 4;
816: env->exception_index = 0;
817: }
818: #else
819: void do_interrupt(int intno)
820: {
821: int cwp;
822:
823: #ifdef DEBUG_PCALL
824: if (loglevel & CPU_LOG_INT) {
825: static int count;
826: fprintf(logfile, "%6d: v=%02x pc=%08x npc=%08x SP=%08x\n",
827: count, intno,
828: env->pc,
829: env->npc, env->regwptr[6]);
830: cpu_dump_state(env, logfile, fprintf, 0);
831: #if 0
832: {
833: int i;
834: uint8_t *ptr;
835:
836: fprintf(logfile, " code=");
837: ptr = (uint8_t *)env->pc;
838: for(i = 0; i < 16; i++) {
839: fprintf(logfile, " %02x", ldub(ptr + i));
840: }
841: fprintf(logfile, "\n");
842: }
843: #endif
844: count++;
845: }
846: #endif
847: #if !defined(CONFIG_USER_ONLY)
848: if (env->psret == 0) {
1.1.1.2 root 849: cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state", env->exception_index);
1.1 root 850: return;
851: }
852: #endif
853: env->psret = 0;
854: cwp = (env->cwp - 1) & (NWINDOWS - 1);
855: set_cwp(cwp);
856: env->regwptr[9] = env->pc;
857: env->regwptr[10] = env->npc;
858: env->psrps = env->psrs;
859: env->psrs = 1;
860: env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
861: env->pc = env->tbr;
862: env->npc = env->pc + 4;
863: env->exception_index = 0;
864: }
865: #endif
866:
867: #if !defined(CONFIG_USER_ONLY)
868:
869: #define MMUSUFFIX _mmu
870: #define GETPC() (__builtin_return_address(0))
871:
872: #define SHIFT 0
873: #include "softmmu_template.h"
874:
875: #define SHIFT 1
876: #include "softmmu_template.h"
877:
878: #define SHIFT 2
879: #include "softmmu_template.h"
880:
881: #define SHIFT 3
882: #include "softmmu_template.h"
883:
884:
885: /* try to fill the TLB and return an exception if error. If retaddr is
886: NULL, it means that the function was called in C code (i.e. not
887: from generated code or from helper.c) */
888: /* XXX: fix it to restore all registers */
889: void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr)
890: {
891: TranslationBlock *tb;
892: int ret;
893: unsigned long pc;
894: CPUState *saved_env;
895:
896: /* XXX: hack to restore env in all cases, even if not called from
897: generated code */
898: saved_env = env;
899: env = cpu_single_env;
900:
901: ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, is_user, 1);
902: if (ret) {
903: if (retaddr) {
904: /* now we have a real cpu fault */
905: pc = (unsigned long)retaddr;
906: tb = tb_find_pc(pc);
907: if (tb) {
908: /* the PC is inside the translated code. It means that we have
909: a virtual CPU fault */
910: cpu_restore_state(tb, env, pc, (void *)T2);
911: }
912: }
913: cpu_loop_exit();
914: }
915: env = saved_env;
916: }
917:
918: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.