]> Git Repo - linux.git/blob - drivers/gpu/drm/imagination/pvr_device.h
Merge tag 'apparmor-pr-2024-07-25' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux.git] / drivers / gpu / drm / imagination / pvr_device.h
1 /* SPDX-License-Identifier: GPL-2.0-only OR MIT */
2 /* Copyright (c) 2023 Imagination Technologies Ltd. */
3
4 #ifndef PVR_DEVICE_H
5 #define PVR_DEVICE_H
6
7 #include "pvr_ccb.h"
8 #include "pvr_device_info.h"
9 #include "pvr_fw.h"
10 #include "pvr_params.h"
11 #include "pvr_rogue_fwif_stream.h"
12 #include "pvr_stream.h"
13
14 #include <drm/drm_device.h>
15 #include <drm/drm_file.h>
16 #include <drm/drm_mm.h>
17
18 #include <linux/bits.h>
19 #include <linux/compiler_attributes.h>
20 #include <linux/compiler_types.h>
21 #include <linux/io.h>
22 #include <linux/iopoll.h>
23 #include <linux/kernel.h>
24 #include <linux/math.h>
25 #include <linux/mutex.h>
26 #include <linux/timer.h>
27 #include <linux/types.h>
28 #include <linux/wait.h>
29 #include <linux/workqueue.h>
30 #include <linux/xarray.h>
31
32 /* Forward declaration from <linux/clk.h>. */
33 struct clk;
34
35 /* Forward declaration from <linux/firmware.h>. */
36 struct firmware;
37
38 /**
39  * struct pvr_gpu_id - Hardware GPU ID information for a PowerVR device
40  * @b: Branch ID.
41  * @v: Version ID.
42  * @n: Number of scalable units.
43  * @c: Config ID.
44  */
45 struct pvr_gpu_id {
46         u16 b, v, n, c;
47 };
48
49 /**
50  * struct pvr_fw_version - Firmware version information
51  * @major: Major version number.
52  * @minor: Minor version number.
53  */
54 struct pvr_fw_version {
55         u16 major, minor;
56 };
57
58 /**
59  * struct pvr_device - powervr-specific wrapper for &struct drm_device
60  */
61 struct pvr_device {
62         /**
63          * @base: The underlying &struct drm_device.
64          *
65          * Do not access this member directly, instead call
66          * from_pvr_device().
67          */
68         struct drm_device base;
69
70         /** @gpu_id: GPU ID detected at runtime. */
71         struct pvr_gpu_id gpu_id;
72
73         /**
74          * @features: Hardware feature information.
75          *
76          * Do not access this member directly, instead use PVR_HAS_FEATURE()
77          * or PVR_FEATURE_VALUE() macros.
78          */
79         struct pvr_device_features features;
80
81         /**
82          * @quirks: Hardware quirk information.
83          *
84          * Do not access this member directly, instead use PVR_HAS_QUIRK().
85          */
86         struct pvr_device_quirks quirks;
87
88         /**
89          * @enhancements: Hardware enhancement information.
90          *
91          * Do not access this member directly, instead use
92          * PVR_HAS_ENHANCEMENT().
93          */
94         struct pvr_device_enhancements enhancements;
95
96         /** @fw_version: Firmware version detected at runtime. */
97         struct pvr_fw_version fw_version;
98
99         /** @regs_resource: Resource representing device control registers. */
100         struct resource *regs_resource;
101
102         /**
103          * @regs: Device control registers.
104          *
105          * These are mapped into memory when the device is initialized; that
106          * location is where this pointer points.
107          */
108         void __iomem *regs;
109
110         /**
111          * @core_clk: General core clock.
112          *
113          * This is the primary clock used by the entire GPU core.
114          */
115         struct clk *core_clk;
116
117         /**
118          * @sys_clk: Optional system bus clock.
119          *
120          * This may be used on some platforms to provide an independent clock to the SoC Interface
121          * (SOCIF). If present, this needs to be enabled/disabled together with @core_clk.
122          */
123         struct clk *sys_clk;
124
125         /**
126          * @mem_clk: Optional memory clock.
127          *
128          * This may be used on some platforms to provide an independent clock to the Memory
129          * Interface (MEMIF). If present, this needs to be enabled/disabled together with @core_clk.
130          */
131         struct clk *mem_clk;
132
133         /** @irq: IRQ number. */
134         int irq;
135
136         /** @fwccb: Firmware CCB. */
137         struct pvr_ccb fwccb;
138
139         /**
140          * @kernel_vm_ctx: Virtual memory context used for kernel mappings.
141          *
142          * This is used for mappings in the firmware address region when a META firmware processor
143          * is in use.
144          *
145          * When a MIPS firmware processor is in use, this will be %NULL.
146          */
147         struct pvr_vm_context *kernel_vm_ctx;
148
149         /** @fw_dev: Firmware related data. */
150         struct pvr_fw_device fw_dev;
151
152         /**
153          * @params: Device-specific parameters.
154          *
155          *          The values of these parameters are initialized from the
156          *          defaults specified as module parameters. They may be
157          *          modified at runtime via debugfs (if enabled).
158          */
159         struct pvr_device_params params;
160
161         /** @stream_musthave_quirks: Bit array of "must-have" quirks for stream commands. */
162         u32 stream_musthave_quirks[PVR_STREAM_TYPE_MAX][PVR_STREAM_EXTHDR_TYPE_MAX];
163
164         /**
165          * @mmu_flush_cache_flags: Records which MMU caches require flushing
166          * before submitting the next job.
167          */
168         atomic_t mmu_flush_cache_flags;
169
170         /**
171          * @ctx_ids: Array of contexts belonging to this device. Array members
172          *           are of type "struct pvr_context *".
173          *
174          * This array is used to allocate IDs used by the firmware.
175          */
176         struct xarray ctx_ids;
177
178         /**
179          * @free_list_ids: Array of free lists belonging to this device. Array members
180          *                 are of type "struct pvr_free_list *".
181          *
182          * This array is used to allocate IDs used by the firmware.
183          */
184         struct xarray free_list_ids;
185
186         /**
187          * @job_ids: Array of jobs belonging to this device. Array members
188          *           are of type "struct pvr_job *".
189          */
190         struct xarray job_ids;
191
192         /**
193          * @queues: Queue-related fields.
194          */
195         struct {
196                 /** @queues.active: Active queue list. */
197                 struct list_head active;
198
199                 /** @queues.idle: Idle queue list. */
200                 struct list_head idle;
201
202                 /** @queues.lock: Lock protecting access to the active/idle
203                  *  lists. */
204                 struct mutex lock;
205         } queues;
206
207         /**
208          * @watchdog: Watchdog for communications with firmware.
209          */
210         struct {
211                 /** @watchdog.work: Work item for watchdog callback. */
212                 struct delayed_work work;
213
214                 /**
215                  * @watchdog.old_kccb_cmds_executed: KCCB command execution
216                  * count at last watchdog poll.
217                  */
218                 u32 old_kccb_cmds_executed;
219
220                 /**
221                  * @watchdog.kccb_stall_count: Number of watchdog polls
222                  * KCCB has been stalled for.
223                  */
224                 u32 kccb_stall_count;
225         } watchdog;
226
227         /**
228          * @kccb: Circular buffer for communications with firmware.
229          */
230         struct {
231                 /** @kccb.ccb: Kernel CCB. */
232                 struct pvr_ccb ccb;
233
234                 /** @kccb.rtn_q: Waitqueue for KCCB command return waiters. */
235                 wait_queue_head_t rtn_q;
236
237                 /** @kccb.rtn_obj: Object representing KCCB return slots. */
238                 struct pvr_fw_object *rtn_obj;
239
240                 /**
241                  * @kccb.rtn: Pointer to CPU mapping of KCCB return slots.
242                  * Must be accessed by READ_ONCE()/WRITE_ONCE().
243                  */
244                 u32 *rtn;
245
246                 /** @kccb.slot_count: Total number of KCCB slots available. */
247                 u32 slot_count;
248
249                 /** @kccb.reserved_count: Number of KCCB slots reserved for
250                  *  future use. */
251                 u32 reserved_count;
252
253                 /**
254                  * @kccb.waiters: List of KCCB slot waiters.
255                  */
256                 struct list_head waiters;
257
258                 /** @kccb.fence_ctx: KCCB fence context. */
259                 struct {
260                         /** @kccb.fence_ctx.id: KCCB fence context ID
261                          *  allocated with dma_fence_context_alloc(). */
262                         u64 id;
263
264                         /** @kccb.fence_ctx.seqno: Sequence number incremented
265                          *  each time a fence is created. */
266                         atomic_t seqno;
267
268                         /**
269                          * @kccb.fence_ctx.lock: Lock used to synchronize
270                          * access to fences allocated by this context.
271                          */
272                         spinlock_t lock;
273                 } fence_ctx;
274         } kccb;
275
276         /**
277          * @lost: %true if the device has been lost.
278          *
279          * This variable is set if the device has become irretrievably unavailable, e.g. if the
280          * firmware processor has stopped responding and can not be revived via a hard reset.
281          */
282         bool lost;
283
284         /**
285          * @reset_sem: Reset semaphore.
286          *
287          * GPU reset code will lock this for writing. Any code that submits commands to the firmware
288          * that isn't in an IRQ handler or on the scheduler workqueue must lock this for reading.
289          * Once this has been successfully locked, &pvr_dev->lost _must_ be checked, and -%EIO must
290          * be returned if it is set.
291          */
292         struct rw_semaphore reset_sem;
293
294         /** @sched_wq: Workqueue for schedulers. */
295         struct workqueue_struct *sched_wq;
296 };
297
298 /**
299  * struct pvr_file - powervr-specific data to be assigned to &struct
300  * drm_file.driver_priv
301  */
302 struct pvr_file {
303         /**
304          * @file: A reference to the parent &struct drm_file.
305          *
306          * Do not access this member directly, instead call from_pvr_file().
307          */
308         struct drm_file *file;
309
310         /**
311          * @pvr_dev: A reference to the powervr-specific wrapper for the
312          * associated device. Saves on repeated calls to to_pvr_device().
313          */
314         struct pvr_device *pvr_dev;
315
316         /**
317          * @ctx_handles: Array of contexts belonging to this file. Array members
318          * are of type "struct pvr_context *".
319          *
320          * This array is used to allocate handles returned to userspace.
321          */
322         struct xarray ctx_handles;
323
324         /**
325          * @free_list_handles: Array of free lists belonging to this file. Array
326          * members are of type "struct pvr_free_list *".
327          *
328          * This array is used to allocate handles returned to userspace.
329          */
330         struct xarray free_list_handles;
331
332         /**
333          * @hwrt_handles: Array of HWRT datasets belonging to this file. Array
334          * members are of type "struct pvr_hwrt_dataset *".
335          *
336          * This array is used to allocate handles returned to userspace.
337          */
338         struct xarray hwrt_handles;
339
340         /**
341          * @vm_ctx_handles: Array of VM contexts belonging to this file. Array
342          * members are of type "struct pvr_vm_context *".
343          *
344          * This array is used to allocate handles returned to userspace.
345          */
346         struct xarray vm_ctx_handles;
347 };
348
349 /**
350  * PVR_HAS_FEATURE() - Tests whether a PowerVR device has a given feature
351  * @pvr_dev: [IN] Target PowerVR device.
352  * @feature: [IN] Hardware feature name.
353  *
354  * Feature names are derived from those found in &struct pvr_device_features by
355  * dropping the 'has_' prefix, which is applied by this macro.
356  *
357  * Return:
358  *  * true if the named feature is present in the hardware
359  *  * false if the named feature is not present in the hardware
360  */
361 #define PVR_HAS_FEATURE(pvr_dev, feature) ((pvr_dev)->features.has_##feature)
362
363 /**
364  * PVR_FEATURE_VALUE() - Gets a PowerVR device feature value
365  * @pvr_dev: [IN] Target PowerVR device.
366  * @feature: [IN] Feature name.
367  * @value_out: [OUT] Feature value.
368  *
369  * This macro will get a feature value for those features that have values.
370  * If the feature is not present, nothing will be stored to @value_out.
371  *
372  * Feature names are derived from those found in &struct pvr_device_features by
373  * dropping the 'has_' prefix.
374  *
375  * Return:
376  *  * 0 on success, or
377  *  * -%EINVAL if the named feature is not present in the hardware
378  */
379 #define PVR_FEATURE_VALUE(pvr_dev, feature, value_out)             \
380         ({                                                         \
381                 struct pvr_device *_pvr_dev = pvr_dev;             \
382                 int _ret = -EINVAL;                                \
383                 if (_pvr_dev->features.has_##feature) {            \
384                         *(value_out) = _pvr_dev->features.feature; \
385                         _ret = 0;                                  \
386                 }                                                  \
387                 _ret;                                              \
388         })
389
390 /**
391  * PVR_HAS_QUIRK() - Tests whether a physical device has a given quirk
392  * @pvr_dev: [IN] Target PowerVR device.
393  * @quirk: [IN] Hardware quirk name.
394  *
395  * Quirk numbers are derived from those found in #pvr_device_quirks by
396  * dropping the 'has_brn' prefix, which is applied by this macro.
397  *
398  * Returns
399  *  * true if the quirk is present in the hardware, or
400  *  * false if the quirk is not present in the hardware.
401  */
402 #define PVR_HAS_QUIRK(pvr_dev, quirk) ((pvr_dev)->quirks.has_brn##quirk)
403
404 /**
405  * PVR_HAS_ENHANCEMENT() - Tests whether a physical device has a given
406  *                         enhancement
407  * @pvr_dev: [IN] Target PowerVR device.
408  * @enhancement: [IN] Hardware enhancement name.
409  *
410  * Enhancement numbers are derived from those found in #pvr_device_enhancements
411  * by dropping the 'has_ern' prefix, which is applied by this macro.
412  *
413  * Returns
414  *  * true if the enhancement is present in the hardware, or
415  *  * false if the enhancement is not present in the hardware.
416  */
417 #define PVR_HAS_ENHANCEMENT(pvr_dev, enhancement) ((pvr_dev)->enhancements.has_ern##enhancement)
418
419 #define from_pvr_device(pvr_dev) (&(pvr_dev)->base)
420
421 #define to_pvr_device(drm_dev) container_of_const(drm_dev, struct pvr_device, base)
422
423 #define from_pvr_file(pvr_file) ((pvr_file)->file)
424
425 #define to_pvr_file(file) ((file)->driver_priv)
426
427 /**
428  * PVR_PACKED_BVNC() - Packs B, V, N and C values into a 64-bit unsigned integer
429  * @b: Branch ID.
430  * @v: Version ID.
431  * @n: Number of scalable units.
432  * @c: Config ID.
433  *
434  * The packed layout is as follows:
435  *
436  *    +--------+--------+--------+-------+
437  *    | 63..48 | 47..32 | 31..16 | 15..0 |
438  *    +========+========+========+=======+
439  *    | B      | V      | N      | C     |
440  *    +--------+--------+--------+-------+
441  *
442  * pvr_gpu_id_to_packed_bvnc() should be used instead of this macro when a
443  * &struct pvr_gpu_id is available in order to ensure proper type checking.
444  *
445  * Return: Packed BVNC.
446  */
447 /* clang-format off */
448 #define PVR_PACKED_BVNC(b, v, n, c) \
449         ((((u64)(b) & GENMASK_ULL(15, 0)) << 48) | \
450          (((u64)(v) & GENMASK_ULL(15, 0)) << 32) | \
451          (((u64)(n) & GENMASK_ULL(15, 0)) << 16) | \
452          (((u64)(c) & GENMASK_ULL(15, 0)) <<  0))
453 /* clang-format on */
454
455 /**
456  * pvr_gpu_id_to_packed_bvnc() - Packs B, V, N and C values into a 64-bit
457  * unsigned integer
458  * @gpu_id: GPU ID.
459  *
460  * The packed layout is as follows:
461  *
462  *    +--------+--------+--------+-------+
463  *    | 63..48 | 47..32 | 31..16 | 15..0 |
464  *    +========+========+========+=======+
465  *    | B      | V      | N      | C     |
466  *    +--------+--------+--------+-------+
467  *
468  * This should be used in preference to PVR_PACKED_BVNC() when a &struct
469  * pvr_gpu_id is available in order to ensure proper type checking.
470  *
471  * Return: Packed BVNC.
472  */
473 static __always_inline u64
474 pvr_gpu_id_to_packed_bvnc(struct pvr_gpu_id *gpu_id)
475 {
476         return PVR_PACKED_BVNC(gpu_id->b, gpu_id->v, gpu_id->n, gpu_id->c);
477 }
478
479 static __always_inline void
480 packed_bvnc_to_pvr_gpu_id(u64 bvnc, struct pvr_gpu_id *gpu_id)
481 {
482         gpu_id->b = (bvnc & GENMASK_ULL(63, 48)) >> 48;
483         gpu_id->v = (bvnc & GENMASK_ULL(47, 32)) >> 32;
484         gpu_id->n = (bvnc & GENMASK_ULL(31, 16)) >> 16;
485         gpu_id->c = bvnc & GENMASK_ULL(15, 0);
486 }
487
488 int pvr_device_init(struct pvr_device *pvr_dev);
489 void pvr_device_fini(struct pvr_device *pvr_dev);
490 void pvr_device_reset(struct pvr_device *pvr_dev);
491
492 bool
493 pvr_device_has_uapi_quirk(struct pvr_device *pvr_dev, u32 quirk);
494 bool
495 pvr_device_has_uapi_enhancement(struct pvr_device *pvr_dev, u32 enhancement);
496 bool
497 pvr_device_has_feature(struct pvr_device *pvr_dev, u32 feature);
498
499 /**
500  * PVR_CR_FIELD_GET() - Extract a single field from a PowerVR control register
501  * @val: Value of the target register.
502  * @field: Field specifier, as defined in "pvr_rogue_cr_defs.h".
503  *
504  * Return: The extracted field.
505  */
506 #define PVR_CR_FIELD_GET(val, field) FIELD_GET(~ROGUE_CR_##field##_CLRMSK, val)
507
508 /**
509  * pvr_cr_read32() - Read a 32-bit register from a PowerVR device
510  * @pvr_dev: Target PowerVR device.
511  * @reg: Target register.
512  *
513  * Return: The value of the requested register.
514  */
515 static __always_inline u32
516 pvr_cr_read32(struct pvr_device *pvr_dev, u32 reg)
517 {
518         return ioread32(pvr_dev->regs + reg);
519 }
520
521 /**
522  * pvr_cr_read64() - Read a 64-bit register from a PowerVR device
523  * @pvr_dev: Target PowerVR device.
524  * @reg: Target register.
525  *
526  * Return: The value of the requested register.
527  */
528 static __always_inline u64
529 pvr_cr_read64(struct pvr_device *pvr_dev, u32 reg)
530 {
531         return ioread64(pvr_dev->regs + reg);
532 }
533
534 /**
535  * pvr_cr_write32() - Write to a 32-bit register in a PowerVR device
536  * @pvr_dev: Target PowerVR device.
537  * @reg: Target register.
538  * @val: Value to write.
539  */
540 static __always_inline void
541 pvr_cr_write32(struct pvr_device *pvr_dev, u32 reg, u32 val)
542 {
543         iowrite32(val, pvr_dev->regs + reg);
544 }
545
546 /**
547  * pvr_cr_write64() - Write to a 64-bit register in a PowerVR device
548  * @pvr_dev: Target PowerVR device.
549  * @reg: Target register.
550  * @val: Value to write.
551  */
552 static __always_inline void
553 pvr_cr_write64(struct pvr_device *pvr_dev, u32 reg, u64 val)
554 {
555         iowrite64(val, pvr_dev->regs + reg);
556 }
557
558 /**
559  * pvr_cr_poll_reg32() - Wait for a 32-bit register to match a given value by
560  *                       polling
561  * @pvr_dev: Target PowerVR device.
562  * @reg_addr: Address of register.
563  * @reg_value: Expected register value (after masking).
564  * @reg_mask: Mask of bits valid for comparison with @reg_value.
565  * @timeout_usec: Timeout length, in us.
566  *
567  * Returns:
568  *  * 0 on success, or
569  *  * -%ETIMEDOUT on timeout.
570  */
571 static __always_inline int
572 pvr_cr_poll_reg32(struct pvr_device *pvr_dev, u32 reg_addr, u32 reg_value,
573                   u32 reg_mask, u64 timeout_usec)
574 {
575         u32 value;
576
577         return readl_poll_timeout(pvr_dev->regs + reg_addr, value,
578                 (value & reg_mask) == reg_value, 0, timeout_usec);
579 }
580
581 /**
582  * pvr_cr_poll_reg64() - Wait for a 64-bit register to match a given value by
583  *                       polling
584  * @pvr_dev: Target PowerVR device.
585  * @reg_addr: Address of register.
586  * @reg_value: Expected register value (after masking).
587  * @reg_mask: Mask of bits valid for comparison with @reg_value.
588  * @timeout_usec: Timeout length, in us.
589  *
590  * Returns:
591  *  * 0 on success, or
592  *  * -%ETIMEDOUT on timeout.
593  */
594 static __always_inline int
595 pvr_cr_poll_reg64(struct pvr_device *pvr_dev, u32 reg_addr, u64 reg_value,
596                   u64 reg_mask, u64 timeout_usec)
597 {
598         u64 value;
599
600         return readq_poll_timeout(pvr_dev->regs + reg_addr, value,
601                 (value & reg_mask) == reg_value, 0, timeout_usec);
602 }
603
604 /**
605  * pvr_round_up_to_cacheline_size() - Round up a provided size to be cacheline
606  *                                    aligned
607  * @pvr_dev: Target PowerVR device.
608  * @size: Initial size, in bytes.
609  *
610  * Returns:
611  *  * Size aligned to cacheline size.
612  */
613 static __always_inline size_t
614 pvr_round_up_to_cacheline_size(struct pvr_device *pvr_dev, size_t size)
615 {
616         u16 slc_cacheline_size_bits = 0;
617         u16 slc_cacheline_size_bytes;
618
619         WARN_ON(!PVR_HAS_FEATURE(pvr_dev, slc_cache_line_size_bits));
620         PVR_FEATURE_VALUE(pvr_dev, slc_cache_line_size_bits,
621                           &slc_cacheline_size_bits);
622         slc_cacheline_size_bytes = slc_cacheline_size_bits / 8;
623
624         return round_up(size, slc_cacheline_size_bytes);
625 }
626
627 /**
628  * DOC: IOCTL validation helpers
629  *
630  * To validate the constraints imposed on IOCTL argument structs, a collection
631  * of macros and helper functions exist in ``pvr_device.h``.
632  *
633  * Of the current helpers, it should only be necessary to call
634  * PVR_IOCTL_UNION_PADDING_CHECK() directly. This macro should be used once in
635  * every code path which extracts a union member from a struct passed from
636  * userspace.
637  */
638
639 /**
640  * pvr_ioctl_union_padding_check() - Validate that the implicit padding between
641  * the end of a union member and the end of the union itself is zeroed.
642  * @instance: Pointer to the instance of the struct to validate.
643  * @union_offset: Offset into the type of @instance of the target union. Must
644  * be 64-bit aligned.
645  * @union_size: Size of the target union in the type of @instance. Must be
646  * 64-bit aligned.
647  * @member_size: Size of the target member in the target union specified by
648  * @union_offset and @union_size. It is assumed that the offset of the target
649  * member is zero relative to @union_offset. Must be 64-bit aligned.
650  *
651  * You probably want to use PVR_IOCTL_UNION_PADDING_CHECK() instead of calling
652  * this function directly, since that macro abstracts away much of the setup,
653  * and also provides some static validation. See its docs for details.
654  *
655  * Return:
656  *  * %true if every byte between the end of the used member of the union and
657  *    the end of that union is zeroed, or
658  *  * %false otherwise.
659  */
660 static __always_inline bool
661 pvr_ioctl_union_padding_check(void *instance, size_t union_offset,
662                               size_t union_size, size_t member_size)
663 {
664         /*
665          * void pointer arithmetic is technically illegal - cast to a byte
666          * pointer so this addition works safely.
667          */
668         void *padding_start = ((u8 *)instance) + union_offset + member_size;
669         size_t padding_size = union_size - member_size;
670
671         return !memchr_inv(padding_start, 0, padding_size);
672 }
673
674 /**
675  * PVR_STATIC_ASSERT_64BIT_ALIGNED() - Inline assertion for 64-bit alignment.
676  * @static_expr_: Target expression to evaluate.
677  *
678  * If @static_expr_ does not evaluate to a constant integer which would be a
679  * 64-bit aligned address (i.e. a multiple of 8), compilation will fail.
680  *
681  * Return:
682  * The value of @static_expr_.
683  */
684 #define PVR_STATIC_ASSERT_64BIT_ALIGNED(static_expr_)                     \
685         ({                                                                \
686                 static_assert(((static_expr_) & (sizeof(u64) - 1)) == 0); \
687                 (static_expr_);                                           \
688         })
689
690 /**
691  * PVR_IOCTL_UNION_PADDING_CHECK() - Validate that the implicit padding between
692  * the end of a union member and the end of the union itself is zeroed.
693  * @struct_instance_: An expression which evaluates to a pointer to a UAPI data
694  * struct.
695  * @union_: The name of the union member of @struct_instance_ to check. If the
696  * union member is nested within the type of @struct_instance_, this may
697  * contain the member access operator (".").
698  * @member_: The name of the member of @union_ to assess.
699  *
700  * This is a wrapper around pvr_ioctl_union_padding_check() which performs
701  * alignment checks and simplifies things for the caller.
702  *
703  * Return:
704  *  * %true if every byte in @struct_instance_ between the end of @member_ and
705  *    the end of @union_ is zeroed, or
706  *  * %false otherwise.
707  */
708 #define PVR_IOCTL_UNION_PADDING_CHECK(struct_instance_, union_, member_)     \
709         ({                                                                   \
710                 typeof(struct_instance_) __instance = (struct_instance_);    \
711                 size_t __union_offset = PVR_STATIC_ASSERT_64BIT_ALIGNED(     \
712                         offsetof(typeof(*__instance), union_));              \
713                 size_t __union_size = PVR_STATIC_ASSERT_64BIT_ALIGNED(       \
714                         sizeof(__instance->union_));                         \
715                 size_t __member_size = PVR_STATIC_ASSERT_64BIT_ALIGNED(      \
716                         sizeof(__instance->union_.member_));                 \
717                 pvr_ioctl_union_padding_check(__instance, __union_offset,    \
718                                               __union_size, __member_size);  \
719         })
720
721 #define PVR_FW_PROCESSOR_TYPE_META  0
722 #define PVR_FW_PROCESSOR_TYPE_MIPS  1
723 #define PVR_FW_PROCESSOR_TYPE_RISCV 2
724
725 #endif /* PVR_DEVICE_H */
This page took 0.068263 seconds and 4 git commands to generate.