]>
git.ipfire.org Git - thirdparty/u-boot.git/blob - common/iotrace.c
1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 2014 Google, Inc.
12 DECLARE_GLOBAL_DATA_PTR
;
15 * struct iotrace - current trace status and checksum
17 * @start: Start address of iotrace buffer
18 * @size: Actual size of iotrace buffer in bytes
19 * @needed_size: Needed of iotrace buffer in bytes
20 * @offset: Current write offset into iotrace buffer
21 * @region_start: Address of IO region to trace
22 * @region_size: Size of region to trace. if 0 will trace all address space
23 * @crc32: Current value of CRC chceksum of trace records
24 * @enabled: true if enabled, false if disabled
26 static struct iotrace
{
37 static void add_record(int flags
, const void *ptr
, ulong value
)
39 struct iotrace_record srec
, *rec
= &srec
;
42 * We don't support iotrace before relocation. Since the trace buffer
43 * is set up by a command, it can't be enabled at present. To change
44 * this we would need to set the iotrace buffer at build-time. See
45 * lib/trace.c for how this might be done if you are interested.
47 if (!(gd
->flags
& GD_FLG_RELOC
) || !iotrace
.enabled
)
50 if (iotrace
.region_size
)
51 if ((ulong
)ptr
< iotrace
.region_start
||
52 (ulong
)ptr
> iotrace
.region_start
+ iotrace
.region_size
)
55 /* Store it if there is room */
56 if (iotrace
.offset
+ sizeof(*rec
) < iotrace
.size
) {
57 rec
= (struct iotrace_record
*)map_sysmem(
58 iotrace
.start
+ iotrace
.offset
,
61 WARN_ONCE(1, "WARNING: iotrace buffer exhausted, please check needed length using \"iotrace stats\"\n");
62 iotrace
.needed_size
+= sizeof(struct iotrace_record
);
66 rec
->timestamp
= timer_get_us();
68 rec
->addr
= map_to_sysmem(ptr
);
71 /* Update our checksum */
72 iotrace
.crc32
= crc32(iotrace
.crc32
, (unsigned char *)rec
,
75 iotrace
.needed_size
+= sizeof(struct iotrace_record
);
76 iotrace
.offset
+= sizeof(struct iotrace_record
);
79 u32
iotrace_readl(const void *ptr
)
84 add_record(IOT_32
| IOT_READ
, ptr
, v
);
89 void iotrace_writel(ulong value
, const void *ptr
)
91 add_record(IOT_32
| IOT_WRITE
, ptr
, value
);
95 u16
iotrace_readw(const void *ptr
)
100 add_record(IOT_16
| IOT_READ
, ptr
, v
);
105 void iotrace_writew(ulong value
, const void *ptr
)
107 add_record(IOT_16
| IOT_WRITE
, ptr
, value
);
111 u8
iotrace_readb(const void *ptr
)
116 add_record(IOT_8
| IOT_READ
, ptr
, v
);
121 void iotrace_writeb(ulong value
, const void *ptr
)
123 add_record(IOT_8
| IOT_WRITE
, ptr
, value
);
127 void iotrace_reset_checksum(void)
132 u32
iotrace_get_checksum(void)
134 return iotrace
.crc32
;
137 void iotrace_set_region(ulong start
, ulong size
)
139 iotrace
.region_start
= start
;
140 iotrace
.region_size
= size
;
143 void iotrace_reset_region(void)
145 iotrace
.region_start
= 0;
146 iotrace
.region_size
= 0;
149 void iotrace_get_region(ulong
*start
, ulong
*size
)
151 *start
= iotrace
.region_start
;
152 *size
= iotrace
.region_size
;
155 void iotrace_set_enabled(int enable
)
157 iotrace
.enabled
= enable
;
160 int iotrace_get_enabled(void)
162 return iotrace
.enabled
;
165 void iotrace_set_buffer(ulong start
, ulong size
)
167 iotrace
.start
= start
;
173 void iotrace_get_buffer(ulong
*start
, ulong
*size
, ulong
*needed_size
, ulong
*offset
, ulong
*count
)
175 *start
= iotrace
.start
;
176 *size
= iotrace
.size
;
177 *needed_size
= iotrace
.needed_size
;
178 *offset
= iotrace
.offset
;
179 *count
= iotrace
.offset
/ sizeof(struct iotrace_record
);