-
Notifications
You must be signed in to change notification settings - Fork 13.3k
precache() - preload code into the flash cache. #6628
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
Conversation
By preloading code into the flash cache we can take control over when SPI Flash reads will occur when code is executing. This can be useful where the timing of a section of code is extremely critical and we don't want random pauses to pull code in from the SPI flash chip. It can also be useful for code that accesses/uses SPI0 which is connected to the flash chip. Non interrupt handler code that is infrequently called but might otherwise require being in valuable IRAM - such as bit-banging I/O code or some code run at bootup can avoid being permanently in IRAM. Macros are provided to make precaching one or more blocks of code in any function easy.
forms part of the solution for #6559 |
(I cancelled your CI, which is broken anyway, to get CI resource for my CI-fixing PR) |
Guess that's what I get for being slack and pushing something without a test compile... it should be ok now that I added the missing include though. |
CI itself was broken, I wasn't commenting on your PR 😆 edit you just did it :) |
ahh, yes I thought the logs looked a bit odd :) |
This might need a little more work - I think it's not getting the length calculation right under some circumstances, so it probably needs another attribute |
With certain alignments/lengths of code it was possible to not read enough into the flash cache. This commit makes the length calculation clearer and adds an extra cache line to ensure we precache enough code.
Precached code needs to be noinline to ensure the no-reorder-blocks is applied.
There's one issue I see here, and I'm not sure how to handle it. This CPU doesn't have 32b load insns, so it uses a GCC doesn't include the So I'm not sure in the general case this is doable. You need 32b access to do any constant address access (i.e. GPIO) or access any global variables/static class members, or do any operation (compare, etc.) with a 32b value... |
From what I've seen in the disassembled code, those literals can come from anywhere in the code although it does prefer to place them beside the function it seems to re-use nearby values. I don't think there's any way we can compensate for that in a transparent way. What we can do is handle it with documentation "access your constants before the precached code". |
Further to the above... |
Ha! It took some ninja level gymnastics with 'volatile' and function pointers but I got SPI_command() to build without any load32 instructions referring to flash in the precached code. One point for documentation though - only call functions in iram or rom. Basically same rules as an interrupt handler. |
Closing in favor of #6674. |
Reopening this for merge given that the rest of #6674 needs further discussion. |
By preloading code into the flash cache we can take control over when
SPI Flash reads will occur when code is executing.
This can be useful where the timing of a section of code is extremely
critical and we don't want random pauses to pull code in from the SPI
flash chip.
It can also be useful for code that accesses/uses SPI0 which is connected
to the flash chip.
Non interrupt handler code that is infrequently called but might otherwise
require being in valuable IRAM - such as bit-banging I/O code or some code
run at bootup can avoid being permanently in IRAM.
Macros are provided to make precaching one or more blocks of code in any
function easy.