50
50
51
51
/* Entry for traps which do nothing */
52
52
53
- #define DUMMY_TRAP \
54
- jmpl %l2, %g0; \
55
- rett %l2 + 4 ; \
56
- nop ; \
53
+ #define DUMMY_TRAP \
54
+ mov %l2, %l1; \
55
+ add %l2, 4 , %l2; \
56
+ b __gnat_return_from_trap; \
57
57
nop ;
58
58
59
59
/* Entry for traps that should not occur. They cause program termination */
@@ -475,8 +475,10 @@ overflow:
475
475
std %i6, [%sp + I6_OFFSET]
476
476
477
477
restore ! Increment CWP
478
- jmpl %l1, %g0 ! Load npc with saved pc
479
- rett %l2 ! return from trap
478
+
479
+ ! %l1 is PC and %l2 is nPC
480
+ b __gnat_return_from_trap
481
+ nop
480
482
481
483
.size overflow, . - overflow
482
484
@@ -507,8 +509,9 @@ underflow:
507
509
save ! Come back to the trap window
508
510
save ! where return address is located
509
511
510
- jmpl %l1, %g0
511
- rett %l2 ! Return from trap
512
+ ! %l1 is PC and %l2 is nPC
513
+ b __gnat_return_from_trap
514
+ nop
512
515
513
516
.size underflow, . - underflow
514
517
.type flush_windows,#function
@@ -605,8 +608,12 @@ flush_windows:
605
608
nop
606
609
nop
607
610
608
- jmp %l2 ! return to nPC
609
- rett %l2 + 4
611
+ mov %l2, %l1
612
+ add %l2, 4 , %l2
613
+
614
+ ! %l1 is PC and %l2 is nPC
615
+ b __gnat_return_from_trap
616
+ nop
610
617
611
618
.size flush_windows, . - flush_windows
612
619
@@ -621,11 +628,54 @@ mask_interrupt_level:
621
628
nop
622
629
nop
623
630
624
- jmp %l2
625
- rett %l2 + 4 ! Return from trap
631
+ mov %l2, %l1
632
+ add %l2, 4 , %l2
633
+
634
+ ! %l1 is PC and %l2 is nPC
635
+ b __gnat_return_from_trap
636
+ nop
626
637
627
638
.size mask_interrupt_level, . - mask_interrupt_level
628
639
640
+
641
+ /* Routine to return from trap, potentially with handling of Leon3 errata.
642
+ %l1 must be set to the PC after return, and %l2 to nPC after return. */
643
+
644
+ .global __gnat_return_from_trap
645
+ .type __gnat_return_from_trap,#function
646
+ __gnat_return_from_trap:
647
+
648
+ #if defined(LEON3)
649
+ /* Comment the #define below to disable the handling of Leon3 errata
650
+ GRLIB-TN-0018 */
651
+ #define LEON3_ERRATA_GRLIB_TN_0018
652
+ #endif
653
+
654
+ #if defined (LEON3_ERRATA_GRLIB_TN_0018)
655
+
656
+ /* LEON3FT RETT Restart Errata (GRLIB-TN-0018) workaround #1 */
657
+ mov %psr, %l0 ! save condition codes
658
+ 1: lda [%g0] 2 , %l3 ! read cache control register
659
+ srl %l3, 15 , %l4 ! check bit 15 if flush in progress
660
+ andcc %l4, 1 , %g0
661
+ bne 1b ! loop back if flushing
662
+ ! let following instruction go into the delay slot
663
+ andn %l3, 3 , %l4 ! mask out DCS field
664
+ ! align cache line boundary at this point for optimum performance
665
+ sta %l4, [%g0] 2 ! write to disable Icache
666
+ mov %l0, %psr ! delay + restore condition codes
667
+ or %l1, %l1, %l1 ! delay + catch rf parity error on l1
668
+ or %l2, %l2, %l2 ! delay + catch rf parity error on l2
669
+ sta %l3, [%g0] 2 ! write to re-enable Icache after rett
670
+ nop ! delay to ensure first insn after gets cached
671
+ jmp %l1
672
+ rett %l2
673
+ #else
674
+ jmpl %l1, %g0 ! PC
675
+ rett %l2 ! nPC
676
+ #endif
677
+ .size __gnat_return_from_trap, . - __gnat_return_from_trap
678
+
629
679
.section ".rodata"
630
680
.align 8
631
681
double_zero:
0 commit comments