hbc/wiipax/stub/main.c

110 lines
2.1 KiB
C
Raw Normal View History

2016-11-23 06:35:12 +01:00
#include "common.h"
#include "string.h"
#include "elf.h"
#include "LzmaDec.h"
extern const u8 __self_start[], __self_end[];
extern const u8 __payload[];
extern void _plunge(u32 entry);
typedef struct {
u8 * const data;
const u32 len_in;
const u32 len_out;
const u8 props[LZMA_PROPS_SIZE];
} __attribute__((packed)) _payload;
const _payload * const payload = (void *) __payload;
u8 * const code_buffer = (u8 *) 0x90100000;
static void *lz_malloc(void *p, size_t size) {
(void) p;
(void) size;
printf("lz_malloc %u\n", size);
return (void *) 0x90081000;
}
static void lz_free(void *p, void *address) {
(void) p;
(void) address;
printf("lz_free %p\n", address);
}
static const ISzAlloc lz_alloc = { lz_malloc, lz_free };
static inline __attribute__((always_inline)) int decode(void) {
SizeT len_in;
SizeT len_out;
ELzmaStatus status;
SRes res;
len_in = payload->len_in;
len_out = payload->len_out;
printf("in: %d out: %d\n", len_in, len_out);
res = LzmaDecode(code_buffer, &len_out, payload->data, &len_in,
payload->props, LZMA_PROPS_SIZE, LZMA_FINISH_END,
&status, (ISzAlloc*)&lz_alloc);
if (res != SZ_OK) {
printf("decoding error %d (%u)\n", res, status);
return res;
}
return 0;
}
void stubmain(void) {
#ifndef NDEBUG
exception_init();
#endif
// clear interrupt mask
write32(0x0c003004, 0);
#ifndef NDEBUG
#ifndef DEVKITFAIL
udelay(500 * 1000); // wait for mini - avoid EXI battle
#endif
gecko_init();
#endif
printf("hello world\n");
printf("payload @%p blob @%p\n", payload, payload->data);
if (decode() == 0 && valid_elf_image(code_buffer)) {
printf("Valid ELF image detected.\n");
u32 entry = load_elf_image(code_buffer);
if (entry) {
// Disable all IRQs; ack all pending IRQs.
write32(0x0c003004, 0);
write32(0x0c003000, 0xffffffff);
printf("Branching to 0x%08x\n", entry);
#ifndef DEVKITFAIL
// detect failkit apps packed with the mini stub
if (entry & 0xc0000000) {
void (*ep)() = (void (*)()) entry;
ep();
} else {
_plunge(entry);
}
#else
void (*ep)() = (void (*)()) entry;
ep();
#endif
}
}
error:
blink();
udelay(500000);
goto error;
}