^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) ========================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) IPF Machine Check (MC) error inject tool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) ========================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) IPF Machine Check (MC) error inject tool is used to inject MC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) errors from Linux. The tool is a test bed for IPF MC work flow including
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) hardware correctable error handling, OS recoverable error handling, MC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) event logging, etc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) The tool includes two parts: a kernel driver and a user application
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) sample. The driver provides interface to PAL to inject error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) and query error injection capabilities. The driver code is in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) arch/ia64/kernel/err_inject.c. The application sample (shown below)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) provides a combination of various errors and calls the driver's interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) (sysfs interface) to inject errors or query error injection capabilities.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) The tool can be used to test Intel IPF machine MC handling capabilities.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) It's especially useful for people who can not access hardware MC injection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) tool to inject error. It's also very useful to integrate with other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) software test suits to do stressful testing on IPF.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) Below is a sample application as part of the whole tool. The sample
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) can be used as a working test tool. Or it can be expanded to include
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) more features. It also can be a integrated into a library or other user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) application to have more thorough test.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) The sample application takes err.conf as error configuration input. GCC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) compiles the code. After you install err_inject driver, you can run
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) this sample application to inject errors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) Errata: Itanium 2 Processors Specification Update lists some errata against
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) the pal_mc_error_inject PAL procedure. The following err.conf has been tested
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) on latest Montecito PAL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) err.conf::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #This is configuration file for err_inject_tool.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #The format of the each line is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #cpu, loop, interval, err_type_info, err_struct_info, err_data_buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #where
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) # cpu: logical cpu number the error will be inject in.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) # loop: times the error will be injected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) # interval: In second. every so often one error is injected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) # err_type_info, err_struct_info: PAL parameters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #Note: All values are hex w/o or w/ 0x prefix.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #On cpu2, inject only total 0x10 errors, interval 5 seconds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #corrected, data cache, hier-2, physical addr(assigned by tool code).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #working on Montecito latest PAL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) 2, 10, 5, 4101, 95
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #On cpu4, inject and consume total 0x10 errors, interval 5 seconds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #corrected, data cache, hier-2, physical addr(assigned by tool code).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #working on Montecito latest PAL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) 4, 10, 5, 4109, 95
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #On cpu15, inject and consume total 0x10 errors, interval 5 seconds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #recoverable, DTR0, hier-2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #working on Montecito latest PAL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) 0xf, 0x10, 5, 4249, 15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) The sample application source code:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) err_injection_tool.c::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * This program is free software; you can redistribute it and/or modify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * it under the terms of the GNU General Public License as published by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * the Free Software Foundation; either version 2 of the License, or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * (at your option) any later version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * This program is distributed in the hope that it will be useful, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * WITHOUT ANY WARRANTY; without even the implied warranty of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * NON INFRINGEMENT. See the GNU General Public License for more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * You should have received a copy of the GNU General Public License
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * along with this program; if not, write to the Free Software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * Copyright (C) 2006 Intel Co
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * Fenghua Yu <fenghua.yu@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #include <sys/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #include <sys/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #include <fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #include <stdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #include <sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #include <stdarg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #include <time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #include <sys/ipc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #include <sys/sem.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #include <sys/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #include <sys/mman.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #include <sys/shm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define MAX_FN_SIZE 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define MAX_BUF_SIZE 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define DATA_BUF_SIZE 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define NR_CPUS 512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define MAX_TASK_NUM 2048
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define MIN_INTERVAL 5 // seconds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define ERR_DATA_BUFFER_SIZE 3 // Three 8-byte.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define PARA_FIELD_NUM 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define MASK_SIZE (NR_CPUS/64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define PATH_FORMAT "/sys/devices/system/cpu/cpu%d/err_inject/"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) int sched_setaffinity(pid_t pid, unsigned int len, unsigned long *mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) int verbose;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define vbprintf if (verbose) printf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) int log_info(int cpu, const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) FILE *log;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) char fn[MAX_FN_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) char buf[MAX_BUF_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) sprintf(fn, "%d.log", cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) log=fopen(fn, "a+");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (log==NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) perror("Error open:");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) va_start(args, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) vprintf(fmt, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) memset(buf, 0, MAX_BUF_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) vsprintf(buf, fmt, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) fwrite(buf, sizeof(buf), 1, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) fclose(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) typedef unsigned long u64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) typedef unsigned int u32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) typedef union err_type_info_u {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) u64 mode : 3, /* 0-2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) err_inj : 3, /* 3-5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) err_sev : 2, /* 6-7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) err_struct : 5, /* 8-12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) struct_hier : 3, /* 13-15 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) reserved : 48; /* 16-63 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) } err_type_info_u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) u64 err_type_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) } err_type_info_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) typedef union err_struct_info_u {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) u64 siv : 1, /* 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) c_t : 2, /* 1-2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) cl_p : 3, /* 3-5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) cl_id : 3, /* 6-8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) cl_dp : 1, /* 9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) reserved1 : 22, /* 10-31 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) tiv : 1, /* 32 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) trigger : 4, /* 33-36 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) trigger_pl : 3, /* 37-39 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) reserved2 : 24; /* 40-63 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) } err_struct_info_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) u64 siv : 1, /* 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) tt : 2, /* 1-2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) tc_tr : 2, /* 3-4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) tr_slot : 8, /* 5-12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) reserved1 : 19, /* 13-31 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) tiv : 1, /* 32 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) trigger : 4, /* 33-36 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) trigger_pl : 3, /* 37-39 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) reserved2 : 24; /* 40-63 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) } err_struct_info_tlb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) u64 siv : 1, /* 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) regfile_id : 4, /* 1-4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) reg_num : 7, /* 5-11 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) reserved1 : 20, /* 12-31 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) tiv : 1, /* 32 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) trigger : 4, /* 33-36 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) trigger_pl : 3, /* 37-39 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) reserved2 : 24; /* 40-63 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) } err_struct_info_register;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) u64 reserved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) } err_struct_info_bus_processor_interconnect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) u64 err_struct_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) } err_struct_info_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) typedef union err_data_buffer_u {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) u64 trigger_addr; /* 0-63 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) u64 inj_addr; /* 64-127 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) u64 way : 5, /* 128-132 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) index : 20, /* 133-152 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) : 39; /* 153-191 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) } err_data_buffer_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) u64 trigger_addr; /* 0-63 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) u64 inj_addr; /* 64-127 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) u64 way : 5, /* 128-132 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) index : 20, /* 133-152 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) reserved : 39; /* 153-191 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) } err_data_buffer_tlb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) u64 trigger_addr; /* 0-63 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) } err_data_buffer_register;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) u64 reserved; /* 0-63 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) } err_data_buffer_bus_processor_interconnect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) u64 err_data_buffer[ERR_DATA_BUFFER_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) } err_data_buffer_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) typedef union capabilities_u {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) u64 i : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) d : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) rv : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) tag : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) data : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) mesi : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) dp : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) reserved1 : 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) pa : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) va : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) wi : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) reserved2 : 20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) trigger : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) trigger_pl : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) reserved3 : 30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) } capabilities_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) u64 d : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) i : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) rv : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) tc : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) tr : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) reserved1 : 27,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) trigger : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) trigger_pl : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) reserved2 : 30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) } capabilities_tlb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) u64 gr_b0 : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) gr_b1 : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) fr : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) br : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) pr : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) ar : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) cr : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) rr : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) pkr : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) dbr : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) ibr : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) pmc : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) pmd : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) reserved1 : 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) regnum : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) reserved2 : 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) trigger : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) trigger_pl : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) reserved3 : 30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) } capabilities_register;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) u64 reserved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) } capabilities_bus_processor_interconnect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) } capabilities_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) typedef struct resources_s {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) u64 ibr0 : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) ibr2 : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) ibr4 : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) ibr6 : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) dbr0 : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) dbr2 : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) dbr4 : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) dbr6 : 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) reserved : 48;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) } resources_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) long get_page_size(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) long page_size=sysconf(_SC_PAGESIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return page_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) #define PAGE_SIZE (get_page_size()==-1?0x4000:get_page_size())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) #define SHM_SIZE (2*PAGE_SIZE*NR_CPUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) #define SHM_VA 0x2000000100000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) int shmid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) void *shmaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) int create_shm(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) key_t key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) char fn[MAX_FN_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) /* cpu0 is always existing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) sprintf(fn, PATH_FORMAT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if ((key = ftok(fn, 's')) == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) perror("ftok");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) shmid = shmget(key, SHM_SIZE, 0644 | IPC_CREAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (shmid == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) if (errno==EEXIST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) shmid = shmget(key, SHM_SIZE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (shmid == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) perror("shmget");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) perror("shmget");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) vbprintf("shmid=%d", shmid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) /* connect to the segment: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) shmaddr = shmat(shmid, (void *)SHM_VA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (shmaddr == (void*)-1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) perror("shmat");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) memset(shmaddr, 0, SHM_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) mlock(shmaddr, SHM_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) int free_shm()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) munlock(shmaddr, SHM_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) shmdt(shmaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) semctl(shmid, 0, IPC_RMID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) #ifdef _SEM_SEMUN_UNDEFINED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) union semun
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) struct semid_ds *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) unsigned short int *array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) struct seminfo *__buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) u32 mode=1; /* 1: physical mode; 2: virtual mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) int one_lock=1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) key_t key[NR_CPUS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) int semid[NR_CPUS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) int create_sem(int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) union semun arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) char fn[MAX_FN_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) int sid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) sprintf(fn, PATH_FORMAT, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) sprintf(fn, "%s/%s", fn, "err_type_info");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if ((key[cpu] = ftok(fn, 'e')) == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) perror("ftok");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (semid[cpu]!=0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) /* clear old semaphore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if ((sid = semget(key[cpu], 1, 0)) != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) semctl(sid, 0, IPC_RMID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) /* get one semaphore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if ((semid[cpu] = semget(key[cpu], 1, IPC_CREAT | IPC_EXCL)) == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) perror("semget");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) printf("Please remove semaphore with key=0x%lx, then run the tool.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) (u64)key[cpu]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) vbprintf("semid[%d]=0x%lx, key[%d]=%lx\n",cpu,(u64)semid[cpu],cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) (u64)key[cpu]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) /* initialize the semaphore to 1: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) arg.val = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (semctl(semid[cpu], 0, SETVAL, arg) == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) perror("semctl");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) static int lock(int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) struct sembuf lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) lock.sem_num = cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) lock.sem_op = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) semop(semid[cpu], &lock, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) static int unlock(int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) struct sembuf unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) unlock.sem_num = cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) unlock.sem_op = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) semop(semid[cpu], &unlock, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) void free_sem(int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) semctl(semid[cpu], 0, IPC_RMID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) int wr_multi(char *fn, unsigned long *data, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) int fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) char buf[MAX_BUF_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) if (size==1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) sprintf(buf, "%lx", *data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) else if (size==3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) sprintf(buf, "%lx,%lx,%lx", data[0], data[1], data[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) fprintf(stderr,"write to file with wrong size!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) fd=open(fn, O_RDWR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (!fd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) perror("Error:");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) ret=write(fd, buf, sizeof(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) int wr(char *fn, unsigned long data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) return wr_multi(fn, &data, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) int rd(char *fn, unsigned long *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) int fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) char buf[MAX_BUF_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) fd=open(fn, O_RDONLY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (fd<0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) perror("Error:");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) read(fd, buf, MAX_BUF_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) *data=strtoul(buf, NULL, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) int rd_status(char *path, int *status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) char fn[MAX_FN_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) sprintf(fn, "%s/status", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if (rd(fn, (u64*)status)<0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) perror("status reading error.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) int rd_capabilities(char *path, u64 *capabilities)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) char fn[MAX_FN_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) sprintf(fn, "%s/capabilities", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (rd(fn, capabilities)<0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) perror("capabilities reading error.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) int rd_all(char *path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) unsigned long err_type_info, err_struct_info, err_data_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) unsigned long capabilities, resources;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) char fn[MAX_FN_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) sprintf(fn, "%s/err_type_info", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (rd(fn, &err_type_info)<0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) perror("err_type_info reading error.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) printf("err_type_info=%lx\n", err_type_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) sprintf(fn, "%s/err_struct_info", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) if (rd(fn, &err_struct_info)<0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) perror("err_struct_info reading error.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) printf("err_struct_info=%lx\n", err_struct_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) sprintf(fn, "%s/err_data_buffer", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) if (rd(fn, &err_data_buffer)<0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) perror("err_data_buffer reading error.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) printf("err_data_buffer=%lx\n", err_data_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) sprintf(fn, "%s/status", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if (rd("status", (u64*)&status)<0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) perror("status reading error.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) printf("status=%d\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) sprintf(fn, "%s/capabilities", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (rd(fn,&capabilities)<0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) perror("capabilities reading error.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) printf("capabilities=%lx\n", capabilities);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) sprintf(fn, "%s/resources", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (rd(fn, &resources)<0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) perror("resources reading error.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) printf("resources=%lx\n", resources);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) int query_capabilities(char *path, err_type_info_t err_type_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) u64 *capabilities)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) char fn[MAX_FN_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) err_struct_info_t err_struct_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) err_data_buffer_t err_data_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) err_struct_info.err_struct_info=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) memset(err_data_buffer.err_data_buffer, -1, ERR_DATA_BUFFER_SIZE*8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) sprintf(fn, "%s/err_type_info", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) wr(fn, err_type_info.err_type_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) sprintf(fn, "%s/err_struct_info", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) wr(fn, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) sprintf(fn, "%s/err_data_buffer", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) wr_multi(fn, err_data_buffer.err_data_buffer, ERR_DATA_BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) // Fire pal_mc_error_inject procedure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) sprintf(fn, "%s/call_start", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) wr(fn, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) if (rd_capabilities(path, capabilities)<0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) int query_all_capabilities()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) err_type_info_t err_type_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) int err_sev, err_struct, struct_hier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) int cap=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) u64 capabilities;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) char path[MAX_FN_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) err_type_info.err_type_info=0; // Initial
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) err_type_info.err_type_info_u.mode=0; // Query mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) err_type_info.err_type_info_u.err_inj=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) printf("All capabilities implemented in pal_mc_error_inject:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) sprintf(path, PATH_FORMAT ,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) for (err_sev=0;err_sev<3;err_sev++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) for (err_struct=0;err_struct<5;err_struct++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) for (struct_hier=0;struct_hier<5;struct_hier++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) status=-1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) capabilities=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) err_type_info.err_type_info_u.err_sev=err_sev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) err_type_info.err_type_info_u.err_struct=err_struct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) err_type_info.err_type_info_u.struct_hier=struct_hier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) if (query_capabilities(path, err_type_info, &capabilities)<0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) if (rd_status(path, &status)<0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) if (status==0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) cap=1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) printf("For err_sev=%d, err_struct=%d, struct_hier=%d: ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) err_sev, err_struct, struct_hier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) printf("capabilities 0x%lx\n", capabilities);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) if (!cap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) printf("No capabilities supported.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) int err_inject(int cpu, char *path, err_type_info_t err_type_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) err_struct_info_t err_struct_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) err_data_buffer_t err_data_buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) char fn[MAX_FN_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) log_info(cpu, "err_type_info=%lx, err_struct_info=%lx, ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) err_type_info.err_type_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) err_struct_info.err_struct_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) log_info(cpu,"err_data_buffer=[%lx,%lx,%lx]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) err_data_buffer.err_data_buffer[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) err_data_buffer.err_data_buffer[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) err_data_buffer.err_data_buffer[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) sprintf(fn, "%s/err_type_info", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) wr(fn, err_type_info.err_type_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) sprintf(fn, "%s/err_struct_info", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) wr(fn, err_struct_info.err_struct_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) sprintf(fn, "%s/err_data_buffer", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) wr_multi(fn, err_data_buffer.err_data_buffer, ERR_DATA_BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) // Fire pal_mc_error_inject procedure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) sprintf(fn, "%s/call_start", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) wr(fn,mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) if (rd_status(path, &status)<0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) vbprintf("fail: read status\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) return -100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) if (status!=0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) log_info(cpu, "fail: status=%d\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) static int construct_data_buf(char *path, err_type_info_t err_type_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) err_struct_info_t err_struct_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) err_data_buffer_t *err_data_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) void *va1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) char fn[MAX_FN_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) u64 virt_addr=0, phys_addr=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) vbprintf("va1=%lx\n", (u64)va1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) memset(&err_data_buffer->err_data_buffer_cache, 0, ERR_DATA_BUFFER_SIZE*8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) switch (err_type_info.err_type_info_u.err_struct) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) case 1: // Cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) switch (err_struct_info.err_struct_info_cache.cl_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) case 1: //Virtual addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) err_data_buffer->err_data_buffer_cache.inj_addr=(u64)va1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) case 2: //Phys addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) sprintf(fn, "%s/virtual_to_phys", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) virt_addr=(u64)va1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) if (wr(fn,virt_addr)<0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) rd(fn, &phys_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) err_data_buffer->err_data_buffer_cache.inj_addr=phys_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) printf("Not supported cl_id\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) case 2: // TLB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) case 3: // Register file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) case 4: // Bus/system interconnect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) printf("Not supported err_struct\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) typedef struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) u64 cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) u64 loop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) u64 interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) u64 err_type_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) u64 err_struct_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) u64 err_data_buffer[ERR_DATA_BUFFER_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) } parameters_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) parameters_t line_para;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) int para;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) static int empty_data_buffer(u64 *err_data_buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) int empty=1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) for (i=0;i<ERR_DATA_BUFFER_SIZE; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if (err_data_buffer[i]!=-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) empty=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) return empty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) int err_inj()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) err_type_info_t err_type_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) err_struct_info_t err_struct_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) err_data_buffer_t err_data_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) FILE *fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) unsigned long cpu, loop, interval, err_type_info_conf, err_struct_info_conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) u64 err_data_buffer_conf[ERR_DATA_BUFFER_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) int num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) char path[MAX_FN_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) parameters_t parameters[MAX_TASK_NUM]={};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) pid_t child_pid[MAX_TASK_NUM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) time_t current_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) if (!para) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) fp=fopen("err.conf", "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) if (fp==NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) perror("Error open err.conf");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) num=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) while (!feof(fp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) char buf[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) memset(buf,0,256);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) fgets(buf, 256, fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) count=sscanf(buf, "%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) &cpu, &loop, &interval,&err_type_info_conf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) &err_struct_info_conf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) &err_data_buffer_conf[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) &err_data_buffer_conf[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) &err_data_buffer_conf[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) if (count!=PARA_FIELD_NUM+3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) err_data_buffer_conf[0]=-1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) err_data_buffer_conf[1]=-1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) err_data_buffer_conf[2]=-1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) count=sscanf(buf, "%lx, %lx, %lx, %lx, %lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) &cpu, &loop, &interval,&err_type_info_conf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) &err_struct_info_conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) if (count!=PARA_FIELD_NUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) parameters[num].cpu=cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) parameters[num].loop=loop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) parameters[num].interval= interval>MIN_INTERVAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) ?interval:MIN_INTERVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) parameters[num].err_type_info=err_type_info_conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) parameters[num].err_struct_info=err_struct_info_conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) memcpy(parameters[num++].err_data_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) err_data_buffer_conf,ERR_DATA_BUFFER_SIZE*8) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) if (num>=MAX_TASK_NUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) parameters[0].cpu=line_para.cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) parameters[0].loop=line_para.loop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) parameters[0].interval= line_para.interval>MIN_INTERVAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) ?line_para.interval:MIN_INTERVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) parameters[0].err_type_info=line_para.err_type_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) parameters[0].err_struct_info=line_para.err_struct_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) memcpy(parameters[0].err_data_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) line_para.err_data_buffer,ERR_DATA_BUFFER_SIZE*8) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) num=1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) /* Create semaphore: If one_lock, one semaphore for all processors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) Otherwise, one semaphore for each processor. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) if (one_lock) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) if (create_sem(0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) printf("Can not create semaphore...exit\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) free_sem(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) for (i=0;i<num;i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if (create_sem(parameters[i].cpu)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) printf("Can not create semaphore for cpu%d...exit\n",i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) free_sem(parameters[num].cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) /* Create a shm segment which will be used to inject/consume errors on.*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) if (create_shm()==-1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) printf("Error to create shm...exit\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) for (i=0;i<num;i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) pid_t pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) current_time=time(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) log_info(parameters[i].cpu, "\nBegine at %s", ctime(¤t_time));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) log_info(parameters[i].cpu, "Configurations:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) log_info(parameters[i].cpu,"On cpu%ld: loop=%lx, interval=%lx(s)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) parameters[i].cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) parameters[i].loop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) parameters[i].interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) log_info(parameters[i].cpu," err_type_info=%lx,err_struct_info=%lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) parameters[i].err_type_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) parameters[i].err_struct_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) sprintf(path, PATH_FORMAT, (int)parameters[i].cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) err_type_info.err_type_info=parameters[i].err_type_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) err_struct_info.err_struct_info=parameters[i].err_struct_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) memcpy(err_data_buffer.err_data_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) parameters[i].err_data_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) ERR_DATA_BUFFER_SIZE*8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) pid=fork();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) if (pid==0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) unsigned long mask[MASK_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) int j, k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) void *va1, *va2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) /* Allocate two memory areas va1 and va2 in shm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) va1=shmaddr+parameters[i].cpu*PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) va2=shmaddr+parameters[i].cpu*PAGE_SIZE+PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) vbprintf("va1=%lx, va2=%lx\n", (u64)va1, (u64)va2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) memset(va1, 0x1, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) memset(va2, 0x2, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) if (empty_data_buffer(err_data_buffer.err_data_buffer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) /* If not specified yet, construct data buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) * with va1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) construct_data_buf(path, err_type_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) err_struct_info, &err_data_buffer,va1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) for (j=0;j<MASK_SIZE;j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) mask[j]=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) cpu=parameters[i].cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) k = cpu%64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) j = cpu/64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) mask[j] = 1UL << k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) if (sched_setaffinity(0, MASK_SIZE*8, mask)==-1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) perror("Error sched_setaffinity:");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) for (j=0; j<parameters[i].loop; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) log_info(parameters[i].cpu,"Injection ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) log_info(parameters[i].cpu,"on cpu%ld: #%d/%ld ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) parameters[i].cpu,j+1, parameters[i].loop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) /* Hold the lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) if (one_lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) lock(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) /* Hold lock on this cpu */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) lock(parameters[i].cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) if ((status=err_inject(parameters[i].cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) path, err_type_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) err_struct_info, err_data_buffer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) ==0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) /* consume the error for "inject only"*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) memcpy(va2, va1, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) memcpy(va1, va2, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) log_info(parameters[i].cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) "successful\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) log_info(parameters[i].cpu,"fail:");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) log_info(parameters[i].cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) "status=%d\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) unlock(parameters[i].cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) if (one_lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) /* Release the lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) unlock(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) /* Release lock on this cpu */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) unlock(parameters[i].cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) if (j < parameters[i].loop-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) sleep(parameters[i].interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) current_time=time(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) log_info(parameters[i].cpu, "Done at %s", ctime(¤t_time));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) else if (pid<0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) perror("Error fork:");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) child_pid[i]=pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) for (i=0;i<num;i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) waitpid(child_pid[i], NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) if (one_lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) free_sem(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) for (i=0;i<num;i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) free_sem(parameters[i].cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) printf("All done.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) void help()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) printf("err_inject_tool:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) printf("\t-q: query all capabilities. default: off\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) printf("\t-m: procedure mode. 1: physical 2: virtual. default: 1\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) printf("\t-i: inject errors. default: off\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) printf("\t-l: one lock per cpu. default: one lock for all\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) printf("\t-e: error parameters:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) printf("\t\tcpu,loop,interval,err_type_info,err_struct_info[,err_data_buffer[0],err_data_buffer[1],err_data_buffer[2]]\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) printf("\t\t cpu: logical cpu number the error will be inject in.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) printf("\t\t loop: times the error will be injected.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) printf("\t\t interval: In second. every so often one error is injected.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) printf("\t\t err_type_info, err_struct_info: PAL parameters.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) printf("\t\t err_data_buffer: PAL parameter. Optional. If not present,\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) printf("\t\t it's constructed by tool automatically. Be\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) printf("\t\t careful to provide err_data_buffer and make\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) printf("\t\t sure it's working with the environment.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) printf("\t Note:no space between error parameters.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) printf("\t default: Take error parameters from err.conf instead of command line.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) printf("\t-v: verbose. default: off\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) printf("\t-h: help\n\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) printf("The tool will take err.conf file as ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) printf("input to inject single or multiple errors ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) printf("on one or multiple cpus in parallel.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) int main(int argc, char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) char c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) int do_err_inj=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) int do_query_all=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) u32 m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) /* Default one lock for all cpu's */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) one_lock=1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) while ((c = getopt(argc, argv, "m:iqvhle:")) != EOF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) switch (c) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) case 'm': /* Procedure mode. 1: phys 2: virt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) count=sscanf(optarg, "%x", &m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) if (count!=1 || (m!=1 && m!=2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) printf("Wrong mode number.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) help();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) mode=m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) case 'i': /* Inject errors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) do_err_inj=1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) case 'q': /* Query */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) do_query_all=1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) case 'v': /* Verbose */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) verbose=1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) case 'l': /* One lock per cpu */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) one_lock=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) case 'e': /* error arguments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) /* Take parameters:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) * #cpu, loop, interval, err_type_info, err_struct_info[, err_data_buffer]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) * err_data_buffer is optional. Recommend not to specify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) * err_data_buffer. Better to use tool to generate it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) count=sscanf(optarg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) "%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) &line_para.cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) &line_para.loop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) &line_para.interval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) &line_para.err_type_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) &line_para.err_struct_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) &line_para.err_data_buffer[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) &line_para.err_data_buffer[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) &line_para.err_data_buffer[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) if (count!=PARA_FIELD_NUM+3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) line_para.err_data_buffer[0]=-1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) line_para.err_data_buffer[1]=-1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) line_para.err_data_buffer[2]=-1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) count=sscanf(optarg, "%lx, %lx, %lx, %lx, %lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) &line_para.cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) &line_para.loop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) &line_para.interval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) &line_para.err_type_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) &line_para.err_struct_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) if (count!=PARA_FIELD_NUM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) printf("Wrong error arguments.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) help();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) para=1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) case 'h':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) help();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) if (do_query_all)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) query_all_capabilities();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) if (do_err_inj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) err_inj();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) if (!do_query_all && !do_err_inj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) help();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) }