Skip to content

Commit 88707eb

Browse files
kedareswararaomichalsimek
authored andcommitted
microblaze: Add custom break vector handler for mb manager
When the TMR Manager detects a fault Lockstep state it is signaled to the MicroBlaze processors by asserting a break signal, When Microblaze gets a break vector from tmr Microblaze it's needed to clear/block the break bit in the tmr manager before performing recovery. In order to perform recovery need to perform the following steps. 1) Store all internal MicroBlaze registers in RAM 2) Execute a suspend instruction which asserts the reset signal 3) Restore all registers from RAM and execute an RTBD instruction to return from the reset handler, to resume execution at the place where the break occurred. This API supports getting called from kernel space only. Signed-off-by: Appana Durga Kedareswara rao <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Michal Simek <[email protected]>
1 parent a5e3aaa commit 88707eb

File tree

2 files changed

+212
-1
lines changed

2 files changed

+212
-1
lines changed

arch/microblaze/kernel/asm-offsets.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,5 +120,12 @@ int main(int argc, char *argv[])
120120
DEFINE(CC_FSR, offsetof(struct cpu_context, fsr));
121121
BLANK();
122122

123+
/* struct cpuinfo */
124+
DEFINE(CI_DCS, offsetof(struct cpuinfo, dcache_size));
125+
DEFINE(CI_DCL, offsetof(struct cpuinfo, dcache_line_length));
126+
DEFINE(CI_ICS, offsetof(struct cpuinfo, icache_size));
127+
DEFINE(CI_ICL, offsetof(struct cpuinfo, icache_line_length));
128+
BLANK();
129+
123130
return 0;
124131
}

arch/microblaze/kernel/entry.S

Lines changed: 205 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
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
9681162
xmb_manager_dev:
9691163
.long 0
@@ -975,6 +1169,8 @@ xmb_manager_callback:
9751169
.long 0
9761170
xmb_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

Comments
 (0)