-
Notifications
You must be signed in to change notification settings - Fork 778
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
[pwrmgr] Don't lock CONTROL until observing core_sleep #23500
Conversation
To avoid race conditions with WFI and locking the CONTROL CSR prematurely, wait until the transition out of FastPwrStateActive that begins low power entry before locking the CONTROL CSR. This allows software to clear CONTROL.LOW_POWER_HINT if an early interrupt caused the "core_sleep" pulse to be too short for pwrmgr to capture. Then, subsequent WFI instructions may still choose between full power and a low power mode. When software wakes up, it must attempt to clear CONTROL.LOW_POWER_HINT, then busy-poll until it reads its value as 0. If pwrmgr triggered low power entry, the CPU will poll until pwrmgr completes the low power sequence. If pwrmgr did not trigger low power entry, the CPU's write will succeed, and the read will immediately return 0. Signed-off-by: Alexander Williams <[email protected]>
@johannheyszl @vogelpi I tagged you because this modifies the behavior of the PWRMGR.CTRL.CONFIG.REGWEN countermeasure. Instead of locking immediately upon writing a 1 to CONTROL.LOW_POWER_HINT, the lock now happens when pwrmgr begins the low power entry sequence. |
Thanks, @matutem, for the great idea to defer the locking! |
c4acc0b
to
c19785e
Compare
@@ -339,7 +340,7 @@ module pwrmgr | |||
lowpwr_cfg_wen <= 1'b1; | |||
end else if (!lowpwr_cfg_wen && (clr_cfg_lock || wkup)) begin | |||
lowpwr_cfg_wen <= 1'b1; | |||
end else if (low_power_hint) begin | |||
end else if (low_power_entry) begin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it's important to have the configuration locked for the synchronization into the slow domain, we can probably do something about that. I noticed that is one other visible bit that is dropped.
If it's not important, we can move on!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it should be okay.
Add pwrmgr test that checks for correct recovery of the CONTROL CSR when Ibex does not issue a long enough pulse for pwrmgr to sample a core sleeping state. This occurs when an IRQ is pending before entering WFI, and the prefetcher is active when WFI is executed. Software should be able to clear LOW_POWER_HINT when pwrmgr does not begin the low power entry sequence. (cherry picked from commit c7e72a6) Signed-off-by: Alexander Williams <[email protected]> Co-authored-by: Edward Hill <[email protected]>
c19785e
to
d3270fe
Compare
Nice work @a-will. I'd just like to double check my understanding of the scenarios. When you set the lower power hint and then execute the
The tricky bit is in 1. after leaving Have I got that right? |
Yup! That's right on all counts. 😄 |
Oh and we should have a follow PR that updates the pwrmgr docs to explain the proper sleep proceedure |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -339,7 +340,7 @@ module pwrmgr | |||
lowpwr_cfg_wen <= 1'b1; | |||
end else if (!lowpwr_cfg_wen && (clr_cfg_lock || wkup)) begin | |||
lowpwr_cfg_wen <= 1'b1; | |||
end else if (low_power_hint) begin | |||
end else if (low_power_entry) begin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it should be okay.
To avoid race conditions with WFI and locking the CONTROL CSR prematurely, wait until the transition out of FastPwrStateActive that begins low power entry before locking the CONTROL CSR.
This allows software to clear CONTROL.LOW_POWER_HINT if an early interrupt caused the "core_sleep" pulse to be too short for pwrmgr to capture. Then, subsequent WFI instructions may still choose between full power and a low power mode.
When software wakes up, it must attempt to clear CONTROL.LOW_POWER_HINT, then busy-poll until it reads its value as 0. If pwrmgr triggered low power entry, the CPU will poll until pwrmgr completes the low power sequence. If pwrmgr did not trigger low power entry, the CPU's write will succeed, and the read will immediately return 0.
Also add a test that causes Ibex to decode WFI with an IRQ pending and not issue core_sleep (modified from a submission from @ecgh0). Check for correct recovery of the CONTROL CSR and that software can clear LOW_POWER_HINT.