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