-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathcs_access_cmnfns.h
More file actions
424 lines (364 loc) · 14.4 KB
/
cs_access_cmnfns.h
File metadata and controls
424 lines (364 loc) · 14.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
/*!
* \file cs_access_cmnfns.h
* \brief CS Access Library - internal library types and function declarations - not exposed on API.
*
* \copyright Copyright (C) ARM Limited, 2014-2016. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _included_cs_access_cmnfns_h
#define _included_cs_access_cmnfns_h
#include "cs_types.h"
/* Now one of UNIX_USERSPACE, UNIX_KERNEL or BAREMETAL will have been defined. */
#include "cs_etm_types.h"
#include "cs_etmv4_types.h"
#include "cs_stm_types.h"
#include "cs_ts_gen.h"
#include "csregisters.h"
#ifdef UNIX_USERSPACE
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#endif /* UNIX_USERSPACE */
#ifdef UNIX_KERNEL
#include <linux/kernel.h>
#include <linux/slab.h>
#define malloc(x) kmalloc(x, GFP_KERNEL)
#define free(p) kfree(p)
#endif /* UNIX_KERNEL */
#if defined(UNIX_USERSPACE) || defined(BAREMETAL)
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#endif
#if defined(UNIX_KERNEL)
#include <linux/string.h>
#include <asm/io.h>
#define assert(x) BUG_ON(x)
#endif
#include <stddef.h>
#include <stdarg.h>
#define CS_LIB_VERSION_MAJ 0x02
#define CS_LIB_VERSION_MIN 0x03
/*
DIAG defines whether this build is capable of writing diagnostic messages.
The actual production of individual messages is controlled by tests under
the DTRACE/DTRACEG macros.
Compile with -DDIAG=0 for a bare-metal build.
*/
#ifndef DIAG
#define DIAG 1
#endif /* DIAG */
/*
CHECK defines whether this build is capable of extra self-checking.
Note that the self-checks may involve additional memory transactions with
the CoreSight devices, e.g. reading back registers after writing.
The actual self-checks are controlled by the DCHECK macro.
*/
#ifndef CHECK
#define CHECK 1
#endif /* CHECK */
/**
* Upper limits on input/output ports of devices in the trace bus
*/
#define CS_MAX_IN_PORTS 8
#define CS_MAX_OUT_PORTS 8
struct cs_device;
struct cs_device_ops {
void (*unregister) (struct cs_device * d);
};
/*
Information relating to a single CoreSight component.
A "component" generally corresponds to a single 4K programmable memory-mapped block.
*/
struct cs_device {
/* Next device in global list - no particular order */
struct cs_device *next;
struct cs_device_ops ops;
/* Generic properties of the device */
cs_physaddr_t phys_addr;
unsigned char volatile *local_addr;
unsigned char devtype_from_id;
cs_devtype_t type;
unsigned short part_number; /**< CoreSight part number, 3 hex digits */
unsigned int devclass;
unsigned int devaff0; /**< Device affinity register for CPU-affine devices - might be CPU's MPIDR, but might also be zero */
cs_cpu_t affine_cpu; /**< Set by the user via the API */
cs_power_domain_t power_domain;
int is_unlocked:1;
int is_permanently_unlocked:1;
#if DIAG
int diag_tracing:1; /**< Diagnostic messages for actions on this device */
#endif /* DIAG */
unsigned int n_api_errors;
/* Trace bus topology */
unsigned int n_in_ports;
unsigned int n_out_ports;
struct cs_device *ins[CS_MAX_IN_PORTS];
unsigned char from_out_port[CS_MAX_IN_PORTS];
struct cs_device *outs[CS_MAX_OUT_PORTS];
unsigned char to_in_port[CS_MAX_OUT_PORTS];
/* Device-specific properties */
union {
struct debug_props {
unsigned int didr; /**< Contents of DBGDIDR */
unsigned int devid; /**< Contents of DBGDEVID, or zero when not present */
unsigned int pcsamplereg; /**< Offset to PC sampling register */
unsigned int debug_arch; /**< debug architecture */
struct cs_device *pmu; /**< PMU for this CPU */
struct cs_device *etm; /**< ETM for this CPU */
struct cs_device *cti; /**< CTI for this CPU */
} debug;
struct pmu_props {
unsigned int cfgr;
unsigned int n_counters; /**< Number of event counters, not including cycle counter */
unsigned char map_scale; /**< Spacing in the memory map (power of 2) */
} pmu;
struct cti_props {
#define CTI_CHANNELS 4
#define CTI_CHANNEL_MASK ((1U << CTI_CHANNELS) - 1) /* i.e. 0x0F for 4-channel CTI */
#define CTI_MAX_IN_PORTS 10
#define CTI_MAX_OUT_PORTS 10
unsigned char n_triggers; /**< Generally 8, but 9 seen for Cortex-A8 */
unsigned char n_channels; /**< Generally 4 */
struct {
struct cs_device *dev;
unsigned int devportid;
} src[CTI_MAX_IN_PORTS];
struct {
struct cs_device *dev;
unsigned int devportid;
} dst[CTI_MAX_OUT_PORTS];
} cti;
struct etm_props {
unsigned int etmidr;
cs_etm_static_config_t sc;
union { // union of arch specifc configs - starting with ETMv4
cs_etm_v4_static_config_t etmv4_sc;
} sc_ex;
} etm;
struct etb_props {
unsigned int buffer_size_bytes;
int currently_reading:1;
int finished_reading:1;
int is_tmc_device:1; /* This is a TMC, as opposed to e.g. a classic ETB */
/* For pre-TMC ETBs, the read and write pointers address words within
the buffer RAM - for CoreSight ETBs the buffer is always 32-bit RAM,
so the pointers are scaled by 4. Only very old pre-CoreSight ETBs
have other RAM sizes and a RAM width register. */
#define ETB_WIDTH_SCALE_SHIFT 2
int pointer_scale_shift:4;
struct tmc_props {
/* Use the CS_TMC_CONFIG_TYPE_XYZ macros to interpret the config_type field */
unsigned int config_type:2; /* Build-time TMC configuration (ETR, ETF, ETB) */
unsigned int memory_width:4; /* Memory width: 2 for 32b up to 5 for 256b */
} tmc;
} etb;
struct itm_props {
unsigned int n_ports;
} itm;
struct stm_props {
unsigned int n_ports;
unsigned int n_masters;
unsigned int current_master;
unsigned char **ext_ports; /**< array of pointers to mappings of master ports. */
int basic_ports:1;
stm_static_config_t s_config; /**< RO features registers */
} stm;
struct ts_gen_props {
cs_ts_gen_config_t config;
} ts;
} v;
};
#define IS_V8(dev) (dev->v.debug.debug_arch == 0x8)
/*
We maintain a list of addresses not to be probed, to avoid bus lockups.
*/
struct addr_exclude {
struct addr_exclude *next;
cs_physaddr_t from;
cs_physaddr_t to;
};
/*
Global information for the system.
Currently "scope of management of CoreSight library" <= "SoC". I.e. there is
no provision for the library managing multiple SoCs, or multiple physical memory
spaces etc.
*/
struct global {
struct cs_device *device_top;
#ifdef UNIX_USERSPACE
int mem_fd; /**< File handle for the memory mapped I/O */
#endif /* UNIX_USERSPACE */
int init_called:1;
int registration_open:1;
int force_writes:1;
int diag_tracing_default:1; /**< Default trace setting for new devices */
int diag_checking:1; /**< Default diag setting for new devices */
unsigned int n_api_errors;
unsigned int n_devices;
cs_power_domain_t power_domain_default;
struct cs_device *timestamp_device;
struct addr_exclude *exclusions;
int phys_addr_lpae:1; /* 1 if built with LPAE */
int virt_addr_64bit:1; /* 1 if built with 64 bit virtual addresses */
int devaff0_used:1; /* Non-zero DEVAFF0 has been seen */
};
/**
* Convert an opaque device descriptor into a pointer to a device structure
*/
#define DEV(d) cs_get_device_struct(d)
/**
* Convert a pointer to a device structure into an opaque device descriptor
*/
#define DEVDESC(d) ((void *)(d))
/**
* The special opaque device descriptor indicating an error
*/
#define ERRDESC ((void *)0)
#ifdef DIAG
#define DTRACE(d) ((d)->diag_tracing || G.diag_tracing_default)
#define DTRACEG (G.diag_tracing_default)
#else /* !DIAG */
#define DTRACE(d) 0
#define DTRACEG 0
#endif /* DIAG */
/*
DCHECK() defines whether extra checks are done on the device.
*/
#if CHECK
#define DCHECK(d) (G.diag_checking)
#else /* !CHECK */
#define DCHECK(d) 0
#endif /* CHECK */
#ifdef UNIX_USERSPACE
/*
Check that the offset argument to mmap() is wide enough that we can map any
physical address in /dev/mem. This might need us to define _FILE_OFFSET_BITS=64.
*/
typedef int check_mmap_offset_is_big_enough[1 /
(sizeof(off_t) >=
sizeof(cs_physaddr_t))];
#endif /* UNIX_USERSPACE */
#ifdef UNIX_KERNEL
#undef DIAG
#endif
#ifdef DIAG
#ifdef UNIX_KERNEL
#define diagf printk
#else
#define diagf _diagf
extern void _diagf(char const *s, ...);
#endif
#else /* !DIAG */
void diagf(char const *s, ...)
{
}
#endif /* DIAG */
/*
This is the "physical address" value for a non-memory-mapped device, e.g.
a replicator, that is represented for topology reasons
*/
#define CS_NO_PHYS_ADDR 1
/*
Coresight devices must be aligned on a 4K page - this may be the case even
if the OS kernel is using larger pages. (We then have to get creative
with memory mappings.)
*/
#define is_4k_page_address(x) (((x) & 0xfff) == 0)
/* Claim tag handling constants */
#define CS_CLAIM_EXTERNAL 0x01
#define CS_CLAIM_INTERNAL 0x02
#define CS_CLAIM_PMU_EXTERNAL 0x04 /* PMU in use - in DBGCLAIM */
#define CS_CLAIM_PMU_INTERNAL 0x08
#define CS_CLAIM_CTI_EXTERNAL 0x10 /* CPU CTI in use - in DBGCLAIM */
#define CS_CLAIM_CTI_INTERNAL 0x20
/* Extern declarations - make common function implementations visible across all compilation
units, but not external API */
/* Non API functions implemented in cs_access_cmnfns.c */
/* data */
extern struct global G;
/* functions */
extern int cs_device_is_non_mmio(struct cs_device *d);
extern int cs_device_is_funnel(struct cs_device *d);
extern int cs_device_is_replicator(struct cs_device *d);
extern char const *cs_device_type_name(struct cs_device *d);
extern int cs_report_error(char const *fmt, ...);
extern int cs_report_device_error(struct cs_device *d, char const *fmt,
...);
extern struct cs_device *cs_get_device_struct(cs_device_t dev);
extern struct cs_device *cs_device_new(cs_physaddr_t addr,
void volatile *local_addr);
extern unsigned int volatile *_cs_get_register_address(struct cs_device *d,
unsigned int off);
extern unsigned int _cs_read(struct cs_device *d, unsigned int off);
extern unsigned long long _cs_read64(struct cs_device *d,
unsigned int off);
extern int _cs_write_wo(struct cs_device *d, unsigned int off,
unsigned int data);
extern int _cs_write64_wo(struct cs_device *d, unsigned int off,
unsigned long long data);
extern int _cs_write_traced(struct cs_device *d, unsigned int off,
unsigned int data, char const *oname);
extern int _cs_write64_traced(struct cs_device *d, unsigned int off,
unsigned long long data, char const *oname);
extern int _cs_write_mask(struct cs_device *d, unsigned int off,
unsigned int mask, unsigned int data);
extern int _cs_set_mask(struct cs_device *d, unsigned int off,
unsigned int mask, unsigned int data);
extern int _cs_set_bit(struct cs_device *d, unsigned int off,
unsigned int mask, int value);
extern int _cs_set(struct cs_device *d, unsigned int off,
unsigned int bits);
extern int _cs_set_wo(struct cs_device *d, unsigned int off,
unsigned int bits);
extern int _cs_clear(struct cs_device *d, unsigned int off,
unsigned int bits);
extern int _cs_isset(struct cs_device *d, unsigned int off,
unsigned int bits);
extern void _cs_set_wait_iterations(int iterations);
extern int _cs_wait(struct cs_device *d, unsigned int off,
unsigned int bit);
extern int _cs_waitnot(struct cs_device *d, unsigned int off,
unsigned int bit);
extern int _cs_waitbits(struct cs_device *d, unsigned int off,
unsigned int bits, cs_reg_waitbits_op_t operation,
unsigned int pattern, unsigned int *p_last_val);
extern int _cs_claim(struct cs_device *d, unsigned int bit);
extern int _cs_unclaim(struct cs_device *d, unsigned int bit);
extern int _cs_isclaimed(struct cs_device *d, unsigned int bit);
extern int _cs_isunlocked(struct cs_device *d);
extern void _cs_unlock(struct cs_device *d);
extern void _cs_lock(struct cs_device *d);
extern void *io_map(cs_physaddr_t addr, unsigned int size, int writable);
extern void io_unmap(void *addr, unsigned int size);
#define _cs_write(d, off, data) _cs_write_traced(d, off, data, #off)
#define _cs_write64(d, off, data) _cs_write64_traced(d, off, data, #off)
/* Non API fns in cs_sw_stim.c */
extern unsigned int cs_stm_get_ext_ports_size(struct cs_device *d);
extern int _cs_swstim_trace_enable(struct cs_device *d);
extern int _cs_swstim_trace_disable(struct cs_device *d);
extern int _cs_swstim_set_trace_id(struct cs_device *d, cs_atid_t id);
extern int _cs_stm_config_static_init(struct cs_device *d);
/* Non API fns in cs_etm.c */
extern unsigned int _cs_etm_version(struct cs_device *d);
extern int _cs_etm_enable_programming(struct cs_device *d);
extern int _cs_etm_disable_programming(struct cs_device *d);
extern int _cs_etm_static_config_init(struct cs_device *d);
/* none API fns in cs_ts_gen.c */
extern int _cs_tsgen_enable(struct cs_device *d, int enable);
#endif /* _included_cs_access_cmnfns_h */
/* end of cs_access_cmnfns.h */