diff --git a/include/l4/glue/arm/message.h b/include/l4/glue/arm/message.h index 2ae7578..5331db4 100644 --- a/include/l4/glue/arm/message.h +++ b/include/l4/glue/arm/message.h @@ -6,13 +6,13 @@ #ifndef __GLUE_ARM_MESSAGE_H__ #define __GLUE_ARM_MESSAGE_H__ -/* +/* * Here's a summary of how ARM registers are used during IPC: * * System registers: * r0 - r2: Passed as arguments to ipc() call. They are the registers * the microkernel will read and they have system-wide meaning. - * + * * Primary message registers: * r3 - r8: These 6 registers are the primary message registers MR0-MR6 * Their format is application-specific, i.e. the microkernel imposes no @@ -58,7 +58,7 @@ * Complicated for you? Suggest a simpler design and it shall be implemented! */ -#define MR_REST (UTCB_SIZE - MR_TOTAL - 2) /* -2 is for fields on utcb */ +#define MR_REST ((UTCB_SIZE >> 2) - MR_TOTAL - 2) /* -2 is for fields on utcb */ #define MR_TOTAL 6 #define MR_TAG 0 /* Contains the purpose of message */ #define MR_SENDER 1 /* For anythread receivers to discover sender */ diff --git a/src/api/ipc.c b/src/api/ipc.c index 487e871..95ee620 100644 --- a/src/api/ipc.c +++ b/src/api/ipc.c @@ -353,6 +353,11 @@ int sys_ipc(syscall_context_t *regs) unsigned int ipc_type = 0; int ret = 0; + if (regs->r2) + __asm__ __volatile__ ( + "1:\n" + "b 1b\n"); + /* Check arguments */ if (from < L4_ANYTHREAD) { ret = -EINVAL; diff --git a/src/arch/arm/exception.c b/src/arch/arm/exception.c index 2b4f4a5..5f5bdd1 100644 --- a/src/arch/arm/exception.c +++ b/src/arch/arm/exception.c @@ -18,7 +18,7 @@ #include INC_SUBARCH(mm.h) /* Abort debugging conditions */ -// #define DEBUG_ABORTS + #define DEBUG_ABORTS #if defined (DEBUG_ABORTS) #define dbg_abort(...) dprintk(__VA_ARGS__) #else diff --git a/tasks/libl4/include/l4lib/arch-arm/syslib.h b/tasks/libl4/include/l4lib/arch-arm/syslib.h index 21d1b42..85b5317 100644 --- a/tasks/libl4/include/l4lib/arch-arm/syslib.h +++ b/tasks/libl4/include/l4lib/arch-arm/syslib.h @@ -146,6 +146,19 @@ static inline int l4_receive_full(l4id_t from) return l4_ipc(L4_NILTHREAD, from, L4_IPC_FLAGS_FULL); } +static inline int l4_sendrecv_full(l4id_t to, l4id_t from, unsigned int tag) +{ + int err; + + BUG_ON(to == L4_NILTHREAD || from == L4_NILTHREAD); + l4_set_tag(tag); + + printf("%s: to %d from %d tag %u\n", __FUNCTION__, to, from, tag); + err = l4_ipc(to, from, L4_IPC_FLAGS_FULL); + + return err; +} + static inline int l4_send_extended(l4id_t to, unsigned int tag, unsigned int size, void *buf) { diff --git a/tasks/libl4/include/l4lib/arch-arm/utcb.h b/tasks/libl4/include/l4lib/arch-arm/utcb.h index 73c7fdc..9e0cd45 100644 --- a/tasks/libl4/include/l4lib/arch-arm/utcb.h +++ b/tasks/libl4/include/l4lib/arch-arm/utcb.h @@ -52,12 +52,18 @@ static inline struct utcb *l4_get_utcb() /* Functions to read/write utcb registers */ static inline unsigned int read_mr(int offset) { - return l4_get_utcb()->mr[offset]; + if (offset < MR_TOTAL) + return l4_get_utcb()->mr[offset]; + else + return l4_get_utcb()->mr_rest[offset - MR_TOTAL]; } static inline void write_mr(unsigned int offset, unsigned int val) { - l4_get_utcb()->mr[offset] = val; + if (offset < MR_TOTAL) + l4_get_utcb()->mr[offset] = val; + else + l4_get_utcb()->mr[offset - MR_TOTAL] = val; } #endif /* !__ASSEMBLY__ */ diff --git a/tasks/libl4/include/l4lib/ipcdefs.h b/tasks/libl4/include/l4lib/ipcdefs.h index 29b1b02..3866c11 100644 --- a/tasks/libl4/include/l4lib/ipcdefs.h +++ b/tasks/libl4/include/l4lib/ipcdefs.h @@ -17,6 +17,7 @@ /*** IPC Tags used between server tasks ***/ /* For ping ponging */ +#define L4_IPC_TAG_SYNC_FULL 2 #define L4_IPC_TAG_SYNC 3 /* To obtain default shared page address */ diff --git a/tasks/libl4/src/arm/syscalls.S b/tasks/libl4/src/arm/syscalls.S index 7ae44fb..430e484 100644 --- a/tasks/libl4/src/arm/syscalls.S +++ b/tasks/libl4/src/arm/syscalls.S @@ -63,10 +63,6 @@ BEGIN_PROC(arch_clone) utcb_address r12 @ Get utcb address. ldmia r12!, {r3-r8} @ Load 6 Message registers from utcb. MR0-MR5 - cmp r2, #0 -1: - bne 1b - ldr r12, =__l4_ipc mov lr, pc ldr pc, [r12] @ Perform the ipc() @@ -106,11 +102,6 @@ BEGIN_PROC(l4_ipc) stmfd sp!, {r4-r8,lr} @ Save context. utcb_address r12 @ Get utcb address. ldmia r12!, {r3-r8} @ Load 6 Message registers from utcb. MR0-MR5 - - cmp r2, #0 -1: - bne 1b - ldr r12, =__l4_ipc mov lr, pc ldr pc, [r12] diff --git a/tasks/mm0/main.c b/tasks/mm0/main.c index e2009d6..7b5dfc2 100644 --- a/tasks/mm0/main.c +++ b/tasks/mm0/main.c @@ -24,6 +24,19 @@ #include #include + + +int ipc_test_full_sync(void) +{ + for (int i = 0; i < MR_TOTAL + MR_REST; i++) { + printf("%s/%s: MR%d: %d\n", __TASKNAME__, __FUNCTION__, + i, read_mr(i)); + /* Reset it to 0 */ + write_mr(i, 0); + } + return 0; +} + void handle_requests(void) { /* Generic ipc data */ @@ -54,6 +67,9 @@ void handle_requests(void) mr[i] = read_mr(MR_UNUSED_START + i); switch(tag) { + case L4_IPC_TAG_SYNC_FULL: + ret = ipc_test_full_sync(); + break; case L4_IPC_TAG_SYNC: mm0_test_global_vm_integrity(); // printf("%s: Synced with waiting thread.\n", __TASKNAME__); diff --git a/tasks/test0/include/tests.h b/tasks/test0/include/tests.h index 3818ce0..c2ade14 100644 --- a/tasks/test0/include/tests.h +++ b/tasks/test0/include/tests.h @@ -13,6 +13,8 @@ #include extern pid_t parent_of_all; +void ipc_full_test(void); + int shmtest(void); int forktest(void); int mmaptest(void); diff --git a/tasks/test0/main.c b/tasks/test0/main.c index 186a78e..5b2030f 100644 --- a/tasks/test0/main.c +++ b/tasks/test0/main.c @@ -33,6 +33,10 @@ void main(void) wait_pager(0); + printf("%s: Full IPC test.\n", __TASKNAME__); + + ipc_full_test(); + printf("%s: Running POSIX API tests.\n", __TASKNAME__); dirtest(); diff --git a/tasks/test0/src/ipctest.c b/tasks/test0/src/ipctest.c new file mode 100644 index 0000000..ab00f25 --- /dev/null +++ b/tasks/test0/src/ipctest.c @@ -0,0 +1,33 @@ +#include +#include + +/* + * Full ipc test. Sends/receives full utcb, done with the pager. + */ +void ipc_full_test(void) +{ + int ret; + + /* Fill in all of the utcb locations */ + for (int i = 0; i < MR_TOTAL + MR_REST; i++) { + printf("Writing: MR%d: %d\n", i, i); + write_mr(i, i); + } + + /* Call the pager */ + if ((ret = l4_sendrecv_full(PAGER_TID, PAGER_TID, L4_IPC_TAG_SYNC_FULL)) < 0) { + printf("%s: Failed with %d\n", __FUNCTION__, ret); + BUG(); + } + /* Read back updated utcb */ + for (int i = MR_UNUSED_START; i < MR_TOTAL + MR_REST; i++) { + printf("Read MR%d: %d\n", i, read_mr(i)); + if (read_mr(i) != 0) { + printf("Expected 0 on all mrs. Failed.\n"); + BUG(); + } + } + while (1) + ; +} + diff --git a/tasks/test0/src/test_exec/test_exec.o b/tasks/test0/src/test_exec/test_exec.o index 165d430..0bc7504 100644 Binary files a/tasks/test0/src/test_exec/test_exec.o and b/tasks/test0/src/test_exec/test_exec.o differ