Add a new field 'spl_addr' to the SoC description structure and adjust the code to honor it. This is needed for supporting Allwinner A80.
Tested on Allwinner A20 by changing the 'spl_addr' to 0x28000 in the 'fel' tool and using a custom build of U-Boot (CONFIG_SPL_TEXT_BASE changed from 0x20 to 0x28020). Signed-off-by: Siarhei Siamashka <[email protected]> --- fel-to-spl-thunk.S | 22 ++++++-------- fel-to-spl-thunk.h | 89 ++++++++++++++++++++++++++---------------------------- fel.c | 29 ++++++++++-------- 3 files changed, 70 insertions(+), 70 deletions(-) diff --git a/fel-to-spl-thunk.S b/fel-to-spl-thunk.S index fb5dfde..e3fa6f2 100644 --- a/fel-to-spl-thunk.S +++ b/fel-to-spl-thunk.S @@ -69,6 +69,7 @@ SWAPTBL .req r4 FULLSIZE .req r5 BUFSIZE .req r6 CHECKSUM .req r7 +SPL_ADDR .req r8 entry_point: b setup_stack @@ -87,7 +88,7 @@ stack_end: /* A function, which walks the table and swaps all buffers */ swap_all_buffers: - adr SWAPTBL, swaptbl_start + adr SWAPTBL, appended_data + 4 swap_next_buffer: ldr BUF1, [SWAPTBL], #4 ldr BUF2, [SWAPTBL], #4 @@ -104,6 +105,7 @@ swap_next_word: b swap_next_buffer setup_stack: /* Save the original SP, LR and CPSR to stack */ + ldr SPL_ADDR, appended_data adr BUF1, stack_end str sp, [BUF1, #-4]! mov sp, BUF1 @@ -125,7 +127,7 @@ setup_stack: /* Save the original SP, LR and CPSR to stack */ verify_checksum: movw CHECKSUM, #0x6c39 movt CHECKSUM, #0x5f0a - mov BUF1, #0 + mov BUF1, SPL_ADDR ldr FULLSIZE, [BUF1, #16] check_next_word: ldr TMP1, [BUF1], #4 @@ -133,39 +135,35 @@ check_next_word: add CHECKSUM, CHECKSUM, TMP1 bne check_next_word - mov BUF1, #0 - ldr TMP1, [BUF1, #12] + ldr TMP1, [SPL_ADDR, #12] subs CHECKSUM, CHECKSUM, TMP1, lsl #1 bne checksum_is_bad /* Change 'eGON.BT0' -> 'eGON.FEL' */ - mov BUF1, #0 movw TMP1, (('F' << 8) + '.') movt TMP1, (('L' << 8) + 'E') - str TMP1, [BUF1, #8] + str TMP1, [SPL_ADDR, #8] /* Call the SPL code */ dsb isb - blx BUF1 + blx SPL_ADDR /* Return back to FEL */ b return_to_fel cache_is_unsupported: /* Bail out if cache is enabled and change 'eGON.BT0' -> 'eGON.???' */ - mov BUF1, #0 movw TMP1, (('?' << 8) + '.') movt TMP1, (('?' << 8) + '?') - str TMP1, [BUF1, #8] + str TMP1, [SPL_ADDR, #8] b return_to_fel_noswap checksum_is_bad: /* The checksum test failed, so change 'eGON.BT0' -> 'eGON.BAD' */ - mov BUF1, #0 movw TMP1, (('B' << 8) + '.') movt TMP1, (('D' << 8) + 'A') - str TMP1, [BUF1, #8] + str TMP1, [SPL_ADDR, #8] return_to_fel: bl swap_all_buffers @@ -175,4 +173,4 @@ return_to_fel_noswap: ldr sp, [sp] bx lr -swaptbl_start: +appended_data: diff --git a/fel-to-spl-thunk.h b/fel-to-spl-thunk.h index 530cea5..636bb81 100644 --- a/fel-to-spl-thunk.h +++ b/fel-to-spl-thunk.h @@ -8,7 +8,7 @@ 0xe1a00000, /* 1c: nop */ 0xe1a00000, /* 20: nop */ 0xe1a00000, /* 24: nop */ - 0xe28f40e4, /* 28: add r4, pc, #228 */ + 0xe28f40dc, /* 28: add r4, pc, #220 */ 0xe4940004, /* 2c: ldr r0, [r4], #4 */ 0xe4941004, /* 30: ldr r1, [r4], #4 */ 0xe4946004, /* 34: ldr r6, [r4], #4 */ @@ -21,49 +21,46 @@ 0xe4803004, /* 50: str r3, [r0], #4 */ 0x1afffff9, /* 54: bne 40 <swap_next_word> */ 0xeafffff3, /* 58: b 2c <swap_next_buffer> */ - 0xe24f0040, /* 5c: sub r0, pc, #64 */ - 0xe520d004, /* 60: str sp, [r0, #-4]! */ - 0xe1a0d000, /* 64: mov sp, r0 */ - 0xe10f2000, /* 68: mrs r2, CPSR */ - 0xe92d4004, /* 6c: push {r2, lr} */ - 0xe38220c0, /* 70: orr r2, r2, #192 */ - 0xe121f002, /* 74: msr CPSR_c, r2 */ - 0xee112f10, /* 78: mrc 15, 0, r2, cr1, cr0, {0} */ - 0xe3013004, /* 7c: movw r3, #4100 */ - 0xe1120003, /* 80: tst r2, r3 */ - 0x1a000014, /* 84: bne dc <cache_is_unsupported> */ - 0xebffffe6, /* 88: bl 28 <swap_all_buffers> */ - 0xe3067c39, /* 8c: movw r7, #27705 */ - 0xe3457f0a, /* 90: movt r7, #24330 */ - 0xe3a00000, /* 94: mov r0, #0 */ - 0xe5905010, /* 98: ldr r5, [r0, #16] */ - 0xe4902004, /* 9c: ldr r2, [r0], #4 */ - 0xe2555004, /* a0: subs r5, r5, #4 */ - 0xe0877002, /* a4: add r7, r7, r2 */ - 0x1afffffb, /* a8: bne 9c <check_next_word> */ - 0xe3a00000, /* ac: mov r0, #0 */ - 0xe590200c, /* b0: ldr r2, [r0, #12] */ + 0xe59f80a4, /* 5c: ldr r8, [pc, #164] */ + 0xe24f0044, /* 60: sub r0, pc, #68 */ + 0xe520d004, /* 64: str sp, [r0, #-4]! */ + 0xe1a0d000, /* 68: mov sp, r0 */ + 0xe10f2000, /* 6c: mrs r2, CPSR */ + 0xe92d4004, /* 70: push {r2, lr} */ + 0xe38220c0, /* 74: orr r2, r2, #192 */ + 0xe121f002, /* 78: msr CPSR_c, r2 */ + 0xee112f10, /* 7c: mrc 15, 0, r2, cr1, cr0, {0} */ + 0xe3013004, /* 80: movw r3, #4100 */ + 0xe1120003, /* 84: tst r2, r3 */ + 0x1a000012, /* 88: bne d8 <cache_is_unsupported> */ + 0xebffffe5, /* 8c: bl 28 <swap_all_buffers> */ + 0xe3067c39, /* 90: movw r7, #27705 */ + 0xe3457f0a, /* 94: movt r7, #24330 */ + 0xe1a00008, /* 98: mov r0, r8 */ + 0xe5905010, /* 9c: ldr r5, [r0, #16] */ + 0xe4902004, /* a0: ldr r2, [r0], #4 */ + 0xe2555004, /* a4: subs r5, r5, #4 */ + 0xe0877002, /* a8: add r7, r7, r2 */ + 0x1afffffb, /* ac: bne a0 <check_next_word> */ + 0xe598200c, /* b0: ldr r2, [r8, #12] */ 0xe0577082, /* b4: subs r7, r7, r2, lsl #1 */ - 0x1a00000c, /* b8: bne f0 <checksum_is_bad> */ - 0xe3a00000, /* bc: mov r0, #0 */ - 0xe304262e, /* c0: movw r2, #17966 */ - 0xe3442c45, /* c4: movt r2, #19525 */ - 0xe5802008, /* c8: str r2, [r0, #8] */ - 0xf57ff04f, /* cc: dsb sy */ - 0xf57ff06f, /* d0: isb sy */ - 0xe12fff30, /* d4: blx r0 */ - 0xea000008, /* d8: b 100 <return_to_fel> */ - 0xe3a00000, /* dc: mov r0, #0 */ - 0xe3032f2e, /* e0: movw r2, #16174 */ - 0xe3432f3f, /* e4: movt r2, #16191 */ - 0xe5802008, /* e8: str r2, [r0, #8] */ - 0xea000004, /* ec: b 104 <return_to_fel_noswap> */ - 0xe3a00000, /* f0: mov r0, #0 */ - 0xe304222e, /* f4: movw r2, #16942 */ - 0xe3442441, /* f8: movt r2, #17473 */ - 0xe5802008, /* fc: str r2, [r0, #8] */ - 0xebffffc8, /* 100: bl 28 <swap_all_buffers> */ - 0xe8bd4004, /* 104: pop {r2, lr} */ - 0xe121f002, /* 108: msr CPSR_c, r2 */ - 0xe59dd000, /* 10c: ldr sp, [sp] */ - 0xe12fff1e, /* 110: bx lr */ + 0x1a00000a, /* b8: bne e8 <checksum_is_bad> */ + 0xe304262e, /* bc: movw r2, #17966 */ + 0xe3442c45, /* c0: movt r2, #19525 */ + 0xe5882008, /* c4: str r2, [r8, #8] */ + 0xf57ff04f, /* c8: dsb sy */ + 0xf57ff06f, /* cc: isb sy */ + 0xe12fff38, /* d0: blx r8 */ + 0xea000006, /* d4: b f4 <return_to_fel> */ + 0xe3032f2e, /* d8: movw r2, #16174 */ + 0xe3432f3f, /* dc: movt r2, #16191 */ + 0xe5882008, /* e0: str r2, [r8, #8] */ + 0xea000003, /* e4: b f8 <return_to_fel_noswap> */ + 0xe304222e, /* e8: movw r2, #16942 */ + 0xe3442441, /* ec: movt r2, #17473 */ + 0xe5882008, /* f0: str r2, [r8, #8] */ + 0xebffffcb, /* f4: bl 28 <swap_all_buffers> */ + 0xe8bd4004, /* f8: pop {r2, lr} */ + 0xe121f002, /* fc: msr CPSR_c, r2 */ + 0xe59dd000, /* 100: ldr sp, [sp] */ + 0xe12fff1e, /* 104: bx lr */ diff --git a/fel.c b/fel.c index 7285b15..c29df86 100644 --- a/fel.c +++ b/fel.c @@ -349,6 +349,7 @@ typedef struct { */ typedef struct { uint32_t soc_id; /* ID of the SoC */ + uint32_t spl_addr; /* SPL load address */ 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 */ @@ -695,7 +696,7 @@ void aw_fel_write_and_execute_spl(libusb_device_handle *usb, uint32_t sp, sp_irq; uint32_t spl_checksum, spl_len, spl_len_limit = SPL_LEN_LIMIT; uint32_t *buf32 = (uint32_t *)buf; - uint32_t written = 0; + uint32_t cur_addr = sram_info->spl_addr; uint32_t *tt = NULL; if (!sram_info || !sram_info->swap_buffers) { @@ -737,23 +738,24 @@ void aw_fel_write_and_execute_spl(libusb_device_handle *usb, swap_buffers = sram_info->swap_buffers; for (i = 0; swap_buffers[i].size; i++) { - if (swap_buffers[i].buf2 < spl_len_limit) - spl_len_limit = swap_buffers[i].buf2; - if (len > 0 && written < swap_buffers[i].buf1) { - uint32_t tmp = swap_buffers[i].buf1 - written; + if ((swap_buffers[i].buf2 >= sram_info->spl_addr) && + (swap_buffers[i].buf2 < sram_info->spl_addr + spl_len_limit)) + spl_len_limit = swap_buffers[i].buf2 - sram_info->spl_addr; + if (len > 0 && cur_addr < swap_buffers[i].buf1) { + uint32_t tmp = swap_buffers[i].buf1 - cur_addr; if (tmp > len) tmp = len; - aw_fel_write(usb, buf, written, tmp); - written += tmp; + aw_fel_write(usb, buf, cur_addr, tmp); + cur_addr += tmp; buf += tmp; len -= tmp; } - if (len > 0 && written == swap_buffers[i].buf1) { + if (len > 0 && cur_addr == swap_buffers[i].buf1) { uint32_t tmp = swap_buffers[i].size; if (tmp > len) tmp = len; aw_fel_write(usb, buf, swap_buffers[i].buf2, tmp); - written += tmp; + cur_addr += tmp; buf += tmp; len -= tmp; } @@ -771,9 +773,10 @@ void aw_fel_write_and_execute_spl(libusb_device_handle *usb, /* Write the remaining part of the SPL */ if (len > 0) - aw_fel_write(usb, buf, written, len); + aw_fel_write(usb, buf, cur_addr, len); - thunk_size = sizeof(fel_to_spl_thunk) + (i + 1) * sizeof(*swap_buffers); + thunk_size = sizeof(fel_to_spl_thunk) + sizeof(sram_info->spl_addr) + + (i + 1) * sizeof(*swap_buffers); if (thunk_size > sram_info->thunk_size) { fprintf(stderr, "SPL: bad thunk size (need %d, have %d)\n", @@ -784,6 +787,8 @@ void aw_fel_write_and_execute_spl(libusb_device_handle *usb, thunk_buf = malloc(thunk_size); memcpy(thunk_buf, fel_to_spl_thunk, sizeof(fel_to_spl_thunk)); memcpy(thunk_buf + sizeof(fel_to_spl_thunk) / sizeof(uint32_t), + &sram_info->spl_addr, sizeof(sram_info->spl_addr)); + memcpy(thunk_buf + sizeof(fel_to_spl_thunk) / sizeof(uint32_t) + 1, swap_buffers, (i + 1) * sizeof(*swap_buffers)); for (i = 0; i < thunk_size / sizeof(uint32_t); i++) @@ -800,7 +805,7 @@ void aw_fel_write_and_execute_spl(libusb_device_handle *usb, usleep(250000); /* Read back the result and check if everything was fine */ - aw_fel_read(usb, 4, header_signature, 8); + aw_fel_read(usb, sram_info->spl_addr + 4, header_signature, 8); if (strcmp(header_signature, "eGON.FEL") != 0) { fprintf(stderr, "SPL: failure code '%s'\n", header_signature); -- 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.
