The safe area to upload and execute code via FEL may be different
for different SoC variants (0x12000 for A80, 0x2000 for everything
else), so we can't have it as a global compile time constant, but
need need to treat it as a property of the SoC.

This patch changes the code to pass the SoC info structure to a
number of functions and adds a new 'scrath_addr' struct field to it.

Signed-off-by: Siarhei Siamashka <[email protected]>
---
 fel.c | 85 +++++++++++++++++++++++++++++++++++++++----------------------------
 1 file changed, 49 insertions(+), 36 deletions(-)

diff --git a/fel.c b/fel.c
index 61ba78d..7285b15 100644
--- a/fel.c
+++ b/fel.c
@@ -348,10 +348,11 @@ typedef struct {
  * addresses are the intended backup locations.
  */
 typedef struct {
-       uint32_t           soc_id;     /* ID of the SoC */
-       uint32_t           thunk_addr; /* Address of the thunk code */
-       uint32_t           thunk_size; /* Maximal size of the thunk code */
-       uint32_t           needs_l2en; /* Set the L2EN bit */
+       uint32_t           soc_id;       /* ID of the SoC */
+       uint32_t           scratch_addr; /* A safe place to upload & run code */
+       uint32_t           thunk_addr;   /* Address of the thunk code */
+       uint32_t           thunk_size;   /* Maximal size of the thunk code */
+       uint32_t           needs_l2en;   /* Set the L2EN bit */
        sram_swap_buffers *swap_buffers;
 } soc_sram_info;
 
@@ -385,43 +386,51 @@ sram_swap_buffers a31_sram_swap_buffers[] = {
 soc_sram_info soc_sram_info_table[] = {
        {
                .soc_id       = 0x1623, /* Allwinner A10 */
+               .scratch_addr = 0x2000,
                .thunk_addr   = 0xAE00, .thunk_size = 0x200,
                .swap_buffers = a10_a13_a20_sram_swap_buffers,
                .needs_l2en   = 1,
        },
        {
                .soc_id       = 0x1625, /* Allwinner A13 */
+               .scratch_addr = 0x2000,
                .thunk_addr   = 0xAE00, .thunk_size = 0x200,
                .swap_buffers = a10_a13_a20_sram_swap_buffers,
                .needs_l2en   = 1,
        },
        {
                .soc_id       = 0x1651, /* Allwinner A20 */
+               .scratch_addr = 0x2000,
                .thunk_addr   = 0xAE00, .thunk_size = 0x200,
                .swap_buffers = a10_a13_a20_sram_swap_buffers,
        },
        {
                .soc_id       = 0x1650, /* Allwinner A23 */
+               .scratch_addr = 0x2000,
                .thunk_addr   = 0x46E00, .thunk_size = 0x200,
                .swap_buffers = a31_sram_swap_buffers,
        },
        {
                .soc_id       = 0x1633, /* Allwinner A31 */
+               .scratch_addr = 0x2000,
                .thunk_addr   = 0x46E00, .thunk_size = 0x200,
                .swap_buffers = a31_sram_swap_buffers,
        },
        {
                .soc_id       = 0x1667, /* Allwinner A33 */
+               .scratch_addr = 0x2000,
                .thunk_addr   = 0x46E00, .thunk_size = 0x200,
                .swap_buffers = a31_sram_swap_buffers,
        },
        {
                .soc_id       = 0x1673, /* Allwinner A83T */
+               .scratch_addr = 0x2000,
                .thunk_addr   = 0x46E00, .thunk_size = 0x200,
                .swap_buffers = a31_sram_swap_buffers,
        },
        {
                .soc_id       = 0x1680, /* Allwinner H3 */
+               .scratch_addr = 0x2000,
                .thunk_addr   = 0x46E00, .thunk_size = 0x200,
                .swap_buffers = a31_sram_swap_buffers,
        },
@@ -444,6 +453,7 @@ sram_swap_buffers generic_sram_swap_buffers[] = {
 };
 
 soc_sram_info generic_sram_info = {
+       .scratch_addr = 0x2000,
        .thunk_addr   = 0x5680, .thunk_size = 0x180,
        .swap_buffers = generic_sram_swap_buffers,
 };
@@ -468,11 +478,10 @@ static uint32_t fel_to_spl_thunk[] = {
        #include "fel-to-spl-thunk.h"
 };
 
-#define        FEL_EXEC_SCRATCH_AREA   0x2000
 #define        DRAM_BASE               0x40000000
 #define        DRAM_SIZE               0x80000000
 
-void aw_enable_l2_cache(libusb_device_handle *usb)
+void aw_enable_l2_cache(libusb_device_handle *usb, soc_sram_info *sram_info)
 {
        uint32_t arm_code[] = {
                htole32(0xee112f30), /* mrc        15, 0, r2, cr1, cr0, {1}  */
@@ -481,11 +490,12 @@ void aw_enable_l2_cache(libusb_device_handle *usb)
                htole32(0xe12fff1e), /* bx         lr                        */
        };
 
-       aw_fel_write(usb, arm_code, FEL_EXEC_SCRATCH_AREA, sizeof(arm_code));
-       aw_fel_execute(usb, FEL_EXEC_SCRATCH_AREA);
+       aw_fel_write(usb, arm_code, sram_info->scratch_addr, sizeof(arm_code));
+       aw_fel_execute(usb, sram_info->scratch_addr);
 }
 
-void aw_get_stackinfo(libusb_device_handle *usb, uint32_t *sp_irq, uint32_t 
*sp)
+void aw_get_stackinfo(libusb_device_handle *usb, soc_sram_info *sram_info,
+                      uint32_t *sp_irq, uint32_t *sp)
 {
        uint32_t results[2] = { 0 };
 #if 0
@@ -497,9 +507,9 @@ void aw_get_stackinfo(libusb_device_handle *usb, uint32_t 
*sp_irq, uint32_t *sp)
                htole32(0xe12fff1e), /* bx         lr                        */
        };
 
-       aw_fel_write(usb, arm_code, FEL_EXEC_SCRATCH_AREA, sizeof(arm_code));
-       aw_fel_execute(usb, FEL_EXEC_SCRATCH_AREA);
-       aw_fel_read(usb, FEL_EXEC_SCRATCH_AREA + 0x10, results, 8);
+       aw_fel_write(usb, arm_code, sram_info->scratch_addr, sizeof(arm_code));
+       aw_fel_execute(usb, sram_info->scratch_addr);
+       aw_fel_read(usb, sram_info->scratch_addr + 0x10, results, 8);
 #else
        /* Works everywhere */
        uint32_t arm_code[] = {
@@ -514,15 +524,15 @@ void aw_get_stackinfo(libusb_device_handle *usb, uint32_t 
*sp_irq, uint32_t *sp)
                htole32(0xe12fff1e), /* bx         lr                        */
        };
 
-       aw_fel_write(usb, arm_code, FEL_EXEC_SCRATCH_AREA, sizeof(arm_code));
-       aw_fel_execute(usb, FEL_EXEC_SCRATCH_AREA);
-       aw_fel_read(usb, FEL_EXEC_SCRATCH_AREA + 0x24, results, 8);
+       aw_fel_write(usb, arm_code, sram_info->scratch_addr, sizeof(arm_code));
+       aw_fel_execute(usb, sram_info->scratch_addr);
+       aw_fel_read(usb, sram_info->scratch_addr + 0x24, results, 8);
 #endif
        *sp_irq = le32toh(results[0]);
        *sp     = le32toh(results[1]);
 }
 
-uint32_t aw_get_ttbr0(libusb_device_handle *usb)
+uint32_t aw_get_ttbr0(libusb_device_handle *usb, soc_sram_info *sram_info)
 {
        uint32_t ttbr0 = 0;
        uint32_t arm_code[] = {
@@ -531,14 +541,14 @@ uint32_t aw_get_ttbr0(libusb_device_handle *usb)
                htole32(0xe12fff1e), /* bx         lr                        */
        };
 
-       aw_fel_write(usb, arm_code, FEL_EXEC_SCRATCH_AREA, sizeof(arm_code));
-       aw_fel_execute(usb, FEL_EXEC_SCRATCH_AREA);
-       aw_fel_read(usb, FEL_EXEC_SCRATCH_AREA + 0x14, &ttbr0, sizeof(ttbr0));
+       aw_fel_write(usb, arm_code, sram_info->scratch_addr, sizeof(arm_code));
+       aw_fel_execute(usb, sram_info->scratch_addr);
+       aw_fel_read(usb, sram_info->scratch_addr + 0x14, &ttbr0, sizeof(ttbr0));
        ttbr0 = le32toh(ttbr0);
        return ttbr0;
 }
 
-uint32_t aw_get_sctlr(libusb_device_handle *usb)
+uint32_t aw_get_sctlr(libusb_device_handle *usb, soc_sram_info *sram_info)
 {
        uint32_t sctlr = 0;
        uint32_t arm_code[] = {
@@ -547,18 +557,19 @@ uint32_t aw_get_sctlr(libusb_device_handle *usb)
                htole32(0xe12fff1e), /* bx         lr                        */
        };
 
-       aw_fel_write(usb, arm_code, FEL_EXEC_SCRATCH_AREA, sizeof(arm_code));
-       aw_fel_execute(usb, FEL_EXEC_SCRATCH_AREA);
-       aw_fel_read(usb, FEL_EXEC_SCRATCH_AREA + 0x14, &sctlr, sizeof(sctlr));
+       aw_fel_write(usb, arm_code, sram_info->scratch_addr, sizeof(arm_code));
+       aw_fel_execute(usb, sram_info->scratch_addr);
+       aw_fel_read(usb, sram_info->scratch_addr + 0x14, &sctlr, sizeof(sctlr));
        sctlr = le32toh(sctlr);
        return sctlr;
 }
 
-uint32_t *aw_backup_and_disable_mmu(libusb_device_handle *usb)
+uint32_t *aw_backup_and_disable_mmu(libusb_device_handle *usb,
+                                    soc_sram_info *sram_info)
 {
        uint32_t *tt = NULL;
-       uint32_t ttbr0 = aw_get_ttbr0(usb);
-       uint32_t sctlr = aw_get_sctlr(usb);
+       uint32_t ttbr0 = aw_get_ttbr0(usb, sram_info);
+       uint32_t sctlr = aw_get_sctlr(usb, sram_info);
        uint32_t i;
 
        uint32_t arm_code[] = {
@@ -606,17 +617,19 @@ uint32_t *aw_backup_and_disable_mmu(libusb_device_handle 
*usb)
        }
 
        pr_info("Disabling I-cache, MMU and branch prediction...");
-       aw_fel_write(usb, arm_code, FEL_EXEC_SCRATCH_AREA, sizeof(arm_code));
-       aw_fel_execute(usb, FEL_EXEC_SCRATCH_AREA);
+       aw_fel_write(usb, arm_code, sram_info->scratch_addr, sizeof(arm_code));
+       aw_fel_execute(usb, sram_info->scratch_addr);
        pr_info(" done.\n");
 
        return tt;
 }
 
-void aw_restore_and_enable_mmu(libusb_device_handle *usb, uint32_t *tt)
+void aw_restore_and_enable_mmu(libusb_device_handle *usb,
+                               soc_sram_info *sram_info,
+                               uint32_t *tt)
 {
        uint32_t i;
-       uint32_t ttbr0 = aw_get_ttbr0(usb);
+       uint32_t ttbr0 = aw_get_ttbr0(usb, sram_info);
 
        uint32_t arm_code[] = {
                /* Invalidate I-cache, TLB and BTB */
@@ -658,8 +671,8 @@ void aw_restore_and_enable_mmu(libusb_device_handle *usb, 
uint32_t *tt)
        aw_fel_write(usb, tt, ttbr0, 16 * 1024);
 
        pr_info("Enabling I-cache, MMU and branch prediction...");
-       aw_fel_write(usb, arm_code, FEL_EXEC_SCRATCH_AREA, sizeof(arm_code));
-       aw_fel_execute(usb, FEL_EXEC_SCRATCH_AREA);
+       aw_fel_write(usb, arm_code, sram_info->scratch_addr, sizeof(arm_code));
+       aw_fel_execute(usb, sram_info->scratch_addr);
        pr_info(" done.\n");
 
        free(tt);
@@ -714,13 +727,13 @@ void aw_fel_write_and_execute_spl(libusb_device_handle 
*usb,
 
        if (sram_info->needs_l2en) {
                pr_info("Enabling the L2 cache\n");
-               aw_enable_l2_cache(usb);
+               aw_enable_l2_cache(usb, sram_info);
        }
 
-       aw_get_stackinfo(usb, &sp_irq, &sp);
+       aw_get_stackinfo(usb, sram_info, &sp_irq, &sp);
        pr_info("Stack pointers: sp_irq=0x%08X, sp=0x%08X\n", sp_irq, sp);
 
-       tt = aw_backup_and_disable_mmu(usb);
+       tt = aw_backup_and_disable_mmu(usb, sram_info);
 
        swap_buffers = sram_info->swap_buffers;
        for (i = 0; swap_buffers[i].size; i++) {
@@ -796,7 +809,7 @@ void aw_fel_write_and_execute_spl(libusb_device_handle *usb,
 
        /* re-enable the MMU if it was enabled by BROM */
        if(tt != NULL)
-               aw_restore_and_enable_mmu(usb, tt);
+               aw_restore_and_enable_mmu(usb, sram_info, tt);
 }
 
 /* Constants taken from ${U-BOOT}/include/image.h */
-- 
2.4.6

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