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

[runtime] Start recovery flow in the runtime #1904

Open
wants to merge 5 commits into
base: main-2.x
Choose a base branch
from

Conversation

swenson
Copy link
Contributor

@swenson swenson commented Jan 23, 2025

This stubs out the recovery flow in the runtime.

We also update the DMA peripheral so that it can be used as a
ureg::Mmio, which will allow us to use the autogenerated I3C recovery
register interface instead of hardcoding offsets.

We also had to modify ureg slightly to add Default, TryFrom<u32>,
and TryInto<u32> constraints to Uint to make it simpler to use with the
DMA interface.

This builds on #1867 and rewrites it to use the updated DMA interface.

@swenson swenson added the Caliptra v2.0 Items to be considered for v2.0 Release label Jan 23, 2025
@@ -62,7 +106,7 @@ pub struct DmaWriteTransaction {

/// Dma Widget
pub struct Dma {
dma: AxiDmaReg,
dma: Cell<Option<AxiDmaReg>>,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We have to switch to a Cell because the Mmio and MmioMut interfaces require that the methods use &self instead of &mut self, so we need interior mutability.

For safety, I used a with_dma() to ensure that the AxiDmaReg is only used by one function at a time, though this is probably overkill since Caliptra is single-threaded.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggest simplifying the code (if possible) with the single-threaded execution assumption.

@swenson swenson force-pushed the download-manifest-mcu-fw branch 2 times, most recently from 9152e52 to c9b226d Compare January 23, 2025 22:00
self.dma.set(Some(dma));
Ok(result)
} else {
Err(CaliptraError::RUNTIME_INTERNAL) // should never happen
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggest renaming this to something like 'DRIVERS_INTERNAL' to disambiguate from a Runtime app error.

.auth_manifest_image_metadata_col = image_metadata_collection;
// [TODO][CAP2]: capture measurement of Soc manifest?
// [TODO][CAP2]: this should be writing to MCU SRAM directly via AXI
let _mcu_size_bytes = dma_recovery.download_image_to_mbox(SOC_MANIFEST_INDEX)?;
Copy link
Collaborator

Choose a reason for hiding this comment

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

This should use the MCU_FIRMWARE_INDEX.

mhatrevi
mhatrevi previously approved these changes Jan 28, 2025
Copy link
Collaborator

@mhatrevi mhatrevi left a comment

Choose a reason for hiding this comment

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

Please see the feedback.

@@ -171,6 +176,9 @@ impl Drivers {
ResetReason::ColdReset => {
cfi_assert_eq(self.soc_ifc.reset_reason(), ResetReason::ColdReset);
Self::initialize_dpe(self)?;
if self.soc_ifc.active_mode() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I wonder if this should be a build-time flag since for a given integration it's either active or not. Otoh, it's probably easier to have a less complicated test matrix for RT.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Would we plan on building a separate active mode ROM then?

Comment on lines 45 to 48
let _soc_size_bytes = dma_recovery.download_image_to_mbox(SOC_MANIFEST_INDEX)?;
let Some(preamble) = AuthManifestPreamble::read_from_prefix(drivers.mbox.raw_mailbox_contents()) else {
return Err(CaliptraError::IMAGE_VERIFIER_ERR_MANIFEST_SIZE_MISMATCH);
};
let Some(image_metadata_collection) = AuthManifestImageMetadataCollection::read_from_prefix(&drivers.mbox.raw_mailbox_contents()[AUTH_MANIFEST_PREAMBLE_SIZE..]) else {
return Err(CaliptraError::IMAGE_VERIFIER_ERR_MANIFEST_SIZE_MISMATCH);
};
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: can probably simplify this by making a single stuct that contains AuthManifestPreamble and AuthManifestImageMetadataCollection and then doing a single read.

ureg/src/lib.rs Outdated Show resolved Hide resolved
ureg/src/lib.rs Outdated
Comment on lines 35 to 37
fn from_u32(val: u32) -> Self {
(val & 0xff) as u8
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this needed for multiple types? I think I would prefer to the the truncation closer to the specific register that needs it so that we can review specific usages as not dropping any meaningful bytes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's not truly needed except on paper, as we don't have any 8- or 16-bit registers.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think we can drop this and replace it with TryFrom<u32>.


// // download SoC manifest
let _soc_size_bytes = dma_recovery.download_image_to_mbox(SOC_MANIFEST_INDEX)?;
let Some(manifest) = AuthorizationManifest::read_from_prefix(drivers.mbox.raw_mailbox_contents()) else {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is not efficient. AuthorizationManifest is of 14284 bytes; most of the time there will only be a handful of image digests in it. I would simply add a TODO here to call the existing set_manifest_code.

@swenson swenson force-pushed the download-manifest-mcu-fw branch from 0eade71 to c56a00d Compare January 30, 2025 18:51
@swenson
Copy link
Contributor Author

swenson commented Jan 30, 2025

PR updated and rebased. PTAL

@swenson swenson force-pushed the download-manifest-mcu-fw branch from c56a00d to 029bf2a Compare January 31, 2025 17:24
This stubs out the recovery flow in the runtime.

We also update the DMA peripheral so that it can be used as a
`ureg::Mmio`, which will allow us to use the autogenerated I3C recovery
register interface instead of hardcoding offsets.

We also had to modify `ureg` slightly to remove the unused `impl Uint`
for `u64` (because we don't don't support 64-bit AXI transfers) and add
a `from_u32()` method for the (unused) `u8` and `u16` implementations.

This builds on #1867 and rewrites it to use the updated DMA interface.
@swenson swenson force-pushed the download-manifest-mcu-fw branch from 029bf2a to 020f2a3 Compare January 31, 2025 17:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Caliptra v2.0 Items to be considered for v2.0 Release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants