mirror of
https://github.com/drasko/codezero.git
synced 2026-01-12 02:43:15 +01:00
Modifications towards full ipc
- Added a full ipc send/recv test - Removed non-zero value checking in r2 for ipc that was there to catch inadvertent full ipc calls. - Added correct hanlding for read/write mrs for current status of utcb. TODO: - Add mapping of every utcb to every task for privileged access so that the kernel can access every utcb without switching spaces. - Removal of same mappings - Upon thread creation need to copy page tables accordingly i.e. each task will have its own utcb mapped with USER access, but every other utcb as kernel access only. Need to handle this case upon page table copying.
This commit is contained in:
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -24,6 +24,19 @@
|
||||
#include <test.h>
|
||||
#include <boot.h>
|
||||
|
||||
|
||||
|
||||
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__);
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#include <sys/types.h>
|
||||
extern pid_t parent_of_all;
|
||||
|
||||
void ipc_full_test(void);
|
||||
|
||||
int shmtest(void);
|
||||
int forktest(void);
|
||||
int mmaptest(void);
|
||||
|
||||
@@ -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();
|
||||
|
||||
33
tasks/test0/src/ipctest.c
Normal file
33
tasks/test0/src/ipctest.c
Normal file
@@ -0,0 +1,33 @@
|
||||
#include <l4lib/arch/syslib.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
|
||||
/*
|
||||
* 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)
|
||||
;
|
||||
}
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user