diff --git a/source/meme/external_utils.c b/source/meme/external_utils.c new file mode 100644 index 0000000..38fa41f --- /dev/null +++ b/source/meme/external_utils.c @@ -0,0 +1,81 @@ +#include "external_utils.h" +#include +#include +#include +#include "../gfx/di.h" +#include "../gfx/gfx.h" +#include "../utils/btn.h" +#include "../utils/util.h" +#include "utils.h" +#include "../libs/fatfs/ff.h" +#include "../storage/sdmmc.h" +#include "graphics.h" +#include "../soc/hw_init.h" +#include "../mem/emc.h" +#include "../mem/sdram.h" +#include "../soc/t210.h" + +extern void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size); +extern boot_cfg_t b_cfg; +extern bool sd_mount(); +extern void sd_unmount(); + +int launch_payload(char *path, int update){ + if (!update) + gfx_clear_grey(0x1B); + gfx_con_setpos(0, 0); + if (!path) + return 1; + + if (sd_mount()){ + FIL fp; + if (f_open(&fp, path, FA_READ)){ + return 2; + } + + // Read and copy the payload to our chosen address + void *buf; + u32 size = f_size(&fp); + + if (size < 0x30000) + buf = (void *)RCM_PAYLOAD_ADDR; + else + buf = (void *)COREBOOT_ADDR; + + if (f_read(&fp, buf, size, NULL)){ + f_close(&fp); + return 3; + } + + f_close(&fp); + free(path); + + if (size < 0x30000){ + if (update) + memcpy((u8 *)(RCM_PAYLOAD_ADDR + PATCHED_RELOC_SZ), &b_cfg, sizeof(boot_cfg_t)); // Transfer boot cfg. + else + reloc_patcher(PATCHED_RELOC_ENTRY, EXT_PAYLOAD_ADDR, ALIGN(size, 0x10)); + + reconfig_hw_workaround(false, byte_swap_32(*(u32 *)(buf + size - sizeof(u32)))); + } + else { + reloc_patcher(PATCHED_RELOC_ENTRY, EXT_PAYLOAD_ADDR, 0x7000); + reconfig_hw_workaround(true, 0); + } + + void (*ext_payload_ptr)() = (void *)EXT_PAYLOAD_ADDR; + void (*update_ptr)() = (void *)RCM_PAYLOAD_ADDR; + + msleep(100); + + // Launch our payload. + if (!update) + (*ext_payload_ptr)(); + else { + EMC(EMC_SCRATCH0) |= EMC_HEKA_UPD; + (*update_ptr)(); + } + } + + return 4; +} \ No newline at end of file diff --git a/source/meme/external_utils.h b/source/meme/external_utils.h new file mode 100644 index 0000000..51dc3fc --- /dev/null +++ b/source/meme/external_utils.h @@ -0,0 +1,15 @@ +#pragma once + +#define RELOC_META_OFF 0x7C +#define PATCHED_RELOC_SZ 0x94 +#define PATCHED_RELOC_STACK 0x40007000 +#define PATCHED_RELOC_ENTRY 0x40010000 +#define EXT_PAYLOAD_ADDR 0xC03C0000 +#define RCM_PAYLOAD_ADDR (EXT_PAYLOAD_ADDR + ALIGN(PATCHED_RELOC_SZ, 0x10)) +#define COREBOOT_ADDR (0xD0000000 - 0x100000) +#define CBFS_DRAM_EN_ADDR 0x4003e000 +#define CBFS_DRAM_MAGIC 0x4452414D // "DRAM" +#define EMC_BASE 0x7001B000 +#define EMC(off) _REG(EMC_BASE, off) + +int launch_payload(char *path, int update); \ No newline at end of file diff --git a/source/meme/mainfunctions.c b/source/meme/mainfunctions.c index 97bcc0f..84fd5f9 100644 --- a/source/meme/mainfunctions.c +++ b/source/meme/mainfunctions.c @@ -7,20 +7,28 @@ #include "../libs/fatfs/ff.h" #include "../storage/sdmmc.h" #include "graphics.h" +#include "external_utils.h" -int _openfilemenu(const char *path, char *clipboardpath){ +int _openfilemenu(char *path, char *clipboardpath){ meme_clearscreen(); FILINFO fno; f_stat(path, &fno); - char *options[4]; + char *options[5]; int res = 0; int mres = -1; int ret = -1; + int i = 4; + bool payload = false; addchartoarray("Back", options, 0); addchartoarray("Copy to clipboard", options, 1); addchartoarray("Move to clipboard", options, 2); addchartoarray("Delete file", options, 3); + if (strstr(path, ".bin") != NULL){ + addchartoarray("Launch payload", options, i); + payload = true; + i++; + } gfx_printf("%kPath: %s%k\n\n", COLOR_GREEN, path, COLOR_WHITE); @@ -29,8 +37,10 @@ int _openfilemenu(const char *path, char *clipboardpath){ gfx_printf("Size: %s", size); - res = gfx_menulist(160, options, 4); + res = gfx_menulist(160, options, i); switch(res){ + case 1: + break; case 2: ret = 0; strcpy(clipboardpath, path); @@ -44,7 +54,7 @@ int _openfilemenu(const char *path, char *clipboardpath){ if (mres == 0) f_unlink(path); break; default: - break; + if (payload) launch_payload(path, 0); } meme_clearscreen(); diff --git a/source/meme/utils.c b/source/meme/utils.c index b88d62a..f410ce8 100644 --- a/source/meme/utils.c +++ b/source/meme/utils.c @@ -10,6 +10,7 @@ #include "../storage/sdmmc.h" #include "graphics.h" + void utils_gfx_init(){ display_backlight_brightness(100, 1000); gfx_clear_grey(0x1B); @@ -28,7 +29,7 @@ void addpartpath(char *path, char *add){ strcat(path, add); } -void return_readable_byte_amounts(int size, char *in){ +void return_readable_byte_amounts(unsigned long int size, char *in){ char type[3]; unsigned long int sizetemp = size; int muhbytes = 0; diff --git a/source/meme/utils.h b/source/meme/utils.h index 44efd3a..90118b5 100644 --- a/source/meme/utils.h +++ b/source/meme/utils.h @@ -15,5 +15,5 @@ int readfolder(char *items[], unsigned int *muhbits, const char *path); int copy(const char *src, const char *dst); void addchartoarray(char *add, char *items[], int spot); int copywithpath(const char *src, const char *dstpath, int mode); -void return_readable_byte_amounts(int size, char *in); +void return_readable_byte_amounts(unsigned long int size, char *in); int getfilesize(const char *path); \ No newline at end of file