[PATCH v3 00/16] rust: io: support register projections and remove relative registers

Gary Guo <[email protected]>
Newsgroups org.kernel.vger.rust-for-linux,dev.linux.lists.driver-core,dev.linux.lists.nova-gpu,org.freedesktop.lists.dri-devel,org.kernel.vger.linux-kernel,org.kernel.vger.linux-pci
Message-ID <[email protected]>
Currently registers work for all untyped I/O regions, which is not ideal.
It allows registers defined for device A to work for another device B and
there is no safeguarding at all.

Change this by requiring a base type for registers. `register!` can still
define registers on untyped `Region`s, although users would need to do so
explicitly and supply a concrete type.

This change makes it possible to use projection for relative registers;
relative registers can be implemented by defining new types for the I/O
subregions and just define registers for these subregion types like normal
registers.

This actually results in more ergnomic code for users of relative registers
(currently only nova-core), because non-array registers can be written to
with

    #[...]
    struct Subregion(...);

    register! {
        base: MyBase;
        SUBREGION: Subregion @ ...;
    }

    register! {
        base: Subregion;
        REG(u32) @ .. { .. }
    }

    let subregion = io_project!(bar, build: SUBREGION);
    subregion.read(REG)
    subregion.write_reg(reg)

instead of

    struct SubregionType;
    struct Subregion;
    impl RegisterBase<SubregionType> for Subregion {
        const BASE: usize = ...;
    }

    register! {
        REG(u32) @ Subregion + .. { .. }
    }

    bar.read(REG::of::<Subregion>())
    bar.write(WithBase::of::<Subregion>(), reg)

This also allows a lot more code sharing between I/O projection and
`register!` macro.

The expressiveness power of Rust declarative macros is becoming limiting,
so it is converted to a proc macro before new features being added to it.

Signed-off-by: Gary Guo <[email protected]>
---
Changes in v3:
- Convert the `register!` macro to syn.
- Add check to ensure register and alias share the same base. (Alex)
- Split transmute functionalities to `kernel::mem`. (Alex)
- Remove some stray trait bound in nova code. (Alex)
- Link to v2: https://patch.msgid.link/[email protected]

Changes in v2:
- Extract type conversion from `register!` to `Io`
- Redesign the API to be centered around regsiter projections.
  * Support register projections in `io_project!`
  * Support adding register definition without defining bitfield
  * Subregions is thus unified with other registers.
- Store projected subregions in `Falcon` for nova.
- Link to v1: https://patch.msgid.link/[email protected]

---
Gary Guo (16):
      rust: io: register: reimplement as proc macro
      rust: mem: add `transmute` with deferred size check
      rust: mem: add `AsRepr` and `AsReprMut`
      rust: io: perform conversions using `AsRepr`
      rust: io: support register projections
      rust: io: register: allow explicit base type specification
      gpu: nova-core: specify base type for registers
      drm/tyr: specify base type for registers
      samples: rust: pci: specify base type for registers
      rust: io: register: make register have a typed base
      rust: io: register: support fixed offset register without bitfield
      gpu: nova-core: use projection for PFALCON and PFALCON2 registers
      gpu: nova-core: convert hshub0 from relative register to projection
      rust: io: register: remove relative registers
      rust: io: register: remove `Register` trait and cleanup macro
      rust: io: register: unify handling of register with/without bitfields

 MAINTAINERS                                        |   1 +
 drivers/gpu/drm/tyr/driver.rs                      |   1 +
 drivers/gpu/drm/tyr/fw.rs                          |   5 +-
 drivers/gpu/drm/tyr/regs.rs                        |  45 +-
 drivers/gpu/nova-core/driver.rs                    |   1 +
 drivers/gpu/nova-core/falcon.rs                    | 157 ++---
 drivers/gpu/nova-core/falcon/fsp.rs                |  63 +-
 drivers/gpu/nova-core/falcon/gsp.rs                |  51 +-
 drivers/gpu/nova-core/falcon/hal/ga102.rs          |  62 +-
 drivers/gpu/nova-core/falcon/hal/tu102.rs          |   9 +-
 drivers/gpu/nova-core/falcon/sec2.rs               |  37 +-
 drivers/gpu/nova-core/fb/hal/gb100.rs              |  59 +-
 drivers/gpu/nova-core/fb/regs.rs                   |  29 +-
 drivers/gpu/nova-core/firmware/fwsec/bootloader.rs |  18 +-
 drivers/gpu/nova-core/gsp/hal/tu102.rs             |   7 +-
 drivers/gpu/nova-core/gsp/regs.rs                  |   9 +-
 drivers/gpu/nova-core/regs.rs                      | 115 ++--
 drivers/gpu/nova-core/vbios.rs                     |  11 +-
 rust/kernel/bitfield.rs                            |  10 +
 rust/kernel/device_id.rs                           |   3 +-
 rust/kernel/io.rs                                  | 188 +++--
 rust/kernel/io/register.rs                         | 757 +++++----------------
 rust/kernel/lib.rs                                 |   1 +
 rust/kernel/mem.rs                                 | 185 +++++
 rust/kernel/sync/atomic.rs                         |   4 +-
 rust/macros/io/mod.rs                              |   3 +
 rust/macros/io/register.rs                         | 284 ++++++++
 rust/macros/lib.rs                                 |  10 +
 samples/rust/rust_driver_pci.rs                    |   4 +
 29 files changed, 1175 insertions(+), 954 deletions(-)
---
base-commit: e6664f2b33db9b6811eb4cec109f06cb2b4f458d
change-id: 20260721-typed_register-176eab3abee7

Best regards,
--  
Gary Guo <[email protected]>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.