1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Cell Broadband Engine OProfile Support 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * (C) Copyright IBM Corporation 2006 6*4882a593Smuzhiyun * 7*4882a593Smuzhiyun * Author: Maynard Johnson <maynardj@us.ibm.com> 8*4882a593Smuzhiyun */ 9*4882a593Smuzhiyun 10*4882a593Smuzhiyun #ifndef PR_UTIL_H 11*4882a593Smuzhiyun #define PR_UTIL_H 12*4882a593Smuzhiyun 13*4882a593Smuzhiyun #include <linux/cpumask.h> 14*4882a593Smuzhiyun #include <linux/oprofile.h> 15*4882a593Smuzhiyun #include <asm/cell-pmu.h> 16*4882a593Smuzhiyun #include <asm/cell-regs.h> 17*4882a593Smuzhiyun #include <asm/spu.h> 18*4882a593Smuzhiyun 19*4882a593Smuzhiyun /* Defines used for sync_start */ 20*4882a593Smuzhiyun #define SKIP_GENERIC_SYNC 0 21*4882a593Smuzhiyun #define SYNC_START_ERROR -1 22*4882a593Smuzhiyun #define DO_GENERIC_SYNC 1 23*4882a593Smuzhiyun #define SPUS_PER_NODE 8 24*4882a593Smuzhiyun #define DEFAULT_TIMER_EXPIRE (HZ / 10) 25*4882a593Smuzhiyun 26*4882a593Smuzhiyun extern struct delayed_work spu_work; 27*4882a593Smuzhiyun extern int spu_prof_running; 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun #define TRACE_ARRAY_SIZE 1024 30*4882a593Smuzhiyun 31*4882a593Smuzhiyun extern spinlock_t oprof_spu_smpl_arry_lck; 32*4882a593Smuzhiyun 33*4882a593Smuzhiyun struct spu_overlay_info { /* map of sections within an SPU overlay */ 34*4882a593Smuzhiyun unsigned int vma; /* SPU virtual memory address from elf */ 35*4882a593Smuzhiyun unsigned int size; /* size of section from elf */ 36*4882a593Smuzhiyun unsigned int offset; /* offset of section into elf file */ 37*4882a593Smuzhiyun unsigned int buf; 38*4882a593Smuzhiyun }; 39*4882a593Smuzhiyun 40*4882a593Smuzhiyun struct vma_to_fileoffset_map { /* map of sections within an SPU program */ 41*4882a593Smuzhiyun struct vma_to_fileoffset_map *next; /* list pointer */ 42*4882a593Smuzhiyun unsigned int vma; /* SPU virtual memory address from elf */ 43*4882a593Smuzhiyun unsigned int size; /* size of section from elf */ 44*4882a593Smuzhiyun unsigned int offset; /* offset of section into elf file */ 45*4882a593Smuzhiyun unsigned int guard_ptr; 46*4882a593Smuzhiyun unsigned int guard_val; 47*4882a593Smuzhiyun /* 48*4882a593Smuzhiyun * The guard pointer is an entry in the _ovly_buf_table, 49*4882a593Smuzhiyun * computed using ovly.buf as the index into the table. Since 50*4882a593Smuzhiyun * ovly.buf values begin at '1' to reference the first (or 0th) 51*4882a593Smuzhiyun * entry in the _ovly_buf_table, the computation subtracts 1 52*4882a593Smuzhiyun * from ovly.buf. 53*4882a593Smuzhiyun * The guard value is stored in the _ovly_buf_table entry and 54*4882a593Smuzhiyun * is an index (starting at 1) back to the _ovly_table entry 55*4882a593Smuzhiyun * that is pointing at this _ovly_buf_table entry. So, for 56*4882a593Smuzhiyun * example, for an overlay scenario with one overlay segment 57*4882a593Smuzhiyun * and two overlay sections: 58*4882a593Smuzhiyun * - Section 1 points to the first entry of the 59*4882a593Smuzhiyun * _ovly_buf_table, which contains a guard value 60*4882a593Smuzhiyun * of '1', referencing the first (index=0) entry of 61*4882a593Smuzhiyun * _ovly_table. 62*4882a593Smuzhiyun * - Section 2 points to the second entry of the 63*4882a593Smuzhiyun * _ovly_buf_table, which contains a guard value 64*4882a593Smuzhiyun * of '2', referencing the second (index=1) entry of 65*4882a593Smuzhiyun * _ovly_table. 66*4882a593Smuzhiyun */ 67*4882a593Smuzhiyun 68*4882a593Smuzhiyun }; 69*4882a593Smuzhiyun 70*4882a593Smuzhiyun struct spu_buffer { 71*4882a593Smuzhiyun int last_guard_val; 72*4882a593Smuzhiyun int ctx_sw_seen; 73*4882a593Smuzhiyun unsigned long *buff; 74*4882a593Smuzhiyun unsigned int head, tail; 75*4882a593Smuzhiyun }; 76*4882a593Smuzhiyun 77*4882a593Smuzhiyun 78*4882a593Smuzhiyun /* The three functions below are for maintaining and accessing 79*4882a593Smuzhiyun * the vma-to-fileoffset map. 80*4882a593Smuzhiyun */ 81*4882a593Smuzhiyun struct vma_to_fileoffset_map *create_vma_map(const struct spu *spu, 82*4882a593Smuzhiyun unsigned long objectid); 83*4882a593Smuzhiyun unsigned int vma_map_lookup(struct vma_to_fileoffset_map *map, 84*4882a593Smuzhiyun unsigned int vma, const struct spu *aSpu, 85*4882a593Smuzhiyun int *grd_val); 86*4882a593Smuzhiyun void vma_map_free(struct vma_to_fileoffset_map *map); 87*4882a593Smuzhiyun 88*4882a593Smuzhiyun /* 89*4882a593Smuzhiyun * Entry point for SPU profiling. 90*4882a593Smuzhiyun * cycles_reset is the SPU_CYCLES count value specified by the user. 91*4882a593Smuzhiyun */ 92*4882a593Smuzhiyun int start_spu_profiling_cycles(unsigned int cycles_reset); 93*4882a593Smuzhiyun void start_spu_profiling_events(void); 94*4882a593Smuzhiyun 95*4882a593Smuzhiyun void stop_spu_profiling_cycles(void); 96*4882a593Smuzhiyun void stop_spu_profiling_events(void); 97*4882a593Smuzhiyun 98*4882a593Smuzhiyun /* add the necessary profiling hooks */ 99*4882a593Smuzhiyun int spu_sync_start(void); 100*4882a593Smuzhiyun 101*4882a593Smuzhiyun /* remove the hooks */ 102*4882a593Smuzhiyun int spu_sync_stop(void); 103*4882a593Smuzhiyun 104*4882a593Smuzhiyun /* Record SPU program counter samples to the oprofile event buffer. */ 105*4882a593Smuzhiyun void spu_sync_buffer(int spu_num, unsigned int *samples, 106*4882a593Smuzhiyun int num_samples); 107*4882a593Smuzhiyun 108*4882a593Smuzhiyun void set_spu_profiling_frequency(unsigned int freq_khz, unsigned int cycles_reset); 109*4882a593Smuzhiyun 110*4882a593Smuzhiyun #endif /* PR_UTIL_H */ 111