diff --git a/Makefile b/Makefile index e34a077..4745615 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ MAKEBIN = python ../makebin.py TARGET = miniios.bin ELF = miniios.elf -OBJECTS = start.o ipcstruct.o main.o ipc.o vsprintf.o string.o gecko.o memory.o memory_asm.o \ +OBJECTS = start.o main.o ipc.o vsprintf.o string.o gecko.o memory.o memory_asm.o \ utils_asm.o utils.o ff.o diskio.o sdhc.o powerpc_elf.o powerpc.o panic.o irq.o irq_asm.o \ exception.o exception_asm.o crypto.o nand.o nandfs.o diff --git a/ipc.c b/ipc.c index fa1c7b0..363ec78 100644 --- a/ipc.c +++ b/ipc.c @@ -5,34 +5,46 @@ #include "utils.h" #include "hollywood.h" #include "gecko.h" -#include "ipcstruct.h" #include "ipc.h" -#define IPC_SLOW_SIZE 128 +static volatile ipc_request in_queue[IPC_IN_SIZE] ALIGNED(32) MEM2_BSS; +static volatile ipc_request out_queue[IPC_OUT_SIZE] ALIGNED(32) MEM2_BSS; +static volatile ipc_request slow_queue[IPC_SLOW_SIZE]; -volatile ipc_request slow[IPC_SLOW_SIZE]; -u16 slow_head; -vu16 slow_tail; +extern char __mem2_area_start[]; -u16 in_head; -u16 out_tail; +const ipc_infohdr __ipc_info ALIGNED(32) MEM2_RODATA = { + .magic = "IPC", + .version = 1, + .mem2_boundary = __mem2_area_start, + .ipc_in = in_queue, + .ipc_in_size = IPC_IN_SIZE, + .ipc_out = out_queue, + .ipc_out_size = IPC_OUT_SIZE, +}; + +static u16 slow_queue_head; +static vu16 slow_queue_tail; + +static u16 in_head; +static u16 out_tail; static inline void poke_outtail(u16 num) { - write16(HW_IPC_ARMMSG, num); + mask32(HW_IPC_ARMMSG, 0xFFFF, num); } static inline void poke_inhead(u16 num) { - write16(HW_IPC_ARMMSG+2, num); + mask32(HW_IPC_ARMMSG, 0xFFFF0000, num<<16); } static inline u16 peek_intail(void) { - return read16(HW_IPC_PPCMSG); + return read32(HW_IPC_PPCMSG) & 0xFFF; } static inline u16 peek_outhead(void) { - return read16(HW_IPC_PPCMSG+2); + return read32(HW_IPC_PPCMSG) >> 16; } void ipc_post(u32 code, u32 tag, u32 num_args, ...) @@ -42,19 +54,19 @@ void ipc_post(u32 code, u32 tag, u32 num_args, ...) u32 cookie = irq_kill(); if(peek_outhead() == ((out_tail + 1)&(IPC_OUT_SIZE-1))) { - gecko_printf("IPC: out queue full, PPC slow/dead/DoSed\n"); + gecko_printf("IPC: out queue full, PPC slow/dead/flooded\n"); while(peek_outhead() == ((out_tail + 1)&(IPC_OUT_SIZE-1))); } - ipc_out[out_tail].code = code; - ipc_out[out_tail].tag = tag; + out_queue[out_tail].code = code; + out_queue[out_tail].tag = tag; if(num_args) { va_start(ap, num_args); while(num_args--) { - ipc_out[out_tail].args[arg++] = va_arg(ap, u32); + out_queue[out_tail].args[arg++] = va_arg(ap, u32); } va_end(ap); } - dc_flushrange((void*)&ipc_out[out_tail], 32); + dc_flushrange((void*)&out_queue[out_tail], 32); out_tail = (out_tail+1)&(IPC_OUT_SIZE-1); poke_outtail(out_tail); write32(HW_IPC_ARMCTRL, IPC_CTRL_INT_RECV | IPC_CTRL_SEND); @@ -64,31 +76,46 @@ void ipc_post(u32 code, u32 tag, u32 num_args, ...) static int process_slow(volatile ipc_request *req) { - gecko_printf("IPC: process slow @ %p\n",req); + //gecko_printf("IPC: process slow_queue @ %p\n",req); - gecko_printf("IPC: req %08x %08x [%08x %08x %08x %08x %08x %08x]\n", req->code, req->tag, - req->args[0], req->args[1], req->args[2], req->args[3], req->args[4], req->args[5]); + //gecko_printf("IPC: req %08x %08x [%08x %08x %08x %08x %08x %08x]\n", req->code, req->tag, + // req->args[0], req->args[1], req->args[2], req->args[3], req->args[4], req->args[5]); - gecko_printf("IPC: unknown SLOW request %02x-%04x\n", req->device, req->req); + switch(req->device) { + case IPC_DEV_SYS: + switch(req->req) { + case IPC_SYS_PING: //PING can be both slow and fast for testing purposes + ipc_post(req->code, req->tag, 0); + break; + default: + gecko_printf("IPC: unknown SLOW SYS request %04x\n", req->req); + } + break; + default: + gecko_printf("IPC: unknown SLOW request %02x-%04x\n", req->device, req->req); + } return 1; } static void process_in(void) { - volatile ipc_request *req = &ipc_in[in_head]; + volatile ipc_request *req = &in_queue[in_head]; - gecko_printf("IPC: process in %d @ %p\n",in_head,req); + //gecko_printf("IPC: process in %d @ %p\n",in_head,req); dc_invalidaterange((void*)req, 32); - gecko_printf("IPC: req %08x %08x [%08x %08x %08x %08x %08x %08x]\n", req->code, req->tag, - req->args[0], req->args[1], req->args[2], req->args[3], req->args[4], req->args[5]); + //gecko_printf("IPC: req %08x %08x [%08x %08x %08x %08x %08x %08x]\n", req->code, req->tag, + // req->args[0], req->args[1], req->args[2], req->args[3], req->args[4], req->args[5]); if(req->flags & IPC_FAST) { switch(req->device) { case IPC_DEV_SYS: // handle fast SYS requests here switch(req->req) { + case IPC_SYS_PING: + ipc_post(req->code, req->tag, 0); + break; case IPC_SYS_WRITE32: write32(req->args[0], req->args[1]); break; @@ -144,34 +171,29 @@ static void process_in(void) break; } } else { - if(slow_head == ((slow_tail + 1)&(IPC_SLOW_SIZE-1))) { + if(slow_queue_head == ((slow_queue_tail + 1)&(IPC_SLOW_SIZE-1))) { gecko_printf("IPC: Slowqueue overrun\n"); panic(0x33); } - slow[slow_tail] = *req; - slow_tail = (slow_tail+1)&(IPC_SLOW_SIZE-1); + slow_queue[slow_queue_tail] = *req; + slow_queue_tail = (slow_queue_tail+1)&(IPC_SLOW_SIZE-1); } } void ipc_irq(void) { int donebell = 0; - gecko_printf("IPC: irq\n"); while(read32(HW_IPC_ARMCTRL) & IPC_CTRL_RECV) { write32(HW_IPC_ARMCTRL, IPC_CTRL_INT_RECV | IPC_CTRL_RECV); - int donereq = 0; while(peek_intail() != in_head) { process_in(); in_head = (in_head+1)&(IPC_IN_SIZE-1); poke_inhead(in_head); - donereq++; } - if(!donereq) - gecko_printf("IPC bell but no reqs\n"); donebell++; } if(!donebell) - gecko_printf("IPC IRQ but no bell!\n"); + gecko_printf("IPC: IRQ but no bell!\n"); } void ipc_initialize(void) @@ -180,8 +202,8 @@ void ipc_initialize(void) write32(HW_IPC_PPCMSG, 0); write32(HW_IPC_PPCCTRL, IPC_CTRL_SENT|IPC_CTRL_RECV); write32(HW_IPC_ARMCTRL, IPC_CTRL_SENT|IPC_CTRL_RECV); - slow_head = 0; - slow_tail = 0; + slow_queue_head = 0; + slow_queue_tail = 0; in_head = 0; out_tail = 0; irq_enable(IRQ_IPC); @@ -195,13 +217,13 @@ void ipc_shutdown(void) void ipc_process_slow(void) { while(1) { - while(slow_head != slow_tail) { - if(!process_slow(&slow[slow_head])) + while(slow_queue_head != slow_queue_tail) { + if(!process_slow(&slow_queue[slow_queue_head])) return; - slow_head = (slow_head+1)&(IPC_SLOW_SIZE-1); + slow_queue_head = (slow_queue_head+1)&(IPC_SLOW_SIZE-1); } u32 cookie = irq_kill(); - if(slow_head == slow_tail) + if(slow_queue_head == slow_queue_tail) irq_wait(); irq_restore(cookie); } diff --git a/ipc.h b/ipc.h index f97634d..4924e05 100644 --- a/ipc.h +++ b/ipc.h @@ -8,7 +8,8 @@ #define IPC_DEV_SYS 0x00 -#define IPC_SYS_JUMP 0x0000 +#define IPC_SYS_PING 0x0000 +#define IPC_SYS_JUMP 0x0001 #define IPC_SYS_WRITE32 0x0100 #define IPC_SYS_WRITE16 0x0101 #define IPC_SYS_WRITE8 0x0102 @@ -25,9 +26,12 @@ #define IPC_SYS_MASK16 0x010d #define IPC_SYS_MASK8 0x010e - #define IPC_CODE (f,d,r) (((f)<<24)|((d)<<16)|(r)) +#define IPC_IN_SIZE 32 +#define IPC_OUT_SIZE 32 +#define IPC_SLOW_SIZE 128 + typedef struct { union { struct { @@ -41,6 +45,16 @@ typedef struct { u32 args[6]; } ipc_request; +typedef const struct { + char magic[3]; + char version; + void *mem2_boundary; + volatile ipc_request *ipc_in; + u32 ipc_in_size; + volatile ipc_request *ipc_out; + u32 ipc_out_size; +} ipc_infohdr; + void ipc_irq(void); void ipc_initialize(void); diff --git a/ipcstruct.S b/ipcstruct.S deleted file mode 100644 index a79547c..0000000 --- a/ipcstruct.S +++ /dev/null @@ -1,29 +0,0 @@ -#include "ipcstruct.h" - - .section .rodata.ipc,"a",%progbits - .globl ipc_header - .type ipc_header, %object - .size ipc_header, 32 - .align 5 -ipc_header: - .ascii "IPC1" - .long 0 - .long ipc_in - .long 32 - .long ipc_out - .long 32 - - .section .bss.ipc,"aw",%nobits - .globl ipc_in - .type ipc_in, %object - .size ipc_in, 32 * IPC_IN_SIZE - .align 5 -ipc_in: - .space 32 * IPC_IN_SIZE - - .globl ipc_out - .type ipc_out, %object - .size ipc_out, 32 * IPC_OUT_SIZE - .align 5 -ipc_out: - .space 32 * IPC_IN_SIZE diff --git a/ipcstruct.h b/ipcstruct.h deleted file mode 100644 index 6097f24..0000000 --- a/ipcstruct.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __IPCSTRUCT_H__ -#define __IPCSTRUCT_H__ - -#define IPC_IN_SIZE 32 -#define IPC_OUT_SIZE 32 - -#ifndef _LANGUAGE_ASSEMBLY - -#include "ipc.h" - -extern volatile ipc_request ipc_in[IPC_IN_SIZE]; -extern volatile ipc_request ipc_out[IPC_OUT_SIZE]; - -#endif - -#endif diff --git a/irq.c b/irq.c index 5d796f6..79517b5 100644 --- a/irq.c +++ b/irq.c @@ -31,7 +31,7 @@ void irq_handler(void) u32 enabled = read32(HW_IRQENABLE); u32 flags = read32(HW_IRQFLAG); - gecko_printf("In IRQ handler: 0x%08x 0x%08x 0x%08x\n", enabled, flags, flags & enabled); + //gecko_printf("In IRQ handler: 0x%08x 0x%08x 0x%08x\n", enabled, flags, flags & enabled); flags = flags & enabled; diff --git a/miniios.ld b/miniios.ld index 40f7959..139ed41 100644 --- a/miniios.ld +++ b/miniios.ld @@ -1,6 +1,7 @@ OUTPUT_FORMAT("elf32-bigarm") OUTPUT_ARCH(arm) EXTERN(_start) +EXTERN(__ipc_info) ENTRY(_start) __stack_size = 0x800; @@ -8,31 +9,26 @@ __irqstack_size = 0x100; __excstack_size = 0x100; MEMORY { - sram : ORIGIN = 0xffff0000, LENGTH = 64K - sram2 : ORIGIN = 0xfffe0000, LENGTH = 32K - mem2 : ORIGIN = 0x13f00000, LENGTH = 1M + sram : ORIGIN = 0xffff0000, LENGTH = 64K + sram2 : ORIGIN = 0xfffe0000, LENGTH = 16K + pagetable : ORIGIN = 0xfffe4000, LENGTH = 16K + mem2 : ORIGIN = 0x13f00000, LENGTH = 1M } +__mem2_area_start = ORIGIN(mem2); +__mem2_area_size = LENGTH(mem2); +__mem2_area_end = ORIGIN(mem2) + LENGTH(mem2); + +__page_table = ORIGIN(pagetable); + SECTIONS { - .rodata.ipc : - { - *(.rodata.ipc) - . = ALIGN(4); - } >mem2 - - .bss.ipc : - { - *(.bss.ipc) - . = ALIGN(4); - } >mem2 - .rodata.mem2 : { *(.rodata.mem2) . = ALIGN(4); } >mem2 - + .data.mem2 : { *(.data.mem2) @@ -47,6 +43,11 @@ SECTIONS __bss2_end = . ; } >mem2 + .ipcinfo __mem2_area_end - 4 : + { + LONG(__ipc_info); + } >mem2 + .init : { *(.init) @@ -73,7 +74,7 @@ SECTIONS *(.gnu.linkonce.r*) . = ALIGN(4); } >sram2 - + .data : { *(.data) @@ -81,14 +82,13 @@ SECTIONS *(.gnu.linkonce.d*) . = ALIGN(4); } >sram2 - + .bss : { __bss_start = . ; *(.dynbss) *(.gnu.linkonce.b*) *(.bss*) - *(.sbss*) *(COMMON) . = ALIGN(4); __bss_end = . ; @@ -110,23 +110,5 @@ SECTIONS __excstack_addr = .; } >sram2 - .pagetable : - { - . = ALIGN(16384); - __page_table = .; - . = . + 16384; - } >sram2 - } -PROVIDE (__page_table = __page_table); -PROVIDE (__stack_end = __stack_end); -PROVIDE (__stack_addr = __stack_addr); -PROVIDE (__irqstack_end = __irqstack_end); -PROVIDE (__irqstack_addr = __irqstack_addr); -PROVIDE (__excstack_end = __excstack_end); -PROVIDE (__excstack_addr = __excstack_addr); -PROVIDE (__bss_start = __bss_start); -PROVIDE (__bss_end = __bss_end); -PROVIDE (__bss2_start = __bss2_start); -PROVIDE (__bss2_end = __bss2_end); diff --git a/powerpc_elf.c b/powerpc_elf.c index 238940a..237a30b 100644 --- a/powerpc_elf.c +++ b/powerpc_elf.c @@ -83,7 +83,7 @@ int powerpc_load_file(const char *path) gecko_puts("ELF load done, booting PPC...\n"); powerpc_upload_stub(NULL,0); powerpc_reset(); - gecko_puts("PPC booted!\n\n"); + gecko_puts("PPC booted!\n"); return 0; }