mirror of
https://github.com/fail0verflow/mini.git
synced 2024-11-30 23:24:19 +01:00
IPC cleanup.
New function ipc_enqueue_slow() to enqueue to the slow in_queue from within mini's irq context. The SDHC driver and the geckoloader uses this, which in return gets our irq stack size down again to a sane value.
This commit is contained in:
parent
456b26c1b7
commit
2100d84d7c
7
gecko.c
7
gecko.c
@ -320,14 +320,13 @@ void gecko_timer(void) {
|
|||||||
// done receiving, handle the command
|
// done receiving, handle the command
|
||||||
switch (_gecko_cmd) {
|
switch (_gecko_cmd) {
|
||||||
case 0x43524150:
|
case 0x43524150:
|
||||||
if (powerpc_boot_mem((u8 *) 0x10100000, _gecko_receive_len))
|
ipc_enqueue_slow(IPC_DEV_PPC, IPC_PPC_BOOT, 3,
|
||||||
gecko_printf("MINI/GECKO: the received binary is not a valid "
|
1, (u32) 0x10100000, _gecko_receive_len);
|
||||||
"PPC ELF. Broadway is dead now.\n");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x5a4f4d47:
|
case 0x5a4f4d47:
|
||||||
// skip headerlen, which is stored at u32[0]
|
// skip headerlen, which is stored at u32[0]
|
||||||
ipc_queue_slow_jump(((u32 *) 0x0)[0]);
|
ipc_enqueue_slow(IPC_DEV_SYS, IPC_SYS_JUMP, 1, ((u32 *) 0x0)[0]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
47
ipc.c
47
ipc.c
@ -185,13 +185,28 @@ static u32 process_slow(volatile ipc_request *req)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ipc_add_slow(volatile ipc_request *req)
|
void ipc_enqueue_slow(u8 device, u16 req, u32 num_args, ...)
|
||||||
{
|
{
|
||||||
|
int arg = 0;
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
if(slow_queue_head == ((slow_queue_tail + 1)&(IPC_SLOW_SIZE-1))) {
|
if(slow_queue_head == ((slow_queue_tail + 1)&(IPC_SLOW_SIZE-1))) {
|
||||||
gecko_printf("IPC: Slowqueue overrun\n");
|
gecko_printf("IPC: Slowqueue overrun\n");
|
||||||
panic2(0, PANIC_IPCOVF);
|
panic2(0, PANIC_IPCOVF);
|
||||||
}
|
}
|
||||||
slow_queue[slow_queue_tail] = *req;
|
|
||||||
|
slow_queue[slow_queue_tail].flags = IPC_SLOW;
|
||||||
|
slow_queue[slow_queue_tail].device = device;
|
||||||
|
slow_queue[slow_queue_tail].req = req;
|
||||||
|
slow_queue[slow_queue_tail].tag = 0;
|
||||||
|
|
||||||
|
if(num_args) {
|
||||||
|
va_start(ap, num_args);
|
||||||
|
while(num_args--)
|
||||||
|
slow_queue[slow_queue_tail].args[arg++] = va_arg(ap, u32);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
slow_queue_tail = (slow_queue_tail+1)&(IPC_SLOW_SIZE-1);
|
slow_queue_tail = (slow_queue_tail+1)&(IPC_SLOW_SIZE-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,7 +284,13 @@ static void process_in(void)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ipc_add_slow(req);
|
if(slow_queue_head == ((slow_queue_tail + 1)&(IPC_SLOW_SIZE-1))) {
|
||||||
|
gecko_printf("IPC: Slowqueue overrun\n");
|
||||||
|
panic2(0, PANIC_IPCOVF);
|
||||||
|
}
|
||||||
|
|
||||||
|
slow_queue[slow_queue_tail] = *req;
|
||||||
|
slow_queue_tail = (slow_queue_tail+1)&(IPC_SLOW_SIZE-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -289,26 +310,6 @@ void ipc_irq(void)
|
|||||||
gecko_printf("IPC: IRQ but no bell!\n");
|
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)
|
void ipc_initialize(void)
|
||||||
{
|
{
|
||||||
write32(HW_IPC_ARMMSG, 0);
|
write32(HW_IPC_ARMMSG, 0);
|
||||||
|
8
ipc.h
8
ipc.h
@ -108,8 +108,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
|
|
||||||
#define IPC_PPC_BOOT 0x0000
|
#define IPC_PPC_BOOT 0x0000
|
||||||
|
|
||||||
//#define IPC_USER0_OHAI 0x8000 <- your code goez here
|
|
||||||
|
|
||||||
#define IPC_CODE (f,d,r) (((f)<<24)|((d)<<16)|(r))
|
#define IPC_CODE (f,d,r) (((f)<<24)|((d)<<16)|(r))
|
||||||
|
|
||||||
#define IPC_IN_SIZE 32
|
#define IPC_IN_SIZE 32
|
||||||
@ -140,7 +138,6 @@ typedef const struct {
|
|||||||
} ipc_infohdr;
|
} ipc_infohdr;
|
||||||
|
|
||||||
void ipc_irq(void);
|
void ipc_irq(void);
|
||||||
void ipc_queue_slow_jump(u32 addr); // only call this from irq context
|
|
||||||
|
|
||||||
void ipc_initialize(void);
|
void ipc_initialize(void);
|
||||||
void ipc_shutdown(void);
|
void ipc_shutdown(void);
|
||||||
@ -148,9 +145,8 @@ void ipc_post(u32 code, u32 tag, u32 num_args, ...);
|
|||||||
void ipc_flush(void);
|
void ipc_flush(void);
|
||||||
u32 ipc_process_slow(void);
|
u32 ipc_process_slow(void);
|
||||||
|
|
||||||
// add an entry to the slow queue from the arm
|
// Enqueues a request in the slow in_queue, use this in IRQ context only.
|
||||||
// (you probably want to use this in irq context)
|
void ipc_enqueue_slow(u8 device, u16 req, u32 num_args, ...);
|
||||||
void ipc_add_slow(volatile ipc_request *req);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
2
mini.ld
2
mini.ld
@ -24,7 +24,7 @@ EXTERN(__ipc_info)
|
|||||||
ENTRY(_start)
|
ENTRY(_start)
|
||||||
|
|
||||||
__stack_size = 0x800;
|
__stack_size = 0x800;
|
||||||
__irqstack_size = 0x400; /* blame the bsd's sdhc_intr function */
|
__irqstack_size = 0x100;
|
||||||
__excstack_size = 0x100;
|
__excstack_size = 0x100;
|
||||||
|
|
||||||
MEMORY {
|
MEMORY {
|
||||||
|
10
powerpc.c
10
powerpc.c
@ -81,10 +81,16 @@ void powerpc_ipc(volatile ipc_request *req)
|
|||||||
{
|
{
|
||||||
switch (req->req) {
|
switch (req->req) {
|
||||||
case IPC_PPC_BOOT:
|
case IPC_PPC_BOOT:
|
||||||
dc_invalidaterange((void *) req->args[0], (u32) req->args[1]);
|
if (req->args[0]) {
|
||||||
int res = powerpc_boot_mem((u8 *) req->args[0], (u32) req->args[1]);
|
// Enqueued from ARM side, do not invalidate mem nor ipc_post
|
||||||
|
powerpc_boot_mem((u8 *) req->args[1], req->args[2]);
|
||||||
|
} else {
|
||||||
|
dc_invalidaterange((void *) req->args[1], req->args[2]);
|
||||||
|
int res = powerpc_boot_mem((u8 *) req->args[1], req->args[2]);
|
||||||
if (res)
|
if (res)
|
||||||
ipc_post(req->code, req->tag, 1, res);
|
ipc_post(req->code, req->tag, 1, res);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
gecko_printf("IPC: unknown SLOW PPC request %04X\n", req->req);
|
gecko_printf("IPC: unknown SLOW PPC request %04X\n", req->req);
|
||||||
|
10
sdhc.c
10
sdhc.c
@ -1059,14 +1059,8 @@ sdhc_intr(void *arg)
|
|||||||
if (ISSET(status, SDHC_CARD_REMOVAL|SDHC_CARD_INSERTION)) {
|
if (ISSET(status, SDHC_CARD_REMOVAL|SDHC_CARD_INSERTION)) {
|
||||||
// this pushed a request to the slow queue so that we
|
// this pushed a request to the slow queue so that we
|
||||||
// don't block other IRQs.
|
// don't block other IRQs.
|
||||||
// this is also static because we are in IRQ context
|
ipc_enqueue_slow(IPC_DEV_SDHC, IPC_SDHC_DISCOVER, 1,
|
||||||
// here and want to save stack space
|
(u32) hp->sdmmc);
|
||||||
static ipc_request req;
|
|
||||||
memset(&req, 0, sizeof(req));
|
|
||||||
req.device = IPC_DEV_SDHC;
|
|
||||||
req.req = IPC_SDHC_DISCOVER;
|
|
||||||
req.args[0] = (u32)hp->sdmmc;
|
|
||||||
ipc_add_slow(&req);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user