mirror of
https://github.com/drasko/codezero.git
synced 2026-02-13 10:23:16 +01:00
Initial commit
This commit is contained in:
78
tasks/libl4/SConstruct
Normal file
78
tasks/libl4/SConstruct
Normal file
@@ -0,0 +1,78 @@
|
||||
#
|
||||
# Copyright (C) 2007 Bahadir Balban
|
||||
#
|
||||
|
||||
import os
|
||||
import glob
|
||||
import sys
|
||||
from os.path import join
|
||||
from string import split
|
||||
|
||||
project_root = "../.."
|
||||
kernel_headers = join(project_root, "include")
|
||||
config_h = join(project_root, "include/l4/config.h")
|
||||
|
||||
env = Environment(CC = 'arm-none-linux-gnueabi-gcc',
|
||||
CCFLAGS = ['-g', '-nostdinc', '-nostdlib', '-ffreestanding'],
|
||||
LINKFLAGS = ['-nostdlib'],
|
||||
ENV = {'PATH' : os.environ['PATH']},
|
||||
LIBS = 'gcc')
|
||||
|
||||
|
||||
def extract_arch_subarch_plat(config_header):
|
||||
'''
|
||||
From the autogenerated kernel config.h, extracts platform, archictecture,
|
||||
subarchitecture information. This is used to include the relevant headers
|
||||
from the kernel directories.
|
||||
'''
|
||||
arch = None
|
||||
subarch = None
|
||||
plat = None
|
||||
|
||||
if not os.path.exists(config_header):
|
||||
print "\n\nconfig.h does not exist. "\
|
||||
"Please run: `scons configure' first\n\n"
|
||||
sys.exit()
|
||||
f = open(config_h, "r")
|
||||
while True:
|
||||
line = f.readline()
|
||||
if line == "":
|
||||
break
|
||||
parts = split(line)
|
||||
if len(parts) > 0:
|
||||
if parts[0] == "#define":
|
||||
if parts[1] == "__ARCH__":
|
||||
arch = parts[2]
|
||||
elif parts[1] == "__PLATFORM__":
|
||||
plat = parts[2]
|
||||
elif parts[1] == "__SUBARCH__":
|
||||
subarch = parts[2]
|
||||
f.close()
|
||||
if arch == None:
|
||||
print "Error: No config symbol found for architecture"
|
||||
sys.exit()
|
||||
if subarch == None:
|
||||
print "Error: No config symbol found for subarchitecture"
|
||||
sys.exit()
|
||||
if plat == None:
|
||||
print "Error: No config symbol found for platform"
|
||||
sys.exit()
|
||||
return arch, subarch, plat
|
||||
|
||||
def create_symlinks(arch):
|
||||
if not os.path.exists("include/l4lib/arch"):
|
||||
os.system("ln -s %s %s" % ("arch-" + arch, "include/l4lib/arch"))
|
||||
|
||||
arch, subarch, plat = extract_arch_subarch_plat(config_h)
|
||||
|
||||
create_symlinks(arch) # Creates symlinks to architecture specific directories.
|
||||
|
||||
headers = ["#include", "#include/libl4/arch", kernel_headers]
|
||||
|
||||
env.Append(CPPPATH = headers)
|
||||
|
||||
src = glob.glob("src/*.c") + glob.glob("src/%s/*.[cS]" % arch)
|
||||
|
||||
libl4 = env.StaticLibrary('l4', src)
|
||||
|
||||
|
||||
1
tasks/libl4/include/l4lib/arch
Symbolic link
1
tasks/libl4/include/l4lib/arch
Symbolic link
@@ -0,0 +1 @@
|
||||
arch-arm
|
||||
15
tasks/libl4/include/l4lib/arch-arm/asm.h
Normal file
15
tasks/libl4/include/l4lib/arch-arm/asm.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef __ARM_ASM_H__
|
||||
#define __ARM_ASM_H__
|
||||
|
||||
#define BEGIN_PROC(name) \
|
||||
.global name; \
|
||||
.type name,function; \
|
||||
.align; \
|
||||
name:
|
||||
|
||||
#define END_PROC(name) \
|
||||
.fend_##name: \
|
||||
.size name,.fend_##name - name;
|
||||
|
||||
#endif /* __ARM_ASM_H__ */
|
||||
|
||||
26
tasks/libl4/include/l4lib/arch-arm/message.h
Normal file
26
tasks/libl4/include/l4lib/arch-arm/message.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef __ARM_MESSAGE_H__
|
||||
#define __ARM_MESSAGE_H__
|
||||
|
||||
#include <l4lib/types.h>
|
||||
#include <l4lib/arch/utcb.h>
|
||||
|
||||
/* Functions to read/write utcb registers */
|
||||
static inline unsigned int read_mr(int offset)
|
||||
{
|
||||
return __L4_ARM_Utcb()->mr[offset];
|
||||
}
|
||||
|
||||
static inline void write_mr(unsigned int val, unsigned int offset)
|
||||
{
|
||||
__L4_ARM_Utcb()->mr[offset] = val;
|
||||
}
|
||||
|
||||
/* Tag definitions */
|
||||
#define L4_TAG_PFLAG (1 << 12) /* Propagation */
|
||||
#define L4_TAG_NFLAG (1 << 13) /* Notify */
|
||||
#define L4_TAG_RFLAG (1 << 14) /* Block-on-receive */
|
||||
#define L4_TAG_SFLAG (1 << 15) /* Block-on-send */
|
||||
#define L4_TAG_XFLAG (1 << 14) /* Crosscall (inter-cpu ipc) */
|
||||
#define L4_TAG_EFLAG (1 << 15) /* Error */
|
||||
|
||||
#endif /* __ARM_MESSAGE_H__ */
|
||||
83
tasks/libl4/include/l4lib/arch-arm/syscalls.h
Normal file
83
tasks/libl4/include/l4lib/arch-arm/syscalls.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* System call prototypes.
|
||||
*
|
||||
* Copyright (C) 2007 Bahadir Balban
|
||||
*/
|
||||
#ifndef __ARM_SYSCALLS_H__
|
||||
#define __ARM_SYSCALLS_H__
|
||||
|
||||
#include <l4lib/arch/types.h>
|
||||
#include <l4lib/arch/vregs.h>
|
||||
#include <l4lib/arch/message.h>
|
||||
#include <l4/generic/space.h>
|
||||
#include <l4/api/space.h>
|
||||
#include <l4/api/kip.h>
|
||||
#include <l4/api/ipc.h>
|
||||
#include <l4/api/thread.h>
|
||||
|
||||
static inline void *
|
||||
l4_kernel_interface(unsigned int *api_version, unsigned int *api_flags,
|
||||
unsigned int *kernel_id)
|
||||
{
|
||||
return (void *)L4_KIP_ADDRESS;
|
||||
}
|
||||
|
||||
typedef unsigned int (*__l4_thread_switch_t)(u32);
|
||||
extern __l4_thread_switch_t __l4_thread_switch;
|
||||
unsigned int l4_thread_switch (u32 dest);
|
||||
|
||||
typedef int (*__l4_getid_t)(struct task_ids *ids);
|
||||
extern __l4_getid_t __l4_getpid;
|
||||
int l4_getid(struct task_ids *ids);
|
||||
|
||||
typedef int (*__l4_ipc_t)(l4id_t to, l4id_t from, u32 tag);
|
||||
extern __l4_ipc_t __l4_ipc;
|
||||
int l4_ipc(l4id_t to, l4id_t from, u32 tag);
|
||||
|
||||
typedef int (*__l4_kread_t)(u32 rd, void *addr);
|
||||
extern __l4_kread_t __l4_kread;
|
||||
int l4_kread(u32 rd, void *addr);
|
||||
|
||||
typedef int (*__l4_map_t)(void *phys, void *virt,
|
||||
u32 npages, u32 flags, l4id_t tid);
|
||||
extern __l4_map_t __l4_map;
|
||||
int l4_map(void *p, void *v, u32 npages, u32 flags, l4id_t tid);
|
||||
|
||||
typedef int (*__l4_unmap_t)(void *virt, unsigned long npages, l4id_t tid);
|
||||
extern __l4_unmap_t __l4_unmap;
|
||||
int l4_unmap(void *virtual, unsigned long numpages, l4id_t tid);
|
||||
|
||||
typedef int (*__l4_thread_control_t)(unsigned int action, struct task_ids *ids);
|
||||
extern __l4_thread_control_t __l4_thread_control;
|
||||
int l4_thread_control(unsigned int action, struct task_ids *ids);
|
||||
|
||||
typedef int (*__l4_space_control_t)(unsigned int action, void *kdata);
|
||||
extern __l4_space_control_t __l4_space_control;
|
||||
int l4_space_control(unsigned int action, void *kdata);
|
||||
|
||||
typedef int (*__l4_ipc_control_t)(unsigned int action, l4id_t blocked_sender,
|
||||
u32 blocked_tag);
|
||||
extern __l4_ipc_control_t __l4_ipc_control;
|
||||
int l4_ipc_control(unsigned int, l4id_t blocked_sender, u32 blocked_tag);
|
||||
|
||||
typedef int (*__l4_exchange_registers_t)(unsigned int pc, unsigned int sp,
|
||||
l4id_t pager, l4id_t tid);
|
||||
extern __l4_exchange_registers_t __l4_exchange_registers;
|
||||
int l4_exchange_registers(unsigned int pc, unsigned int sp, int pager, l4id_t tid);
|
||||
|
||||
typedef int (*__l4_kmem_reclaim_t)(unsigned long *pfn, int *npages);
|
||||
extern __l4_kmem_reclaim_t __l4_kmem_reclaim;
|
||||
int l4_kmem_reclaim(unsigned long *pfn, int *npages);
|
||||
|
||||
typedef int (*__l4_kmem_grant_t)(unsigned long pfn, int npages);
|
||||
extern __l4_kmem_grant_t __l4_kmem_grant;
|
||||
int l4_kmem_grant(unsigned long pfn, int npages);
|
||||
|
||||
|
||||
/* To be supplied by server tasks. */
|
||||
void *virt_to_phys(void *);
|
||||
void *phys_to_virt(void *);
|
||||
|
||||
|
||||
#endif /* __ARM_SYSCALLS_H__ */
|
||||
|
||||
179
tasks/libl4/include/l4lib/arch-arm/syslib.h
Normal file
179
tasks/libl4/include/l4lib/arch-arm/syslib.h
Normal file
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Helper functions that wrap raw l4 syscalls.
|
||||
*
|
||||
* Copyright (C) 2007 Bahadir Balban
|
||||
*/
|
||||
|
||||
#ifndef __L4LIB_SYSLIB_H__
|
||||
#define __L4LIB_SYSLIB_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4/macros.h>
|
||||
|
||||
/*
|
||||
* NOTE:
|
||||
* Its best to use these wrappers because they generalise the way
|
||||
* common ipc data like sender id, error, ipc tag are passed
|
||||
* between ipc parties.
|
||||
*
|
||||
* The arguments to l4_ipc() are used by the microkernel to initiate
|
||||
* the ipc. Any data passed in message registers may or may not be
|
||||
* a duplicate of this data, but the distinction is that anything
|
||||
* that is passed via the mrs are meant to be used by the other party
|
||||
* participating in the ipc.
|
||||
*/
|
||||
|
||||
/* For system call arguments */
|
||||
#define L4SYS_ARG0 (MR_UNUSED_START)
|
||||
#define L4SYS_ARG1 (MR_UNUSED_START + 1)
|
||||
#define L4SYS_ARG2 (MR_UNUSED_START + 2)
|
||||
|
||||
/*
|
||||
* Servers get sender.
|
||||
*/
|
||||
static inline l4id_t l4_get_sender(void)
|
||||
{
|
||||
return (l4id_t)read_mr(MR_SENDER);
|
||||
}
|
||||
|
||||
static inline void l4_set_sender(l4id_t id)
|
||||
{
|
||||
write_mr(MR_SENDER, (unsigned int)id);
|
||||
}
|
||||
|
||||
static inline unsigned int l4_get_tag(void)
|
||||
{
|
||||
return read_mr(MR_TAG);
|
||||
}
|
||||
|
||||
static inline void l4_set_tag(unsigned int tag)
|
||||
{
|
||||
write_mr(MR_TAG, tag);
|
||||
}
|
||||
|
||||
static inline l4id_t self_tid(void)
|
||||
{
|
||||
struct task_ids ids;
|
||||
|
||||
l4_getid(&ids);
|
||||
return ids.tid;
|
||||
}
|
||||
|
||||
static inline int l4_send(l4id_t to, unsigned int tag)
|
||||
{
|
||||
l4_set_tag(tag);
|
||||
l4_set_sender(self_tid());
|
||||
return l4_ipc(to, L4_NILTHREAD, 0);
|
||||
}
|
||||
|
||||
static inline int l4_sendrecv(l4id_t to, l4id_t from, unsigned int tag)
|
||||
{
|
||||
BUG_ON(to == L4_NILTHREAD || from == L4_NILTHREAD);
|
||||
l4_set_tag(tag);
|
||||
l4_set_sender(self_tid());
|
||||
return l4_ipc(to, from, 0);
|
||||
}
|
||||
|
||||
static inline int l4_receive(l4id_t from)
|
||||
{
|
||||
return l4_ipc(L4_NILTHREAD, from, 0);
|
||||
}
|
||||
|
||||
/* Servers:
|
||||
* Sets the message register for returning errors back to client task.
|
||||
* These are usually posix error codes.
|
||||
*/
|
||||
static inline void l4_set_retval(int retval)
|
||||
{
|
||||
write_mr(MR_RETURN, retval);
|
||||
}
|
||||
|
||||
/* Clients:
|
||||
* Learn result of request.
|
||||
*/
|
||||
static inline int l4_get_retval(void)
|
||||
{
|
||||
return read_mr(MR_RETURN);
|
||||
}
|
||||
|
||||
/* Servers:
|
||||
* Return the ipc result back to requesting task.
|
||||
*/
|
||||
static inline int l4_ipc_return(int retval)
|
||||
{
|
||||
unsigned int tag = l4_get_tag();
|
||||
l4id_t sender = l4_get_sender();
|
||||
|
||||
l4_set_retval(retval);
|
||||
return l4_send(sender, tag);
|
||||
}
|
||||
|
||||
/* A helper that translates and maps a physical address to virtual */
|
||||
static inline void *l4_map_helper(void *phys, int npages)
|
||||
{
|
||||
struct task_ids ids;
|
||||
|
||||
l4_getid(&ids);
|
||||
l4_map(phys, phys_to_virt(phys), npages, MAP_USR_RW_FLAGS, ids.tid);
|
||||
return phys_to_virt(phys);
|
||||
}
|
||||
|
||||
|
||||
/* A helper that translates and maps a physical address to virtual */
|
||||
static inline void *l4_unmap_helper(void *virt, int npages)
|
||||
{
|
||||
struct task_ids ids;
|
||||
|
||||
l4_getid(&ids);
|
||||
l4_unmap(virt, npages, ids.tid);
|
||||
return virt_to_phys(virt);
|
||||
}
|
||||
|
||||
/*
|
||||
* A helper to produce grant ipc between a pager and its client, or a
|
||||
* synchronous syscall to the kernel in case the grant is to the kernel.
|
||||
*/
|
||||
static inline int l4_grant_pages(unsigned long pfn, int npages, l4id_t tid)
|
||||
{
|
||||
/* Only a pager can grant pages to kernel. */
|
||||
if (tid == KERNEL_TID) {
|
||||
/* Granting physical pages via a system call in kernel case. */
|
||||
return l4_kmem_grant(pfn, npages);
|
||||
} else {
|
||||
/*
|
||||
* FIXME: This should set up appropriate message registers and
|
||||
* call l4_ipc() on the target thread. Pages given are virtual.
|
||||
*/
|
||||
while(1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE: This is just brainstroming yet.
|
||||
* A helper to reclaim unused pages. A pager can reclaim pages from kernel or
|
||||
* other tasks this way.
|
||||
*/
|
||||
static inline int l4_reclaim_pages(l4id_t tid)
|
||||
{
|
||||
unsigned long pfn;
|
||||
int npages;
|
||||
|
||||
if (tid == KERNEL_TID) {
|
||||
/*
|
||||
* A single contiguous sequence of physical pages are returned
|
||||
* by kernel via a syscall. Simpler the better for now.
|
||||
*/
|
||||
l4_kmem_reclaim(&pfn, &npages);
|
||||
} else {
|
||||
/*
|
||||
* An ipc to a task where pfn and npages come in message regs.
|
||||
*/
|
||||
while(1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif /* __L4LIB_SYSLIB_H__ */
|
||||
12
tasks/libl4/include/l4lib/arch-arm/types.h
Normal file
12
tasks/libl4/include/l4lib/arch-arm/types.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef __L4_ARCH_ARM__
|
||||
#define __L4_ARCH_ARM__
|
||||
|
||||
#define TASK_ID_INVALID -1
|
||||
struct task_ids {
|
||||
int tid;
|
||||
int spid;
|
||||
};
|
||||
|
||||
#include <l4/arch/arm/types.h>
|
||||
|
||||
#endif
|
||||
43
tasks/libl4/include/l4lib/arch-arm/utcb.h
Normal file
43
tasks/libl4/include/l4lib/arch-arm/utcb.h
Normal file
@@ -0,0 +1,43 @@
|
||||
#ifndef __ARM_UTCB_H__
|
||||
#define __ARM_UTCB_H__
|
||||
|
||||
#include <l4lib/types.h>
|
||||
#include <l4lib/arch/vregs.h>
|
||||
|
||||
/* FIXME: LICENSE/LICENCE */
|
||||
|
||||
/*
|
||||
* NOTE: In syslib.h the first few mrs are used by data frequently
|
||||
* needed for all ipcs. Those mrs are defined here.
|
||||
*/
|
||||
|
||||
/* MRs always used on receive by syslib */
|
||||
#define MR_RETURN 0 /* Contains the posix return value. */
|
||||
|
||||
/* MRs always used on send by syslib */
|
||||
#define MR_TAG 0 /* Defines the message purpose */
|
||||
#define MR_SENDER 1 /* For anythread receivers to discover sender */
|
||||
|
||||
/* These define the mr start - end range that aren't used by syslib */
|
||||
#define MR_UNUSED_START 2 /* The first mr that's not used by syslib.h */
|
||||
#define MR_TOTAL 6
|
||||
#define MR_UNUSED_TOTAL (MR_TOTAL - MR_UNUSED_START)
|
||||
|
||||
/* Compact utcb for now! :-) */
|
||||
struct utcb {
|
||||
u32 mr[MR_TOTAL];
|
||||
u32 tid; /* Thread id */
|
||||
|
||||
/*
|
||||
* This field is used by servers as the ptr to current tcb,
|
||||
* i.e. the task that this server is serving to.
|
||||
*/
|
||||
unsigned long usr_handle;
|
||||
};
|
||||
|
||||
static inline struct utcb *__L4_ARM_Utcb()
|
||||
{
|
||||
return (struct utcb *)(*(struct utcb **)USER_UTCB_REF);
|
||||
}
|
||||
|
||||
#endif /* __ARM_UTCB_H__ */
|
||||
13
tasks/libl4/include/l4lib/arch-arm/vregs.h
Normal file
13
tasks/libl4/include/l4lib/arch-arm/vregs.h
Normal file
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Copyright (C) 2007 Bahadir Balban
|
||||
*/
|
||||
#ifndef __L4_ARM_VREGS_H__
|
||||
#define __L4_ARM_VREGS_H__
|
||||
|
||||
/* FIXME: LICENSE/LICENCE */
|
||||
#define USER_UTCB_REF 0xFF000FF0
|
||||
#define L4_KIP_ADDRESS 0xFF000000
|
||||
#define UTCB_KIP_OFFSET 0xFF0
|
||||
|
||||
#endif /* __L4_ARM_VREGS_H__ */
|
||||
|
||||
42
tasks/libl4/include/l4lib/ipcdefs.h
Normal file
42
tasks/libl4/include/l4lib/ipcdefs.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2007 Bahadir Balban
|
||||
*
|
||||
* This file contains ipc definitions that are needed for server tasks
|
||||
* to communicate with each other. For example common shared memory ids
|
||||
* between two servers, or common ipc tags used between two servers are
|
||||
* defined here.
|
||||
*/
|
||||
#ifndef __IPCDEFS_H__
|
||||
#define __IPCDEFS_H__
|
||||
|
||||
#include <l4/api/ipc.h>
|
||||
|
||||
/* SHMID used betweeen FS0 and BLKDEV0 servers */
|
||||
#define FS_BLKDEV_SHMID 0
|
||||
|
||||
|
||||
/*** IPC Tags used between server tasks ***/
|
||||
|
||||
/* For ping ponging */
|
||||
#define L4_IPC_TAG_PINGPONG 3
|
||||
|
||||
/* To negotiate a shared memory mapping */
|
||||
#define L4_IPC_TAG_SHM 4
|
||||
|
||||
/* To negotiate a grant mapping */
|
||||
#define L4_IPC_TAG_GRANT 5
|
||||
|
||||
/* Posix system call tags */
|
||||
#define L4_IPC_TAG_SHMGET 6
|
||||
#define L4_IPC_TAG_SHMAT 7
|
||||
#define L4_IPC_TAG_SHMDT 8
|
||||
#define L4_IPC_TAG_MMAP 9
|
||||
#define L4_IPC_TAG_MUNMAP 10
|
||||
#define L4_IPC_TAG_MSYNC 11
|
||||
#define L4_IPC_TAG_OPEN 12
|
||||
#define L4_IPC_TAG_READ 13
|
||||
#define L4_IPC_TAG_WRITE 14
|
||||
#define L4_IPC_TAG_LSEEK 15
|
||||
#define L4_IPC_TAG_CLOSE 16
|
||||
|
||||
#endif /* __IPCDEFS_H__ */
|
||||
15
tasks/libl4/include/l4lib/kip.h
Normal file
15
tasks/libl4/include/l4lib/kip.h
Normal file
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Kernel Interface Page
|
||||
*
|
||||
* Copyright (C) 2007 Bahadir Balban
|
||||
*
|
||||
*/
|
||||
#ifndef __L4LIB_KIP_H__
|
||||
#define __L4LIB_KIP_H__
|
||||
|
||||
/* Use the kernel header */
|
||||
#include <l4lib/types.h>
|
||||
#include <l4lib/arch/syscalls.h>
|
||||
#include <l4/api/kip.h>
|
||||
|
||||
#endif /* __KIP_H__ */
|
||||
17
tasks/libl4/include/l4lib/types.h
Normal file
17
tasks/libl4/include/l4lib/types.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef __TYPES_H__
|
||||
#define __TYPES_H__
|
||||
|
||||
/* Copyright (C) 2003 - 2004 NICTA */
|
||||
|
||||
#include <l4lib/arch/types.h>
|
||||
|
||||
#define l4_nilpage 0
|
||||
|
||||
#define l4_nilthread -1
|
||||
#define l4_anythread -2
|
||||
|
||||
#define l4_niltag 0
|
||||
#define l4_notifytag (1 << 13)
|
||||
#define l4_waittag (1 << 14)
|
||||
|
||||
#endif /* __TYPES_H__ */
|
||||
10
tasks/libl4/include/l4lib/utcb.h
Normal file
10
tasks/libl4/include/l4lib/utcb.h
Normal file
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Copyright (C) 2007 Bahadir Balban
|
||||
*/
|
||||
#ifndef __UTCB_H__
|
||||
#define __UTCB_H__
|
||||
|
||||
#include <l4lib/types.h>
|
||||
#include <l4lib/arch/utcb.h>
|
||||
|
||||
#endif /* __UTCB_H__ */
|
||||
157
tasks/libl4/src/arm/syscalls.S
Normal file
157
tasks/libl4/src/arm/syscalls.S
Normal file
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Userspace system call interface.
|
||||
*
|
||||
* Copyright (C) 2007 Bahadir Balban
|
||||
*/
|
||||
#include <l4lib/arch/asm.h>
|
||||
#include <l4lib/arch/vregs.h>
|
||||
#include <l4/generic/space.h>
|
||||
|
||||
.macro utcb_address rx
|
||||
mov \rx, #L4_KIP_ADDRESS
|
||||
add \rx, \rx, #UTCB_KIP_OFFSET
|
||||
ldr \rx, [\rx]
|
||||
.endm
|
||||
|
||||
BEGIN_PROC(l4_thread_switch)
|
||||
ldr r12, =__l4_thread_switch
|
||||
ldr pc, [r12] @ Jump into the SWI. Kernel returns to LR_USR, which is the caller.
|
||||
END_PROC(l4_thread_switch)
|
||||
|
||||
/*
|
||||
* The syscall returns process ids. This function saves the returned values in the
|
||||
* arguments passed by reference. @r0 = struct task_ids *
|
||||
*/
|
||||
BEGIN_PROC(l4_getid)
|
||||
ldr r12, =__l4_getid @ See l4_kdata_read for why its so simple.
|
||||
ldr pc, [r12] @ Return.
|
||||
END_PROC(l4_getid)
|
||||
|
||||
/*
|
||||
* Reads data from the kernel into given buffer. Data is defined by request descriptor.
|
||||
* @r0 = request descriptor, @r1 = buffer address.
|
||||
*/
|
||||
BEGIN_PROC(l4_kread)
|
||||
ldr r12, =__l4_kread
|
||||
ldr pc, [r12] @ Jump into the SWI
|
||||
/*
|
||||
* The LR_USR points at the return address of this function. The system
|
||||
* call return path directly jumps to LR_USR so we don't even need a
|
||||
* return instruction here.
|
||||
*/
|
||||
END_PROC(l4_kread)
|
||||
|
||||
/*
|
||||
* Inter-process communication. Loads message registers as arguments before the call,
|
||||
* and stores them as results after the call. @r0 = to, @r1 = from, @r2 = tag.
|
||||
*/
|
||||
BEGIN_PROC(l4_ipc)
|
||||
stmfd sp!, {r4-r8,lr} @ Save context.
|
||||
utcb_address r12 @ Get utcb address.
|
||||
ldmib r12!, {r3-r8} @ Load 5 Message registers from utcb. MR1-MR5
|
||||
ldr r12, =__l4_ipc
|
||||
mov lr, pc
|
||||
ldr pc, [r12]
|
||||
utcb_address r12 @ Get utcb address.
|
||||
stmia r12, {r3-r8} @ Store 6 Message registers to utcb. MR0-MR5
|
||||
ldmfd sp!, {r4-r8,pc} @ Return restoring pc, and context.
|
||||
END_PROC(l4_ipc)
|
||||
|
||||
/*
|
||||
* System call that maps an area of memory into the given address space.
|
||||
* @r0 = physical address, @r1 = virtual address, @r2 = map size in pages,
|
||||
* @r3 = map flags, @r4 = The tgid of the address space to map.
|
||||
*/
|
||||
BEGIN_PROC(l4_map)
|
||||
stmfd sp!, {r4, lr}
|
||||
ldr r4, [sp, #8] @ FIXME: Is this right?
|
||||
ldr r12, =__l4_map
|
||||
mov lr, pc @ We must return here to restore r4.
|
||||
ldr pc, [r12]
|
||||
ldmfd sp!, {r4, pc}
|
||||
END_PROC(l4_map)
|
||||
|
||||
/*
|
||||
* System call that unmaps an area of memory into the given address space.
|
||||
* @r0 = virtual, @r1 = pages, @r2 = tid of address space to unmap
|
||||
*/
|
||||
BEGIN_PROC(l4_unmap)
|
||||
stmfd sp!, {lr}
|
||||
ldr r12, =__l4_unmap
|
||||
mov lr, pc
|
||||
ldr pc, [r12]
|
||||
ldmfd sp!, {pc} @ Restore original lr and return.
|
||||
END_PROC(l4_unmap)
|
||||
|
||||
/*
|
||||
* System call that grants a set of pages to the kernel.
|
||||
* @r0 = physical pfn, @r1 = number of pages
|
||||
*/
|
||||
BEGIN_PROC(l4_kmem_grant)
|
||||
stmfd sp!, {lr}
|
||||
ldr r12, =__l4_kmem_grant
|
||||
mov lr, pc
|
||||
ldr pc, [r12]
|
||||
ldmfd sp!, {pc} @ Restore original lr and return.
|
||||
END_PROC(l4_kmem_grant)
|
||||
|
||||
/*
|
||||
* System call that reclaims a set of pages from the kernel.
|
||||
* @r0 = ptr to physical pfn, @r1 = ptr to number of pages
|
||||
*/
|
||||
BEGIN_PROC(l4_kmem_reclaim)
|
||||
stmfd sp!, {lr}
|
||||
ldr r12, =__l4_kmem_reclaim
|
||||
mov lr, pc
|
||||
ldr pc, [r12]
|
||||
ldmfd sp!, {pc} @ Restore original lr and return.
|
||||
END_PROC(l4_kmem_reclaim)
|
||||
|
||||
/*
|
||||
* System call that controls thread creation, destruction and modification.
|
||||
* @r0 = thread action, @r1 = &ids
|
||||
*/
|
||||
BEGIN_PROC(l4_thread_control)
|
||||
stmfd sp!, {lr}
|
||||
ldr r12, =__l4_thread_control
|
||||
mov lr, pc
|
||||
ldr pc, [r12]
|
||||
ldmfd sp!, {pc} @ Restore original lr and return.
|
||||
END_PROC(l4_thread_control)
|
||||
|
||||
/*
|
||||
* System call that modifies ipc blocked sender lists of receivers.
|
||||
* @r0 = Action (e.g. block/unblock), @r1 = sender id, @r2 = sender tag
|
||||
*/
|
||||
BEGIN_PROC(l4_ipc_control)
|
||||
stmfd sp!, {lr}
|
||||
ldr r12, =__l4_ipc_control
|
||||
mov lr, pc
|
||||
ldr pc, [r12]
|
||||
ldmfd sp!, {pc} @ Restore original lr and return.
|
||||
END_PROC(l4_ipc_control)
|
||||
|
||||
/*
|
||||
* Manipulates address spaces, e.g. sets up shared memory areas between threads
|
||||
* @r0 = operation code, @r1 = struct shm_kdata *kdata
|
||||
*/
|
||||
BEGIN_PROC(l4_space_control)
|
||||
stmfd sp!, {lr}
|
||||
ldr r12, =__l4_space_control
|
||||
mov lr, pc
|
||||
ldr pc, [r12]
|
||||
ldmfd sp!, {pc} @ Restore original lr and return.
|
||||
END_PROC(l4_space_control)
|
||||
|
||||
/*
|
||||
* Sets registers of a thread and its pager.
|
||||
* @r0 = pc to set, @r1 = sp to set @r2 = pager id, @r3 = tid of thread.
|
||||
*/
|
||||
BEGIN_PROC(l4_exchange_registers)
|
||||
stmfd sp!, {lr}
|
||||
ldr r12, =__l4_exchange_registers
|
||||
mov lr, pc
|
||||
ldr pc, [r12]
|
||||
ldmfd sp!, {pc} @ Restore original lr and return.
|
||||
END_PROC(l4_exchange_registers)
|
||||
|
||||
40
tasks/libl4/src/init.c
Normal file
40
tasks/libl4/src/init.c
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Initialise system call offsets.
|
||||
*
|
||||
* Copyright (C) 2007 Bahadir Balban
|
||||
*/
|
||||
#include <l4lib/kip.h>
|
||||
|
||||
__l4_ipc_t __l4_ipc = 0;
|
||||
__l4_map_t __l4_map = 0;
|
||||
__l4_unmap_t __l4_unmap = 0;
|
||||
__l4_kread_t __l4_kread = 0;
|
||||
__l4_getid_t __l4_getid = 0;
|
||||
__l4_thread_switch_t __l4_thread_switch = 0;
|
||||
__l4_thread_control_t __l4_thread_control = 0;
|
||||
__l4_ipc_control_t __l4_ipc_control = 0;
|
||||
__l4_space_control_t __l4_space_control = 0;
|
||||
__l4_exchange_registers_t __l4_exchange_registers = 0;
|
||||
__l4_kmem_grant_t __l4_kmem_grant = 0;
|
||||
__l4_kmem_reclaim_t __l4_kmem_reclaim = 0;
|
||||
|
||||
struct kip *kip;
|
||||
|
||||
void __l4_init(void)
|
||||
{
|
||||
kip = l4_kernel_interface(0, 0, 0);
|
||||
|
||||
__l4_ipc = (__l4_ipc_t)kip->ipc;
|
||||
__l4_map = (__l4_map_t)kip->map;
|
||||
__l4_unmap = (__l4_unmap_t)kip->unmap;
|
||||
__l4_kread = (__l4_kread_t)kip->kread;
|
||||
__l4_getid = (__l4_getid_t)kip->getid;
|
||||
__l4_thread_switch =(__l4_thread_switch_t)kip->thread_switch;
|
||||
__l4_thread_control=(__l4_thread_control_t)kip->thread_control;
|
||||
__l4_ipc_control= (__l4_ipc_control_t)kip->ipc_control;
|
||||
__l4_space_control=(__l4_space_control_t)kip->space_control;
|
||||
__l4_exchange_registers =(__l4_exchange_registers_t)kip->exchange_registers;
|
||||
__l4_kmem_grant =(__l4_kmem_grant_t)kip->kmem_grant;
|
||||
__l4_kmem_reclaim =(__l4_kmem_reclaim_t)kip->kmem_reclaim;
|
||||
}
|
||||
|
||||
20
tasks/libl4/tagfilelist
Normal file
20
tasks/libl4/tagfilelist
Normal file
@@ -0,0 +1,20 @@
|
||||
./src/init.c
|
||||
./include/l4lib/kip.h
|
||||
./include/l4lib/posix/l4shm.h
|
||||
./include/l4lib/arch-arm/asm.h
|
||||
./include/l4lib/arch-arm/types.h
|
||||
./include/l4lib/arch-arm/utcb.h
|
||||
./include/l4lib/arch-arm/syscalls.h
|
||||
./include/l4lib/arch-arm/message.h
|
||||
./include/l4lib/arch-arm/vregs.h
|
||||
./include/l4lib/types.h
|
||||
./include/l4lib/ipcdefs.h
|
||||
./include/l4lib/utcb.h
|
||||
./include/l4lib/examples/ipc.h
|
||||
./include/l4lib/examples/message_stuff.h
|
||||
./include/l4lib/examples/space.h
|
||||
./include/l4lib/examples/thread.h
|
||||
./include/l4lib/examples/syscalls.h
|
||||
./include/l4lib/examples/message.h
|
||||
./include/l4lib/examples/schedule.h
|
||||
./src/arm/syscalls.S
|
||||
Reference in New Issue
Block a user