mirror of
https://github.com/fail0verflow/mini.git
synced 2024-11-28 06:04:19 +01:00
Reworked vectoring for mini's _main()
ipc_process_slow() and friends return a vector where bootmii branches to upon exit. Implemented IPC_SYS_JUMP via ipc_queue_slow_jump(). Ability to upload armboot.bin with the bootmii client.
This commit is contained in:
parent
a5c87a6127
commit
68397f67cd
3
Makefile
3
Makefile
@ -24,6 +24,9 @@ $(TARGET_BIN): $(TARGET) $(ELFLOADER)
|
||||
@echo "MAKEBIN $@"
|
||||
@$(MAKEBIN) $(ELFLOADER) $< $@
|
||||
|
||||
upload: $(TARGET_BIN)
|
||||
@$(WIIDEV)/bin/bootmii -a $<
|
||||
|
||||
clean: myclean
|
||||
|
||||
myclean:
|
||||
|
28
boot2.c
28
boot2.c
@ -38,7 +38,6 @@ static u8 boot2_initialized = 0;
|
||||
static u8 boot2_copy;
|
||||
static u8 pages_read;
|
||||
static u8 *page_ptr;
|
||||
extern void *vector;
|
||||
|
||||
typedef struct {
|
||||
u32 len;
|
||||
@ -332,7 +331,7 @@ static u32 patch[] = {
|
||||
0x48415858,
|
||||
};
|
||||
|
||||
void boot2_run(u32 tid_hi, u32 tid_lo) {
|
||||
u32 boot2_run(u32 tid_hi, u32 tid_lo) {
|
||||
u8 *ptr;
|
||||
int i;
|
||||
ioshdr *hdr;
|
||||
@ -356,37 +355,40 @@ void boot2_run(u32 tid_hi, u32 tid_lo) {
|
||||
}
|
||||
|
||||
hdr->argument = 0x42;
|
||||
vector = (u8 *)0x11000000 + hdr->hdrsize;
|
||||
gecko_printf("boot2 is at %p\n", vector);
|
||||
return;
|
||||
|
||||
u32 vector = 0x11000000 + hdr->hdrsize;
|
||||
gecko_printf("boot2 is at 0x%08x\n", vector);
|
||||
return vector;
|
||||
}
|
||||
|
||||
int boot2_ipc(volatile ipc_request *req)
|
||||
u32 boot2_ipc(volatile ipc_request *req)
|
||||
{
|
||||
u32 vector = 0;
|
||||
|
||||
switch (req->req) {
|
||||
case IPC_BOOT2_RUN:
|
||||
if(boot2_initialized) {
|
||||
// post first so that the memory protection doesn't kill IPC for the PowerPC
|
||||
ipc_post(req->code, req->tag, 1, boot2_copy);
|
||||
ipc_flush();
|
||||
boot2_run((u32)req->args[0], (u32)req->args[1]);
|
||||
vector = boot2_run((u32)req->args[0], (u32)req->args[1]);
|
||||
} else {
|
||||
ipc_post(req->code, req->tag, 1, -1);
|
||||
}
|
||||
return 0;
|
||||
|
||||
break;
|
||||
|
||||
case IPC_BOOT2_TMD:
|
||||
if (boot2_initialized) {
|
||||
if (boot2_initialized)
|
||||
ipc_post(req->code, req->tag, 1, &boot2_tmd);
|
||||
} else {
|
||||
else
|
||||
ipc_post(req->code, req->tag, 1, -1);
|
||||
}
|
||||
return 1;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
gecko_printf("IPC: unknown SLOW BOOT2 request %04X\n", req->req);
|
||||
}
|
||||
return 1;
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
4
boot2.h
4
boot2.h
@ -3,8 +3,8 @@
|
||||
|
||||
#include "ipc.h"
|
||||
|
||||
int boot2_run(u32 tid_hi, u32 tid_lo);
|
||||
u32 boot2_run(u32 tid_hi, u32 tid_lo);
|
||||
void boot2_init();
|
||||
void boot2_ipc(volatile ipc_request *req);
|
||||
u32 boot2_ipc(volatile ipc_request *req);
|
||||
|
||||
#endif
|
||||
|
58
gecko.c
58
gecko.c
@ -214,8 +214,8 @@ int gecko_printf(const char *fmt, ...)
|
||||
// irq context
|
||||
|
||||
#define GECKO_STATE_NONE 0
|
||||
#define GECKO_STATE_RECEIVE_ELF_SIZE 1
|
||||
#define GECKO_STATE_RECEIVE_ELF 2
|
||||
#define GECKO_STATE_RECEIVE_BUFFER_SIZE 1
|
||||
#define GECKO_STATE_RECEIVE_BUFFER 2
|
||||
|
||||
static u32 _gecko_cmd = 0;
|
||||
static u32 _gecko_cmd_start_time = 0;
|
||||
@ -257,21 +257,32 @@ void gecko_timer(void) {
|
||||
switch (_gecko_cmd) {
|
||||
// upload powerpc ELF
|
||||
case 0x43524150:
|
||||
_gecko_state = GECKO_STATE_RECEIVE_ELF_SIZE;
|
||||
_gecko_state = GECKO_STATE_RECEIVE_BUFFER_SIZE;
|
||||
_gecko_receive_len = 0;
|
||||
_gecko_receive_left = 4;
|
||||
_gecko_receive_buffer = (u8 *) 0x10100000;
|
||||
|
||||
irq_set_alarm(1, 0);
|
||||
_gecko_cmd_start_time = read32(HW_TIMER);
|
||||
|
||||
gecko_console_enabled = 0;
|
||||
break;
|
||||
|
||||
// upload ARM ELF
|
||||
case 0x5a4f4d47:
|
||||
_gecko_state = GECKO_STATE_RECEIVE_BUFFER_SIZE;
|
||||
_gecko_receive_len = 0;
|
||||
_gecko_receive_left = 4;
|
||||
_gecko_receive_buffer = (u8 *) 0x0; // yarly
|
||||
|
||||
irq_set_alarm(1, 0);
|
||||
_gecko_cmd_start_time = read32(HW_TIMER);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
case GECKO_STATE_RECEIVE_ELF_SIZE:
|
||||
case GECKO_STATE_RECEIVE_BUFFER_SIZE:
|
||||
if (!_gecko_checkrecv() || !_gecko_recvbyte(&b))
|
||||
return;
|
||||
|
||||
@ -280,8 +291,7 @@ void gecko_timer(void) {
|
||||
_gecko_receive_left--;
|
||||
|
||||
if (!_gecko_receive_left) {
|
||||
_gecko_state = GECKO_STATE_RECEIVE_ELF;
|
||||
_gecko_receive_buffer = (u8 *) 0x10100000;
|
||||
_gecko_state = GECKO_STATE_RECEIVE_BUFFER;
|
||||
_gecko_receive_left = _gecko_receive_len;
|
||||
|
||||
powerpc_hang();
|
||||
@ -289,7 +299,7 @@ void gecko_timer(void) {
|
||||
|
||||
return;
|
||||
|
||||
case GECKO_STATE_RECEIVE_ELF:
|
||||
case GECKO_STATE_RECEIVE_BUFFER:
|
||||
while (_gecko_receive_left) {
|
||||
if (!_gecko_checkrecv() || !_gecko_recvbyte(_gecko_receive_buffer))
|
||||
return;
|
||||
@ -298,23 +308,33 @@ void gecko_timer(void) {
|
||||
_gecko_receive_left--;
|
||||
}
|
||||
|
||||
if (!_gecko_receive_left) {
|
||||
irq_set_alarm(100, 0);
|
||||
_gecko_cmd = 0;
|
||||
_gecko_cmd_start_time = 0;
|
||||
_gecko_state = GECKO_STATE_NONE;
|
||||
|
||||
gecko_console_enabled = 1;
|
||||
|
||||
if (powerpc_boot_mem((u8 *) 0x10100000, _gecko_receive_len))
|
||||
gecko_printf("GECKOTIMER: elflolwtf?\n");
|
||||
}
|
||||
if (!_gecko_receive_left)
|
||||
break;
|
||||
|
||||
return;
|
||||
|
||||
default:
|
||||
gecko_printf("GECKOTIMER: statelolwtf?\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// done receiving, handle the command
|
||||
switch (_gecko_cmd) {
|
||||
case 0x43524150:
|
||||
if (powerpc_boot_mem((u8 *) 0x10100000, _gecko_receive_len))
|
||||
gecko_printf("GECKOTIMER: elflolwtf?\n");
|
||||
break;
|
||||
|
||||
case 0x5a4f4d47:
|
||||
// skip headerlen, which is stored at u32[0]
|
||||
ipc_queue_slow_jump(((u32 *) 0x0)[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
irq_set_alarm(100, 0);
|
||||
|
||||
_gecko_cmd = 0;
|
||||
_gecko_cmd_start_time = 0;
|
||||
_gecko_state = GECKO_STATE_NONE;
|
||||
}
|
||||
|
||||
|
41
ipc.c
41
ipc.c
@ -104,7 +104,7 @@ void ipc_flush(void)
|
||||
while(peek_outhead() != out_tail);
|
||||
}
|
||||
|
||||
static int process_slow(volatile ipc_request *req)
|
||||
static u32 process_slow(volatile ipc_request *req)
|
||||
{
|
||||
//gecko_printf("IPC: process slow_queue @ %p\n",req);
|
||||
|
||||
@ -117,6 +117,8 @@ static int process_slow(volatile ipc_request *req)
|
||||
case IPC_SYS_PING: //PING can be both slow and fast for testing purposes
|
||||
ipc_post(req->code, req->tag, 0);
|
||||
break;
|
||||
case IPC_SYS_JUMP:
|
||||
return req->args[0];
|
||||
default:
|
||||
gecko_printf("IPC: unknown SLOW SYS request %04x\n", req->req);
|
||||
}
|
||||
@ -142,7 +144,8 @@ static int process_slow(volatile ipc_request *req)
|
||||
default:
|
||||
gecko_printf("IPC: unknown SLOW request %02x-%04x\n", req->device, req->req);
|
||||
}
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void process_in(void)
|
||||
@ -244,6 +247,26 @@ void ipc_irq(void)
|
||||
gecko_printf("IPC: IRQ but no bell!\n");
|
||||
}
|
||||
|
||||
void ipc_queue_slow_jump(u32 addr)
|
||||
{
|
||||
volatile ipc_request *req = &in_queue[in_head];
|
||||
|
||||
if(slow_queue_head == ((slow_queue_tail + 1)&(IPC_SLOW_SIZE-1))) {
|
||||
gecko_printf("IPC: Slowqueue overrun\n");
|
||||
panic2(0, PANIC_IPCOVF);
|
||||
}
|
||||
|
||||
req->flags = IPC_SLOW;
|
||||
req->device = IPC_DEV_SYS;
|
||||
req->req = IPC_SYS_JUMP;
|
||||
|
||||
req->tag = 0;
|
||||
req->args[0] = addr;
|
||||
|
||||
slow_queue[slow_queue_tail] = *req;
|
||||
slow_queue_tail = (slow_queue_tail+1)&(IPC_SLOW_SIZE-1);
|
||||
}
|
||||
|
||||
void ipc_initialize(void)
|
||||
{
|
||||
write32(HW_IPC_ARMMSG, 0);
|
||||
@ -269,18 +292,22 @@ void ipc_shutdown(void)
|
||||
irq_disable(IRQ_IPC);
|
||||
}
|
||||
|
||||
void ipc_process_slow(void)
|
||||
u32 ipc_process_slow(void)
|
||||
{
|
||||
while(1) {
|
||||
while(slow_queue_head != slow_queue_tail) {
|
||||
if(!process_slow(&slow_queue[slow_queue_head]))
|
||||
return;
|
||||
u32 vector = 0;
|
||||
|
||||
while (!vector) {
|
||||
while (slow_queue_head != slow_queue_tail) {
|
||||
vector = process_slow(&slow_queue[slow_queue_head]);
|
||||
slow_queue_head = (slow_queue_head+1)&(IPC_SLOW_SIZE-1);
|
||||
}
|
||||
|
||||
u32 cookie = irq_kill();
|
||||
if(slow_queue_head == slow_queue_tail)
|
||||
irq_wait();
|
||||
irq_restore(cookie);
|
||||
}
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
|
3
ipc.h
3
ipc.h
@ -89,11 +89,12 @@ typedef const struct {
|
||||
} ipc_infohdr;
|
||||
|
||||
void ipc_irq(void);
|
||||
void ipc_queue_slow_jump(u32 addr); // only call this from irq context
|
||||
|
||||
void ipc_initialize(void);
|
||||
void ipc_shutdown(void);
|
||||
void ipc_post(u32 code, u32 tag, u32 num_args, ...);
|
||||
void ipc_flush(void);
|
||||
void ipc_process_slow(void);
|
||||
u32 ipc_process_slow(void);
|
||||
|
||||
#endif
|
||||
|
11
main.c
11
main.c
@ -38,8 +38,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include "nand.h"
|
||||
#include "boot2.h"
|
||||
|
||||
void *vector;
|
||||
|
||||
typedef struct {
|
||||
u32 hdrsize;
|
||||
u32 loadersize;
|
||||
@ -167,10 +165,11 @@ void *patch_boot2(void *base, u64 titleID)
|
||||
return (void*)(((u32)parhdr) + parhdr->hdrsize);
|
||||
}
|
||||
|
||||
void *_main(void *base)
|
||||
u32 _main(void *base)
|
||||
{
|
||||
FRESULT fres;
|
||||
int res;
|
||||
u32 vector;
|
||||
|
||||
gecko_init();
|
||||
gecko_printf("mini v0.2 loading\n");
|
||||
@ -212,7 +211,7 @@ void *_main(void *base)
|
||||
|
||||
if (read32(0x0d800190) & 2) {
|
||||
gecko_printf("GameCube compatibility mode detected...\n");
|
||||
boot2_run(1, 0x101);
|
||||
vector = boot2_run(1, 0x101);
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
@ -230,7 +229,7 @@ void *_main(void *base)
|
||||
}
|
||||
|
||||
gecko_printf("Going into IPC mainloop...\n");
|
||||
ipc_process_slow();
|
||||
vector = ipc_process_slow();
|
||||
gecko_printf("IPC mainloop done!\n");
|
||||
gecko_printf("Shutting down IPC...\n");
|
||||
ipc_shutdown();
|
||||
@ -241,6 +240,6 @@ shutdown:
|
||||
gecko_printf("Shutting down caches and MMU...\n");
|
||||
mem_shutdown();
|
||||
|
||||
gecko_printf("Vectoring to %p...\n",vector);
|
||||
gecko_printf("Vectoring to 0x%08x...\n", vector);
|
||||
return vector;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user