mirror of
https://github.com/fail0verflow/mini.git
synced 2024-11-28 06:04:19 +01:00
miniIOS IPC updates
This commit is contained in:
parent
d4cdb1f01d
commit
29caadc06b
2
Makefile
2
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
|
||||
|
||||
|
100
ipc.c
100
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);
|
||||
}
|
||||
|
18
ipc.h
18
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);
|
||||
|
29
ipcstruct.S
29
ipcstruct.S
@ -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
|
16
ipcstruct.h
16
ipcstruct.h
@ -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
|
2
irq.c
2
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;
|
||||
|
||||
|
56
miniios.ld
56
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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user