mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-08-14 22:23:56 +09:00
![Simon Glass](/assets/img/avatar_default.png)
When debugging drivers it is useful to see what I/O accesses were done and in what order. Even if the individual accesses are of little interest it can be useful to verify that the access pattern is consistent each time an operation is performed. In this case a checksum can be used to characterise the operation of a driver. The checksum can be compared across different runs of the operation to verify that the driver is working properly. In particular, when performing major refactoring of the driver, where the access pattern should not change, the checksum provides assurance that the refactoring work has not broken the driver. Add an I/O tracing feature and associated commands to provide this facility. It works by sneaking into the io.h heder for an architecture and redirecting I/O accesses through its tracing mechanism. For now no commands are provided to examine the trace buffer. The format is fairly simple, so 'md' is a reasonable substitute. Note: The checksum feature is only useful for I/O regions where the contents do not change outside of software control. Where this is not suitable you can fall back to manually comparing the addresses. It might be useful to enhance tracing to only checksum the accesses and not the data read/written. Signed-off-by: Simon Glass <sjg@chromium.org>
105 lines
2.8 KiB
C
105 lines
2.8 KiB
C
/*
|
|
* Copyright (c) 2014 Google, Inc.
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0+
|
|
*/
|
|
|
|
#ifndef __IOTRACE_H
|
|
#define __IOTRACE_H
|
|
|
|
#include <linux/types.h>
|
|
|
|
/*
|
|
* This file is designed to be included in arch/<arch>/include/asm/io.h.
|
|
* It redirects all IO access through a tracing/checksumming feature for
|
|
* testing purposes.
|
|
*/
|
|
|
|
#if defined(CONFIG_IO_TRACE) && !defined(IOTRACE_IMPL) && \
|
|
!defined(CONFIG_SPL_BUILD)
|
|
|
|
#undef readl
|
|
#define readl(addr) iotrace_readl((const void *)(addr))
|
|
|
|
#undef writel
|
|
#define writel(val, addr) iotrace_writel(val, (const void *)(addr))
|
|
|
|
#undef readw
|
|
#define readw(addr) iotrace_readw((const void *)(addr))
|
|
|
|
#undef writew
|
|
#define writew(val, addr) iotrace_writew(val, (const void *)(addr))
|
|
|
|
#undef readb
|
|
#define readb(addr) iotrace_readb((const void *)(addr))
|
|
|
|
#undef writeb
|
|
#define writeb(val, addr) iotrace_writeb(val, (const void *)(addr))
|
|
|
|
#endif
|
|
|
|
/* Tracing functions which mirror their io.h counterparts */
|
|
u32 iotrace_readl(const void *ptr);
|
|
void iotrace_writel(ulong value, const void *ptr);
|
|
u16 iotrace_readw(const void *ptr);
|
|
void iotrace_writew(ulong value, const void *ptr);
|
|
u8 iotrace_readb(const void *ptr);
|
|
void iotrace_writeb(ulong value, const void *ptr);
|
|
|
|
/**
|
|
* iotrace_reset_checksum() - Reset the iotrace checksum
|
|
*/
|
|
void iotrace_reset_checksum(void);
|
|
|
|
/**
|
|
* iotrace_get_checksum() - Get the current checksum value
|
|
*
|
|
* @return currect checksum value
|
|
*/
|
|
u32 iotrace_get_checksum(void);
|
|
|
|
/**
|
|
* iotrace_set_enabled() - Set whether iotracing is enabled or not
|
|
*
|
|
* This controls whether the checksum is updated and a trace record added
|
|
* for each I/O access.
|
|
*
|
|
* @enable: true to enable iotracing, false to disable
|
|
*/
|
|
void iotrace_set_enabled(int enable);
|
|
|
|
/**
|
|
* iotrace_get_enabled() - Get whether iotracing is enabled or not
|
|
*
|
|
* @return true if enabled, false if disabled
|
|
*/
|
|
int iotrace_get_enabled(void);
|
|
|
|
/**
|
|
* iotrace_set_buffer() - Set position and size of iotrace buffer
|
|
*
|
|
* Defines where the iotrace buffer goes, and resets the output pointer to
|
|
* the start of the buffer.
|
|
*
|
|
* The buffer can be 0 size in which case the checksum is updated but no
|
|
* trace records are writen. If the buffer is exhausted, the offset will
|
|
* continue to increase but not new data will be written.
|
|
*
|
|
* @start: Start address of buffer
|
|
* @size: Size of buffer in bytes
|
|
*/
|
|
void iotrace_set_buffer(ulong start, ulong size);
|
|
|
|
/**
|
|
* iotrace_get_buffer() - Get buffer information
|
|
*
|
|
* @start: Returns start address of buffer
|
|
* @size: Returns size of buffer in bytes
|
|
* @offset: Returns the byte offset where the next output trace record will
|
|
* @count: Returns the number of trace records recorded
|
|
* be written (or would be if the buffer was large enough)
|
|
*/
|
|
void iotrace_get_buffer(ulong *start, ulong *size, ulong *offset, ulong *count);
|
|
|
|
#endif /* __IOTRACE_H */
|