xref: /linux/drivers/gpu/nova-core/gsp/fw/commands.rs (revision cc4adab164b772a34b3340d644b7c4728498581e)
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