diff --git a/.github/workflows/changelog.yaml b/.github/workflows/changelog.yaml index 85ccda85..86541174 100644 --- a/.github/workflows/changelog.yaml +++ b/.github/workflows/changelog.yaml @@ -21,6 +21,8 @@ jobs: - 'riscv/**' riscv-rt: - 'riscv-rt/**' + riscv-pac: + - 'riscv-pac/**' - name: Check for CHANGELOG.md (riscv) if: steps.changes.outputs.riscv == 'true' @@ -37,3 +39,11 @@ jobs: changeLogPath: ./riscv-rt/CHANGELOG.md skipLabels: 'skip changelog' missingUpdateErrorMessage: 'Please add a changelog entry in the riscv-rt/CHANGELOG.md file.' + + - name: Check for CHANGELOG.md (riscv-pac) + if: steps.changes.outputs.riscv-pac == 'true' + uses: dangoslen/changelog-enforcer@v3 + with: + changeLogPath: ./riscv-pac/CHANGELOG.md + skipLabels: 'skip changelog' + missingUpdateErrorMessage: 'Please add a changelog entry in the riscv-pac/CHANGELOG.md file.' diff --git a/Cargo.toml b/Cargo.toml index 4533b2e7..b97d6de3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,5 +2,6 @@ resolver = "2" members = [ "riscv", + "riscv-pac", "riscv-rt", ] diff --git a/riscv-pac/CHANGELOG.md b/riscv-pac/CHANGELOG.md new file mode 100644 index 00000000..d17dc4a1 --- /dev/null +++ b/riscv-pac/CHANGELOG.md @@ -0,0 +1,12 @@ +# Change Log + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/) +and this project adheres to [Semantic Versioning](http://semver.org/). + +## [Unreleased] + +### Added + +- Add `InterruptNumber`, `PriorityNumber`, and `HartIdNumber` traits. diff --git a/riscv-pac/Cargo.toml b/riscv-pac/Cargo.toml new file mode 100644 index 00000000..1e8d5cc3 --- /dev/null +++ b/riscv-pac/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "riscv-pac" +version = "0.1.0" +edition = "2021" +rust-version = "1.60" +repository = "https://github.com/rust-embedded/riscv" +authors = ["The RISC-V Team "] +categories = ["embedded", "hardware-support", "no-std"] +description = "Low level access to RISC-V processors" +documentation = "https://docs.rs/riscv-pac" +keywords = ["riscv", "register", "peripheral"] +license = "ISC" + +[package.metadata.docs.rs] +default-target = "riscv64imac-unknown-none-elf" +targets = [ + "riscv32i-unknown-none-elf", "riscv32imc-unknown-none-elf", "riscv32imac-unknown-none-elf", + "riscv64imac-unknown-none-elf", "riscv64gc-unknown-none-elf", +] diff --git a/riscv-pac/README.md b/riscv-pac/README.md new file mode 100644 index 00000000..61c50447 --- /dev/null +++ b/riscv-pac/README.md @@ -0,0 +1,40 @@ +[![crates.io](https://img.shields.io/crates/d/riscv.svg)](https://crates.io/crates/riscv) +[![crates.io](https://img.shields.io/crates/v/riscv.svg)](https://crates.io/crates/riscv) + +# `riscv-pac` + +> Target-specific traits to be implemented by PACs + +This project is developed and maintained by the [RISC-V team][team]. + +## [Documentation](https://docs.rs/crate/riscv) + +## Minimum Supported Rust Version (MSRV) + +This crate is guaranteed to compile on stable Rust 1.60 and up. It *might* +compile with older versions but that may change in any new patch release. + +## License + +Copyright 2023-2024s [RISC-V team][team] + +Permission to use, copy, modify, and/or distribute this software for any purpose +with or without fee is hereby granted, provided that the above copyright notice +and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +## Code of Conduct + +Contribution to this crate is organized under the terms of the [Rust Code of +Conduct][CoC], the maintainer of this crate, the [RISC-V team][team], promises +to intervene to uphold that code of conduct. + +[CoC]: CODE_OF_CONDUCT.md +[team]: https://github.com/rust-embedded/wg#the-risc-v-team diff --git a/riscv-pac/src/lib.rs b/riscv-pac/src/lib.rs new file mode 100644 index 00000000..934e7aad --- /dev/null +++ b/riscv-pac/src/lib.rs @@ -0,0 +1,79 @@ +#![no_std] + +/// Trait for enums of target-specific external interrupt numbers. +/// +/// This trait should be implemented by a peripheral access crate (PAC) +/// on its enum of available external interrupts for a specific device. +/// Each variant must convert to a `u16` of its interrupt number. +/// +/// # Safety +/// +/// * This trait must only be implemented on a PAC of a RISC-V target. +/// * This trait must only be implemented on enums of external interrupts. +/// * Each enum variant must represent a distinct value (no duplicates are permitted), +/// * Each enum variant must always return the same value (do not change at runtime). +/// * All the interrupt numbers must be less than or equal to `MAX_INTERRUPT_NUMBER`. +/// * `MAX_INTERRUPT_NUMBER` must coincide with the highest allowed interrupt number. +pub unsafe trait InterruptNumber: Copy { + /// Highest number assigned to an interrupt source. + const MAX_INTERRUPT_NUMBER: u16; + + /// Converts an interrupt source to its corresponding number. + fn number(self) -> u16; + + /// Tries to convert a number to a valid interrupt source. + /// If the conversion fails, it returns an error with the number back. + fn from_number(value: u16) -> Result; +} + +/// Trait for enums of priority levels. +/// +/// This trait should be implemented by a peripheral access crate (PAC) +/// on its enum of available priority numbers for a specific device. +/// Each variant must convert to a `u8` of its priority level. +/// +/// # Safety +/// +/// * This trait must only be implemented on a PAC of a RISC-V target. +/// * This trait must only be implemented on enums of priority levels. +/// * Each enum variant must represent a distinct value (no duplicates are permitted). +/// * Each enum variant must always return the same value (do not change at runtime). +/// * All the priority level numbers must be less than or equal to `MAX_PRIORITY_NUMBER`. +/// * `MAX_PRIORITY_NUMBER` must coincide with the highest allowed priority number. +pub unsafe trait PriorityNumber: Copy { + /// Number assigned to the highest priority level. + const MAX_PRIORITY_NUMBER: u8; + + /// Converts a priority level to its corresponding number. + fn number(self) -> u8; + + /// Tries to convert a number to a valid priority level. + /// If the conversion fails, it returns an error with the number back. + fn from_number(value: u8) -> Result; +} + +/// Trait for enums of HART identifiers. +/// +/// This trait should be implemented by a peripheral access crate (PAC) +/// on its enum of available HARTs for a specific device. +/// Each variant must convert to a `u16` of its HART ID number. +/// +/// # Safety +/// +/// * This trait must only be implemented on a PAC of a RISC-V target. +/// * This trait must only be implemented on enums of HART IDs. +/// * Each enum variant must represent a distinct value (no duplicates are permitted), +/// * Each anum variant must always return the same value (do not change at runtime). +/// * All the HART ID numbers must be less than or equal to `MAX_HART_ID_NUMBER`. +/// * `MAX_HART_ID_NUMBER` must coincide with the highest allowed HART ID number. +pub unsafe trait HartIdNumber: Copy { + /// Highest number assigned to a context. + const MAX_HART_ID_NUMBER: u16; + + /// Converts a HART ID to its corresponding number. + fn number(self) -> u16; + + /// Tries to convert a number to a valid HART ID. + /// If the conversion fails, it returns an error with the number back. + fn from_number(value: u16) -> Result; +}