Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * This contains all required hardware related helper functions for
0004  * Trace Buffer Extension (TRBE) driver in the coresight framework.
0005  *
0006  * Copyright (C) 2020 ARM Ltd.
0007  *
0008  * Author: Anshuman Khandual <anshuman.khandual@arm.com>
0009  */
0010 #include <linux/coresight.h>
0011 #include <linux/device.h>
0012 #include <linux/irq.h>
0013 #include <linux/kernel.h>
0014 #include <linux/of.h>
0015 #include <linux/platform_device.h>
0016 #include <linux/smp.h>
0017 
0018 #include "coresight-etm-perf.h"
0019 
0020 static inline bool is_trbe_available(void)
0021 {
0022     u64 aa64dfr0 = read_sysreg_s(SYS_ID_AA64DFR0_EL1);
0023     unsigned int trbe = cpuid_feature_extract_unsigned_field(aa64dfr0, ID_AA64DFR0_TRBE_SHIFT);
0024 
0025     return trbe >= 0b0001;
0026 }
0027 
0028 static inline bool is_trbe_enabled(void)
0029 {
0030     u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
0031 
0032     return trblimitr & TRBLIMITR_ENABLE;
0033 }
0034 
0035 #define TRBE_EC_OTHERS      0
0036 #define TRBE_EC_STAGE1_ABORT    36
0037 #define TRBE_EC_STAGE2_ABORT    37
0038 
0039 static inline int get_trbe_ec(u64 trbsr)
0040 {
0041     return (trbsr >> TRBSR_EC_SHIFT) & TRBSR_EC_MASK;
0042 }
0043 
0044 #define TRBE_BSC_NOT_STOPPED 0
0045 #define TRBE_BSC_FILLED      1
0046 #define TRBE_BSC_TRIGGERED   2
0047 
0048 static inline int get_trbe_bsc(u64 trbsr)
0049 {
0050     return (trbsr >> TRBSR_BSC_SHIFT) & TRBSR_BSC_MASK;
0051 }
0052 
0053 static inline void clr_trbe_irq(void)
0054 {
0055     u64 trbsr = read_sysreg_s(SYS_TRBSR_EL1);
0056 
0057     trbsr &= ~TRBSR_IRQ;
0058     write_sysreg_s(trbsr, SYS_TRBSR_EL1);
0059 }
0060 
0061 static inline bool is_trbe_irq(u64 trbsr)
0062 {
0063     return trbsr & TRBSR_IRQ;
0064 }
0065 
0066 static inline bool is_trbe_trg(u64 trbsr)
0067 {
0068     return trbsr & TRBSR_TRG;
0069 }
0070 
0071 static inline bool is_trbe_wrap(u64 trbsr)
0072 {
0073     return trbsr & TRBSR_WRAP;
0074 }
0075 
0076 static inline bool is_trbe_abort(u64 trbsr)
0077 {
0078     return trbsr & TRBSR_ABORT;
0079 }
0080 
0081 static inline bool is_trbe_running(u64 trbsr)
0082 {
0083     return !(trbsr & TRBSR_STOP);
0084 }
0085 
0086 #define TRBE_TRIG_MODE_STOP     0
0087 #define TRBE_TRIG_MODE_IRQ      1
0088 #define TRBE_TRIG_MODE_IGNORE       3
0089 
0090 #define TRBE_FILL_MODE_FILL     0
0091 #define TRBE_FILL_MODE_WRAP     1
0092 #define TRBE_FILL_MODE_CIRCULAR_BUFFER  3
0093 
0094 static inline bool get_trbe_flag_update(u64 trbidr)
0095 {
0096     return trbidr & TRBIDR_FLAG;
0097 }
0098 
0099 static inline bool is_trbe_programmable(u64 trbidr)
0100 {
0101     return !(trbidr & TRBIDR_PROG);
0102 }
0103 
0104 static inline int get_trbe_address_align(u64 trbidr)
0105 {
0106     return (trbidr >> TRBIDR_ALIGN_SHIFT) & TRBIDR_ALIGN_MASK;
0107 }
0108 
0109 static inline unsigned long get_trbe_write_pointer(void)
0110 {
0111     return read_sysreg_s(SYS_TRBPTR_EL1);
0112 }
0113 
0114 static inline void set_trbe_write_pointer(unsigned long addr)
0115 {
0116     WARN_ON(is_trbe_enabled());
0117     write_sysreg_s(addr, SYS_TRBPTR_EL1);
0118 }
0119 
0120 static inline unsigned long get_trbe_limit_pointer(void)
0121 {
0122     u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
0123     unsigned long addr = trblimitr & (TRBLIMITR_LIMIT_MASK << TRBLIMITR_LIMIT_SHIFT);
0124 
0125     WARN_ON(!IS_ALIGNED(addr, PAGE_SIZE));
0126     return addr;
0127 }
0128 
0129 static inline unsigned long get_trbe_base_pointer(void)
0130 {
0131     u64 trbbaser = read_sysreg_s(SYS_TRBBASER_EL1);
0132     unsigned long addr = trbbaser & (TRBBASER_BASE_MASK << TRBBASER_BASE_SHIFT);
0133 
0134     WARN_ON(!IS_ALIGNED(addr, PAGE_SIZE));
0135     return addr;
0136 }
0137 
0138 static inline void set_trbe_base_pointer(unsigned long addr)
0139 {
0140     WARN_ON(is_trbe_enabled());
0141     WARN_ON(!IS_ALIGNED(addr, (1UL << TRBBASER_BASE_SHIFT)));
0142     WARN_ON(!IS_ALIGNED(addr, PAGE_SIZE));
0143     write_sysreg_s(addr, SYS_TRBBASER_EL1);
0144 }