/******************************************************************************* HWDD memory module Copyright (c) 2011 Network Appliance, Inc. hwdd_mem.h: main header file for HWDD memory module *******************************************************************************/ #ifndef _HWDD_MEM_H_ #define _HWDD_MEM_H_ #include #define HDD_MAX_RANGE 8 /* types of memory supported, last one is for NVMEM */ #define MAX_PROCS 32 /* maximum HWDD memory processes that can be running at a time */ #define MEG 0x100000 #define GIG 0x40000000 #define GIG4 0x100000000ull #define MAX_REMAPSIZE 0x4000000 /* ioremap will first be attempted with this size */ #define CHECKER_PATTERN 0x5a5a5a5a5a5a5a5a /* pattern used during checker board test */ #define SLEEP_SEC 1 /* value here will determine the number of seconds a test run before preemption*/ #define SLEEP_AFTER (jiffies + SLEEP_SEC*HZ)/* number of seconds before preemption */ #define PASS 0 #define FAIL -1 #define HWDD_MEM_VERSION "1.0" #define MEM_DEV "mem" #define MEM_THRESHOLD 100 #define mix_random(in,rand) \ in = in * 12217211221721 + 6831410368314103; \ rand = in & 0xffffffff00000000; \ in = in * 12217211221721 + 6831410368314103; \ rand |= (in >> 32) & 0xffffffff; #define mix_seed(in) \ in = in * 12217211221721+ 6831410368314103; #define MAXMASK(in, mask) \ (in > mask) ? (in & mask) : in #define bytes_to_mbytes(bytes) \ (bytes >> 20) #define LAST_LEVEL_CACHE_SIZE ((current_cpu_data.x86_cache_size) * 1024) //x86_cache_size consists cahce size in KB extern int get_memory_bandwidth(void *); extern pid_t get_parent_pid(void); extern int hwdd_sleep_checkstop(unsigned long *expire, pid_t ppid); extern int hwdd_mem_randdata_test(u64 virt_start, u64 virt_end, u64 phys_start, pid_t ppid, void* ptr); extern int hwdd_mem_randaddr_test(u64 virt_start, u64 virt_end, u64 phys_start, pid_t ppid, void* ptr); extern int hwdd_test_checker(u64 virt_start, u64 virt_end, u64 phys_start, pid_t ppid, void* ptr); extern int hwdd_mem_data_walk(u64 start, u64 end, u64 phys_start, pid_t ppid, void* ptr); extern int hwdd_mem_addr_walk(u64 start, u64 end, u64 phys_start, pid_t ppid, void* ptr); extern int mem_stuck_faults(u64 start, u64 end, u64 phys_start, pid_t ppid, void* ptr); extern int mem_fill_data(u64 start, u64 end, char pattern[], u64 phys_start, pid_t ppid, void* ptr); extern int mem_check_data(u64 start, u64 end, char pattern[], u64 phys_start, pid_t ppid, void* ptr); extern int mem_word_walk(u64 start, u64 end, u64 phys_start, pid_t ppid, void* ptr); extern int mem_byte_walk(u64 start, u64 end, u64 phys_start, pid_t ppid, void* ptr); extern int mem_alt_addr(u64 start, u64 end, u64 phys_start, pid_t ppid, void* ptr); extern int mem_parity(u64 start, u64 end, u64 phys_start, pid_t ppid, void* ptr); extern int mem_byte_pat(u64 start, u64 end, u64 phys_start, pid_t ppid, void* ptr); extern int mem_partial(u64 start, u64 end, u64 phys_start, pid_t ppid, void* ptr); extern int dump_memory_utility(u64 start, u64 end, u64 phys_start, pid_t ppid, void* ptr); extern int hwdd_acpi_einj_support(void); extern int hwdd_acpi_inject_memerr(u32 type, u64 address); extern int cache_data_walk(u64 cache_base, u64 cache_end, u64 phys_start, pid_t ppid, void *log_ptr); extern int cache_stuck_faults(u64 cache_base, u64 cache_end, u64 phys_start, pid_t ppid, void *log_ptr); extern int cache_rand_rw(u64 cache_base, u64 cache_end, u64 phys_start, pid_t ppid, void *log_ptr); extern int cache_rand_data(u64 cache_base, u64 cache_end, u64 phys_start, pid_t ppid, void *log_ptr); extern int cache_rand_addr(u64 cache_base, u64 cache_end, u64 phys_start, pid_t ppid, void *log_ptr); extern int cache_tag(u64 cache_base, u64 cache_end, u64 phys_start, pid_t ppid, void *log_ptr); /* test index passed by user should be one of these */ enum memory_tests { RANDOM_DATA_TEST, RANDOM_ADDRESS_TEST, WALKING_DATA_BITS_TEST, WALKING_ADDRESS_TEST, CHECKER_BOARD_TEST, STUCK_FAULTS_TEST, WALKING_DATA_WORDS_TEST, WALKING_DATA_BYTES_TEST, FILL_MEMORY_WITH_DATA_PATTERN, CHECK_MEMORY_WITH_DATA_PATTERN, BYTE_PATTERNS_TEST, PARTIAL_WORDS_TEST, ALTERNATING_ADDRESS_TEST, PARITY_BITS_TEST, MEMORY_DUMP_UTILITY, CACHE_DATA_WALK = 18, CACHE_STUCK_FAULT, CACHE_RAND_RW, CACHE_RAND_DATA, CACHE_RAND_ADDR, CACHE_TAG }; /* various memory types considered */ enum mem_type { HDD_TYPE_DRAM, HDD_TYPE_NVMEM, HDD_TYPE_UNDEF, }; /* records the start and end of memory and the type */ typedef struct _hdd_memranges { u64 phys_mem_start; u64 phys_mem_end; u8 mem_type; /* DRAM/NVMEM etc */ }hdd_memranges; /* holds information on launched test */ typedef struct launch_test { pid_t pid; /* pid for which the work got launched */ int cnt; /* number of workers for this pid */ u8 stop; /* set when the user isues a STOP */ u64 mem_start; u64 mem_end; int r_err_cnt; /* number of errors recorded before the test starts */ }hwdd_launch; /* this structure is used to hold the status and ECC count of completed test */ typedef struct test_status { pid_t pid; /* pid of the completed test */ int d_err_cnt; /* total number of detected errors */ u8 status; /* completion status */ }hwdd_status; /* global details */ typedef struct _hdd_memdetails { u64 phys_mem_start; /* start of physical memory */ u64 phys_mem_end; /* end of physical memory */ u64 testable_mem_start; /* starting address from where memory can be write tested */ u64 user_phys_mem_start; /* user given memory start */ u64 user_phys_mem_end; /* user given memory end */ u8 index; /* there may be multiple memory ranges, keep track of the last index */ hdd_memranges mem_ranges[HDD_MAX_RANGE];/* memory range information */ u8 cache_status; /* 1 on and 0 off */ u16 errors; /* error threshold */ spinlock_t hwdd_launchpidlock; /* lock for hwdd_launchpid array */ spinlock_t hwdd_statuspidlock; /* lock for statuspid array */ hwdd_launch hwdd_launchpid[MAX_PROCS]; /* holds info on launched tests, TODO: have this a list */ hwdd_status hwdd_statuspid[MAX_PROCS]; /* status info on the completed test */ int launch_pid_cnt; /* count of number of tests launched */ int status_pid_cnt; /* count of completed status */ }hwdd_memdetails; /* container structure that workers will use for launching a test */ typedef struct _hwdd_testdesc { u64 start; /* start address to test from */ u64 end; /* end address */ u16 index; /* test index, to identify the test to launch */ pid_t pid; /* pid of the application that requested for the test */ u8 cache_status; /* cache state desired by user, used during ioremap */ char hex_pattern[80]; char mode[32]; // value 32 should be in consistent with DISPLAY_MODE_LENGTH macro in hwdd_memioctl.h struct work_struct work; }hwdd_test_desc; #endif /* _HWDD_MEM_H_ */