]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blame - arch/powerpc/platforms/cell/spufs/spufs.h
treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 153
[mirror_ubuntu-hirsute-kernel.git] / arch / powerpc / platforms / cell / spufs / spufs.h
CommitLineData
de6cc651 1/* SPDX-License-Identifier: GPL-2.0-or-later */
67207b96
AB
2/*
3 * SPU file system
4 *
5 * (C) Copyright IBM Deutschland Entwicklung GmbH 2005
6 *
7 * Author: Arnd Bergmann <arndb@de.ibm.com>
67207b96
AB
8 */
9#ifndef SPUFS_H
10#define SPUFS_H
11
12#include <linux/kref.h>
650f8b02 13#include <linux/mutex.h>
67207b96
AB
14#include <linux/spinlock.h>
15#include <linux/fs.h>
ea1ae594 16#include <linux/cpumask.h>
174cd4b1 17#include <linux/sched/signal.h>
67207b96
AB
18
19#include <asm/spu.h>
5473af04 20#include <asm/spu_csa.h>
b9e3bd77 21#include <asm/spu_info.h>
67207b96 22
87ff6090
JK
23#define SPUFS_PS_MAP_SIZE 0x20000
24#define SPUFS_MFC_MAP_SIZE 0x1000
25#define SPUFS_CNTL_MAP_SIZE 0x1000
87ff6090
JK
26#define SPUFS_SIGNAL_MAP_SIZE PAGE_SIZE
27#define SPUFS_MSS_MAP_SIZE 0x1000
28
67207b96
AB
29/* The magic number for our file system */
30enum {
31 SPUFS_MAGIC = 0x23c9b64e,
32};
33
8b3d6663 34struct spu_context_ops;
6263203e
AB
35struct spu_gang;
36
36aaccc1
BN
37/* ctx->sched_flags */
38enum {
39 SPU_SCHED_NOTIFY_ACTIVE,
b2c863bd 40 SPU_SCHED_WAS_ACTIVE, /* was active upon spu_acquire_saved() */
ce7c191b 41 SPU_SCHED_SPU_RUN, /* context is within spu_run */
36aaccc1
BN
42};
43
5158e9b5
CH
44enum {
45 SWITCH_LOG_BUFSIZE = 4096,
46};
47
48enum {
49 SWITCH_LOG_START,
50 SWITCH_LOG_STOP,
51 SWITCH_LOG_EXIT,
52};
53
54struct switch_log {
5158e9b5
CH
55 wait_queue_head_t wait;
56 unsigned long head;
57 unsigned long tail;
58 struct switch_log_entry {
cef37ac1 59 struct timespec64 tstamp;
5158e9b5
CH
60 s32 spu_id;
61 u32 type;
62 u32 val;
63 u64 timebase;
64 } log[];
65};
66
67207b96
AB
67struct spu_context {
68 struct spu *spu; /* pointer to a physical SPU */
5473af04 69 struct spu_state csa; /* SPU context save area. */
67207b96 70 spinlock_t mmio_lock; /* protects mmio access */
6df10a82
MN
71 struct address_space *local_store; /* local store mapping. */
72 struct address_space *mfc; /* 'mfc' area mappings. */
43c2bbd9
CH
73 struct address_space *cntl; /* 'control' area mappings. */
74 struct address_space *signal1; /* 'signal1' area mappings. */
75 struct address_space *signal2; /* 'signal2' area mappings. */
76 struct address_space *mss; /* 'mss' area mappings. */
77 struct address_space *psmap; /* 'psmap' area mappings. */
47d3a5fa 78 struct mutex mapping_lock;
86767277 79 u64 object_id; /* user space pointer for oprofile */
8b3d6663
AB
80
81 enum { SPU_STATE_RUNNABLE, SPU_STATE_SAVED } state;
650f8b02 82 struct mutex state_mutex;
e45d48a3 83 struct mutex run_mutex;
8b3d6663
AB
84
85 struct mm_struct *owner;
67207b96
AB
86
87 struct kref kref;
8b3d6663
AB
88 wait_queue_head_t ibox_wq;
89 wait_queue_head_t wbox_wq;
5110459f 90 wait_queue_head_t stop_wq;
a33a7d73 91 wait_queue_head_t mfc_wq;
33bfd7a7 92 wait_queue_head_t run_wq;
a33a7d73 93 u32 tagwait;
8b3d6663 94 struct spu_context_ops *ops;
2a911f0b 95 struct work_struct reap_work;
9add11da
AB
96 unsigned long flags;
97 unsigned long event_return;
6263203e
AB
98
99 struct list_head gang_list;
100 struct spu_gang *gang;
1474855d
BN
101 struct kref *prof_priv_kref;
102 void ( * prof_priv_release) (struct kref *kref);
8389998a 103
476273ad
CH
104 /* owner thread */
105 pid_t tid;
106
8389998a 107 /* scheduler fields */
7022543e 108 struct list_head rq;
37901802 109 unsigned int time_slice;
26bec673 110 unsigned long sched_flags;
ea1ae594 111 cpumask_t cpus_allowed;
2eb1b120 112 int policy;
8389998a 113 int prio;
7a214200 114 int last_ran;
e9f8a0b6
CH
115
116 /* statistics */
117 struct {
118 /* updates protected by ctx->state_mutex */
27ec41d3
AD
119 enum spu_utilization_state util_state;
120 unsigned long long tstamp; /* time of last state switch */
121 unsigned long long times[SPU_UTIL_MAX];
e9f8a0b6
CH
122 unsigned long long vol_ctx_switch;
123 unsigned long long invol_ctx_switch;
124 unsigned long long min_flt;
125 unsigned long long maj_flt;
126 unsigned long long hash_flt;
127 unsigned long long slb_flt;
128 unsigned long long slb_flt_base; /* # at last ctx switch */
129 unsigned long long class2_intr;
130 unsigned long long class2_intr_base; /* # at last ctx switch */
131 unsigned long long libassist;
132 } stats;
8e68e2f2 133
5158e9b5
CH
134 /* context switch log */
135 struct switch_log *switch_log;
136
8e68e2f2
AB
137 struct list_head aff_list;
138 int aff_head;
c5fc8d2a 139 int aff_offset;
6263203e
AB
140};
141
142struct spu_gang {
143 struct list_head list;
144 struct mutex mutex;
145 struct kref kref;
146 int contexts;
8e68e2f2
AB
147
148 struct spu_context *aff_ref_ctx;
149 struct list_head aff_list_head;
150 struct mutex aff_mutex;
151 int aff_flags;
c5fc8d2a
AB
152 struct spu *aff_ref_spu;
153 atomic_t aff_sched_count;
8b3d6663
AB
154};
155
8e68e2f2
AB
156/* Flag bits for spu_gang aff_flags */
157#define AFF_OFFSETS_SET 1
158#define AFF_MERGED 2
159
a33a7d73
AB
160struct mfc_dma_command {
161 int32_t pad; /* reserved */
162 uint32_t lsa; /* local storage address */
163 uint64_t ea; /* effective address */
164 uint16_t size; /* transfer size */
165 uint16_t tag; /* command tag */
166 uint16_t class; /* class ID */
167 uint16_t cmd; /* command opcode */
168};
169
170
8b3d6663
AB
171/* SPU context query/set operations. */
172struct spu_context_ops {
173 int (*mbox_read) (struct spu_context * ctx, u32 * data);
174 u32(*mbox_stat_read) (struct spu_context * ctx);
8153a5ea 175 __poll_t (*mbox_stat_poll)(struct spu_context *ctx, __poll_t events);
8b3d6663
AB
176 int (*ibox_read) (struct spu_context * ctx, u32 * data);
177 int (*wbox_write) (struct spu_context * ctx, u32 data);
178 u32(*signal1_read) (struct spu_context * ctx);
179 void (*signal1_write) (struct spu_context * ctx, u32 data);
180 u32(*signal2_read) (struct spu_context * ctx);
181 void (*signal2_write) (struct spu_context * ctx, u32 data);
182 void (*signal1_type_set) (struct spu_context * ctx, u64 val);
183 u64(*signal1_type_get) (struct spu_context * ctx);
184 void (*signal2_type_set) (struct spu_context * ctx, u64 val);
185 u64(*signal2_type_get) (struct spu_context * ctx);
186 u32(*npc_read) (struct spu_context * ctx);
187 void (*npc_write) (struct spu_context * ctx, u32 data);
188 u32(*status_read) (struct spu_context * ctx);
189 char*(*get_ls) (struct spu_context * ctx);
cc210b3e 190 void (*privcntl_write) (struct spu_context *ctx, u64 data);
3960c260 191 u32 (*runcntl_read) (struct spu_context * ctx);
5110459f 192 void (*runcntl_write) (struct spu_context * ctx, u32 data);
c25620d7 193 void (*runcntl_stop) (struct spu_context * ctx);
ee2d7340
AB
194 void (*master_start) (struct spu_context * ctx);
195 void (*master_stop) (struct spu_context * ctx);
a33a7d73
AB
196 int (*set_mfc_query)(struct spu_context * ctx, u32 mask, u32 mode);
197 u32 (*read_mfc_tagstatus)(struct spu_context * ctx);
198 u32 (*get_mfc_free_elements)(struct spu_context *ctx);
b9e3bd77
DGM
199 int (*send_mfc_command)(struct spu_context * ctx,
200 struct mfc_dma_command * cmd);
201 void (*dma_info_read) (struct spu_context * ctx,
202 struct spu_dma_info * info);
203 void (*proxydma_info_read) (struct spu_context * ctx,
204 struct spu_proxydma_info * info);
57dace23 205 void (*restart_dma)(struct spu_context *ctx);
67207b96
AB
206};
207
8b3d6663
AB
208extern struct spu_context_ops spu_hw_ops;
209extern struct spu_context_ops spu_backing_ops;
210
67207b96
AB
211struct spufs_inode_info {
212 struct spu_context *i_ctx;
6263203e 213 struct spu_gang *i_gang;
67207b96 214 struct inode vfs_inode;
43c2bbd9 215 int i_openers;
67207b96
AB
216};
217#define SPUFS_I(inode) \
218 container_of(inode, struct spufs_inode_info, vfs_inode)
219
23d893f5
JK
220struct spufs_tree_descr {
221 const char *name;
222 const struct file_operations *ops;
c6684b26 223 umode_t mode;
23d893f5
JK
224 size_t size;
225};
226
74254647
JK
227extern const struct spufs_tree_descr spufs_dir_contents[];
228extern const struct spufs_tree_descr spufs_dir_nosched_contents[];
229extern const struct spufs_tree_descr spufs_dir_debug_contents[];
67207b96
AB
230
231/* system call implementation */
98f06978 232extern struct spufs_calls spufs_calls;
cdc3d562 233struct coredump_params;
50af32a9 234long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *status);
1ba10681 235long spufs_create(struct path *nd, struct dentry *dentry, unsigned int flags,
c6684b26 236 umode_t mode, struct file *filp);
48cad41f
ME
237/* ELF coredump callbacks for writing SPU ELF notes */
238extern int spufs_coredump_extra_notes_size(void);
cdc3d562 239extern int spufs_coredump_extra_notes_write(struct coredump_params *cprm);
48cad41f 240
9c2e08c5 241extern const struct file_operations spufs_context_fops;
67207b96 242
6263203e
AB
243/* gang management */
244struct spu_gang *alloc_spu_gang(void);
245struct spu_gang *get_spu_gang(struct spu_gang *gang);
246int put_spu_gang(struct spu_gang *gang);
247void spu_gang_remove_ctx(struct spu_gang *gang, struct spu_context *ctx);
248void spu_gang_add_ctx(struct spu_gang *gang, struct spu_context *ctx);
249
57dace23
AB
250/* fault handling */
251int spufs_handle_class1(struct spu_context *ctx);
d6ad39bc 252int spufs_handle_class0(struct spu_context *ctx);
57dace23 253
c5fc8d2a
AB
254/* affinity */
255struct spu *affinity_check(struct spu_context *ctx);
256
67207b96 257/* context management */
65de66f0 258extern atomic_t nr_spu_contexts;
c9101bdb 259static inline int __must_check spu_acquire(struct spu_context *ctx)
6a0641e5 260{
c9101bdb 261 return mutex_lock_interruptible(&ctx->state_mutex);
6a0641e5
CH
262}
263
264static inline void spu_release(struct spu_context *ctx)
265{
266 mutex_unlock(&ctx->state_mutex);
267}
268
6263203e 269struct spu_context * alloc_spu_context(struct spu_gang *gang);
67207b96
AB
270void destroy_spu_context(struct kref *kref);
271struct spu_context * get_spu_context(struct spu_context *ctx);
272int put_spu_context(struct spu_context *ctx);
5110459f 273void spu_unmap_mappings(struct spu_context *ctx);
67207b96 274
8b3d6663 275void spu_forget(struct spu_context *ctx);
c9101bdb 276int __must_check spu_acquire_saved(struct spu_context *ctx);
27b1ea09 277void spu_release_saved(struct spu_context *ctx);
50b520d4 278
e65c2f6f
LB
279int spu_stopped(struct spu_context *ctx, u32 * stat);
280void spu_del_from_rq(struct spu_context *ctx);
26bec673 281int spu_activate(struct spu_context *ctx, unsigned long flags);
8b3d6663
AB
282void spu_deactivate(struct spu_context *ctx);
283void spu_yield(struct spu_context *ctx);
36aaccc1 284void spu_switch_notify(struct spu *spu, struct spu_context *ctx);
5158e9b5
CH
285void spu_switch_log_notify(struct spu *spu, struct spu_context *ctx,
286 u32 type, u32 val);
fe443ef2 287void spu_set_timeslice(struct spu_context *ctx);
2cf2b3b4
CH
288void spu_update_sched_info(struct spu_context *ctx);
289void __spu_update_sched_info(struct spu_context *ctx);
8b3d6663 290int __init spu_sched_init(void);
d1450317 291void spu_sched_exit(void);
8b3d6663 292
c6730ed4
JK
293extern char *isolated_loader;
294
ce8ab854
AB
295/*
296 * spufs_wait
7022543e 297 * Same as wait_event_interruptible(), except that here
ce8ab854
AB
298 * we need to call spu_release(ctx) before sleeping, and
299 * then spu_acquire(ctx) when awoken.
eebead5b 300 *
73ac36ea 301 * Returns with state_mutex re-acquired when successful or
eebead5b 302 * with -ERESTARTSYS and the state_mutex dropped when interrupted.
ce8ab854
AB
303 */
304
305#define spufs_wait(wq, condition) \
306({ \
307 int __ret = 0; \
308 DEFINE_WAIT(__wait); \
309 for (;;) { \
310 prepare_to_wait(&(wq), &__wait, TASK_INTERRUPTIBLE); \
311 if (condition) \
312 break; \
eebead5b 313 spu_release(ctx); \
d3764397
JK
314 if (signal_pending(current)) { \
315 __ret = -ERESTARTSYS; \
316 break; \
ce8ab854 317 } \
d3764397 318 schedule(); \
c9101bdb
CH
319 __ret = spu_acquire(ctx); \
320 if (__ret) \
321 break; \
ce8ab854
AB
322 } \
323 finish_wait(&(wq), &__wait); \
324 __ret; \
325})
326
8b3d6663
AB
327size_t spu_wbox_write(struct spu_context *ctx, u32 data);
328size_t spu_ibox_read(struct spu_context *ctx, u32 *data);
329
330/* irq callback funcs. */
331void spufs_ibox_callback(struct spu *spu);
332void spufs_wbox_callback(struct spu *spu);
f3d69e05 333void spufs_stop_callback(struct spu *spu, int irq);
a33a7d73 334void spufs_mfc_callback(struct spu *spu);
9add11da 335void spufs_dma_callback(struct spu *spu, int type);
8b3d6663 336
bf1ab978
DGM
337extern struct spu_coredump_calls spufs_coredump_calls;
338struct spufs_coredump_reader {
339 char *name;
340 ssize_t (*read)(struct spu_context *ctx,
341 char __user *buffer, size_t size, loff_t *pos);
74de08bc 342 u64 (*get)(struct spu_context *ctx);
bf1ab978
DGM
343 size_t size;
344};
74254647 345extern const struct spufs_coredump_reader spufs_coredump_read[];
bf1ab978
DGM
346extern int spufs_coredump_num_notes;
347
7cd58e43
JK
348extern int spu_init_csa(struct spu_state *csa);
349extern void spu_fini_csa(struct spu_state *csa);
350extern int spu_save(struct spu_state *prev, struct spu *spu);
351extern int spu_restore(struct spu_state *new, struct spu *spu);
352extern int spu_switch(struct spu_state *prev, struct spu_state *new,
353 struct spu *spu);
354extern int spu_alloc_lscsa(struct spu_state *csa);
355extern void spu_free_lscsa(struct spu_state *csa);
356
357extern void spuctx_switch_state(struct spu_context *ctx,
358 enum spu_utilization_state new_state);
fe2f896d 359
67207b96 360#endif