This patch set goes across all the toolchains and brings
in the support for split SVD descriptions of SoCs.
This is helpful for dealing with designs that have multiple
"top" files for the same core IP set. For exmaple, you may have
a SoC that you are developing that targets silicon, but
you have a version that wraps this in additional peripherals
available only in an FPGA emulator that are used for debugging.
In this case, you can have one SVD file be the description of
the SoC itself, and another SVD file describe just the "delta"
introduced by the FPGA wrapper that emulates/controls the SoC.
- make the "base" field no longer public. It is accessible, but only
through an `unsafe` method, because, it is unsafe.
- add accessors to offest/mask fields. Because, it's not at all
unsafe to access these, and it can be useful for bit-ops that are
not part of the generic set of UTRA.
- add Arc to AtomicCSR, and require `std` for AtomicCSR types.
This should not break anything, I checked inside @foundation-devices
keyOS and they don't seem to be using AtomicCSR anywhere.
The Arc makes it a bit safer to clone the AtomicCSR base pointer
and share it between threads, but it will have an impact on performance.
The USB stack (which requires AtomicCSR) was regression testing and the
impact seems minimal.
Recall that the main purpose of AtomicCSR is to provide a CSR accessor
that does not require a mutable reference to the base object. This
can make certain Rust idioms a bit cleaner. We wrap the base accessor
in Arc+Atomic to try and improve the safety of throwing the borrow
checker under the bus, but it's still not perfect because hardware
mutable state can have side-effects within hardware itself that cannot
be modeled or checked by Rust's borrow checker.
this fix makes it so that
1) you always get a correct build when the SVD spec is toggled
2) you don't always rebuild when nothing has changed
(2) is with the caveat that the no-change flag is only clean
after your second build (i.e. your third run will be fast).
I'm not quite sure why but I think it's because the "changes"
to the config file tracker are computed throughout the first
build and the second build still sees that file as recently
changed, so, it'll trigger a rebuild (could also just be
a race condition because the timestamp of the rebuild is
at the same second that the file was regenerated, so conservatively
you'd rebuild the next time).
this cleans up some namespace issues when including
the utra crate which also refers to utra::generated::utra,
and there are CONST at the crate-level, and also functions
at the module-level which need disambiguation. By naming
the crate utra-lib this saves a bit of syntatic wrangling
at the top of every file.