Skip to content

Commit

Permalink
Use alternate chip reset for updates
Browse files Browse the repository at this point in the history
The standard ARM system reset will not reset certain hardware blocks,
notably the flash lock registers for the protected flash regions.
Use the alternate syscon reset to ensure we can write our CFPA updates.
  • Loading branch information
labbott committed Sep 5, 2023
1 parent f6f0966 commit 09c9708
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 5 deletions.
23 changes: 19 additions & 4 deletions drv/lpc55-syscon/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,17 @@ impl idl::InOrderSysconImpl for ServerImpl<'_> {

Ok(())
}

fn chip_reset(
&mut self,
_: &RecvMessage,
) -> Result<(), RequestError<core::convert::Infallible>> {
// Documented in 4.5.16 Software reset register of UM11126
self.syscon
.swr_reset
.write(|w| unsafe { w.swr_reset().bits(0x5a00_0001) });
panic!();
}
}

#[export_name = "main"]
Expand All @@ -219,7 +230,13 @@ fn main() -> ! {
// turning on PLLs and such
syscon.hslspiclksel.modify(|_, w| w.sel().enum_0x2());

set_reset_reason();
let pmc = unsafe { &*device::PMC::ptr() };

// Need this to be able to use the syscon reset that works for CFPA
// update
pmc.resetctrl.write(|w| w.swrresetenable().enable());

set_reset_reason(pmc);

let mut server = ServerImpl { syscon };

Expand All @@ -229,9 +246,7 @@ fn main() -> ! {
}
}

fn set_reset_reason() {
let pmc = unsafe { &*device::PMC::ptr() };

fn set_reset_reason(pmc: &device::pmc::RegisterBlock) {
// The Reset Reason is stored in the AOREG1 register in the power
// management block. This crypticly named register is set based
// on another undocumented register in the power management space.
Expand Down
2 changes: 1 addition & 1 deletion drv/lpc55-update-server/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ impl idl::InOrderUpdateImpl for ServerImpl<'_> {
if self.state == UpdateState::InProgress {
return Err(UpdateError::UpdateInProgress.into());
}
task_jefe_api::Jefe::from(JEFE.get_task_id()).request_reset();
self.syscon.chip_reset();
panic!()
}
}
Expand Down
5 changes: 5 additions & 0 deletions idl/syscon.idol
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,10 @@ Interface(
reply: Simple("()"),
idempotent: true,
),
"chip_reset": (
reply: Simple("()"),
idempotent: true,
),

}
)

0 comments on commit 09c9708

Please sign in to comment.