1010#include <asm/page.h> /* I/O is all done through memory accesses */
1111#include <linux/string.h> /* for memset() and memcpy() */
1212#include <linux/types.h>
13+ #include <linux/instruction_pointer.h>
1314
1415#ifdef CONFIG_GENERIC_IOMAP
1516#include <asm-generic/iomap.h>
6162#define __io_par (v ) __io_ar(v)
6263#endif
6364
65+ /*
66+ * "__DISABLE_TRACE_MMIO__" flag can be used to disable MMIO tracing for
67+ * specific kernel drivers in case of excessive/unwanted logging.
68+ *
69+ * Usage: Add a #define flag at the beginning of the driver file.
70+ * Ex: #define __DISABLE_TRACE_MMIO__
71+ * #include <...>
72+ * ...
73+ */
74+ #if IS_ENABLED (CONFIG_TRACE_MMIO_ACCESS ) && !(defined(__DISABLE_TRACE_MMIO__ ))
75+ #include <linux/tracepoint-defs.h>
76+
77+ DECLARE_TRACEPOINT (rwmmio_write );
78+ DECLARE_TRACEPOINT (rwmmio_post_write );
79+ DECLARE_TRACEPOINT (rwmmio_read );
80+ DECLARE_TRACEPOINT (rwmmio_post_read );
81+
82+ void log_write_mmio (u64 val , u8 width , volatile void __iomem * addr ,
83+ unsigned long caller_addr );
84+ void log_post_write_mmio (u64 val , u8 width , volatile void __iomem * addr ,
85+ unsigned long caller_addr );
86+ void log_read_mmio (u8 width , const volatile void __iomem * addr ,
87+ unsigned long caller_addr );
88+ void log_post_read_mmio (u64 val , u8 width , const volatile void __iomem * addr ,
89+ unsigned long caller_addr );
90+
91+ #else
92+
93+ static inline void log_write_mmio (u64 val , u8 width , volatile void __iomem * addr ,
94+ unsigned long caller_addr ) {}
95+ static inline void log_post_write_mmio (u64 val , u8 width , volatile void __iomem * addr ,
96+ unsigned long caller_addr ) {}
97+ static inline void log_read_mmio (u8 width , const volatile void __iomem * addr ,
98+ unsigned long caller_addr ) {}
99+ static inline void log_post_read_mmio (u64 val , u8 width , const volatile void __iomem * addr ,
100+ unsigned long caller_addr ) {}
101+
102+ #endif /* CONFIG_TRACE_MMIO_ACCESS */
64103
65104/*
66105 * __raw_{read,write}{b,w,l,q}() access memory in native endianness.
@@ -149,9 +188,11 @@ static inline u8 readb(const volatile void __iomem *addr)
149188{
150189 u8 val ;
151190
191+ log_read_mmio (8 , addr , _THIS_IP_ );
152192 __io_br ();
153193 val = __raw_readb (addr );
154194 __io_ar (val );
195+ log_post_read_mmio (val , 8 , addr , _THIS_IP_ );
155196 return val ;
156197}
157198#endif
@@ -162,9 +203,11 @@ static inline u16 readw(const volatile void __iomem *addr)
162203{
163204 u16 val ;
164205
206+ log_read_mmio (16 , addr , _THIS_IP_ );
165207 __io_br ();
166208 val = __le16_to_cpu ((__le16 __force )__raw_readw (addr ));
167209 __io_ar (val );
210+ log_post_read_mmio (val , 16 , addr , _THIS_IP_ );
168211 return val ;
169212}
170213#endif
@@ -175,9 +218,11 @@ static inline u32 readl(const volatile void __iomem *addr)
175218{
176219 u32 val ;
177220
221+ log_read_mmio (32 , addr , _THIS_IP_ );
178222 __io_br ();
179223 val = __le32_to_cpu ((__le32 __force )__raw_readl (addr ));
180224 __io_ar (val );
225+ log_post_read_mmio (val , 32 , addr , _THIS_IP_ );
181226 return val ;
182227}
183228#endif
@@ -189,9 +234,11 @@ static inline u64 readq(const volatile void __iomem *addr)
189234{
190235 u64 val ;
191236
237+ log_read_mmio (64 , addr , _THIS_IP_ );
192238 __io_br ();
193239 val = __le64_to_cpu (__raw_readq (addr ));
194240 __io_ar (val );
241+ log_post_read_mmio (val , 64 , addr , _THIS_IP_ );
195242 return val ;
196243}
197244#endif
@@ -201,29 +248,35 @@ static inline u64 readq(const volatile void __iomem *addr)
201248#define writeb writeb
202249static inline void writeb (u8 value , volatile void __iomem * addr )
203250{
251+ log_write_mmio (value , 8 , addr , _THIS_IP_ );
204252 __io_bw ();
205253 __raw_writeb (value , addr );
206254 __io_aw ();
255+ log_post_write_mmio (value , 8 , addr , _THIS_IP_ );
207256}
208257#endif
209258
210259#ifndef writew
211260#define writew writew
212261static inline void writew (u16 value , volatile void __iomem * addr )
213262{
263+ log_write_mmio (value , 16 , addr , _THIS_IP_ );
214264 __io_bw ();
215265 __raw_writew ((u16 __force )cpu_to_le16 (value ), addr );
216266 __io_aw ();
267+ log_post_write_mmio (value , 16 , addr , _THIS_IP_ );
217268}
218269#endif
219270
220271#ifndef writel
221272#define writel writel
222273static inline void writel (u32 value , volatile void __iomem * addr )
223274{
275+ log_write_mmio (value , 32 , addr , _THIS_IP_ );
224276 __io_bw ();
225277 __raw_writel ((u32 __force )__cpu_to_le32 (value ), addr );
226278 __io_aw ();
279+ log_post_write_mmio (value , 32 , addr , _THIS_IP_ );
227280}
228281#endif
229282
@@ -232,9 +285,11 @@ static inline void writel(u32 value, volatile void __iomem *addr)
232285#define writeq writeq
233286static inline void writeq (u64 value , volatile void __iomem * addr )
234287{
288+ log_write_mmio (value , 64 , addr , _THIS_IP_ );
235289 __io_bw ();
236290 __raw_writeq (__cpu_to_le64 (value ), addr );
237291 __io_aw ();
292+ log_post_write_mmio (value , 64 , addr , _THIS_IP_ );
238293}
239294#endif
240295#endif /* CONFIG_64BIT */
@@ -248,63 +303,91 @@ static inline void writeq(u64 value, volatile void __iomem *addr)
248303#define readb_relaxed readb_relaxed
249304static inline u8 readb_relaxed (const volatile void __iomem * addr )
250305{
251- return __raw_readb (addr );
306+ u8 val ;
307+
308+ log_read_mmio (8 , addr , _THIS_IP_ );
309+ val = __raw_readb (addr );
310+ log_post_read_mmio (val , 8 , addr , _THIS_IP_ );
311+ return val ;
252312}
253313#endif
254314
255315#ifndef readw_relaxed
256316#define readw_relaxed readw_relaxed
257317static inline u16 readw_relaxed (const volatile void __iomem * addr )
258318{
259- return __le16_to_cpu (__raw_readw (addr ));
319+ u16 val ;
320+
321+ log_read_mmio (16 , addr , _THIS_IP_ );
322+ val = __le16_to_cpu (__raw_readw (addr ));
323+ log_post_read_mmio (val , 16 , addr , _THIS_IP_ );
324+ return val ;
260325}
261326#endif
262327
263328#ifndef readl_relaxed
264329#define readl_relaxed readl_relaxed
265330static inline u32 readl_relaxed (const volatile void __iomem * addr )
266331{
267- return __le32_to_cpu (__raw_readl (addr ));
332+ u32 val ;
333+
334+ log_read_mmio (32 , addr , _THIS_IP_ );
335+ val = __le32_to_cpu (__raw_readl (addr ));
336+ log_post_read_mmio (val , 32 , addr , _THIS_IP_ );
337+ return val ;
268338}
269339#endif
270340
271341#if defined(readq ) && !defined(readq_relaxed )
272342#define readq_relaxed readq_relaxed
273343static inline u64 readq_relaxed (const volatile void __iomem * addr )
274344{
275- return __le64_to_cpu (__raw_readq (addr ));
345+ u64 val ;
346+
347+ log_read_mmio (64 , addr , _THIS_IP_ );
348+ val = __le64_to_cpu (__raw_readq (addr ));
349+ log_post_read_mmio (val , 64 , addr , _THIS_IP_ );
350+ return val ;
276351}
277352#endif
278353
279354#ifndef writeb_relaxed
280355#define writeb_relaxed writeb_relaxed
281356static inline void writeb_relaxed (u8 value , volatile void __iomem * addr )
282357{
358+ log_write_mmio (value , 8 , addr , _THIS_IP_ );
283359 __raw_writeb (value , addr );
360+ log_post_write_mmio (value , 8 , addr , _THIS_IP_ );
284361}
285362#endif
286363
287364#ifndef writew_relaxed
288365#define writew_relaxed writew_relaxed
289366static inline void writew_relaxed (u16 value , volatile void __iomem * addr )
290367{
368+ log_write_mmio (value , 16 , addr , _THIS_IP_ );
291369 __raw_writew (cpu_to_le16 (value ), addr );
370+ log_post_write_mmio (value , 16 , addr , _THIS_IP_ );
292371}
293372#endif
294373
295374#ifndef writel_relaxed
296375#define writel_relaxed writel_relaxed
297376static inline void writel_relaxed (u32 value , volatile void __iomem * addr )
298377{
378+ log_write_mmio (value , 32 , addr , _THIS_IP_ );
299379 __raw_writel (__cpu_to_le32 (value ), addr );
380+ log_post_write_mmio (value , 32 , addr , _THIS_IP_ );
300381}
301382#endif
302383
303384#if defined(writeq ) && !defined(writeq_relaxed )
304385#define writeq_relaxed writeq_relaxed
305386static inline void writeq_relaxed (u64 value , volatile void __iomem * addr )
306387{
388+ log_write_mmio (value , 64 , addr , _THIS_IP_ );
307389 __raw_writeq (__cpu_to_le64 (value ), addr );
390+ log_post_write_mmio (value , 64 , addr , _THIS_IP_ );
308391}
309392#endif
310393
0 commit comments