If an SoC has the "secure boot" fuse burned, it will enter FEL mode in
non-secure state, so with the SCR.NS bit set. Since in this mode the
secure/non-secure state restrictions are actually observed, we suffer
from several restrictions:
- No access to the SID information (both via memory mapped and "register").
- No access to secure SRAM (SRAM A2 on H3/A64/H5).
- No access to the secure side of the GIC, so it can't be configured to
  be accessible from non-secure world.
- No RMR trigger on ARMv8 cores to bring the core into AArch64.
Those limitations make a board pretty useless for many applications.

However it has been found out that a simple "smc" call will immediately
return from monitor mode, but with the NS bit cleared, so access to all
secure peripherals is suddenly possible.

Add a sunxi-fel command called "smc" which will issue exactly this
instruction to make those boards useful in "secure boot" FEL mode.

It should be given early in the command queue to given subsequent code
full access to the system:
$ ./sunxi-fel -v -p smc spl sunxi-spl.bin ...

Signed-off-by: Andre Przywara <[email protected]>
---
Hi,

if that sounds vaguely useful (it definitedly is for me to get the Remix
Mini PC started), I can follow the Github process if you prefer that.

Cheers,
Andre.

 fel.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/fel.c b/fel.c
index 295d5d8..9364fc0 100644
--- a/fel.c
+++ b/fel.c
@@ -403,6 +403,24 @@ void aw_set_sctlr(feldev_handle *dev, soc_info_t *soc_info,
 }
 
 /*
+ * Issue a "smc #0" instruction. This brings a SoC booted in "secure boot"
+ * state from the default non-secure FEL into secure FEL.
+ * This crashes on devices using "non-secure boot", as the BROM does not
+ * provide a handler address in MVBAR.
+ */
+void aw_do_smc(feldev_handle *dev)
+{
+       soc_info_t *soc_info = dev->soc_info;
+       uint32_t arm_code[] = {
+               htole32(0xe1600070), /* smc     #0      */
+               htole32(0xe12fff1e), /* bx      lr      */
+       };
+
+       aw_fel_write(dev, arm_code, soc_info->scratch_addr, sizeof(arm_code));
+       aw_fel_execute(dev, soc_info->scratch_addr);
+}
+
+/*
  * Reconstruct the same MMU translation table as used by the A20 BROM.
  * We are basically reverting the changes, introduced in newer SoC
  * variants. This works fine for the SoC variants with the memory
@@ -994,6 +1012,7 @@ void usage(const char *cmd) {
                "       dump address length             Binary memory dump\n"
                "       exe[cute] address               Call function address\n"
                "       reset64 address                 RMR request for AArch64 
warm boot\n"
+               "       smc                             issue smc #0 
instruction\n"
                "       memmove dest source size        Copy <size> bytes 
within device memory\n"
                "       readl address                   Read 32-bit value from 
device memory\n"
                "       writel address value            Write 32-bit value to 
device memory\n"
@@ -1127,6 +1146,8 @@ int main(int argc, char **argv)
                        aw_fel_print_sid(handle, false);
                } else if (strcmp(argv[1], "sid-registers") == 0) {
                        aw_fel_print_sid(handle, true); /* enforce register 
access */
+               } else if (strcmp(argv[1], "smc") == 0) {
+                       aw_do_smc(handle);
                } else if (strcmp(argv[1], "write") == 0 && argc > 3) {
                        skip += 2 * file_upload(handle, 1, argc - 2, argv + 2,
                                        pflag_active ? progress_bar : NULL);
-- 
2.8.2

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to