mirror of
https://github.com/drasko/codezero.git
synced 2026-01-14 20:03:16 +01:00
Towards finishing exchange_registers()
- Added mutex_trylock() - Implemented most of exchange_registers() - thread_control() now needs a lock for operations that can modify thread context. - thread_start() does not initialise scheduler flags, now done in thread_create. TODO: - Fork/clone'ed threads should retain their context in tcb, not syscall stack. - exchange_registers() calls in userspace need cleaning up.
This commit is contained in:
@@ -144,6 +144,9 @@
|
||||
#define EOWNERDEAD 130 /* Owner died */
|
||||
#define ENOTRECOVERABLE 131 /* State not recoverable */
|
||||
|
||||
/* Codezero specific error codes */
|
||||
#define EACTIVE 132 /* Task active */
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
/* Should never be seen by user programs */
|
||||
|
||||
22
include/l4/api/exregs.h
Normal file
22
include/l4/api/exregs.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Exchange registers system call data.
|
||||
*
|
||||
* Copyright (C) 2008 Bahadir Balban
|
||||
*/
|
||||
#ifndef __EXREGS_H__
|
||||
#define __EXREGS_H__
|
||||
|
||||
#include <l4/macros.h>
|
||||
#include INC_GLUE(syscall.h)
|
||||
#include INC_GLUE(context.h)
|
||||
#include <l4/types.h>
|
||||
|
||||
/* Structure passed by userspace pagers for exchanging registers */
|
||||
struct exregs_data {
|
||||
exregs_context_t context;
|
||||
u32 valid_vect;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* __EXREGS_H__ */
|
||||
@@ -1,16 +1,18 @@
|
||||
#ifndef __THREAD_H__
|
||||
#define __THREAD_H__
|
||||
|
||||
#define THREAD_FLAGS_MASK 0x00F0
|
||||
|
||||
/* Create new thread, copy given space */
|
||||
#define THREAD_CREATE_COPYSPC 0x0010
|
||||
#define THREAD_CREATE_MASK 0x00F0
|
||||
|
||||
/* Create new thread and new space */
|
||||
#define THREAD_CREATE_NEWSPC 0x0020
|
||||
#define THREAD_NEW_SPACE 0x0010
|
||||
|
||||
/* Create new thread, copy given space */
|
||||
#define THREAD_COPY_SPACE 0x0020
|
||||
|
||||
/* Create new thread, use given space */
|
||||
#define THREAD_CREATE_SAMESPC 0x0030
|
||||
#define THREAD_SAME_SPACE 0x0030
|
||||
|
||||
|
||||
|
||||
|
||||
#define THREAD_ACTION_MASK 0x000F
|
||||
|
||||
@@ -75,6 +75,17 @@ static inline void irq_local_disable()
|
||||
/* This is filled on entry to irq handler, only if a process was interrupted.*/
|
||||
extern unsigned int preempted_psr;
|
||||
|
||||
#include <l4/generic/tcb.h>
|
||||
static inline int task_in_kernel(struct tcb *t)
|
||||
{
|
||||
return ((t->context.spsr & ARM_MODE_MASK) == ARM_MODE_SVC) ? 1 : 0;
|
||||
}
|
||||
|
||||
static inline int task_in_user(struct tcb *t)
|
||||
{
|
||||
return !task_in_kernel(t);
|
||||
}
|
||||
|
||||
static inline int in_kernel()
|
||||
{
|
||||
return (((preempted_psr & ARM_MODE_MASK) == ARM_MODE_SVC)) ? 1 : 0;
|
||||
|
||||
@@ -34,10 +34,6 @@ static inline struct ktcb *current_task(void)
|
||||
#define SCHED_FL_MASK (SCHED_FL_SLEEP | SCHED_FL_RESUME \
|
||||
| SCHED_FL_SUSPEND)
|
||||
|
||||
#define __IPC_FL_WAIT 4
|
||||
#define IPC_FL_WAIT (1 << __IPC_FL_WAIT)
|
||||
#define IPC_FL_MASK IPC_FL_WAIT
|
||||
|
||||
void sched_runqueue_init(void);
|
||||
void sched_start_task(struct ktcb *task);
|
||||
void sched_resume_task(struct ktcb *task);
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include INC_GLUE(memory.h)
|
||||
#include INC_GLUE(syscall.h)
|
||||
#include INC_GLUE(message.h)
|
||||
#include INC_GLUE(context.h)
|
||||
#include INC_SUBARCH(mm.h)
|
||||
|
||||
enum task_state {
|
||||
@@ -21,32 +22,6 @@ enum task_state {
|
||||
TASK_RUNNABLE = 2,
|
||||
};
|
||||
|
||||
/*
|
||||
* This describes the user space register context of each task. Simply set them
|
||||
* as regular structure fields, and they'll be copied onto real registers upon
|
||||
* a context switch. In the ARM case, they're copied from memory to userspace
|
||||
* registers using the LDM instruction with ^, no-pc flavor. See ARMARM.
|
||||
*/
|
||||
typedef struct arm_context {
|
||||
u32 spsr; /* 0x0 */
|
||||
u32 r0; /* 0x4 */
|
||||
u32 r1; /* 0x8 */
|
||||
u32 r2; /* 0xC */
|
||||
u32 r3; /* 0x10 */
|
||||
u32 r4; /* 0x14 */
|
||||
u32 r5; /* 0x18 */
|
||||
u32 r6; /* 0x1C */
|
||||
u32 r7; /* 0x20 */
|
||||
u32 r8; /* 0x24 */
|
||||
u32 r9; /* 0x28 */
|
||||
u32 r10; /* 0x2C */
|
||||
u32 r11; /* 0x30 */
|
||||
u32 r12; /* 0x34 */
|
||||
u32 sp; /* 0x38 */
|
||||
u32 lr; /* 0x3C */
|
||||
u32 pc; /* 0x40 */
|
||||
} __attribute__((__packed__)) task_context_t;
|
||||
|
||||
#define TASK_ID_INVALID -1
|
||||
struct task_ids {
|
||||
l4id_t tid;
|
||||
@@ -75,7 +50,9 @@ struct ktcb {
|
||||
|
||||
/* Flags to hint scheduler on future task state */
|
||||
unsigned int schedfl;
|
||||
unsigned int flags;
|
||||
|
||||
/* Lock for blocking thread state modifications via a syscall */
|
||||
struct mutex thread_control_lock;
|
||||
|
||||
/* Other related threads */
|
||||
l4id_t pagerid;
|
||||
|
||||
53
include/l4/glue/arm/context.h
Normal file
53
include/l4/glue/arm/context.h
Normal file
@@ -0,0 +1,53 @@
|
||||
#ifndef __ARM_CONTEXT_H__
|
||||
#define __ARM_CONTEXT_H__
|
||||
|
||||
#include <l4/types.h>
|
||||
|
||||
/*
|
||||
* This describes the register context of each task. Simply set
|
||||
* them as regular structure fields, and they'll be copied onto
|
||||
* real registers upon a context switch to that task. Normally
|
||||
* exchange_registers() system call is designed for this, whose
|
||||
* input structure is defined further below.
|
||||
*/
|
||||
typedef struct arm_context {
|
||||
u32 spsr; /* 0x0 */
|
||||
u32 r0; /* 0x4 */
|
||||
u32 r1; /* 0x8 */
|
||||
u32 r2; /* 0xC */
|
||||
u32 r3; /* 0x10 */
|
||||
u32 r4; /* 0x14 */
|
||||
u32 r5; /* 0x18 */
|
||||
u32 r6; /* 0x1C */
|
||||
u32 r7; /* 0x20 */
|
||||
u32 r8; /* 0x24 */
|
||||
u32 r9; /* 0x28 */
|
||||
u32 r10; /* 0x2C */
|
||||
u32 r11; /* 0x30 */
|
||||
u32 r12; /* 0x34 */
|
||||
u32 sp; /* 0x38 */
|
||||
u32 lr; /* 0x3C */
|
||||
u32 pc; /* 0x40 */
|
||||
} __attribute__((__packed__)) task_context_t;
|
||||
|
||||
|
||||
typedef struct arm_exregs_context {
|
||||
u32 r0; /* 0x4 */
|
||||
u32 r1; /* 0x8 */
|
||||
u32 r2; /* 0xC */
|
||||
u32 r3; /* 0x10 */
|
||||
u32 r4; /* 0x14 */
|
||||
u32 r5; /* 0x18 */
|
||||
u32 r6; /* 0x1C */
|
||||
u32 r7; /* 0x20 */
|
||||
u32 r8; /* 0x24 */
|
||||
u32 r9; /* 0x28 */
|
||||
u32 r10; /* 0x2C */
|
||||
u32 r11; /* 0x30 */
|
||||
u32 r12; /* 0x34 */
|
||||
u32 sp; /* 0x38 */
|
||||
u32 lr; /* 0x3C */
|
||||
u32 pc; /* 0x40 */
|
||||
} __attribute__((__packed__)) exregs_context_t;
|
||||
|
||||
#endif /* __ARM_CONTEXT_H__ */
|
||||
@@ -68,4 +68,7 @@
|
||||
#define KERN_ADDR(x) ((x >= KERNEL_AREA_START) && (x < KERNEL_AREA_END))
|
||||
#define USER_ADDR(x) ((x >= USER_AREA_START) && (x < USER_AREA_END))
|
||||
|
||||
#define PRIVILEGED_ADDR(x) (KERN_ADDR(x) || (x >= ARM_HIGH_VECTOR) || \
|
||||
(x >= IO_AREA_START && x < IO_AREA_END))
|
||||
|
||||
#endif /* __MEMLAYOUT_H__ */
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
* ARM-specific system call details.
|
||||
*
|
||||
* Copyright (C) 2007 Bahadir Balban
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __ARM_GLUE_SYSCALL_H__
|
||||
#define __ARM_GLUE_SYSCALL_H__
|
||||
|
||||
#include <l4/types.h>
|
||||
|
||||
/* Only specific call is the trap that gives back the kip address
|
||||
* from which other system calls can be discovered. */
|
||||
#define L4_TRAP_KIP 0xB4
|
||||
@@ -52,7 +53,8 @@ typedef struct msg_regs {
|
||||
|
||||
/* NOTE:
|
||||
* These references are valid only when they have been explicitly set
|
||||
* by a kernel entry point, e.g. a system call, a data abort handler.
|
||||
* by a kernel entry point, e.g. a system call, a data abort handler
|
||||
* that imitates a page fault ipc etc.
|
||||
*/
|
||||
#define KTCB_REF_ARG0(ktcb) (&(ktcb)->syscall_regs->r0)
|
||||
#define KTCB_REF_MR0(ktcb) (&(ktcb)->syscall_regs->r3)
|
||||
|
||||
@@ -28,6 +28,7 @@ static inline void mutex_init(struct mutex *mutex)
|
||||
INIT_LIST_HEAD(&mutex->wq.task_list);
|
||||
}
|
||||
|
||||
int mutex_trylock(struct mutex *mutex);
|
||||
void mutex_lock(struct mutex *mutex);
|
||||
void mutex_unlock(struct mutex *mutex);
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ static inline void spin_lock_init(struct spinlock *s)
|
||||
*/
|
||||
static inline void spin_lock(struct spinlock *s)
|
||||
{
|
||||
preempt_disable();
|
||||
preempt_disable(); /* This must disable local preempt */
|
||||
#if defined(CONFIG_SMP)
|
||||
__spin_lock(&s->lock);
|
||||
#endif
|
||||
|
||||
@@ -75,6 +75,9 @@
|
||||
#define printk printf
|
||||
#endif
|
||||
|
||||
/* Converts an int-sized field offset in a struct into a bit offset in a word */
|
||||
#define FIELD_TO_BIT(type, field) (1 << (offsetof(type, field) >> 2))
|
||||
|
||||
/* Functions who may either return a pointer or an error code can use these: */
|
||||
#define PTR_ERR(x) ((void *)(x))
|
||||
/* checks up to -1000, the rest might be valid pointers!!! E.g. 0xE0000000 */
|
||||
|
||||
Reference in New Issue
Block a user