diff --git a/src/api/syscall.c b/src/api/syscall.c index 04f6174..ff0ed4a 100644 --- a/src/api/syscall.c +++ b/src/api/syscall.c @@ -41,37 +41,37 @@ void do_exchange_registers(struct ktcb *task, struct exregs_data *exregs) */ /* Check register valid bit and copy registers */ - if (exregs->valid_vect & FIELD_TO_BIT(task_context_t, r0)) + if (exregs->valid_vect & FIELD_TO_BIT(exregs_context_t, r0)) context->r0 = exregs->context.r0; - if (exregs->valid_vect & FIELD_TO_BIT(task_context_t, r1)) + if (exregs->valid_vect & FIELD_TO_BIT(exregs_context_t, r1)) context->r1 = exregs->context.r1; - if (exregs->valid_vect & FIELD_TO_BIT(task_context_t, r2)) + if (exregs->valid_vect & FIELD_TO_BIT(exregs_context_t, r2)) context->r2 = exregs->context.r2; - if (exregs->valid_vect & FIELD_TO_BIT(task_context_t, r3)) + if (exregs->valid_vect & FIELD_TO_BIT(exregs_context_t, r3)) context->r3 = exregs->context.r3; - if (exregs->valid_vect & FIELD_TO_BIT(task_context_t, r4)) + if (exregs->valid_vect & FIELD_TO_BIT(exregs_context_t, r4)) context->r4 = exregs->context.r4; - if (exregs->valid_vect & FIELD_TO_BIT(task_context_t, r5)) + if (exregs->valid_vect & FIELD_TO_BIT(exregs_context_t, r5)) context->r5 = exregs->context.r5; - if (exregs->valid_vect & FIELD_TO_BIT(task_context_t, r6)) + if (exregs->valid_vect & FIELD_TO_BIT(exregs_context_t, r6)) context->r6 = exregs->context.r6; - if (exregs->valid_vect & FIELD_TO_BIT(task_context_t, r7)) + if (exregs->valid_vect & FIELD_TO_BIT(exregs_context_t, r7)) context->r7 = exregs->context.r7; - if (exregs->valid_vect & FIELD_TO_BIT(task_context_t, r8)) + if (exregs->valid_vect & FIELD_TO_BIT(exregs_context_t, r8)) context->r8 = exregs->context.r8; - if (exregs->valid_vect & FIELD_TO_BIT(task_context_t, r9)) + if (exregs->valid_vect & FIELD_TO_BIT(exregs_context_t, r9)) context->r9 = exregs->context.r9; - if (exregs->valid_vect & FIELD_TO_BIT(task_context_t, r10)) + if (exregs->valid_vect & FIELD_TO_BIT(exregs_context_t, r10)) context->r10 = exregs->context.r10; - if (exregs->valid_vect & FIELD_TO_BIT(task_context_t, r11)) + if (exregs->valid_vect & FIELD_TO_BIT(exregs_context_t, r11)) context->r11 = exregs->context.r11; - if (exregs->valid_vect & FIELD_TO_BIT(task_context_t, r12)) + if (exregs->valid_vect & FIELD_TO_BIT(exregs_context_t, r12)) context->r12 = exregs->context.r12; - if (exregs->valid_vect & FIELD_TO_BIT(task_context_t, sp)) + if (exregs->valid_vect & FIELD_TO_BIT(exregs_context_t, sp)) context->sp = exregs->context.sp; - if (exregs->valid_vect & FIELD_TO_BIT(task_context_t, lr)) + if (exregs->valid_vect & FIELD_TO_BIT(exregs_context_t, lr)) context->lr = exregs->context.lr; - if (exregs->valid_vect & FIELD_TO_BIT(task_context_t, pc)) + if (exregs->valid_vect & FIELD_TO_BIT(exregs_context_t, pc)) context->pc = exregs->context.pc; /* Set thread's pager if one is supplied */ diff --git a/tasks/mm0/include/exregs.h b/tasks/libl4/include/l4lib/exregs.h similarity index 90% rename from tasks/mm0/include/exregs.h rename to tasks/libl4/include/l4lib/exregs.h index 5d5b17a..f5489d0 100644 --- a/tasks/mm0/include/exregs.h +++ b/tasks/libl4/include/l4lib/exregs.h @@ -4,7 +4,7 @@ #include void exregs_set_stack(struct exregs_data *s, unsigned long sp); -void exregs_set_mr_return(struct exregs_data *s, unsigned long retreg); +void exregs_set_mr(struct exregs_data *s, int offset, unsigned long val); void exregs_set_pc(struct exregs_data *s, unsigned long pc); void exregs_set_pager(struct exregs_data *s, l4id_t pagerid); diff --git a/tasks/libl4/src/arm/exregs.c b/tasks/libl4/src/arm/exregs.c new file mode 100644 index 0000000..1c7f138 --- /dev/null +++ b/tasks/libl4/src/arm/exregs.c @@ -0,0 +1,45 @@ +/* + * Generic to arch-specific interface for + * exchange_registers() + * + * Copyright (C) 2008 Bahadir Balban + */ +#include +#include +#include INC_GLUE(message.h) + + +void exregs_set_mr(struct exregs_data *s, int offset, unsigned long val) +{ + /* Get MR0 */ + u32 *mr = &s->context.r3; + + /* Sanity check */ + BUG_ON(offset > MR_TOTAL || offset < 0); + + /* Set MR */ + mr[offset] = val; + + /* Set valid bit for mr register */ + s->valid_vect |= offsetof(exregs_context_t, r3) + + (offset * sizeof(int)); +} + +void exregs_set_pager(struct exregs_data *s, l4id_t pagerid) +{ + s->pagerid = pagerid; + s->flags |= EXREGS_SET_PAGER; +} + +void exregs_set_stack(struct exregs_data *s, unsigned long sp) +{ + s->context.sp = sp; + s->valid_vect |= 1 << (offsetof(exregs_context_t, sp) >> 2); +} + +void exregs_set_pc(struct exregs_data *s, unsigned long pc) +{ + s->context.pc = pc; + s->valid_vect |= 1 << (offsetof(exregs_context_t, pc) >> 2); +} + diff --git a/tasks/libl4/src/arm/syscalls.S b/tasks/libl4/src/arm/syscalls.S index f65b4f5..8b964a7 100644 --- a/tasks/libl4/src/arm/syscalls.S +++ b/tasks/libl4/src/arm/syscalls.S @@ -65,7 +65,7 @@ BEGIN_PROC(arch_clone) */ cmp r0, #0 @ Check ipc success blt ipc_failed - cmp r2, #0 @ Check ipc return register MR_RETURN. + cmp r3, #0 @ Check ipc return register MR_RETURN. blt clone_failed @ Ipc was ok but clone() failed. bgt parent_return @ It has child pid, goto parent return. child: diff --git a/tasks/mm0/src/arch-arm/exregs.c b/tasks/mm0/src/arch-arm/exregs.c deleted file mode 100644 index a5bdb50..0000000 --- a/tasks/mm0/src/arch-arm/exregs.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Generic to arch-specific interface for - * exchange_registers() - * - * Copyright (C) 2008 Bahadir Balban - */ -#include - - -void exregs_set_pager(struct exregs_data *s, l4id_t pagerid) -{ - s->pagerid = pagerid; - s->flags |= EXREGS_SET_PAGER; -} - -void exregs_set_stack(struct exregs_data *s, unsigned long sp) -{ - s->context.sp = sp; - s->valid_vect |= 1 << (offsetof(task_context_t, sp) >> 2); -} - -void exregs_set_pc(struct exregs_data *s, unsigned long pc) -{ - s->context.pc = pc; - s->valid_vect |= 1 << (offsetof(task_context_t, pc) >> 2); -} - diff --git a/tasks/mm0/src/clone.c b/tasks/mm0/src/clone.c index 1c46e0d..eec2947 100755 --- a/tasks/mm0/src/clone.c +++ b/tasks/mm0/src/clone.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -49,7 +50,9 @@ int vfs_notify_fork(struct tcb *child, struct tcb *parent) int do_fork(struct tcb *parent) { + int err; struct tcb *child; + struct exregs_data exregs; struct vm_file *utcb_shm; struct task_ids ids = { .tid = TASK_ID_INVALID, @@ -70,6 +73,12 @@ int do_fork(struct tcb *parent) return 0; } + /* Set child's fork return value to 0 */ + memset(&exregs, 0, sizeof(exregs)); + exregs_set_mr(&exregs, MR_RETURN, 0); + if ((err = l4_exchange_registers(&exregs, child->tid)) < 0) + BUG(); + /* Create new utcb for child since it can't use its parent's */ child->utcb = utcb_vaddr_new(); diff --git a/tasks/mm0/src/task.c b/tasks/mm0/src/task.c index 3b38bd8..6e69aa2 100644 --- a/tasks/mm0/src/task.c +++ b/tasks/mm0/src/task.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -26,7 +27,6 @@ #include #include #include -#include struct tcb_head { struct list_head list;