3030
3131#include <linux/errno.h>
3232#include <asm/signal.h>
33+ #include <asm/mmu.h>
3334
3435#undef DEBUG
3536
@@ -287,6 +288,44 @@ syscall_debug_table:
287288
288289.text
289290
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+
290329/*
291330 * User trap.
292331 *
@@ -753,6 +792,160 @@ IRQ_return: /* MS: Make global symbol for debugging */
753792 rtid r14, 0
754793 nop
755794
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+
756949/*
757950 * Debug trap for KGDB. Enter to _debug_exception by brki r16, 0x18
758951 * and call handling function with saved pt_regs
@@ -964,6 +1157,7 @@ ENTRY(_switch_to)
9641157.global xmb_manager_crval
9651158.global xmb_manager_callback
9661159.global xmb_manager_reset_callback
1160+ .global xmb_manager_stackpointer
9671161.align 4
9681162xmb_manager_dev:
9691163 .long 0
@@ -975,6 +1169,8 @@ xmb_manager_callback:
9751169 .long 0
9761170xmb_manager_reset_callback:
9771171 .long 0
1172+ xmb_manager_stackpointer:
1173+ .long 0
9781174
9791175/*
9801176 * When the break vector gets asserted because of error injection,
@@ -1008,16 +1204,24 @@ ENTRY(_reset)
10081204 /* These are compiled and loaded into high memory, then
10091205 * copied into place in mach_early_setup */
10101206 .section .init.ivt, "ax"
1011- #if CONFIG_MANUAL_RESET_VECTOR
1207+ #if CONFIG_MANUAL_RESET_VECTOR && !defined(CONFIG_MB_MANAGER)
10121208 .org 0x0
10131209 brai CONFIG_MANUAL_RESET_VECTOR
1210+ #elif defined(CONFIG_MB_MANAGER)
1211+ .org 0x0
1212+ brai TOPHYS(_xtmr_manager_reset);
10141213#endif
10151214 .org 0x8
10161215 brai TOPHYS(_user_exception); /* syscall handler */
10171216 .org 0x10
10181217 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
10191222 .org 0x18
10201223 brai TOPHYS(_debug_exception); /* debug trap handler */
1224+ #endif
10211225 .org 0x20
10221226 brai TOPHYS(_hw_exception_handler); /* HW exception handler */
10231227
0 commit comments