mirror of
https://github.com/fail0verflow/mini.git
synced 2024-11-28 06:04:19 +01:00
IPC to boot in-mem PPC ELF, with some test code.
This commit is contained in:
parent
05efa74484
commit
b409c9694e
4
boot2.h
4
boot2.h
@ -1,8 +1,10 @@
|
||||
#ifndef __BOOT2_H__
|
||||
#define __BOOT2_H__
|
||||
|
||||
void boot2_ipc(volatile ipc_request *req);
|
||||
#include "ipc.h"
|
||||
|
||||
int boot2_run(u32 tid_hi, u32 tid_lo);
|
||||
void boot2_init();
|
||||
void boot2_ipc(volatile ipc_request *req);
|
||||
|
||||
#endif
|
||||
|
4
ipc.c
4
ipc.c
@ -10,6 +10,7 @@
|
||||
#include "sdhc.h"
|
||||
#include "crypto.h"
|
||||
#include "boot2.h"
|
||||
#include "powerpc.h"
|
||||
#include "panic.h"
|
||||
|
||||
static volatile ipc_request in_queue[IPC_IN_SIZE] ALIGNED(32) MEM2_BSS;
|
||||
@ -136,6 +137,9 @@ static int process_slow(volatile ipc_request *req)
|
||||
boot2_ipc(req);
|
||||
return 0;
|
||||
break;
|
||||
case IPC_DEV_PPC:
|
||||
powerpc_ipc(req);
|
||||
break;
|
||||
default:
|
||||
gecko_printf("IPC: unknown SLOW request %02x-%04x\n", req->device, req->req);
|
||||
}
|
||||
|
3
ipc.h
3
ipc.h
@ -12,6 +12,7 @@
|
||||
#define IPC_DEV_KEYS 0x03
|
||||
#define IPC_DEV_AES 0x04
|
||||
#define IPC_DEV_BOOT2 0x05
|
||||
#define IPC_DEV_PPC 0x06
|
||||
|
||||
#define IPC_SYS_PING 0x0000
|
||||
#define IPC_SYS_JUMP 0x0001
|
||||
@ -56,6 +57,8 @@
|
||||
|
||||
#define IPC_BOOT2_RUN 0x0000
|
||||
|
||||
#define IPC_PPC_BOOT 0x0000
|
||||
|
||||
#define IPC_CODE (f,d,r) (((f)<<24)|((d)<<16)|(r))
|
||||
|
||||
#define IPC_IN_SIZE 32
|
||||
|
2
main.c
2
main.c
@ -222,7 +222,7 @@ void *_main(void *base)
|
||||
|
||||
gecko_printf("Trying to boot:" PPC_BOOT_FILE "\n");
|
||||
|
||||
res = powerpc_load_file(PPC_BOOT_FILE);
|
||||
res = powerpc_boot_file(PPC_BOOT_FILE);
|
||||
if(res < 0) {
|
||||
gecko_printf("Failed to boot PPC: %d\n", res);
|
||||
gecko_printf("Continuing anyway\n");
|
||||
|
17
powerpc.c
17
powerpc.c
@ -20,7 +20,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*/
|
||||
#include "types.h"
|
||||
#include "memory.h"
|
||||
#include "powerpc.h"
|
||||
#include "powerpc_elf.h"
|
||||
#include "hollywood.h"
|
||||
#include "utils.h"
|
||||
#include "start.h"
|
||||
@ -73,3 +75,18 @@ void powerpc_reset()
|
||||
udelay(100000);
|
||||
set32(HW_EXICTRL, EXICTRL_ENABLE_EXI);
|
||||
}
|
||||
|
||||
void powerpc_ipc(volatile ipc_request *req)
|
||||
{
|
||||
switch (req->req) {
|
||||
case IPC_PPC_BOOT:
|
||||
dc_invalidaterange((void *) req->args[0], (u32) req->args[1]);
|
||||
int res = powerpc_boot_mem((u8 *) req->args[0], (u32) req->args[1]);
|
||||
if (res)
|
||||
ipc_post(req->code, req->tag, 1, res);
|
||||
break;
|
||||
default:
|
||||
gecko_printf("IPC: unknown SLOW PPC request %04X\n", req->req);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,12 @@
|
||||
#ifndef __POWERPC_H__
|
||||
#define __POWERPC_H__ 1
|
||||
|
||||
void ppc_boot_code();
|
||||
#include "ipc.h"
|
||||
|
||||
void powerpc_upload_stub(u32 entry);
|
||||
void powerpc_hang();
|
||||
void powerpc_reset();
|
||||
void powerpc_ipc(volatile ipc_request *req);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -16,7 +16,7 @@ static Elf32_Ehdr elfhdr;
|
||||
static Elf32_Phdr phdrs[PHDR_MAX];
|
||||
static FIL fd;
|
||||
|
||||
int powerpc_load_file(const char *path)
|
||||
int powerpc_boot_file(const char *path)
|
||||
{
|
||||
u32 read;
|
||||
FRESULT fres;
|
||||
@ -90,3 +90,61 @@ int powerpc_load_file(const char *path)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int powerpc_boot_mem(const u8 *addr, u32 len)
|
||||
{
|
||||
if (len < sizeof(Elf32_Ehdr))
|
||||
return -100;
|
||||
|
||||
Elf32_Ehdr *ehdr = (Elf32_Ehdr *) addr;
|
||||
|
||||
if (memcmp("\x7F" "ELF\x01\x02\x01\x00\x00", ehdr->e_ident, 9)) {
|
||||
gecko_printf("Invalid ELF header! 0x%02x 0x%02x 0x%02x 0x%02x\n",
|
||||
ehdr->e_ident[0], ehdr->e_ident[1],
|
||||
ehdr->e_ident[2], ehdr->e_ident[3]);
|
||||
return -101;
|
||||
}
|
||||
|
||||
if (ehdr->e_phoff == 0 || ehdr->e_phnum == 0) {
|
||||
gecko_printf("ELF has no program headers!\n");
|
||||
return -102;
|
||||
}
|
||||
|
||||
if (ehdr->e_phnum > PHDR_MAX) {
|
||||
gecko_printf("ELF has too many (%d) program headers!\n",
|
||||
elfhdr.e_phnum);
|
||||
return -102;
|
||||
}
|
||||
|
||||
int count = ehdr->e_phnum;
|
||||
if (len < ehdr->e_phoff + count * sizeof(Elf32_Phdr))
|
||||
return -103;
|
||||
|
||||
Elf32_Phdr *phdr = (Elf32_Phdr *) &addr[ehdr->e_phoff];
|
||||
|
||||
// TODO: add more checks here
|
||||
// - phdrs out of bounds?
|
||||
// - loaded ELF overwrites itself?
|
||||
|
||||
powerpc_hang();
|
||||
|
||||
while (count--) {
|
||||
if (phdr->p_type != PT_LOAD) {
|
||||
gecko_printf("Skipping PHDR of type %d\n", phdr->p_type);
|
||||
} else {
|
||||
gecko_printf("LOAD 0x%x -> %p [0x%x]\n", phdr->p_offset, phdr->p_paddr, phdr->p_filesz);
|
||||
memcpy((void *) phdr->p_paddr, &addr[phdr->p_offset],
|
||||
phdr->p_filesz);
|
||||
}
|
||||
phdr++;
|
||||
}
|
||||
|
||||
dc_flushall();
|
||||
|
||||
gecko_printf("ELF load done, booting PPC...\n");
|
||||
powerpc_upload_stub(ehdr->e_entry);
|
||||
powerpc_reset();
|
||||
gecko_printf("PPC booted!\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#ifndef __POWERPC_H__
|
||||
#define __POWERPC_H__ 1
|
||||
#ifndef __POWERPC_ELF_H__
|
||||
#define __POWERPC_ELF_H__ 1
|
||||
|
||||
int powerpc_load_file(const char *path);
|
||||
int powerpc_boot_file(const char *path);
|
||||
int powerpc_boot_mem(const u8 *addr, u32 len);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user