mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 09:20:13 -04:00
gpu: nova-core: build SetRegistry entries dynamically
The GSP SetRegistry command currently stores its registry entries in a fixed-size array. That makes every additional runtime-dependent registry object require reshaping the command data structure at the same time as the feature that needs the new entry. Keep the existing registry contents unchanged, but store them in a KVec so SetRegistry can be constructed dynamically. The constructor now returns a Result to propagate allocation failures while the command payload layout is still computed from the final entry list. Cc: Alexandre Courbot <acourbot@nvidia.com> Signed-off-by: Zhi Wang <zhiw@nvidia.com> Link: https://patch.msgid.link/20260701062622.3499033-7-zhiw@nvidia.com [acourbot: remove orphan comment.] Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
This commit is contained in:
committed by
Alexandre Courbot
parent
2493c44165
commit
d85845b64c
@@ -135,7 +135,7 @@ pub(crate) fn boot(
|
||||
self.cmdq
|
||||
.send_command_no_wait(bar, commands::SetSystemInfo::new(pdev, chipset))?;
|
||||
self.cmdq
|
||||
.send_command_no_wait(bar, commands::SetRegistry::new())?;
|
||||
.send_command_no_wait(bar, commands::SetRegistry::new()?)?;
|
||||
|
||||
hal.post_boot(&self, &ctx, &gsp_fw)?;
|
||||
|
||||
|
||||
@@ -67,37 +67,44 @@ struct RegistryEntry {
|
||||
|
||||
/// The `SetRegistry` command.
|
||||
pub(crate) struct SetRegistry {
|
||||
entries: [RegistryEntry; Self::NUM_ENTRIES],
|
||||
entries: KVec<RegistryEntry>,
|
||||
}
|
||||
|
||||
impl SetRegistry {
|
||||
// For now we hard-code the registry entries. Future work will allow others to
|
||||
// be added as module parameters.
|
||||
const NUM_ENTRIES: usize = 3;
|
||||
|
||||
/// Creates a new `SetRegistry` command, using a set of hardcoded entries.
|
||||
pub(crate) fn new() -> Self {
|
||||
Self {
|
||||
entries: [
|
||||
// RMSecBusResetEnable - enables PCI secondary bus reset
|
||||
RegistryEntry {
|
||||
key: "RMSecBusResetEnable",
|
||||
value: 1,
|
||||
},
|
||||
// RMForcePcieConfigSave - forces GSP-RM to preserve PCI configuration registers on
|
||||
// any PCI reset.
|
||||
RegistryEntry {
|
||||
key: "RMForcePcieConfigSave",
|
||||
value: 1,
|
||||
},
|
||||
// RMDevidCheckIgnore - allows GSP-RM to boot even if the PCI dev ID is not found
|
||||
// in the internal product name database.
|
||||
RegistryEntry {
|
||||
key: "RMDevidCheckIgnore",
|
||||
value: 1,
|
||||
},
|
||||
],
|
||||
}
|
||||
pub(crate) fn new() -> Result<Self> {
|
||||
let mut entries = KVec::new();
|
||||
|
||||
// RMSecBusResetEnable - enables PCI secondary bus reset
|
||||
entries.push(
|
||||
RegistryEntry {
|
||||
key: "RMSecBusResetEnable",
|
||||
value: 1,
|
||||
},
|
||||
GFP_KERNEL,
|
||||
)?;
|
||||
|
||||
// RMForcePcieConfigSave - forces GSP-RM to preserve PCI configuration registers on
|
||||
// any PCI reset.
|
||||
entries.push(
|
||||
RegistryEntry {
|
||||
key: "RMForcePcieConfigSave",
|
||||
value: 1,
|
||||
},
|
||||
GFP_KERNEL,
|
||||
)?;
|
||||
|
||||
// RMDevidCheckIgnore - allows GSP-RM to boot even if the PCI dev ID is not found
|
||||
// in the internal product name database.
|
||||
entries.push(
|
||||
RegistryEntry {
|
||||
key: "RMDevidCheckIgnore",
|
||||
value: 1,
|
||||
},
|
||||
GFP_KERNEL,
|
||||
)?;
|
||||
|
||||
Ok(Self { entries })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,15 +115,18 @@ impl CommandToGsp for SetRegistry {
|
||||
type InitError = Infallible;
|
||||
|
||||
fn init(&self) -> impl Init<Self::Command, Self::InitError> {
|
||||
Self::Command::init(Self::NUM_ENTRIES as u32, self.variable_payload_len() as u32)
|
||||
Self::Command::init(
|
||||
self.entries.len() as u32,
|
||||
self.variable_payload_len() as u32,
|
||||
)
|
||||
}
|
||||
|
||||
fn variable_payload_len(&self) -> usize {
|
||||
let mut key_size = 0;
|
||||
for i in 0..Self::NUM_ENTRIES {
|
||||
key_size += self.entries[i].key.len() + 1; // +1 for NULL terminator
|
||||
for entry in self.entries.iter() {
|
||||
key_size += entry.key.len() + 1; // +1 for NULL terminator
|
||||
}
|
||||
Self::NUM_ENTRIES * size_of::<fw::commands::PackedRegistryEntry>() + key_size
|
||||
self.entries.len() * size_of::<fw::commands::PackedRegistryEntry>() + key_size
|
||||
}
|
||||
|
||||
fn init_variable_payload(
|
||||
@@ -124,12 +134,12 @@ fn init_variable_payload(
|
||||
dst: &mut SBufferIter<core::array::IntoIter<&mut [u8], 2>>,
|
||||
) -> Result {
|
||||
let string_data_start_offset = size_of::<Self::Command>()
|
||||
+ Self::NUM_ENTRIES * size_of::<fw::commands::PackedRegistryEntry>();
|
||||
+ self.entries.len() * size_of::<fw::commands::PackedRegistryEntry>();
|
||||
|
||||
// Array for string data.
|
||||
let mut string_data = KVec::new();
|
||||
|
||||
for entry in self.entries.iter().take(Self::NUM_ENTRIES) {
|
||||
for entry in self.entries.iter() {
|
||||
dst.write_all(
|
||||
fw::commands::PackedRegistryEntry::new(
|
||||
(string_data_start_offset + string_data.len()) as u32,
|
||||
|
||||
Reference in New Issue
Block a user