30
30
31
31
#include <linux/errno.h>
32
32
#include <asm/signal.h>
33
+ #include <asm/mmu.h>
33
34
34
35
#undef DEBUG
35
36
@@ -287,6 +288,44 @@ syscall_debug_table:
287
288
288
289
.text
289
290
291
+ .extern cpuinfo
292
+
293
+ C_ENTRY(mb_flush_dcache):
294
+ addik r1, r1, -PT_SIZE
295
+ SAVE_REGS
296
+
297
+ addik r3, r0, cpuinfo
298
+ lwi r7, r3, CI_DCS
299
+ lwi r8, r3, CI_DCL
300
+ sub r9, r7, r8
301
+ 1:
302
+ wdc.flush r9, r0
303
+ bgtid r9, 1b
304
+ addk r9, r9, r8
305
+
306
+ RESTORE_REGS
307
+ addik r1, r1, PT_SIZE
308
+ rtsd r15, 8
309
+ nop
310
+
311
+ C_ENTRY(mb_invalidate_icache):
312
+ addik r1, r1, -PT_SIZE
313
+ SAVE_REGS
314
+
315
+ addik r3, r0, cpuinfo
316
+ lwi r7, r3, CI_ICS
317
+ lwi r8, r3, CI_ICL
318
+ sub r9, r7, r8
319
+ 1:
320
+ wic r9, r0
321
+ bgtid r9, 1b
322
+ addk r9, r9, r8
323
+
324
+ RESTORE_REGS
325
+ addik r1, r1, PT_SIZE
326
+ rtsd r15, 8
327
+ nop
328
+
290
329
/*
291
330
* User trap.
292
331
*
@@ -753,6 +792,160 @@ IRQ_return: /* MS: Make global symbol for debugging */
753
792
rtid r14, 0
754
793
nop
755
794
795
+ #ifdef CONFIG_MB_MANAGER
796
+
797
+ #define PT_PID PT_SIZE
798
+ #define PT_TLBI PT_SIZE + 4
799
+ #define PT_ZPR PT_SIZE + 8
800
+ #define PT_TLBL0 PT_SIZE + 12
801
+ #define PT_TLBH0 PT_SIZE + 16
802
+
803
+ C_ENTRY(_xtmr_manager_reset):
804
+ lwi r1, r0, xmb_manager_stackpointer
805
+
806
+ /* Restore MSR */
807
+ lwi r2, r1, PT_MSR
808
+ mts rmsr, r2
809
+ bri 4
810
+
811
+ /* restore Special purpose registers */
812
+ lwi r2, r1, PT_PID
813
+ mts rpid, r2
814
+
815
+ lwi r2, r1, PT_TLBI
816
+ mts rtlbx, r2
817
+
818
+ lwi r2, r1, PT_ZPR
819
+ mts rzpr, r2
820
+
821
+ #if CONFIG_XILINX_MICROBLAZE0_USE_FPU
822
+ lwi r2, r1, PT_FSR
823
+ mts rfsr, r2
824
+ #endif
825
+
826
+ /* restore all the tlb's */
827
+ addik r3, r0, TOPHYS(tlb_skip)
828
+ addik r6, r0, PT_TLBL0
829
+ addik r7, r0, PT_TLBH0
830
+ restore_tlb:
831
+ add r6, r6, r1
832
+ add r7, r7, r1
833
+ lwi r2, r6, 0
834
+ mts rtlblo, r2
835
+ lwi r2, r7, 0
836
+ mts rtlbhi, r2
837
+ addik r6, r6, 4
838
+ addik r7, r7, 4
839
+ bgtid r3, restore_tlb
840
+ addik r3, r3, -1
841
+
842
+ lwi r5, r0, TOPHYS(xmb_manager_dev)
843
+ lwi r8, r0, TOPHYS(xmb_manager_reset_callback)
844
+ set_vms
845
+ /* return from reset need -8 to adjust for rtsd r15, 8 */
846
+ addik r15, r0, ret_from_reset - 8
847
+ rtbd r8, 0
848
+ nop
849
+
850
+ ret_from_reset:
851
+ set_bip /* Ints masked for state restore */
852
+ VM_OFF
853
+ /* MS: Restore all regs */
854
+ RESTORE_REGS
855
+ lwi r14, r1, PT_R14
856
+ lwi r16, r1, PT_PC
857
+ addik r1, r1, PT_SIZE + 36
858
+ rtbd r16, 0
859
+ nop
860
+
861
+ /*
862
+ * Break handler for MB Manager. Enter to _xmb_manager_break by
863
+ * injecting fault in one of the TMR Microblaze core.
864
+ * FIXME: This break handler supports getting
865
+ * called from kernel space only.
866
+ */
867
+ C_ENTRY(_xmb_manager_break):
868
+ /*
869
+ * Reserve memory in the stack for context store/restore
870
+ * (which includes memory for storing tlbs (max two tlbs))
871
+ */
872
+ addik r1, r1, -PT_SIZE - 36
873
+ swi r1, r0, xmb_manager_stackpointer
874
+ SAVE_REGS
875
+ swi r14, r1, PT_R14 /* rewrite saved R14 value */
876
+ swi r16, r1, PT_PC; /* PC and r16 are the same */
877
+
878
+ lwi r6, r0, TOPHYS(xmb_manager_baseaddr)
879
+ lwi r7, r0, TOPHYS(xmb_manager_crval)
880
+ /*
881
+ * When the break vector gets asserted because of error injection,
882
+ * the break signal must be blocked before exiting from the
883
+ * break handler, below code configures the tmr manager
884
+ * control register to block break signal.
885
+ */
886
+ swi r7, r6, 0
887
+
888
+ /* Save the special purpose registers */
889
+ mfs r2, rpid
890
+ swi r2, r1, PT_PID
891
+
892
+ mfs r2, rtlbx
893
+ swi r2, r1, PT_TLBI
894
+
895
+ mfs r2, rzpr
896
+ swi r2, r1, PT_ZPR
897
+
898
+ #if CONFIG_XILINX_MICROBLAZE0_USE_FPU
899
+ mfs r2, rfsr
900
+ swi r2, r1, PT_FSR
901
+ #endif
902
+ mfs r2, rmsr
903
+ swi r2, r1, PT_MSR
904
+
905
+ /* Save all the tlb's */
906
+ addik r3, r0, TOPHYS(tlb_skip)
907
+ addik r6, r0, PT_TLBL0
908
+ addik r7, r0, PT_TLBH0
909
+ save_tlb:
910
+ add r6, r6, r1
911
+ add r7, r7, r1
912
+ mfs r2, rtlblo
913
+ swi r2, r6, 0
914
+ mfs r2, rtlbhi
915
+ swi r2, r7, 0
916
+ addik r6, r6, 4
917
+ addik r7, r7, 4
918
+ bgtid r3, save_tlb
919
+ addik r3, r3, -1
920
+
921
+ lwi r5, r0, TOPHYS(xmb_manager_dev)
922
+ lwi r8, r0, TOPHYS(xmb_manager_callback)
923
+ /* return from break need -8 to adjust for rtsd r15, 8 */
924
+ addik r15, r0, ret_from_break - 8
925
+ rtbd r8, 0
926
+ nop
927
+
928
+ ret_from_break:
929
+ /* flush the d-cache */
930
+ bralid r15, mb_flush_dcache
931
+ nop
932
+
933
+ /*
934
+ * To make sure microblaze i-cache is in a proper state
935
+ * invalidate the i-cache.
936
+ */
937
+ bralid r15, mb_invalidate_icache
938
+ nop
939
+
940
+ set_bip; /* Ints masked for state restore */
941
+ VM_OFF;
942
+ mbar 1
943
+ mbar 2
944
+ bri 4
945
+ suspend
946
+ nop
947
+ #endif
948
+
756
949
/*
757
950
* Debug trap for KGDB. Enter to _debug_exception by brki r16, 0x18
758
951
* and call handling function with saved pt_regs
@@ -964,6 +1157,7 @@ ENTRY(_switch_to)
964
1157
.global xmb_manager_crval
965
1158
.global xmb_manager_callback
966
1159
.global xmb_manager_reset_callback
1160
+ .global xmb_manager_stackpointer
967
1161
.align 4
968
1162
xmb_manager_dev:
969
1163
.long 0
@@ -975,6 +1169,8 @@ xmb_manager_callback:
975
1169
.long 0
976
1170
xmb_manager_reset_callback:
977
1171
.long 0
1172
+ xmb_manager_stackpointer:
1173
+ .long 0
978
1174
979
1175
/*
980
1176
* When the break vector gets asserted because of error injection,
@@ -1008,16 +1204,24 @@ ENTRY(_reset)
1008
1204
/* These are compiled and loaded into high memory, then
1009
1205
* copied into place in mach_early_setup */
1010
1206
.section .init.ivt, "ax"
1011
- #if CONFIG_MANUAL_RESET_VECTOR
1207
+ #if CONFIG_MANUAL_RESET_VECTOR && !defined(CONFIG_MB_MANAGER)
1012
1208
.org 0x0
1013
1209
brai CONFIG_MANUAL_RESET_VECTOR
1210
+ #elif defined(CONFIG_MB_MANAGER)
1211
+ .org 0x0
1212
+ brai TOPHYS(_xtmr_manager_reset);
1014
1213
#endif
1015
1214
.org 0x8
1016
1215
brai TOPHYS(_user_exception); /* syscall handler */
1017
1216
.org 0x10
1018
1217
brai TOPHYS(_interrupt); /* Interrupt handler */
1218
+ #ifdef CONFIG_MB_MANAGER
1219
+ .org 0x18
1220
+ brai TOPHYS(_xmb_manager_break); /* microblaze manager break handler */
1221
+ #else
1019
1222
.org 0x18
1020
1223
brai TOPHYS(_debug_exception); /* debug trap handler */
1224
+ #endif
1021
1225
.org 0x20
1022
1226
brai TOPHYS(_hw_exception_handler); /* HW exception handler */
1023
1227
0 commit comments