56 lines
1.9 KiB
C
56 lines
1.9 KiB
C
|
#include "types.h"
|
||
|
#include "t124.h"
|
||
|
|
||
|
extern u32 __payload_bin_start;
|
||
|
extern u32 __payload_bin_end;
|
||
|
|
||
|
typedef void (*post_relocation_t)( void );
|
||
|
typedef void (*payload_ep_t)( void );
|
||
|
typedef void (*_memcpy_t)( void *dst, const void *src, size_t len );
|
||
|
|
||
|
void _memcpy( void *dst, const void *src, size_t len ) {
|
||
|
|
||
|
for ( size_t i = 0; i < len; i++ ) {
|
||
|
( (u8 *)dst )[i] = ( (u8 *)src )[i];
|
||
|
}
|
||
|
|
||
|
}
|
||
|
// Probably I could trust in have relative PC branches, so no address would
|
||
|
// require to be updated. This would work since there is a whole new copy
|
||
|
// of the binary on the relocated area and PC would be working on that area
|
||
|
// but having memcpy address on a register and update it to the relocated
|
||
|
// area when required should improve the chances of the compiler not messing
|
||
|
// up with the memcpy calls.
|
||
|
register _memcpy_t memcpy asm("r7");
|
||
|
|
||
|
void _post_relocation() {
|
||
|
|
||
|
// Same with these arguments....
|
||
|
register u32 payload_bef_len = *( (u32 *) IRAM_ADD_PAYLOAD_BEF_LENVAR );
|
||
|
register u32 payload_aft_len = *( (u32 *) IRAM_ADD_PAYLOAD_AFT_LENVAR );
|
||
|
register u32 payload_thumb_mode = *( (u32 *) IRAM_ADD_PAYLOAD_THUMB_MODE );
|
||
|
|
||
|
memcpy -= INTERMEZZO_LEN;
|
||
|
memcpy( (u8 *) BOOTROM_PAYLOAD_ENTRY, (u8 *) IRAM_ADD_PAYLOAD_START, payload_bef_len );
|
||
|
memcpy( (u8 *) (BOOTROM_PAYLOAD_ENTRY + payload_bef_len), (u8 *) IRAM_ADD_PAYLOAD_CONT, payload_aft_len );
|
||
|
|
||
|
payload_ep_t payload_ep = (payload_ep_t) ( BOOTROM_PAYLOAD_ENTRY | payload_thumb_mode );
|
||
|
payload_ep();
|
||
|
|
||
|
}
|
||
|
|
||
|
__attribute__((section(".init")))
|
||
|
void pre_relocation() {
|
||
|
|
||
|
u32 payload_bin_size = (u32)&__payload_bin_end - (u32)&__payload_bin_start;
|
||
|
u8 *dest = (u8 *) ( BOOTROM_PAYLOAD_ENTRY - INTERMEZZO_LEN );
|
||
|
|
||
|
memcpy = _memcpy;
|
||
|
memcpy( dest, &__payload_bin_start, payload_bin_size );
|
||
|
|
||
|
post_relocation_t post_relocation = _post_relocation - INTERMEZZO_LEN;
|
||
|
post_relocation();
|
||
|
|
||
|
}
|
||
|
|