1 // SPDX-License-Identifier: GPL-2.0 2 3 use kernel::uapi; 4 5 // TODO Work out some common infrastructure to avoid boilerplate code for uAPI abstractions. 6 7 macro_rules! define_uapi_abstraction { 8 ($name:ident <= $inner:ty) => { 9 #[repr(transparent)] 10 pub struct $name(::kernel::types::Opaque<$inner>); 11 12 impl ::core::convert::From<&::kernel::types::Opaque<$inner>> for &$name { 13 fn from(value: &::kernel::types::Opaque<$inner>) -> Self { 14 // SAFETY: `Self` is a transparent wrapper of `$inner`. 15 unsafe { ::core::mem::transmute(value) } 16 } 17 } 18 }; 19 } 20 21 define_uapi_abstraction!(Getparam <= uapi::drm_nova_getparam); 22 23 impl Getparam { 24 pub fn param(&self) -> u64 { 25 // SAFETY: `self.get()` is a valid pointer to a `struct drm_nova_getparam`. 26 unsafe { (*self.0.get()).param } 27 } 28 29 pub fn set_value(&self, v: u64) { 30 // SAFETY: `self.get()` is a valid pointer to a `struct drm_nova_getparam`. 31 unsafe { (*self.0.get()).value = v }; 32 } 33 } 34 35 define_uapi_abstraction!(GemCreate <= uapi::drm_nova_gem_create); 36 37 impl GemCreate { 38 pub fn size(&self) -> u64 { 39 // SAFETY: `self.get()` is a valid pointer to a `struct drm_nova_gem_create`. 40 unsafe { (*self.0.get()).size } 41 } 42 43 pub fn set_handle(&self, handle: u32) { 44 // SAFETY: `self.get()` is a valid pointer to a `struct drm_nova_gem_create`. 45 unsafe { (*self.0.get()).handle = handle }; 46 } 47 } 48 49 define_uapi_abstraction!(GemInfo <= uapi::drm_nova_gem_info); 50 51 impl GemInfo { 52 pub fn handle(&self) -> u32 { 53 // SAFETY: `self.get()` is a valid pointer to a `struct drm_nova_gem_info`. 54 unsafe { (*self.0.get()).handle } 55 } 56 57 pub fn set_size(&self, size: u64) { 58 // SAFETY: `self.get()` is a valid pointer to a `struct drm_nova_gem_info`. 59 unsafe { (*self.0.get()).size = size }; 60 } 61 } 62