We should do as little 'damage' when attaching to the processor, so
don't reset the entire QSPI IO and PADS subsystems. We can assume that
either the bootloader or the running program has setup the QSPI pins
into some kindn of useable mode. Similarly no need to clear the XIP
cache as we will not be making any cacheable XIP accesses.
Using the fuctions provided by the bootrom to access the flash chip
causes an interuption in the program execution. Implementing our own
functions allows us to leave things exactly how the used to be, thus the
program can be continued after attaching.
Defining these methods highly accelerates the flash loading time as we
no longer return the flash to XIP mode after each buffered write,
instead we wait until the entire transaction has finished before
returning to XIP mode.
Reading the sfdp parameter table in the flash causes the spi peripheral
to be reconfigure, and, while the previous configuration is restored,
this causes the running program to be aboarded. Reading the sfdp table
before erasing the memory could be considered safe as we are going to be
modifying the flash anyway.
The rp2040 will clear the CDBGPWRUPREQ bit after the processor has
rebooted and halted so we shouldn't clear it ourselves. We can also
check when it has been cleared so we know this process has completed.
In B2.4 of the ADIv5 architecture specification it states that "If
CDBGRSTREQ is removed before the reset controller asserts CDBGRSTACK,
the behavior is UNPREDICTABLE.". Thus we should wait until after
checking for CDBGRSTACK before deasserting CDBGRSTREQ.
Target write operations return boolean values: `true` indicates a write
was successful, while `false` indicates there was a failure.
Inside the rpi target, there is a delegate function `rp_rom_call` that
performs the heavy lifting. It also returns `true` on success and
`false` on failure.
The rp_flash_write() function was inverting this logic, which caused it
to return `false` on success and `true` on failure. This behaviour was
exhibited as only the first 0x89c bytes successfully write to the
device.
Invert this logic in order to get rpi working again.
Signed-off-by: Sean Cross <sean@xobs.io>
- A previous comment in lpc546xx.c was incorrect - one cannot rely on
resetting the target to leave the main clock set to the 12MHz FRO.
- A comparison in lpc_common.c was incorrect causing flash erase not to
work.
- The IAP API status field was not being explicitly initialized. If
somehow an API call didn't execute properly (for example if it caused an
exception), we might not notice. This is fixed by initializing the
status to a value that the API would never return.
AppleClang has several incompatibilities with __attribute__((weak,
alias)) that prevent sane GCC-like usage on macOS:
- it does not support __attribute__((alias)) at all, only the #pragma
weak symbol1 = symbol2 syntax [1]
- the compiler removes unused static functions prior to aliasing, which
renders the above into an error [2].
To fix this, I implemented weak aliasing using the #pragma directive and
the recommended indirection macros from the GCC docs [3] and removing
the static inline specifiers from the functions if building under macOS.
Fixes#1204
[1]: See, for instance, https://sourceforge.net/p/openocd/tickets/304/
and Google "error: aliases are not supported on darwin".
[2]: https://bugs.llvm.org/show_bug.cgi?id=17775
[3]: https://gcc.gnu.org/onlinedocs/cpp/Pragmas.html