Commit 3606620b authored by Alexandre Courbot's avatar Alexandre Courbot Committed by Danilo Krummrich
Browse files

gpu: nova-core: update and annotate TODO list



A few new dependencies are required to remove some of the TODO items:

- A way to safely convert from byte slices to types implementing
  `FromBytes`,
- A way to obtain slices and write into a `CoherentAllocation`,
- Several improvements to the `register!()` macro,
- Alignment operations to powers of two, and an equivalent to the C
  `fls`,
- Support for `xa_alloc` in the XAlloc bindings.

Some items have also become obsolete:

- The auxiliary bus abstractions have been implemented and are in use,
- The ELF utilities are not considered for being part of the core kernel
  bindings anymore.
- VBIOS, falcon and GPU timer have been completed.

We now have quite a few TODO entries in the code, so annotate them with
a 4 letter code representing the corresponding task in `todo.rst`. This
allows to easily find which part of the code corresponds to a given
entry (and conversely).

Signed-off-by: default avatarAlexandre Courbot <acourbot@nvidia.com>
Link: https://lore.kernel.org/r/20250619-nova-frts-v6-24-ecf41ef99252@nvidia.com


Signed-off-by: default avatarDanilo Krummrich <dakr@kernel.org>
parent 859aa3d9
Loading
Loading
Loading
Loading
+57 −50
Original line number Diff line number Diff line
@@ -14,14 +14,17 @@ Tasks may have the following fields:
- ``Contact``: The person that can be contacted for further information about
  the task.

A task might have `[ABCD]` code after its name. This code can be used to grep
into the code for `TODO` entries related to it.

Enablement (Rust)
=================

Tasks that are not directly related to nova-core, but are preconditions in terms
of required APIs.

FromPrimitive API
-----------------
FromPrimitive API [FPRI]
------------------------

Sometimes the need arises to convert a number to a value of an enum or a
structure.
@@ -41,8 +44,27 @@ automatically generates the corresponding mappings between a value and a number.
| Complexity: Beginner
| Link: https://docs.rs/num/latest/num/trait.FromPrimitive.html

Generic register abstraction
----------------------------
Conversion from byte slices for types implementing FromBytes [TRSM]
-------------------------------------------------------------------

We retrieve several structures from byte streams coming from the BIOS or loaded
firmware. At the moment converting the bytes slice into the proper type require
an inelegant `unsafe` operation; this will go away once `FromBytes` implements
a proper `from_bytes` method.

| Complexity: Beginner

CoherentAllocation improvements [COHA]
--------------------------------------

`CoherentAllocation` needs a safe way to write into the allocation, and to
obtain slices within the allocation.

| Complexity: Beginner
| Contact: Abdiel Janulgue

Generic register abstraction [REGA]
-----------------------------------

Work out how register constants and structures can be automatically generated
through generalized macros.
@@ -102,16 +124,40 @@ Usage:
	let boot0 = Boot0::read(&bar);
	pr_info!("Revision: {}\n", boot0.revision());

Note: a work-in-progress implementation currently resides in
A work-in-progress implementation currently resides in
`drivers/gpu/nova-core/regs/macros.rs` and is used in nova-core. It would be
nice to improve it (possibly using proc macros) and move it to the `kernel`
crate so it can be used by other components as well.

Features desired before this happens:

* Relative register with build-time base address validation,
* Arrays of registers with build-time index validation,
* Make I/O optional I/O (for field values that are not registers),
* Support other sizes than `u32`,
* Allow visibility control for registers and individual fields,
* Use Rust slice syntax to express fields ranges.

| Complexity: Advanced
| Contact: Alexandre Courbot

Delay / Sleep abstractions
--------------------------
Numerical operations [NUMM]
---------------------------

Nova uses integer operations that are not part of the standard library (or not
implemented in an optimized way for the kernel). These include:

- Aligning up and down to a power of two,
- The "Find Last Set Bit" (`fls` function of the C part of the kernel)
  operation.

A `num` core kernel module is being designed to provide these operations.

| Complexity: Intermediate
| Contact: Alexandre Courbot

Delay / Sleep abstractions [DLAY]
---------------------------------

Rust abstractions for the kernel's delay() and sleep() functions.

@@ -159,18 +205,6 @@ mailing list yet.
| Complexity: Intermediate
| Contact: Abdiel Janulgue

ELF utils
---------

Rust implementation of ELF header representation to retrieve section header
tables, names, and data from an ELF-formatted images.

There is preceding work from Abdiel Janulgue, which hasn't made it to the
mailing list yet.

| Complexity: Beginner
| Contact: Abdiel Janulgue

PCI MISC APIs
-------------

@@ -179,12 +213,11 @@ capability, MSI API abstractions.

| Complexity: Beginner

Auxiliary bus abstractions
--------------------------

Rust abstraction for the auxiliary bus APIs.
XArray bindings [XARR]
----------------------

This is needed to connect nova-core to the nova-drm driver.
We need bindings for `xa_alloc`/`xa_alloc_cyclic` in order to generate the
auxiliary device IDs.

| Complexity: Intermediate

@@ -216,15 +249,6 @@ Build the radix3 page table to map the firmware.
| Complexity: Intermediate
| Contact: Abdiel Janulgue

vBIOS support
-------------

Parse the vBIOS and probe the structures required for driver initialization.

| Contact: Dave Airlie
| Reference: Vec extensions
| Complexity: Intermediate

Initial Devinit support
-----------------------

@@ -234,23 +258,6 @@ configuration.
| Contact: Dave Airlie
| Complexity: Beginner

Boot Falcon controller
----------------------

Infrastructure to load and execute falcon (sec2) firmware images; handle the
GSP falcon processor and fwsec loading.

| Complexity: Advanced
| Contact: Dave Airlie

GPU Timer support
-----------------

Support for the GPU's internal timer peripheral.

| Complexity: Beginner
| Contact: Dave Airlie

MMU / PT management
-------------------

+1 −1
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ pub(crate) fn new(dev: &device::Device<device::Bound>, len: usize) -> Result<Sel

    pub(crate) fn from_data(dev: &device::Device<device::Bound>, data: &[u8]) -> Result<Self> {
        Self::new(dev, data.len()).map(|mut dma_obj| {
            // TODO: replace with `CoherentAllocation::write()` once available.
            // TODO[COHA]: replace with `CoherentAllocation::write()` once available.
            // SAFETY:
            // - `dma_obj`'s size is at least `data.len()`.
            // - We have just created this object and there is no other user at this stage.
+1 −1
Original line number Diff line number Diff line
@@ -42,7 +42,7 @@ fn probe(pdev: &pci::Device<Core>, _info: &Self::IdInfo) -> Result<Pin<KBox<Self
                _reg: auxiliary::Registration::new(
                    pdev.as_ref(),
                    c_str!("nova-drm"),
                    0, // TODO: Once it lands, use XArray; for now we don't use the ID.
                    0, // TODO[XARR]: Once it lands, use XArray; for now we don't use the ID.
                    crate::MODULE_NAME
                )?,
            }),
+7 −1
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ pub(crate) enum FalconCoreRev {
    Rev7 = 7,
}

// TODO[FPRI]: replace with `FromPrimitive`.
impl TryFrom<u8> for FalconCoreRev {
    type Error = Error;

@@ -68,6 +69,7 @@ pub(crate) enum FalconCoreRevSubversion {
    Subversion3 = 3,
}

// TODO[FPRI]: replace with `FromPrimitive`.
impl TryFrom<u8> for FalconCoreRevSubversion {
    type Error = Error;

@@ -101,6 +103,7 @@ pub(crate) enum FalconSecurityModel {
    Heavy = 3,
}

// TODO[FPRI]: replace with `FromPrimitive`.
impl TryFrom<u8> for FalconSecurityModel {
    type Error = Error;

@@ -128,6 +131,7 @@ pub(crate) enum FalconModSelAlgo {
    Rsa3k = 1,
}

// TODO[FPRI]: replace with `FromPrimitive`.
impl TryFrom<u8> for FalconModSelAlgo {
    type Error = Error;

@@ -148,6 +152,7 @@ pub(crate) enum DmaTrfCmdSize {
    Size256B = 0x6,
}

// TODO[FPRI]: replace with `FromPrimitive`.
impl TryFrom<u8> for DmaTrfCmdSize {
    type Error = Error;

@@ -199,6 +204,7 @@ pub(crate) enum FalconFbifTarget {
    NoncoherentSysmem = 2,
}

// TODO[FPRI]: replace with `FromPrimitive`.
impl TryFrom<u8> for FalconFbifTarget {
    type Error = Error;

@@ -354,7 +360,7 @@ fn reset_eng(&self, bar: &Bar0) -> Result {

        regs::NV_PFALCON_FALCON_ENGINE::alter(bar, E::BASE, |v| v.set_reset(true));

        // TODO: replace with udelay() or equivalent once available.
        // TODO[DLAY]: replace with udelay() or equivalent once available.
        // TIMEOUT: falcon engine should not take more than 10us to reset.
        let _: Result = util::wait_on(Duration::from_micros(10), || None);

+5 −5
Original line number Diff line number Diff line
@@ -42,10 +42,10 @@ fn signature_reg_fuse_version_ga102(
    engine_id_mask: u16,
    ucode_id: u8,
) -> Result<u32> {
    // TODO: The ucode fuse versions are contained in the FUSE_OPT_FPF_<ENGINE>_UCODE<X>_VERSION
    // registers, which are an array. Our register definition macros do not allow us to manage them
    // properly, so we need to hardcode their addresses for now. Clean this up once we support
    // register arrays.
    // TODO[REGA]: The ucode fuse versions are contained in the
    // FUSE_OPT_FPF_<ENGINE>_UCODE<X>_VERSION registers, which are an array. Our register
    // definition macros do not allow us to manage them properly, so we need to hardcode their
    // addresses for now. Clean this up once we support register arrays.

    // Each engine has 16 ucode version registers numbered from 1 to 16.
    if ucode_id == 0 || ucode_id > 16 {
@@ -69,7 +69,7 @@ fn signature_reg_fuse_version_ga102(
    let reg_fuse_version =
        bar.read32(reg_fuse_base + ((ucode_id - 1) as usize * core::mem::size_of::<u32>()));

    // TODO: replace with `last_set_bit` once it lands.
    // TODO[NUMM]: replace with `last_set_bit` once it lands.
    Ok(u32::BITS - reg_fuse_version.leading_zeros())
}

Loading