Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use riscv section for RISC-V targets #856

Merged
merged 2 commits into from
Oct 21, 2024

Conversation

romancardenas
Copy link
Contributor

This PR uses my proposed riscv SVD section to generate RISC-V PACs using the new set of traits in riscv-pac.

In this PR, the mod interrupt in RISC-V targets is handled differently, and includes:

  • ExternalInterrupts (very similar to current Interrupts)
  • CoreInterrupts (this is new, previously it just assumed the peripheral follows the RISC-V standard)
  • Priority levels (necessary for interfacing standard peripherals with trait bounds)
  • HartIds (necessary for interfacing standard peripherals with trait bounds).

Also, the PAC does not directly generate all the handlers array and so on. Instead, it relies on macros exposed in riscv-pac.

I still need some time to pollish everything, but feedback is more than welcome :)

Solves #786

@romancardenas romancardenas requested a review from a team as a code owner July 1, 2024 07:22
@romancardenas
Copy link
Contributor Author

This PR shows how an updated PAC would look like over e310x chips

@romancardenas
Copy link
Contributor Author

Added the unstable-riscv feature to optionally activate the proposed new functionality. I still have to include support for riscv-peripheral implementations depending on the name of the peripheral.

Copy link
Member

@Emilgardis Emilgardis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good start! should probably be marked as a draft, I see a bunch of todos

CHANGELOG.md Outdated Show resolved Hide resolved
@Emilgardis Emilgardis marked this pull request as draft August 20, 2024 15:36
@Emilgardis Emilgardis requested review from Emilgardis and a team August 20, 2024 15:36
@romancardenas
Copy link
Contributor Author

Yes! I'm currently working on a bunch of changes to use standard peripherals when possible, so it will take a few more iterations until it is ready to merge

@romancardenas
Copy link
Contributor Author

romancardenas commented Aug 20, 2024

As shown in this PR, now it is possible to use riscv-peripheral standard implementations (i.e., CLINT and PLIC) instead of the ones generated by svd2rust. This shows the new outcome. Note that it only takes one macro call per standard peripheral:

riscv_peripheral :: clint_codegen ! (base 0x2000000 , mtimecmps [mtimecmp0 = (crate :: interrupt :: Hart :: H0 , "[0](crate::interrupt::Hart::H0)")] , msips [msip0 = (crate :: interrupt :: Hart :: H0 , "[0](crate::interrupt::Hart::H0)")] ,);
riscv_peripheral :: plic_codegen ! (base 0xC000000 , ctxs [ctx0 = (crate :: interrupt :: Hart :: H0 , "[0](crate::interrupt::Hart::H0)")] ,);

To do list

  • Configuration parameter to select whether to use the standard macros or the old-school way.
  • A mechanism to specify the CLINT's clock frequency to benefit from its embedded-hal implementation.
  • Configuration parameter to activate the use of async_delay flag for CLINT.

Regarding the second point: what do you think about providing the CLINT clock frequency via a configuration parameter?

@romancardenas
Copy link
Contributor Author

I started with the configuration parameters... and decided to explore using configuration parameters only, leaving the SVD file untouched.

For the E310x chip, the configuration file would look like this.
What do you think about this alternative? I personally like it more.

@burrbull
Copy link
Member

I started with the configuration parameters... and decided to explore using configuration parameters only, leaving the SVD file untouched.

For the E310x chip, the configuration file would look like this.
What do you think about this alternative? I personally like it more.

Makes sense. But why a TOML? YAML should looks much cleaner for such things.

Also what should we do with svd-rs changes and released crates?

@romancardenas
Copy link
Contributor Author

Makes sense. But why a TOML? YAML should looks much cleaner for such things.

I converted the TOML file to YAML and the following command fails:

svd2rust --target riscv -c svd2rust.yaml -g -i e310x.svd
[ERROR svd2rust] Failed to parse value for parser #2
    
    Caused by:
        0: Failed parse TOML
        1: TOML parse error at line 1, column 16
             |
           1 | core_interrupts:
             |                ^
           expected `.`, `=`

From here, it looks like svd2rust only supports TOML configuration files

Also what should we do with svd-rs changes and released crates?

If we prefer this isolated configuration file approach (which I do), then all the stuff under the unstable-riscv feature will no longer be necessary, as all the RISC-V magic will happen in svd2rust only.

@burrbull
Copy link
Member

I think this should not be in svd2rust config file. It's better to use another --riscv-config file.yaml option as you may want to use different configs for different input SVDs but with the same svd2rust.toml.

@romancardenas
Copy link
Contributor Author

I addressed your suggestions. I'm not sure if my independent YAML file implementation is the best approach, let me know what you think.

You can see how I use it for E310x chips here

@romancardenas
Copy link
Contributor Author

romancardenas commented Sep 4, 2024

  • PAC using this PR: e310x
  • HAL using the result PAC: e310x-hal
  • BSP using the resulting HAL: hifive1
    • It contains an example using the PLIC and CLINT peripherals. You can emulate the CLINT example with QEMU
  • Software Interrupt handler SLIC: riscv-slic

@burrbull
Copy link
Member

@romancardenas still a draft?

@romancardenas
Copy link
Contributor Author

Not really, I don't expect to add any changes. I'm waiting to release the next version of the riscv crates in crates.io, though.

src/config.rs Outdated
Comment on lines 323 to 326
pub core_interrupts: Option<Vec<RiscvEnumItem>>,
pub exceptions: Option<Vec<RiscvEnumItem>>,
pub priorities: Option<Vec<RiscvEnumItem>>,
pub harts: Option<Vec<RiscvEnumItem>>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is None different from Some(Vec::empty) here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, if you define core_interrupts in your YAML file, svd2rust will generate a custom CoreInterrupt struct for your target, regardless of whether it is empty or not. Thus, an empty vector would probably be meaningless. I can change this behavior following any of your design decisions.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to say that you can leave just Vec<T> and check vec.is_empty() instead of option.is_some.

Possibly you should also mark a field with serde(default). Not sure.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will take a look to your suggestion!

@romancardenas romancardenas marked this pull request as ready for review October 20, 2024 08:36
@burrbull
Copy link
Member

I think this should not be in svd2rust config file. It's better to use another --riscv-config file.yaml option as you may want to use different configs for different input SVDs but with the same svd2rust.toml.

What about this?

I'd want to see something like this:

/// Common svd2rust options
struct Config {
   ...
   /// Path to YAML file with chip related settings
   pub settings: Option<PathBuf>,
}

#[non_exhaustive]
struct Settings {
    pub riscv_config: Option<RiscvConfig>,
    
    // other settings (for example #576)
}

@romancardenas
Copy link
Contributor Author

I'd want to see something like this:

/// Common svd2rust options
struct Config {
   ...
   /// Path to YAML file with chip related settings
   pub settings: Option<PathBuf>,
}

#[non_exhaustive]
struct Settings {
    pub riscv_config: Option<RiscvConfig>,
    
    // other settings (for example #576)
}

Oh, I see! I added a riscv_config parameter to the general configuration, but maybe it will be more scalable having a separate settings.yml file that includes the RISC-V-specific configuration (together with potentially new parameters such as Zaamo-only registers).

@romancardenas
Copy link
Contributor Author

@burrbull Let me know if the new version looks as you expected

@@ -30,6 +30,14 @@ pub fn render(d: &Device, config: &Config, device_x: &mut String) -> Result<Toke
}
};

let _settings = match config.settings.as_ref() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is it underscored?

Cargo.toml Outdated
@@ -35,13 +35,14 @@ default = ["bin", "json", "yaml"]
bin = ["dep:clap", "dep:env_logger", "serde", "dep:irx-config"]
json = ["dep:serde_json"]
yaml = ["dep:serde_yaml"]
unstable-riscv = ["irx-config/yaml"]
unstable-riscv = []
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it unstable yet?

@burrbull
Copy link
Member

Squash commits, please.

@romancardenas
Copy link
Contributor Author

Done

We use setting.yaml to support riscv 0.12.0 and riscv-rt 0.13.0
This feature also allows RISC-V targets to use standard peripheral
implementations with the riscv-peripheral crate.
@burrbull burrbull added this pull request to the merge queue Oct 21, 2024
Merged via the queue into rust-embedded:master with commit 8b809ac Oct 21, 2024
46 checks passed
@burrbull
Copy link
Member

Please, revert commits from svd-rs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants