summaryrefslogtreecommitdiff
path: root/gxp-core-telemetry.h
blob: 0ceeb606bc7387e6b43bff4d38b56d97371705b7 (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
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * GXP core telemetry support
 *
 * Copyright (C) 2021-2022 Google LLC
 */

#ifndef __GXP_CORE_TELEMETRY_H__
#define __GXP_CORE_TELEMETRY_H__

#include <linux/eventfd.h>
#include <linux/refcount.h>
#include <linux/types.h>

#include "gxp-dma.h"
#include "gxp-internal.h"
#include "gxp.h"

/* Default telemetry buffer size per core */
#define CORE_TELEMETRY_DEFAULT_BUFFER_SIZE GXP_CORE_TELEMETRY_BUFFER_UNIT_SIZE
/**
 * Maximum core telemetry buffer size that can be represented by GXP_GET_SPECS
 * ioctl. 8 bits are reserved to represent telemetry buffer size in GXP_GET_SPECS
 * ioctl and the size is represented in unit of GXP_CORE_TELEMETRY_BUFFER_UNIT_SIZE.
 */
#define CORE_TELEMETRY_MAX_BUFFER_SIZE (U8_MAX * GXP_CORE_TELEMETRY_BUFFER_UNIT_SIZE)
/* Secure telemetry buffer size per core */
#define SECURE_CORE_TELEMETRY_BUFFER_SIZE GXP_CORE_TELEMETRY_BUFFER_UNIT_SIZE

struct gxp_core_telemetry_work {
	struct work_struct work;
	struct gxp_dev *gxp;
	uint core;
};

struct gxp_core_telemetry_manager {
	struct buffer_data {
		u32 host_status;
		struct gxp_coherent_buf buffers[GXP_NUM_CORES];
		u32 size;
		refcount_t ref_count;
		bool is_enabled;
	} *logging_buff_data_legacy, *tracing_buff_data_legacy,
	  *logging_buff_data, *tracing_buff_data;
	/* Protects logging_buff_data and tracing_buff_data */
	struct mutex lock;
	struct gxp_core_telemetry_work notification_works[GXP_NUM_CORES];
	wait_queue_head_t waitq;
	struct eventfd_ctx *logging_efd;
	struct eventfd_ctx *tracing_efd;
};

/**
 * gxp_core_telemetry_init() - Initialize telemetry support
 * @gxp: The GXP device to initialize core telemetry support for
 *
 * Return:
 * * 0       - Success
 * * -ENOMEM - Insufficient memory is available to initialize support
 */
int gxp_core_telemetry_init(struct gxp_dev *gxp);

/**
 * gxp_core_telemetry_mmap_buffers() - Maps the preallocated telemetry
 *                                     buffers to the user-space vma.
 * @gxp: The GXP device to create the buffers for.
 * @type: Either `GXP_TELEMETRY_TYPE_LOGGING` or `GXP_TELEMETRY_TYPE_TRACING`.
 * @vma: The vma from user-space which all cores' buffers will be mapped into.
 *
 * Return:
 * * 0       - Success.
 * * -ENODEV - Core telemetry support has not been initialized. Must explicitly
 *             check this, since this function is called based on user-input.
 * * -EINVAL - Either the vma size is not aligned or @type is not valid.
 */
int gxp_core_telemetry_mmap_buffers(struct gxp_dev *gxp, u8 type,
				    struct vm_area_struct *vma);

/**
 * gxp_core_telemetry_mmap_buffers_legacy() - Allocate a telemetry buffer for
 *                                            each core and map them to their
 *                                            core and the user-space vma
 * @gxp: The GXP device to create the buffers for
 * @type: EIther `GXP_TELEMETRY_TYPE_LOGGING` or `GXP_TELEMETRY_TYPE_TRACING`
 * @vma: The vma from user-space which all cores' buffers will be mapped into
 *
 * Return:
 * * 0       - Success
 * * -ENODEV - Core telemetry support has not been initialized. Must explicitly
 *             check this, since this function is called based on user-input.
 * * -EBUSY  - The requested core telemetry @type is already in use
 * * -EINVAL - Either the vma size is not aligned or @type is not valid
 * * -ENOMEM - Insufficient memory is available to allocate and map the buffers
 */
int gxp_core_telemetry_mmap_buffers_legacy(struct gxp_dev *gxp, u8 type,
                                           struct vm_area_struct *vma);

/**
 * gxp_core_telemetry_enable() - Enable logging or tracing for all DSP cores
 * @gxp: The GXP device to enable either logging or tracing for
 * @type: Either `GXP_TELEMETRY_TYPE_LOGGING` or `GXP_TELEMETRY_TYPE_TRACING`
 *
 * Return:
 * * 0       - Success
 * * -EINVAL - The @type provided is not valid
 * * -ENXIO  - Buffers for @type have not been created/mapped yet
 */
int gxp_core_telemetry_enable(struct gxp_dev *gxp, u8 type);

/**
 * gxp_core_telemetry_disable() - Disable logging or tracing for all DSP cores
 * @gxp: The GXP device to disable either logging or tracing for
 * @type: Either `GXP_TELEMETRY_TYPE_LOGGING` or `GXP_TELEMETRY_TYPE_TRACING`
 *
 * Return:
 * * 0       - Success
 * * -EINVAL - The @type provided is not valid
 * * -ENXIO  - Buffers for @type have not been created/mapped yet
 */
int gxp_core_telemetry_disable(struct gxp_dev *gxp, u8 type);

/**
 * gxp_core_telemetry_register_eventfd() - Register an eventfd to be signaled
 *                                         when core telemetry notifications
 *                                         arrive while the specified @type of
 *                                         core telemetry is enabled
 * @gxp: The GXP device to register the eventfd for
 * @type: Either `GXP_TELEMETRY_TYPE_LOGGING` or `GXP_TELEMETRY_TYPE_TRACING`
 * @fd: A file descriptor for an eventfd from user-space
 *
 * If another eventfd has already been registered for the given @type, the old
 * eventfd will be unregistered and replaced.
 *
 * Return:
 * * 0       - Success
 * * -EBADF  - @fd is not a valid file descriptor (via `eventfd_ctx_fdget()`)
 * * -EINVAL - Invalid @type or @fd is not an eventfd
 */
int gxp_core_telemetry_register_eventfd(struct gxp_dev *gxp, u8 type, int fd);

/**
 * gxp_core_telemetry_unregister_eventfd() - Unregister and release a reference
 *                                           to a previously registered eventfd
 * @gxp: The GXP device to unregister the eventfd for
 * @type: Either `GXP_TELEMETRY_TYPE_LOGGING` or `GXP_TELEMETRY_TYPE_TRACING`
 *
 * Return:
 * * 0       - Success
 * * -EINVAL - The @type provided is not valid
 */
int gxp_core_telemetry_unregister_eventfd(struct gxp_dev *gxp, u8 type);

/**
 * gxp_core_telemetry_get_notification_handler() - Get the notification handler
 *                                                 work for the specified core
 * @gxp: The GXP device to obtain the handler for
 * @core: The physical core number to obtain the handler
 *
 * Return: A pointer to the work_struct for the @core's notification handler if
 *         successful. NULL if core telemetry has not been initialized or @core
 *         is invalid.
 */
struct work_struct *
gxp_core_telemetry_get_notification_handler(struct gxp_dev *gxp, uint core);

/**
 * gxp_core_telemetry_status_notify() - Checks the telemetry status of the
 *                                      specified core and signals the eventfd.
 * @gxp: The GXP device to obtain the handler for
 * @core: The physical core number to obtain the handler
 *
 */
void gxp_core_telemetry_status_notify(struct gxp_dev *gxp, uint core);

/**
 * gxp_core_telemetry_exit() - Reverts gxp_core_telemetry_init() to release the
 *                             resources acquired by core telemetry manager.
 * @gxp: The GXP device to obtain the handler for
 *
 */
void gxp_core_telemetry_exit(struct gxp_dev *gxp);


#endif /* __GXP_CORE_TELEMETRY_H__ */