xref: /linux/drivers/gpu/nova-core/mm.rs (revision b05ff82081b7b90fdd70cc7d07b3da9d85184f88)
1 // SPDX-License-Identifier: GPL-2.0
2 // SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3 
4 //! Memory management subsystems.
5 
6 #![expect(dead_code)]
7 
8 use core::{
9     fmt::LowerHex,
10     ops, //
11 };
12 
13 use kernel::{
14     fmt,
15     prelude::*,
16     ptr::{
17         Alignable,
18         Alignment, //
19     },
20 };
21 
22 mod hal;
23 mod regs;
24 
25 /// Physical VRAM address in GPU video memory.
26 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
27 #[repr(transparent)]
28 pub(crate) struct VramAddress(u64);
29 
30 impl VramAddress {
31     /// The zero address.
32     pub(crate) const ZERO: Self = Self::from_raw(0);
33 
34     /// Creates an address from a raw value.
35     pub(crate) const fn from_raw(addr: u64) -> Self {
36         Self(addr)
37     }
38 
39     /// Returns the address as a raw value.
40     pub(crate) const fn into_raw(self) -> u64 {
41         self.0
42     }
43 
44     /// Adds `rhs` to this address, returning [`None`] on overflow.
45     pub(crate) const fn checked_add(self, rhs: u64) -> Option<Self> {
46         match self.into_raw().checked_add(rhs) {
47             Some(addr) => Some(Self::from_raw(addr)),
48             None => None,
49         }
50     }
51 }
52 
53 impl Alignable for VramAddress {
54     fn align_down(self, alignment: Alignment) -> Self {
55         Self::from_raw(self.into_raw().align_down(alignment))
56     }
57 
58     fn align_up(self, alignment: Alignment) -> Option<Self> {
59         self.into_raw().align_up(alignment).map(Self::from_raw)
60     }
61 }
62 
63 impl LowerHex for VramAddress {
64     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65         LowerHex::fmt(&self.into_raw(), f)
66     }
67 }
68 
69 impl fmt::Debug for VramAddress {
70     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71         f.write_fmt(fmt!("{:#x}", self))
72     }
73 }
74 
75 impl ops::Add<u64> for VramAddress {
76     type Output = Self;
77 
78     fn add(self, rhs: u64) -> Self::Output {
79         Self::from_raw(self.into_raw() + rhs)
80     }
81 }
82 
83 impl ops::Sub for VramAddress {
84     type Output = u64;
85 
86     fn sub(self, rhs: Self) -> Self::Output {
87         self.into_raw() - rhs.into_raw()
88     }
89 }
90