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

sw: Refactored pinmux driver #354

Merged
merged 3 commits into from
Nov 14, 2024
Merged

sw: Refactored pinmux driver #354

merged 3 commits into from
Nov 14, 2024

Conversation

HU90m
Copy link
Member

@HU90m HU90m commented Nov 13, 2024

The changes allow for easier access control and compartmentalisation.

Also the pinmux block input documentation names to match the driver. The names in the driver can't have square brackets for IO indices.

The changes allow for easier access control and compartmentalisation.
Copy link
Contributor

@AlexJones0 AlexJones0 left a comment

Choose a reason for hiding this comment

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

This looks like a big improvement to me, thanks for working on this @HU90m! Just a few comments.

I've tested with the manual pinmux check procedure and that still works fine. The simple pinmux check is broken however, due to some slightly incorrect logic when I wrote that (I wait for the transmit FIFO to be empty, but not necessarily for transmission to finish). The change from using pinmux.select...() to sink.disable() actually optimises the pinmux enough that it causes this bug to manifest. I fixed it with the following patch:

diff --git a/sw/cheri/checks/pinmux_check.cc b/sw/cheri/checks/pinmux_check.cc
index e6d71535..be8cd027 100644
--- a/sw/cheri/checks/pinmux_check.cc
+++ b/sw/cheri/checks/pinmux_check.cc
@@ -25,9 +25,7 @@ using namespace CHERI;
  * Blocks until the UART transmit FIFO is empty.
  */
 void block_until_uart_tx_done(Capability<volatile OpenTitanUart> uart) {
-  while (uart->transmit_fifo_level() > 0) {
-    asm volatile("");
-  }
+  while (!(uart->status & uart->StatusTransmitIdle));
 }
 
 /**

Haven't had a chance to run the RS485 checks but I think those only use Pinmux for the initial configuration so they should be fine.

sw/cheri/common/platform-pinmux.hh.tpl Outdated Show resolved Hide resolved
Debug::log("Selected option is not valid for this block.");
bool select(uint8_t source) {
if (source >= sources_number(sink)) {
Debug::log("Selected source not within the range of valid sources.");
Copy link
Contributor

Choose a reason for hiding this comment

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

Just a quick thought while we're making changes: it might be nicer to have this debug log actually report the maximum value, so that a user can match it against what they expect to see in the docs and more quickly/easily notice uses of the wrong pins, or outdated docs/drivers. Maybe something like "Selected source {source} not within the range of {num_sources} valid sources for sink at offset {sink}"?

sw/cheri/common/platform-pinmux.hh.tpl Outdated Show resolved Hide resolved
Comment on lines +153 to +162
inline Sink<SinkEnum> _get_sink(volatile uint8_t *base_register, const SinkEnum sink) {
CHERI::Capability reg = {base_register + static_cast<ptrdiff_t>(sink)};
reg.bounds() = sizeof(uint8_t);
return Sink<SinkEnum>{reg, sink};
Copy link
Contributor

Choose a reason for hiding this comment

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

Out of curiosity, how do you plan to handle this in the RTOS version of the driver? Currently I think you'd have to get a capability to the entire Pinmux range and then modify that to only the range of the specific sink selector register, and so while the compartmentalisation would be nicer, auditing would still show access to the entire Pinmux MMIO region even if only a small subset is being used.

Or is the idea that you would just have one isolated auditable compartment that gets the entire capability, and provides specific sink capabilities to other compartments?

Copy link
Member Author

Choose a reason for hiding this comment

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

There will be two contiguous MMIO regions described in the board file: block sinks and pin sinks. Any compartment could request access to either or both. This can be audited normally.

Yes, the idea of having {Pin,Block}Sinks::get() return a capability with a bound only covering the particular sink is that this allows a compartment to give another compartment permission to configure the particular sink, without giving access to the whole region.

Copy link
Contributor

Choose a reason for hiding this comment

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

I see, that makes sense. I think it would be nicer if for auditing purposes no compartments were ever made to get access to the full MMIO regions, and instead only had to get access to the pins required, but I suppose that would either require defining 155 sink devices in the board description file, or (preferably) changes in upstream cheriot-rtos to support this kind of granular capability loading functionality (e.g. MMIO_CAPABILITY(uint8_t, pinmux, offset=0x012, bounds=0x8) would be nice for example).

sw/cheri/common/platform-pinmux.hh.tpl Outdated Show resolved Hide resolved
sw/cheri/common/platform-pinmux.hh.tpl Outdated Show resolved Hide resolved
sw/cheri/common/platform-pinmux.hh.tpl Outdated Show resolved Hide resolved
sw/cheri/checks/pinmux_check.cc Show resolved Hide resolved
sw/cheri/tests/pinmux_tests.hh Outdated Show resolved Hide resolved
sw/cheri/tests/pinmux_tests.hh Show resolved Hide resolved
HU90m and others added 2 commits November 14, 2024 13:53
The names in the driver can't have square brackets for IO indices.
Check only waited for an empty fifo and not for the transmission to be
finished. New pinmux driver allowed optimisations caused the check to
break because of this.

Co-authored-by: Alex Jones <[email protected]>
@HU90m
Copy link
Member Author

HU90m commented Nov 14, 2024

Thanks for the speedy and thorough review Alex!

@HU90m HU90m merged commit 453f0b2 into lowRISC:main Nov 14, 2024
3 checks passed
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.

2 participants