This patch makes use of the new aw_fel_readl_n() function to output
the first four 32-bit values (SID key) from an SoC-specific address.
The corresponding e-fuses may not necessarily start at the SID
"base" address, e.g. on H3/A83T they are at <base+0x200>.

Note: SoC support is currently incomplete. In particular, reading
the SID on A31(s) is unsupported. Accessing it there is complicated
by the fact that Allwinner moved this information from the SoC into
the PMIC/AXP221.

Signed-off-by: Bernhard Nortmann <[email protected]>
---
 fel.c | 33 +++++++++++++++++++++++++++++++--
 1 file changed, 31 insertions(+), 2 deletions(-)

diff --git a/fel.c b/fel.c
index e3a327a..a255acb 100644
--- a/fel.c
+++ b/fel.c
@@ -456,6 +456,7 @@ typedef struct {
        uint32_t           thunk_size;   /* Maximal size of the thunk code */
        bool               needs_l2en;   /* Set the L2EN bit */
        uint32_t           mmu_tt_addr;  /* MMU translation table address */
+       uint32_t           sid_addr;     /* base address for SID_KEY[0-3] 
registers */
        sram_swap_buffers *swap_buffers;
 } soc_sram_info;
 
@@ -503,6 +504,7 @@ soc_sram_info soc_sram_info_table[] = {
                .thunk_addr   = 0xAE00, .thunk_size = 0x200,
                .swap_buffers = a10_a13_a20_sram_swap_buffers,
                .needs_l2en   = true,
+               .sid_addr     = 0x01C23800,
        },
        {
                .soc_id       = 0x1625, /* Allwinner A13 */
@@ -510,18 +512,21 @@ soc_sram_info soc_sram_info_table[] = {
                .thunk_addr   = 0xAE00, .thunk_size = 0x200,
                .swap_buffers = a10_a13_a20_sram_swap_buffers,
                .needs_l2en   = true,
+               .sid_addr     = 0x01C23800,
        },
        {
                .soc_id       = 0x1651, /* Allwinner A20 */
                .scratch_addr = 0x1000,
                .thunk_addr   = 0xAE00, .thunk_size = 0x200,
                .swap_buffers = a10_a13_a20_sram_swap_buffers,
+               .sid_addr     = 0x01C23800,
        },
        {
                .soc_id       = 0x1650, /* Allwinner A23 */
                .scratch_addr = 0x1000,
                .thunk_addr   = 0x46E00, .thunk_size = 0x200,
                .swap_buffers = a31_sram_swap_buffers,
+               .sid_addr     = 0x01C23800,
        },
        {
                .soc_id       = 0x1633, /* Allwinner A31 */
@@ -534,12 +539,14 @@ soc_sram_info soc_sram_info_table[] = {
                .scratch_addr = 0x1000,
                .thunk_addr   = 0x46E00, .thunk_size = 0x200,
                .swap_buffers = a31_sram_swap_buffers,
+               .sid_addr     = 0x01C23800,
        },
        {
                .soc_id       = 0x1673, /* Allwinner A83T */
                .scratch_addr = 0x1000,
                .thunk_addr   = 0x46E00, .thunk_size = 0x200,
                .swap_buffers = a31_sram_swap_buffers,
+               .sid_addr     = 0x01C14200,
        },
        {
                .soc_id       = 0x1680, /* Allwinner H3 */
@@ -547,6 +554,7 @@ soc_sram_info soc_sram_info_table[] = {
                .mmu_tt_addr  = 0x44000,
                .thunk_addr   = 0x46E00, .thunk_size = 0x200,
                .swap_buffers = a31_sram_swap_buffers,
+               .sid_addr     = 0x01C14200,
        },
        {
                .soc_id       = 0x1639, /* Allwinner A80 */
@@ -729,6 +737,25 @@ void aw_fel_writel(libusb_device_handle *usb, uint32_t 
addr, uint32_t val)
        aw_fel_writel_n(usb, addr, &val, 1);
 }
 
+void aw_fel_print_sid(libusb_device_handle *usb)
+{
+       soc_sram_info *soc_info = aw_fel_get_sram_info(usb);
+       if (soc_info->sid_addr) {
+               pr_info("SID key (e-fuses) at 0x%08X\n", soc_info->sid_addr);
+
+               uint32_t key[4];
+               aw_fel_readl_n(usb, soc_info->sid_addr, key, 4);
+
+               unsigned int i;
+               /* output SID in a format similar to U-Boot's "md.l <sid_addr> 
4" */
+               for (i = 0; i <= 3; i++)
+                       printf("%08x%c", key[i], i < 3 ? ' ' : '\n');
+       } else {
+               printf("SID registers for your SoC (id=%04X) are unknown or 
inaccessible.\n",
+                       soc_info->soc_id);
+       }
+}
+
 void aw_enable_l2_cache(libusb_device_handle *usb, soc_sram_info *sram_info)
 {
        uint32_t arm_code[] = {
@@ -1474,6 +1501,7 @@ int main(int argc, char **argv)
                        "                                         <#> addr file 
[addr file [...]]\n"
                        "       echo-gauge \"some text\"                Update 
prompt/caption for gauge output\n"
                        "       ver[sion]                       Show BROM 
version\n"
+                       "       sid                             Retrieve and 
output 128-bit SID key\n"
                        "       clear address length            Clear memory\n"
                        "       fill address length value       Fill memory\n"
                        , argv[0]
@@ -1543,9 +1571,10 @@ int main(int argc, char **argv)
                } else if (strncmp(argv[1], "exe", 3) == 0 && argc > 2) {
                        aw_fel_execute(handle, strtoul(argv[2], NULL, 0));
                        skip=3;
-               } else if (strncmp(argv[1], "ver", 3) == 0 && argc > 1) {
+               } else if (strncmp(argv[1], "ver", 3) == 0) {
                        aw_fel_print_version(handle);
-                       skip=1;
+               } else if (strcmp(argv[1], "sid") == 0) {
+                       aw_fel_print_sid(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.4.10

-- 
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