| // SPDX-License-Identifier: GPL-2.0 |
| |
| use kernel::uapi; |
| |
| // TODO Work out some common infrastructure to avoid boilerplate code for uAPI abstractions. |
| |
| macro_rules! define_uapi_abstraction { |
| ($name:ident <= $inner:ty) => { |
| #[repr(transparent)] |
| pub struct $name(::kernel::types::Opaque<$inner>); |
| |
| impl ::core::convert::From<&::kernel::types::Opaque<$inner>> for &$name { |
| fn from(value: &::kernel::types::Opaque<$inner>) -> Self { |
| // SAFETY: `Self` is a transparent wrapper of `$inner`. |
| unsafe { ::core::mem::transmute(value) } |
| } |
| } |
| }; |
| } |
| |
| define_uapi_abstraction!(Getparam <= uapi::drm_nova_getparam); |
| |
| impl Getparam { |
| pub fn param(&self) -> u64 { |
| // SAFETY: `self.get()` is a valid pointer to a `struct drm_nova_getparam`. |
| unsafe { (*self.0.get()).param } |
| } |
| |
| pub fn set_value(&self, v: u64) { |
| // SAFETY: `self.get()` is a valid pointer to a `struct drm_nova_getparam`. |
| unsafe { (*self.0.get()).value = v }; |
| } |
| } |
| |
| define_uapi_abstraction!(GemCreate <= uapi::drm_nova_gem_create); |
| |
| impl GemCreate { |
| pub fn size(&self) -> u64 { |
| // SAFETY: `self.get()` is a valid pointer to a `struct drm_nova_gem_create`. |
| unsafe { (*self.0.get()).size } |
| } |
| |
| pub fn set_handle(&self, handle: u32) { |
| // SAFETY: `self.get()` is a valid pointer to a `struct drm_nova_gem_create`. |
| unsafe { (*self.0.get()).handle = handle }; |
| } |
| } |
| |
| define_uapi_abstraction!(GemInfo <= uapi::drm_nova_gem_info); |
| |
| impl GemInfo { |
| pub fn handle(&self) -> u32 { |
| // SAFETY: `self.get()` is a valid pointer to a `struct drm_nova_gem_info`. |
| unsafe { (*self.0.get()).handle } |
| } |
| |
| pub fn set_size(&self, size: u64) { |
| // SAFETY: `self.get()` is a valid pointer to a `struct drm_nova_gem_info`. |
| unsafe { (*self.0.get()).size = size }; |
| } |
| } |