1edcb1342SAlistair Popple // SPDX-License-Identifier: GPL-2.0 2edcb1342SAlistair Popple 3edcb1342SAlistair Popple use kernel::prelude::*; 4edcb1342SAlistair Popple use kernel::transmute::{AsBytes, FromBytes}; 5edcb1342SAlistair Popple use kernel::{device, pci}; 6edcb1342SAlistair Popple 7edcb1342SAlistair Popple use crate::gsp::GSP_PAGE_SIZE; 8edcb1342SAlistair Popple 9edcb1342SAlistair Popple use super::bindings; 10edcb1342SAlistair Popple 11edcb1342SAlistair Popple /// Payload of the `GspSetSystemInfo` command. 12edcb1342SAlistair Popple #[repr(transparent)] 13edcb1342SAlistair Popple pub(crate) struct GspSetSystemInfo { 14edcb1342SAlistair Popple inner: bindings::GspSystemInfo, 15edcb1342SAlistair Popple } 16edcb1342SAlistair Popple static_assert!(size_of::<GspSetSystemInfo>() < GSP_PAGE_SIZE); 17edcb1342SAlistair Popple 18edcb1342SAlistair Popple impl GspSetSystemInfo { 19edcb1342SAlistair Popple /// Returns an in-place initializer for the `GspSetSystemInfo` command. 20edcb1342SAlistair Popple #[allow(non_snake_case)] 21edcb1342SAlistair Popple pub(crate) fn init<'a>(dev: &'a pci::Device<device::Bound>) -> impl Init<Self, Error> + 'a { 22edcb1342SAlistair Popple type InnerGspSystemInfo = bindings::GspSystemInfo; 23edcb1342SAlistair Popple let init_inner = try_init!(InnerGspSystemInfo { 24edcb1342SAlistair Popple gpuPhysAddr: dev.resource_start(0)?, 25edcb1342SAlistair Popple gpuPhysFbAddr: dev.resource_start(1)?, 26edcb1342SAlistair Popple gpuPhysInstAddr: dev.resource_start(3)?, 27edcb1342SAlistair Popple nvDomainBusDeviceFunc: u64::from(dev.dev_id()), 28edcb1342SAlistair Popple 29edcb1342SAlistair Popple // Using TASK_SIZE in r535_gsp_rpc_set_system_info() seems wrong because 30edcb1342SAlistair Popple // TASK_SIZE is per-task. That's probably a design issue in GSP-RM though. 31edcb1342SAlistair Popple maxUserVa: (1 << 47) - 4096, 32edcb1342SAlistair Popple pciConfigMirrorBase: 0x088000, 33edcb1342SAlistair Popple pciConfigMirrorSize: 0x001000, 34edcb1342SAlistair Popple 35edcb1342SAlistair Popple PCIDeviceID: (u32::from(dev.device_id()) << 16) | u32::from(dev.vendor_id().as_raw()), 36edcb1342SAlistair Popple PCISubDeviceID: (u32::from(dev.subsystem_device_id()) << 16) 37edcb1342SAlistair Popple | u32::from(dev.subsystem_vendor_id()), 38edcb1342SAlistair Popple PCIRevisionID: u32::from(dev.revision_id()), 39edcb1342SAlistair Popple bIsPrimary: 0, 40edcb1342SAlistair Popple bPreserveVideoMemoryAllocations: 0, 41edcb1342SAlistair Popple ..Zeroable::init_zeroed() 42edcb1342SAlistair Popple }); 43edcb1342SAlistair Popple 44edcb1342SAlistair Popple try_init!(GspSetSystemInfo { 45edcb1342SAlistair Popple inner <- init_inner, 46edcb1342SAlistair Popple }) 47edcb1342SAlistair Popple } 48edcb1342SAlistair Popple } 49edcb1342SAlistair Popple 50edcb1342SAlistair Popple // SAFETY: These structs don't meet the no-padding requirements of AsBytes but 51edcb1342SAlistair Popple // that is not a problem because they are not used outside the kernel. 52edcb1342SAlistair Popple unsafe impl AsBytes for GspSetSystemInfo {} 53edcb1342SAlistair Popple 54edcb1342SAlistair Popple // SAFETY: These structs don't meet the no-padding requirements of FromBytes but 55edcb1342SAlistair Popple // that is not a problem because they are not used outside the kernel. 56edcb1342SAlistair Popple unsafe impl FromBytes for GspSetSystemInfo {} 5719b0a6e7SAlistair Popple 5819b0a6e7SAlistair Popple #[repr(transparent)] 5919b0a6e7SAlistair Popple pub(crate) struct PackedRegistryEntry(bindings::PACKED_REGISTRY_ENTRY); 6019b0a6e7SAlistair Popple 6119b0a6e7SAlistair Popple impl PackedRegistryEntry { 6219b0a6e7SAlistair Popple pub(crate) fn new(offset: u32, value: u32) -> Self { 6319b0a6e7SAlistair Popple Self({ 6419b0a6e7SAlistair Popple bindings::PACKED_REGISTRY_ENTRY { 6519b0a6e7SAlistair Popple nameOffset: offset, 6619b0a6e7SAlistair Popple 6719b0a6e7SAlistair Popple // We only support DWORD types for now. Support for other types 6819b0a6e7SAlistair Popple // will come later if required. 6919b0a6e7SAlistair Popple type_: bindings::REGISTRY_TABLE_ENTRY_TYPE_DWORD as u8, 7019b0a6e7SAlistair Popple __bindgen_padding_0: Default::default(), 7119b0a6e7SAlistair Popple data: value, 7219b0a6e7SAlistair Popple length: 0, 7319b0a6e7SAlistair Popple } 7419b0a6e7SAlistair Popple }) 7519b0a6e7SAlistair Popple } 7619b0a6e7SAlistair Popple } 7719b0a6e7SAlistair Popple 7819b0a6e7SAlistair Popple // SAFETY: Padding is explicit and will not contain uninitialized data. 7919b0a6e7SAlistair Popple unsafe impl AsBytes for PackedRegistryEntry {} 8019b0a6e7SAlistair Popple 8119b0a6e7SAlistair Popple /// Payload of the `SetRegistry` command. 8219b0a6e7SAlistair Popple #[repr(transparent)] 8319b0a6e7SAlistair Popple pub(crate) struct PackedRegistryTable { 8419b0a6e7SAlistair Popple inner: bindings::PACKED_REGISTRY_TABLE, 8519b0a6e7SAlistair Popple } 8619b0a6e7SAlistair Popple 8719b0a6e7SAlistair Popple impl PackedRegistryTable { 8819b0a6e7SAlistair Popple #[allow(non_snake_case)] 8919b0a6e7SAlistair Popple pub(crate) fn init(num_entries: u32, size: u32) -> impl Init<Self> { 9019b0a6e7SAlistair Popple type InnerPackedRegistryTable = bindings::PACKED_REGISTRY_TABLE; 9119b0a6e7SAlistair Popple let init_inner = init!(InnerPackedRegistryTable { 9219b0a6e7SAlistair Popple numEntries: num_entries, 9319b0a6e7SAlistair Popple size, 9419b0a6e7SAlistair Popple entries: Default::default() 9519b0a6e7SAlistair Popple }); 9619b0a6e7SAlistair Popple 9719b0a6e7SAlistair Popple init!(PackedRegistryTable { inner <- init_inner }) 9819b0a6e7SAlistair Popple } 9919b0a6e7SAlistair Popple } 10019b0a6e7SAlistair Popple 10119b0a6e7SAlistair Popple // SAFETY: Padding is explicit and will not contain uninitialized data. 10219b0a6e7SAlistair Popple unsafe impl AsBytes for PackedRegistryTable {} 10319b0a6e7SAlistair Popple 10419b0a6e7SAlistair Popple // SAFETY: This struct only contains integer types for which all bit patterns 10519b0a6e7SAlistair Popple // are valid. 10619b0a6e7SAlistair Popple unsafe impl FromBytes for PackedRegistryTable {} 107*13f85988SAlistair Popple 108*13f85988SAlistair Popple /// Payload of the `GetGspStaticInfo` command and message. 109*13f85988SAlistair Popple #[repr(transparent)] 110*13f85988SAlistair Popple pub(crate) struct GspStaticConfigInfo(bindings::GspStaticConfigInfo_t); 111*13f85988SAlistair Popple 112*13f85988SAlistair Popple impl GspStaticConfigInfo { 113*13f85988SAlistair Popple /// Returns a bytes array containing the (hopefully) zero-terminated name of this GPU. 114*13f85988SAlistair Popple pub(crate) fn gpu_name_str(&self) -> [u8; 64] { 115*13f85988SAlistair Popple self.0.gpuNameString 116*13f85988SAlistair Popple } 117*13f85988SAlistair Popple } 118*13f85988SAlistair Popple 119*13f85988SAlistair Popple // SAFETY: Padding is explicit and will not contain uninitialized data. 120*13f85988SAlistair Popple unsafe impl AsBytes for GspStaticConfigInfo {} 121*13f85988SAlistair Popple 122*13f85988SAlistair Popple // SAFETY: This struct only contains integer types for which all bit patterns 123*13f85988SAlistair Popple // are valid. 124*13f85988SAlistair Popple unsafe impl FromBytes for GspStaticConfigInfo {} 125*13f85988SAlistair Popple 126*13f85988SAlistair Popple // SAFETY: This struct only contains integer types and fixed-size arrays for which 127*13f85988SAlistair Popple // all bit patterns are valid. 128*13f85988SAlistair Popple unsafe impl Zeroable for GspStaticConfigInfo {} 129