oxidecomputer / oxidecomputer/hubris

want a way to add attribute to types generated by `fpga-regmap`

Open
#2,656 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

build
Dominant language
Rust
Stars
3.6k
Forks
239
Avg merge
1d 12h
Merged PRs (30d)
23

Description

This originally came up in https://github.com/oxidecomputer/hubris/pull/2652#discussion_r3817895716.

It would be nice if there was a way for users of the fpga-regmap codegen to request that additional Rust attributes be added to generated types. This is mostly so that we can add derive attributes for additional traits we'd like the generated types to implement (such as counters::Count, microcbor::Encode for ereports, serde traits, etc).

I think it's probably better to be able to pass in an arbitrary attribute rather than "derive these additional traits", because that way, we can also request an attribute like #[cfg(feature = "counters", derive(counters::Count)]. This way, if the regmap codegen is being included in a library crate rather than a driver, the crate can feature flag things like counters or serialization. This is mostly important in the Tofino sequencer regmap currently, since types it generates are used by a couple different tasks.

I imagine the interface to this would be something like a CodegenSettings type in fpga-regmap that provides a builder interface to add additional attributes. Then, the drv-sidecar-mainboard-controller build script could write something like this:

    let out_dir = build_util::out_dir();
    let out_file = out_dir.join("sidecar_mainboard_controller.rs");
    let mut file = fs::File::create(out_file)?;
    
    let fpga_codegen = fpga_regmap::CodegenSettings::default()
        // Naming subject to change...
        .additional_attribute(
           "Reg::TOFINO_SEQ_ERROR::ValueEncoded", // the name of the generated type
           "#[cfg_attr(feature = \"counters\", derive(counters::Count)]", // attribute
        )
        // example of multiple types
        .additional_attribute(
           "Reg::TOFINO_SEQ_STEP::ValueEncoded",
           "#[derive(microcbor::Encode)]",
        );
    write!(
        &mut file,
        "{}",
        fpga_codegen.fpga_regs(include_str!("sidecar_mainboard_controller.json"))?,
    )?;

Then, when generating the register map, the codegen would check if a generated type name is in the map of types that want additional attributes, and add those attributes to the generated code.

I'd probably want this to return an error if there were any type names which the user requested additional attributes for but which the codegen did not generate. This would indicate that you either got the name of the generated type wrong, or the FPGA register map has changed in a way that no longer generates that type, and I think it should fail loudly instead of silently in that case.

I don't remember if the fpga-regmap codegen is using quote! or just strings with Rust code off the top of my head, but if it's using quote!, we could probably also take impl ToTokens or whatever instead of string arguments for the attribute, and syn::Path[^1] for the type name. That way, we are enforcing in the API that the things the caller passes in parse as valid Rust code, rather than just slamming random strings into the generated code.

[^1]: I think that's the right syn type, it could be something else?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the fpga-regmap codegen entry point and the drv/sidecar-mainboard-controller/build.rs example, then trace how generated type names and attributes are emitted. Define the CodegenSettings interface, attribute handling, and validation for unmatched type names. Done means callers can request attributes for generated types and receive an error for names that are not generated.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
build-system, embedded-iot, tooling
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.