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:
dhewg 2009-04-15 20:23:07 +02:00 committed by bushing
parent 456b26c1b7
commit 2100d84d7c
6 changed files with 44 additions and 48 deletions

View File

@ -320,14 +320,13 @@ void gecko_timer(void) {
// done receiving, handle the command
switch (_gecko_cmd) {
case 0x43524150:
if (powerpc_boot_mem((u8 *) 0x10100000, _gecko_receive_len))
gecko_printf("MINI/GECKO: the received binary is not a valid "
"PPC ELF. Broadway is dead now.\n");
ipc_enqueue_slow(IPC_DEV_PPC, IPC_PPC_BOOT, 3,
1, (u32) 0x10100000, _gecko_receive_len);
break;
case 0x5a4f4d47:
// 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;
}

47
ipc.c
View File

@ -185,13 +185,28 @@ static u32 process_slow(volatile ipc_request *req)
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))) {
gecko_printf("IPC: Slowqueue overrun\n");
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);
}
@ -269,7 +284,13 @@ static void process_in(void)
break;
}
} 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");
}
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);

8
ipc.h
View File

@ -108,8 +108,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#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_IN_SIZE 32
@ -140,7 +138,6 @@ 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);
@ -148,9 +145,8 @@ void ipc_post(u32 code, u32 tag, u32 num_args, ...);
void ipc_flush(void);
u32 ipc_process_slow(void);
// add an entry to the slow queue from the arm
// (you probably want to use this in irq context)
void ipc_add_slow(volatile ipc_request *req);
// Enqueues a request in the slow in_queue, use this in IRQ context only.
void ipc_enqueue_slow(u8 device, u16 req, u32 num_args, ...);
#endif

View File

@ -24,7 +24,7 @@ EXTERN(__ipc_info)
ENTRY(_start)
__stack_size = 0x800;
__irqstack_size = 0x400; /* blame the bsd's sdhc_intr function */
__irqstack_size = 0x100;
__excstack_size = 0x100;
MEMORY {

View File

@ -81,10 +81,16 @@ 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);
if (req->args[0]) {
// 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)
ipc_post(req->code, req->tag, 1, res);
}
break;
default:
gecko_printf("IPC: unknown SLOW PPC request %04X\n", req->req);

14
sdhc.c
View File

@ -1057,16 +1057,10 @@ sdhc_intr(void *arg)
* Wake up the sdmmc event thread to scan for cards.
*/
if (ISSET(status, SDHC_CARD_REMOVAL|SDHC_CARD_INSERTION)) {
// this pushed a request to the slow queue so that we
// don't block other IRQs.
// this is also static because we are in IRQ context
// here and want to save stack space
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);
// this pushed a request to the slow queue so that we
// don't block other IRQs.
ipc_enqueue_slow(IPC_DEV_SDHC, IPC_SDHC_DISCOVER, 1,
(u32) hp->sdmmc);
}
/*