John Hubbard
2025-Dec-03 05:59 UTC
[PATCH 17/31] gpu: nova-core: Hopper/Blackwell: calculate reserved FB heap size
Various "reserved" areas of FB (frame buffer: vidmem) have to be
calculated, because the GSP booting process needs this information.
The calculations are const, so a new const-compatible alignment function
is also added to num.rs, in order to align the reserved areas.
Signed-off-by: John Hubbard <jhubbard at nvidia.com>
---
drivers/gpu/nova-core/fb.rs | 18 ++++++++++++++++++
drivers/gpu/nova-core/gsp/fw.rs | 6 +++++-
drivers/gpu/nova-core/num.rs | 10 ++++++++++
3 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/nova-core/fb.rs b/drivers/gpu/nova-core/fb.rs
index 9fcd915e12e1..e697436de29a 100644
--- a/drivers/gpu/nova-core/fb.rs
+++ b/drivers/gpu/nova-core/fb.rs
@@ -153,6 +153,9 @@ pub(crate) struct FbLayout {
pub(crate) wpr2: FbRange,
pub(crate) heap: FbRange,
pub(crate) vf_partition_count: u8,
+ /// Total reserved size (heap + PMU reserved), aligned to 2MB.
+ #[allow(dead_code)]
+ pub(crate) total_reserved_size: u32,
}
impl FbLayout {
@@ -240,6 +243,16 @@ pub(crate) fn new(chipset: Chipset, bar: &Bar0, gsp_fw:
&GspFirmware) -> Result<
FbRange(wpr2.start - HEAP_SIZE..wpr2.start)
};
+ // Calculate reserved sizes. PMU reservation is a subset of the total
reserved size.
+ let heap_size = (heap.end - heap.start) as u64;
+ let pmu_reserved_size = u64::from(PMU_RESERVED_SIZE);
+
+ let total_reserved_size = {
+ let total = heap_size + pmu_reserved_size;
+ const RSVD_ALIGN: Alignment = Alignment::new::<SZ_2M>();
+ total.align_up(RSVD_ALIGN).ok_or(EINVAL)?
+ };
+
Ok(Self {
fb,
vga_workspace,
@@ -250,6 +263,11 @@ pub(crate) fn new(chipset: Chipset, bar: &Bar0, gsp_fw:
&GspFirmware) -> Result<
wpr2,
heap,
vf_partition_count: 0,
+ total_reserved_size: total_reserved_size as u32,
})
}
}
+
+/// PMU reserved size, aligned to 128KB.
+pub(crate) const PMU_RESERVED_SIZE: u32 +
crate::num::const_align_up::<SZ_128K>(SZ_8M + SZ_16M + SZ_4K) as u32;
diff --git a/drivers/gpu/nova-core/gsp/fw.rs b/drivers/gpu/nova-core/gsp/fw.rs
index abffd6beec65..8d668a24142c 100644
--- a/drivers/gpu/nova-core/gsp/fw.rs
+++ b/drivers/gpu/nova-core/gsp/fw.rs
@@ -27,7 +27,10 @@
};
use crate::{
- fb::FbLayout,
+ fb::{
+ FbLayout,
+ PMU_RESERVED_SIZE, //
+ },
firmware::gsp::GspFirmware,
gpu::Chipset,
gsp::{
@@ -183,6 +186,7 @@ pub(crate) fn new(gsp_firmware: &GspFirmware, fb_layout:
&FbLayout) -> Self {
fbSize: fb_layout.fb.end - fb_layout.fb.start,
vgaWorkspaceOffset: fb_layout.vga_workspace.start,
vgaWorkspaceSize: fb_layout.vga_workspace.end -
fb_layout.vga_workspace.start,
+ pmuReservedSize: PMU_RESERVED_SIZE,
..Default::default()
})
}
diff --git a/drivers/gpu/nova-core/num.rs b/drivers/gpu/nova-core/num.rs
index c952a834e662..f068722c5bdf 100644
--- a/drivers/gpu/nova-core/num.rs
+++ b/drivers/gpu/nova-core/num.rs
@@ -215,3 +215,13 @@ pub(crate) const fn [<$from _into_ $into>]<const
N: $from>() -> $into {
impl_const_into!(u64 => { u8, u16, u32 });
impl_const_into!(u32 => { u8, u16 });
impl_const_into!(u16 => { u8 });
+
+/// Aligns `value` up to `ALIGN` at compile time.
+///
+/// This is the const-compatible equivalent of
[`kernel::ptr::Alignable::align_up`].
+/// `ALIGN` must be a power of two (enforced at compile time).
+#[inline(always)]
+pub(crate) const fn const_align_up<const ALIGN: usize>(value: usize)
-> usize {
+ build_assert!(ALIGN.is_power_of_two());
+ (value + (ALIGN - 1)) & !(ALIGN - 1)
+}
--
2.52.0
Timur Tabi
2025-Dec-03 20:48 UTC
[PATCH 17/31] gpu: nova-core: Hopper/Blackwell: calculate reserved FB heap size
On Tue, 2025-12-02 at 21:59 -0800, John Hubbard wrote:> +#[inline(always)] > +pub(crate) const fn const_align_up<const ALIGN: usize>(value: usize) -> usize { > +??? build_assert!(ALIGN.is_power_of_two()); > +??? (value + (ALIGN - 1)) & !(ALIGN - 1) > +}So this is just like the issue I'm having with .next_multiple_of() in my patch #10. Shouldn't you have a check to make sure that value + (ALIGN - 1) doesn't overflow? Since I need to align up to the nearest const power of two, I could use this function instead of align_up() and avoid testing for an error condition.