1 // SPDX-License-Identifier: GPL-2.0 2 3 use kernel::prelude::*; 4 use kernel::transmute::{AsBytes, FromBytes}; 5 use kernel::{device, pci}; 6 7 use crate::gsp::GSP_PAGE_SIZE; 8 9 use super::bindings; 10 11 /// Payload of the `GspSetSystemInfo` command. 12 #[repr(transparent)] 13 pub(crate) struct GspSetSystemInfo { 14 inner: bindings::GspSystemInfo, 15 } 16 static_assert!(size_of::<GspSetSystemInfo>() < GSP_PAGE_SIZE); 17 18 impl GspSetSystemInfo { 19 /// Returns an in-place initializer for the `GspSetSystemInfo` command. 20 #[allow(non_snake_case)] 21 pub(crate) fn init<'a>(dev: &'a pci::Device<device::Bound>) -> impl Init<Self, Error> + 'a { 22 type InnerGspSystemInfo = bindings::GspSystemInfo; 23 let init_inner = try_init!(InnerGspSystemInfo { 24 gpuPhysAddr: dev.resource_start(0)?, 25 gpuPhysFbAddr: dev.resource_start(1)?, 26 gpuPhysInstAddr: dev.resource_start(3)?, 27 nvDomainBusDeviceFunc: u64::from(dev.dev_id()), 28 29 // Using TASK_SIZE in r535_gsp_rpc_set_system_info() seems wrong because 30 // TASK_SIZE is per-task. That's probably a design issue in GSP-RM though. 31 maxUserVa: (1 << 47) - 4096, 32 pciConfigMirrorBase: 0x088000, 33 pciConfigMirrorSize: 0x001000, 34 35 PCIDeviceID: (u32::from(dev.device_id()) << 16) | u32::from(dev.vendor_id().as_raw()), 36 PCISubDeviceID: (u32::from(dev.subsystem_device_id()) << 16) 37 | u32::from(dev.subsystem_vendor_id()), 38 PCIRevisionID: u32::from(dev.revision_id()), 39 bIsPrimary: 0, 40 bPreserveVideoMemoryAllocations: 0, 41 ..Zeroable::init_zeroed() 42 }); 43 44 try_init!(GspSetSystemInfo { 45 inner <- init_inner, 46 }) 47 } 48 } 49 50 // SAFETY: These structs don't meet the no-padding requirements of AsBytes but 51 // that is not a problem because they are not used outside the kernel. 52 unsafe impl AsBytes for GspSetSystemInfo {} 53 54 // SAFETY: These structs don't meet the no-padding requirements of FromBytes but 55 // that is not a problem because they are not used outside the kernel. 56 unsafe impl FromBytes for GspSetSystemInfo {} 57 58 #[repr(transparent)] 59 pub(crate) struct PackedRegistryEntry(bindings::PACKED_REGISTRY_ENTRY); 60 61 impl PackedRegistryEntry { 62 pub(crate) fn new(offset: u32, value: u32) -> Self { 63 Self({ 64 bindings::PACKED_REGISTRY_ENTRY { 65 nameOffset: offset, 66 67 // We only support DWORD types for now. Support for other types 68 // will come later if required. 69 type_: bindings::REGISTRY_TABLE_ENTRY_TYPE_DWORD as u8, 70 __bindgen_padding_0: Default::default(), 71 data: value, 72 length: 0, 73 } 74 }) 75 } 76 } 77 78 // SAFETY: Padding is explicit and will not contain uninitialized data. 79 unsafe impl AsBytes for PackedRegistryEntry {} 80 81 /// Payload of the `SetRegistry` command. 82 #[repr(transparent)] 83 pub(crate) struct PackedRegistryTable { 84 inner: bindings::PACKED_REGISTRY_TABLE, 85 } 86 87 impl PackedRegistryTable { 88 #[allow(non_snake_case)] 89 pub(crate) fn init(num_entries: u32, size: u32) -> impl Init<Self> { 90 type InnerPackedRegistryTable = bindings::PACKED_REGISTRY_TABLE; 91 let init_inner = init!(InnerPackedRegistryTable { 92 numEntries: num_entries, 93 size, 94 entries: Default::default() 95 }); 96 97 init!(PackedRegistryTable { inner <- init_inner }) 98 } 99 } 100 101 // SAFETY: Padding is explicit and will not contain uninitialized data. 102 unsafe impl AsBytes for PackedRegistryTable {} 103 104 // SAFETY: This struct only contains integer types for which all bit patterns 105 // are valid. 106 unsafe impl FromBytes for PackedRegistryTable {} 107 108 /// Payload of the `GetGspStaticInfo` command and message. 109 #[repr(transparent)] 110 pub(crate) struct GspStaticConfigInfo(bindings::GspStaticConfigInfo_t); 111 112 impl GspStaticConfigInfo { 113 /// Returns a bytes array containing the (hopefully) zero-terminated name of this GPU. 114 pub(crate) fn gpu_name_str(&self) -> [u8; 64] { 115 self.0.gpuNameString 116 } 117 } 118 119 // SAFETY: Padding is explicit and will not contain uninitialized data. 120 unsafe impl AsBytes for GspStaticConfigInfo {} 121 122 // SAFETY: This struct only contains integer types for which all bit patterns 123 // are valid. 124 unsafe impl FromBytes for GspStaticConfigInfo {} 125 126 // SAFETY: This struct only contains integer types and fixed-size arrays for which 127 // all bit patterns are valid. 128 unsafe impl Zeroable for GspStaticConfigInfo {} 129