summaryrefslogtreecommitdiffstats
path: root/libpdbg/libpdbg.h
blob: 4fad15846fafa67cd18818c31a151838fba58119 (plain)
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
#ifndef __LIBPDBG_H
#define __LIBPDBG_H

#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdarg.h>

#include <stdbool.h>

#ifdef __cplusplus
extern "C" {
#endif

struct pdbg_target;
struct pdbg_target_class;

/* loops/iterators */
struct pdbg_target *__pdbg_next_compatible_node(struct pdbg_target *root,
                                                struct pdbg_target *prev,
                                                const char *compat);
struct pdbg_target *__pdbg_next_target(const char *klass, struct pdbg_target *parent, struct pdbg_target *last);
struct pdbg_target *__pdbg_next_child_target(struct pdbg_target *parent, struct pdbg_target *last);

/*
 * Each target has a status associated with it. This is what each status means:
 *
 * enabled     - the target exists and has been probed, will be released by
 *               the release call.
 *
 * disabled    - the target has not been probed and will never be probed. Target
 *               selection code may use this to prevent probing of certain
 *               targets if it knows they are unnecessary.
 *
 * nonexistant - the target has been probed but did not exist. It will never be
 *               reprobed.
 *
 * unknown     - the target has not been probed but will be probed if required.
 *
 * mustexist   - the target has not been probed but an error will be reported if
 *               it does not exist as it is required for correct operation.
 *               Selection code may set this.
 *
 * released    - the target was enabled and has now been released.
 *
 * Initially these properties are read from the device tree. This allows the
 * client application to select which targets it does not care about to avoid
 * unneccessary probing by marking them disabled. If no status property exists
 * it defaults to "unknown".
 */
enum pdbg_target_status {PDBG_TARGET_UNKNOWN = 0, PDBG_TARGET_ENABLED,
			 PDBG_TARGET_DISABLED, PDBG_TARGET_MUSTEXIST,
			 PDBG_TARGET_NONEXISTENT, PDBG_TARGET_RELEASED};

#define pdbg_for_each_compatible(parent, target, compat)		\
        for (target = NULL;                                             \
             (target = __pdbg_next_compatible_node(parent, target, compat)) != NULL;)

#define pdbg_for_each_target(class, parent, target)			\
	for (target = __pdbg_next_target(class, parent, NULL);		\
	     target;							\
	     target = __pdbg_next_target(class, parent, target))

#define pdbg_for_each_class_target(class, target)		\
	for (target = __pdbg_next_target(class, NULL, NULL);	\
	     target;						\
	     target = __pdbg_next_target(class, NULL, target))

#define pdbg_for_each_child_target(parent, target)	      \
	for (target = __pdbg_next_child_target(parent, NULL); \
	     target;					      \
	     target = __pdbg_next_child_target(parent, target))

/* Return the first parent target of the given class, or NULL if the given
 * target does not have a parent of the given class. */
struct pdbg_target *pdbg_target_parent(const char *klass, struct pdbg_target *target);

/* Same as above but instead of returning NULL causes an assert failure. */
struct pdbg_target *pdbg_target_require_parent(const char *klass, struct pdbg_target *target);

/* Set the given property. Will automatically add one if one doesn't exist */
void pdbg_target_set_property(struct pdbg_target *target, const char *name, const void *val, size_t size);

/* Get the given property and return the size */
void *pdbg_target_property(struct pdbg_target *target, const char *name, size_t *size);
int pdbg_target_u32_property(struct pdbg_target *target, const char *name, uint32_t *val);
int pdbg_target_u32_index(struct pdbg_target *target, const char *name, int index, uint32_t *val);
uint64_t pdbg_target_address(struct pdbg_target *target, uint64_t *size);

/* Old deprecated for names for the above. Do not use for new projects
 * as these will be removed at some future point. */
#define pdbg_set_target_property(target, name, val, size)	\
	pdbg_target_set_property(target, name, val, size)
#define pdbg_get_target_property(target, name, size) \
	pdbg_target_property(target, name, size)
#define pdbg_get_address(target, index, size) \
	(index == 0 ? pdbg_target_address(target, size) : assert(0))

/* Misc. */
void pdbg_targets_init(void *fdt);
void pdbg_target_probe_all(struct pdbg_target *parent);
enum pdbg_target_status pdbg_target_probe(struct pdbg_target *target);
void pdbg_target_release(struct pdbg_target *target);
enum pdbg_target_status pdbg_target_status(struct pdbg_target *target);
void pdbg_target_status_set(struct pdbg_target *target, enum pdbg_target_status status);
uint32_t pdbg_target_index(struct pdbg_target *target);
char *pdbg_target_path(const struct pdbg_target *target);
struct pdbg_target *pdbg_target_from_path(struct pdbg_target *target, const char *path);
uint32_t pdbg_parent_index(struct pdbg_target *target, char *klass);
char *pdbg_target_class_name(struct pdbg_target *target);
char *pdbg_target_name(struct pdbg_target *target);
const char *pdbg_target_dn_name(struct pdbg_target *target);
void *pdbg_target_priv(struct pdbg_target *target);
void pdbg_target_priv_set(struct pdbg_target *target, void *priv);
struct pdbg_target *pdbg_target_root(void);
bool pdbg_target_compatible(struct pdbg_target *target, const char *compatible);

/* Translate an address offset for a target to absolute address in address
 * space of a "base" target.  */
struct pdbg_target *pdbg_address_absolute(struct pdbg_target *target, uint64_t *addr);

/* Procedures */
int fsi_read(struct pdbg_target *target, uint32_t addr, uint32_t *val);
int fsi_write(struct pdbg_target *target, uint32_t addr, uint32_t val);

int pib_read(struct pdbg_target *target, uint64_t addr, uint64_t *val);
int pib_write(struct pdbg_target *target, uint64_t addr, uint64_t val);
int pib_wait(struct pdbg_target *pib_dt, uint64_t addr, uint64_t mask, uint64_t data);

struct thread_regs {
	uint64_t nia;
	uint64_t msr;
	uint64_t cfar;
	uint64_t lr;
	uint64_t ctr;
	uint64_t tar;
	uint32_t cr;
	uint64_t xer;
	uint64_t gprs[32];

	uint64_t lpcr;
	uint64_t ptcr;
	uint64_t lpidr;
	uint64_t pidr;
	uint64_t hfscr;
	uint32_t hdsisr;
	uint64_t hdar;
	uint64_t hsrr0;
	uint64_t hsrr1;
	uint64_t hdec;
	uint32_t heir;
	uint64_t hid;
	uint64_t hsprg0;
	uint64_t hsprg1;
	uint64_t fscr;
	uint32_t dsisr;
	uint64_t dar;
	uint64_t srr0;
	uint64_t srr1;
	uint64_t dec;
	uint64_t tb;
	uint64_t sprg0;
	uint64_t sprg1;
	uint64_t sprg2;
	uint64_t sprg3;
	uint64_t ppr;
};

int ram_putmsr(struct pdbg_target *target, uint64_t val);
int ram_getmem(struct pdbg_target *thread, uint64_t addr, uint64_t *value);
int ram_putnia(struct pdbg_target *target, uint64_t val);
int ram_putspr(struct pdbg_target *target, int spr, uint64_t val);
int ram_putgpr(struct pdbg_target *target, int spr, uint64_t val);
int ram_getmsr(struct pdbg_target *target, uint64_t *val);
int ram_getcr(struct pdbg_target *thread,  uint32_t *value);
int ram_putcr(struct pdbg_target *thread,  uint32_t value);
int ram_getnia(struct pdbg_target *target, uint64_t *val);
int ram_getspr(struct pdbg_target *target, int spr, uint64_t *val);
int ram_getgpr(struct pdbg_target *target, int gpr, uint64_t *val);
int ram_start_thread(struct pdbg_target *target);
int ram_step_thread(struct pdbg_target *target, int steps);
int ram_stop_thread(struct pdbg_target *target);
int ram_sreset_thread(struct pdbg_target *target);
int ram_state_thread(struct pdbg_target *target, struct thread_regs *regs);
struct thread_state thread_status(struct pdbg_target *target);
int ram_getxer(struct pdbg_target *thread, uint64_t *value);
int ram_putxer(struct pdbg_target *thread, uint64_t value);
int getring(struct pdbg_target *chiplet_target, uint64_t ring_addr, uint64_t ring_len, uint32_t result[]);

enum pdbg_sleep_state {PDBG_THREAD_STATE_RUN, PDBG_THREAD_STATE_DOZE,
		       PDBG_THREAD_STATE_NAP, PDBG_THREAD_STATE_SLEEP,
		       PDBG_THREAD_STATE_STOP};

enum pdbg_smt_state {PDBG_SMT_UNKNOWN, PDBG_SMT_1, PDBG_SMT_2, PDBG_SMT_4, PDBG_SMT_8};

struct thread_state {
	bool active;
	bool quiesced;
	enum pdbg_sleep_state sleep_state;
	enum pdbg_smt_state smt_state;
};

int htm_start(struct pdbg_target *target);
int htm_stop(struct pdbg_target *target);
int htm_status(struct pdbg_target *target);
int htm_dump(struct pdbg_target *target, char *filename);
int htm_record(struct pdbg_target *target, char *filename);

int adu_getmem(struct pdbg_target *target, uint64_t addr,
	       uint8_t *ouput, uint64_t size);
int adu_putmem(struct pdbg_target *target, uint64_t addr,
	       uint8_t *input, uint64_t size);
int adu_getmem_ci(struct pdbg_target *target, uint64_t addr,
		  uint8_t *ouput, uint64_t size);
int adu_putmem_ci(struct pdbg_target *target, uint64_t addr,
		  uint8_t *input, uint64_t size);
int adu_getmem_io(struct pdbg_target *adu_target, uint64_t start_addr,
		  uint8_t *output, uint64_t size, uint8_t blocksize);
int adu_putmem_io(struct pdbg_target *adu_target, uint64_t start_addr,
		  uint8_t *input, uint64_t size, uint8_t block_size);
int __adu_getmem(struct pdbg_target *target, uint64_t addr, uint8_t *ouput,
		 uint64_t size, bool ci);
int __adu_putmem(struct pdbg_target *target, uint64_t addr, uint8_t *input,
		 uint64_t size, bool ci);

int mem_read(struct pdbg_target *target, uint64_t addr, uint8_t *output, uint64_t size, uint8_t block_size, bool ci);
int mem_write(struct pdbg_target *target, uint64_t addr, uint8_t *input, uint64_t size, uint8_t block_size, bool ci);

int opb_read(struct pdbg_target *target, uint32_t addr, uint32_t *data);
int opb_write(struct pdbg_target *target, uint32_t addr, uint32_t data);

typedef void (*pdbg_progress_tick_t)(uint64_t cur, uint64_t end);

void pdbg_set_progress_tick(pdbg_progress_tick_t fn);
void pdbg_progress_tick(uint64_t cur, uint64_t end);

#define PDBG_ERROR	0
#define PDBG_WARNING	1
#define PDBG_NOTICE	2
#define PDBG_INFO	3
#define PDBG_DEBUG	4

typedef void (*pdbg_log_func_t)(int loglevel, const char *fmt, va_list ap);

void pdbg_set_logfunc(pdbg_log_func_t fn);
void pdbg_set_loglevel(int loglevel);
void pdbg_log(int loglevel, const char *fmt, ...);

#ifdef __cplusplus
}
#endif

#endif
OpenPOWER on IntegriCloud