Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'microblaze-v6.1' of git://git.monstr.eu/linux-2.6-microblaze

Pull microblaze updates from Michal Simek:
"This adds architecture support for error injection which can be done
only via local memory (BRAM) with enabling path for recovery after
reset.

These patches targets Triple Modular Redundacy (TMR) configuration
where 3 Microblazes are running in parallel with monitoring logic.

When an error happens (or is injected) system goes to break handler
with full CPU reset and system recovery back to origin context. More
information can be found at [1]"

Link: https://www.xilinx.com/content/dam/xilinx/support/documents/ip_documentation/tmr/v1_0/pg268-tmr.pdf [1]

* tag 'microblaze-v6.1' of git://git.monstr.eu/linux-2.6-microblaze:
microblaze: Add support for error injection
microblaze: Add custom break vector handler for mb manager
microblaze: Add xmb_manager_register function

+347 -1
+10
arch/microblaze/Kconfig
··· 204 204 hex "Size of user task space" if TASK_SIZE_BOOL 205 205 default "0x80000000" 206 206 207 + config MB_MANAGER 208 + bool "Support for Microblaze Manager" 209 + depends on ADVANCED_OPTIONS 210 + help 211 + This option enables API for configuring the MicroBlaze manager 212 + control register, which is consumed by the break handler to 213 + block the break. 214 + 215 + Say N here unless you know what you are doing. 216 + 207 217 endmenu 208 218 209 219 menu "Bus Options"
+29
arch/microblaze/include/asm/xilinx_mb_manager.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (C) 2022 Xilinx, Inc. 4 + */ 5 + #ifndef _XILINX_MB_MANAGER_H 6 + #define _XILINX_MB_MANAGER_H 7 + 8 + # ifndef __ASSEMBLY__ 9 + 10 + #include <linux/of_address.h> 11 + 12 + /* 13 + * When the break vector gets asserted because of error injection, the break 14 + * signal must be blocked before exiting from the break handler, Below api 15 + * updates the manager address and control register and error counter callback 16 + * arguments, which will be used by the break handler to block the break and 17 + * call the callback function. 18 + */ 19 + void xmb_manager_register(uintptr_t phys_baseaddr, u32 cr_val, 20 + void (*callback)(void *data), 21 + void *priv, void (*reset_callback)(void *data)); 22 + asmlinkage void xmb_inject_err(void); 23 + 24 + # endif /* __ASSEMBLY__ */ 25 + 26 + /* Error injection offset */ 27 + #define XMB_INJECT_ERR_OFFSET 0x200 28 + 29 + #endif /* _XILINX_MB_MANAGER_H */
+7
arch/microblaze/kernel/asm-offsets.c
··· 120 120 DEFINE(CC_FSR, offsetof(struct cpu_context, fsr)); 121 121 BLANK(); 122 122 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 + 123 130 return 0; 124 131 }
+301 -1
arch/microblaze/kernel/entry.S
··· 27 27 28 28 #include <asm/page.h> 29 29 #include <asm/unistd.h> 30 + #include <asm/xilinx_mb_manager.h> 30 31 31 32 #include <linux/errno.h> 32 33 #include <asm/signal.h> 34 + #include <asm/mmu.h> 33 35 34 36 #undef DEBUG 35 37 ··· 288 286 2: lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); 289 287 290 288 .text 289 + 290 + .extern cpuinfo 291 + 292 + C_ENTRY(mb_flush_dcache): 293 + addik r1, r1, -PT_SIZE 294 + SAVE_REGS 295 + 296 + addik r3, r0, cpuinfo 297 + lwi r7, r3, CI_DCS 298 + lwi r8, r3, CI_DCL 299 + sub r9, r7, r8 300 + 1: 301 + wdc.flush r9, r0 302 + bgtid r9, 1b 303 + addk r9, r9, r8 304 + 305 + RESTORE_REGS 306 + addik r1, r1, PT_SIZE 307 + rtsd r15, 8 308 + nop 309 + 310 + C_ENTRY(mb_invalidate_icache): 311 + addik r1, r1, -PT_SIZE 312 + SAVE_REGS 313 + 314 + addik r3, r0, cpuinfo 315 + lwi r7, r3, CI_ICS 316 + lwi r8, r3, CI_ICL 317 + sub r9, r7, r8 318 + 1: 319 + wic r9, r0 320 + bgtid r9, 1b 321 + addk r9, r9, r8 322 + 323 + RESTORE_REGS 324 + addik r1, r1, PT_SIZE 325 + rtsd r15, 8 326 + nop 291 327 292 328 /* 293 329 * User trap. ··· 793 753 rtid r14, 0 794 754 nop 795 755 756 + #ifdef CONFIG_MB_MANAGER 757 + 758 + #define PT_PID PT_SIZE 759 + #define PT_TLBI PT_SIZE + 4 760 + #define PT_ZPR PT_SIZE + 8 761 + #define PT_TLBL0 PT_SIZE + 12 762 + #define PT_TLBH0 PT_SIZE + 16 763 + 764 + C_ENTRY(_xtmr_manager_reset): 765 + lwi r1, r0, xmb_manager_stackpointer 766 + 767 + /* Restore MSR */ 768 + lwi r2, r1, PT_MSR 769 + mts rmsr, r2 770 + bri 4 771 + 772 + /* restore Special purpose registers */ 773 + lwi r2, r1, PT_PID 774 + mts rpid, r2 775 + 776 + lwi r2, r1, PT_TLBI 777 + mts rtlbx, r2 778 + 779 + lwi r2, r1, PT_ZPR 780 + mts rzpr, r2 781 + 782 + #if CONFIG_XILINX_MICROBLAZE0_USE_FPU 783 + lwi r2, r1, PT_FSR 784 + mts rfsr, r2 785 + #endif 786 + 787 + /* restore all the tlb's */ 788 + addik r3, r0, TOPHYS(tlb_skip) 789 + addik r6, r0, PT_TLBL0 790 + addik r7, r0, PT_TLBH0 791 + restore_tlb: 792 + add r6, r6, r1 793 + add r7, r7, r1 794 + lwi r2, r6, 0 795 + mts rtlblo, r2 796 + lwi r2, r7, 0 797 + mts rtlbhi, r2 798 + addik r6, r6, 4 799 + addik r7, r7, 4 800 + bgtid r3, restore_tlb 801 + addik r3, r3, -1 802 + 803 + lwi r5, r0, TOPHYS(xmb_manager_dev) 804 + lwi r8, r0, TOPHYS(xmb_manager_reset_callback) 805 + set_vms 806 + /* return from reset need -8 to adjust for rtsd r15, 8 */ 807 + addik r15, r0, ret_from_reset - 8 808 + rtbd r8, 0 809 + nop 810 + 811 + ret_from_reset: 812 + set_bip /* Ints masked for state restore */ 813 + VM_OFF 814 + /* MS: Restore all regs */ 815 + RESTORE_REGS 816 + lwi r14, r1, PT_R14 817 + lwi r16, r1, PT_PC 818 + addik r1, r1, PT_SIZE + 36 819 + rtbd r16, 0 820 + nop 821 + 822 + /* 823 + * Break handler for MB Manager. Enter to _xmb_manager_break by 824 + * injecting fault in one of the TMR Microblaze core. 825 + * FIXME: This break handler supports getting 826 + * called from kernel space only. 827 + */ 828 + C_ENTRY(_xmb_manager_break): 829 + /* 830 + * Reserve memory in the stack for context store/restore 831 + * (which includes memory for storing tlbs (max two tlbs)) 832 + */ 833 + addik r1, r1, -PT_SIZE - 36 834 + swi r1, r0, xmb_manager_stackpointer 835 + SAVE_REGS 836 + swi r14, r1, PT_R14 /* rewrite saved R14 value */ 837 + swi r16, r1, PT_PC; /* PC and r16 are the same */ 838 + 839 + lwi r6, r0, TOPHYS(xmb_manager_baseaddr) 840 + lwi r7, r0, TOPHYS(xmb_manager_crval) 841 + /* 842 + * When the break vector gets asserted because of error injection, 843 + * the break signal must be blocked before exiting from the 844 + * break handler, below code configures the tmr manager 845 + * control register to block break signal. 846 + */ 847 + swi r7, r6, 0 848 + 849 + /* Save the special purpose registers */ 850 + mfs r2, rpid 851 + swi r2, r1, PT_PID 852 + 853 + mfs r2, rtlbx 854 + swi r2, r1, PT_TLBI 855 + 856 + mfs r2, rzpr 857 + swi r2, r1, PT_ZPR 858 + 859 + #if CONFIG_XILINX_MICROBLAZE0_USE_FPU 860 + mfs r2, rfsr 861 + swi r2, r1, PT_FSR 862 + #endif 863 + mfs r2, rmsr 864 + swi r2, r1, PT_MSR 865 + 866 + /* Save all the tlb's */ 867 + addik r3, r0, TOPHYS(tlb_skip) 868 + addik r6, r0, PT_TLBL0 869 + addik r7, r0, PT_TLBH0 870 + save_tlb: 871 + add r6, r6, r1 872 + add r7, r7, r1 873 + mfs r2, rtlblo 874 + swi r2, r6, 0 875 + mfs r2, rtlbhi 876 + swi r2, r7, 0 877 + addik r6, r6, 4 878 + addik r7, r7, 4 879 + bgtid r3, save_tlb 880 + addik r3, r3, -1 881 + 882 + lwi r5, r0, TOPHYS(xmb_manager_dev) 883 + lwi r8, r0, TOPHYS(xmb_manager_callback) 884 + /* return from break need -8 to adjust for rtsd r15, 8 */ 885 + addik r15, r0, ret_from_break - 8 886 + rtbd r8, 0 887 + nop 888 + 889 + ret_from_break: 890 + /* flush the d-cache */ 891 + bralid r15, mb_flush_dcache 892 + nop 893 + 894 + /* 895 + * To make sure microblaze i-cache is in a proper state 896 + * invalidate the i-cache. 897 + */ 898 + bralid r15, mb_invalidate_icache 899 + nop 900 + 901 + set_bip; /* Ints masked for state restore */ 902 + VM_OFF; 903 + mbar 1 904 + mbar 2 905 + bri 4 906 + suspend 907 + nop 908 + #endif 909 + 796 910 /* 797 911 * Debug trap for KGDB. Enter to _debug_exception by brki r16, 0x18 798 912 * and call handling function with saved pt_regs ··· 1151 957 rtsd r15, 8 1152 958 nop 1153 959 960 + #ifdef CONFIG_MB_MANAGER 961 + .global xmb_inject_err 962 + .section .text 963 + .align 2 964 + .ent xmb_inject_err 965 + .type xmb_inject_err, @function 966 + xmb_inject_err: 967 + addik r1, r1, -PT_SIZE 968 + SAVE_REGS 969 + 970 + /* Switch to real mode */ 971 + VM_OFF; 972 + set_bip; 973 + mbar 1 974 + mbar 2 975 + bralid r15, XMB_INJECT_ERR_OFFSET 976 + nop; 977 + 978 + /* enable virtual mode */ 979 + set_vms; 980 + /* barrier for instructions and data accesses */ 981 + mbar 1 982 + mbar 2 983 + /* 984 + * Enable Interrupts, Virtual Protected Mode, equalize 985 + * initial state for all possible entries. 986 + */ 987 + rtbd r0, 1f 988 + nop; 989 + 1: 990 + RESTORE_REGS 991 + addik r1, r1, PT_SIZE 992 + rtsd r15, 8; 993 + nop; 994 + .end xmb_inject_err 995 + 996 + .section .data 997 + .global xmb_manager_dev 998 + .global xmb_manager_baseaddr 999 + .global xmb_manager_crval 1000 + .global xmb_manager_callback 1001 + .global xmb_manager_reset_callback 1002 + .global xmb_manager_stackpointer 1003 + .align 4 1004 + xmb_manager_dev: 1005 + .long 0 1006 + xmb_manager_baseaddr: 1007 + .long 0 1008 + xmb_manager_crval: 1009 + .long 0 1010 + xmb_manager_callback: 1011 + .long 0 1012 + xmb_manager_reset_callback: 1013 + .long 0 1014 + xmb_manager_stackpointer: 1015 + .long 0 1016 + 1017 + /* 1018 + * When the break vector gets asserted because of error injection, 1019 + * the break signal must be blocked before exiting from the 1020 + * break handler, Below api updates the manager address and 1021 + * control register and error count callback arguments, 1022 + * which will be used by the break handler to block the 1023 + * break and call the callback function. 1024 + */ 1025 + .global xmb_manager_register 1026 + .section .text 1027 + .align 2 1028 + .ent xmb_manager_register 1029 + .type xmb_manager_register, @function 1030 + xmb_manager_register: 1031 + swi r5, r0, xmb_manager_baseaddr 1032 + swi r6, r0, xmb_manager_crval 1033 + swi r7, r0, xmb_manager_callback 1034 + swi r8, r0, xmb_manager_dev 1035 + swi r9, r0, xmb_manager_reset_callback 1036 + 1037 + rtsd r15, 8; 1038 + nop; 1039 + .end xmb_manager_register 1040 + #endif 1041 + 1154 1042 ENTRY(_reset) 1155 1043 VM_OFF 1156 1044 brai 0; /* Jump to reset vector */ ··· 1240 964 /* These are compiled and loaded into high memory, then 1241 965 * copied into place in mach_early_setup */ 1242 966 .section .init.ivt, "ax" 1243 - #if CONFIG_MANUAL_RESET_VECTOR 967 + #if CONFIG_MANUAL_RESET_VECTOR && !defined(CONFIG_MB_MANAGER) 1244 968 .org 0x0 1245 969 brai CONFIG_MANUAL_RESET_VECTOR 970 + #elif defined(CONFIG_MB_MANAGER) 971 + .org 0x0 972 + brai TOPHYS(_xtmr_manager_reset); 1246 973 #endif 1247 974 .org 0x8 1248 975 brai TOPHYS(_user_exception); /* syscall handler */ 1249 976 .org 0x10 1250 977 brai TOPHYS(_interrupt); /* Interrupt handler */ 978 + #ifdef CONFIG_MB_MANAGER 979 + .org 0x18 980 + brai TOPHYS(_xmb_manager_break); /* microblaze manager break handler */ 981 + #else 1251 982 .org 0x18 1252 983 brai TOPHYS(_debug_exception); /* debug trap handler */ 984 + #endif 1253 985 .org 0x20 1254 986 brai TOPHYS(_hw_exception_handler); /* HW exception handler */ 987 + 988 + #ifdef CONFIG_MB_MANAGER 989 + /* 990 + * For TMR Inject API which injects the error should 991 + * be executed from LMB. 992 + * TMR Inject is programmed with address of 0x200 so that 993 + * when program counter matches with this address error will 994 + * be injected. 0x200 is expected to be next available bram 995 + * offset, hence used for this api. 996 + */ 997 + .org XMB_INJECT_ERR_OFFSET 998 + xmb_inject_error: 999 + nop 1000 + rtsd r15, 8 1001 + nop 1002 + #endif 1255 1003 1256 1004 .section .rodata,"a" 1257 1005 #include "syscall_table.S"