mirror of
https://github.com/drasko/codezero.git
synced 2026-02-01 12:43:15 +01:00
Changes since April
Clean up of build directories. Simplifications to capability model.
This commit is contained in:
11
conts/baremetal/empty/SConscript
Normal file
11
conts/baremetal/empty/SConscript
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
# Inherit global environment
|
||||
Import('env')
|
||||
|
||||
# The set of source files associated with this SConscript file.
|
||||
src_local = Glob('*.[cS]')
|
||||
src_local += Glob('src/*.[cS]')
|
||||
|
||||
obj = env.Object(src_local)
|
||||
Return('obj')
|
||||
|
||||
@@ -7,60 +7,49 @@
|
||||
import os, shelve, sys
|
||||
from os.path import *
|
||||
|
||||
PROJRELROOT = '../..'
|
||||
CONTS_XXX = '../..'
|
||||
BAREMETAL_CONTS_XXX = '../../..'
|
||||
sys.path.append(CONTS_XXX)
|
||||
sys.path.append(BAREMETAL_CONTS_XXX)
|
||||
|
||||
sys.path.append(PROJRELROOT)
|
||||
|
||||
from config.projpaths import *
|
||||
from config.configuration import *
|
||||
from scripts.config.projpaths import *
|
||||
from scripts.conts.containers import *
|
||||
from scripts.config.configuration import *
|
||||
|
||||
config = configuration_retrieve()
|
||||
platform = config.platform
|
||||
arch = config.arch
|
||||
gcc_arch_flag = config.gcc_arch_flag
|
||||
|
||||
LIBL4_RELDIR = 'conts/libl4'
|
||||
KERNEL_INCLUDE = join(PROJROOT, 'include')
|
||||
LIBL4_DIR = join(PROJROOT, LIBL4_RELDIR)
|
||||
LIBL4_INCLUDE = join(LIBL4_DIR, 'include')
|
||||
LIBL4_LIBPATH = join(BUILDDIR, LIBL4_RELDIR)
|
||||
cid = int(ARGUMENTS.get('cid', 0))
|
||||
cont = find_container_from_cid(cid)
|
||||
|
||||
# Locally important paths are here
|
||||
LIBC_RELDIR = 'conts/libc'
|
||||
LIBC_DIR = join(PROJROOT, LIBC_RELDIR)
|
||||
LIBC_LIBPATH = join(BUILDDIR, LIBC_RELDIR)
|
||||
LIBC_INCLUDE = [join(LIBC_DIR, 'include'), \
|
||||
join(LIBC_DIR, 'include/arch' + '/' + arch)]
|
||||
builddir = join(join(BUILDDIR, 'cont') + str(cid), cont.name)
|
||||
|
||||
LIBDEV_RELDIR = 'conts/libdev'
|
||||
LIBDEV_DIR = join(PROJROOT, LIBDEV_RELDIR)
|
||||
LIBDEV_LIBPATH = join(join(BUILDDIR, LIBDEV_RELDIR), 'sys-userspace')
|
||||
LIBDEV_INCLUDE = [join(LIBDEV_DIR, 'uart/include')]
|
||||
|
||||
LIBMEM_RELDIR = 'conts/libmem'
|
||||
LIBMEM_DIR = join(PROJROOT, LIBMEM_RELDIR)
|
||||
LIBMEM_LIBPATH = join(BUILDDIR, LIBMEM_RELDIR)
|
||||
LIBMEM_INCLUDE = LIBMEM_DIR
|
||||
# linker.lds is generated either in conts/xxx or build/contx/include
|
||||
if cont.duplicate == 0:
|
||||
linker_lds = join(builddir, 'include/linker.lds')
|
||||
else:
|
||||
linker_lds = 'include/linker.lds'
|
||||
|
||||
env = Environment(CC = config.toolchain_userspace + 'gcc',
|
||||
# We don't use -nostdinc because sometimes we need standard headers,
|
||||
# such as stdarg.h e.g. for variable args, as in printk().
|
||||
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', \
|
||||
'-Werror', '-march=' + gcc_arch_flag],
|
||||
LINKFLAGS = ['-nostdlib', '-T' + "include/linker.lds", "-u_start"],
|
||||
ASFLAGS = ['-D__ASSEMBLY__'], \
|
||||
PROGSUFFIX = '.elf', # The suffix to use for final executable\
|
||||
ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path\
|
||||
LIBS = ['gcc', 'libl4', 'c-userspace', 'libdev-userspace', 'gcc', \
|
||||
'libmm', 'libmc', 'libmalloc','c-userspace'], # libgcc.a - This is required for division routines.
|
||||
CPPPATH = ["#include", KERNEL_INCLUDE, LIBL4_INCLUDE, LIBDEV_INCLUDE, \
|
||||
LIBC_INCLUDE, LIBMEM_INCLUDE],
|
||||
LIBPATH = [LIBL4_LIBPATH, LIBDEV_LIBPATH, LIBC_LIBPATH, LIBMEM_LIBPATH],
|
||||
CPPFLAGS = '-include l4/config.h -include l4/macros.h -include l4/types.h')
|
||||
# We don't use -nostdinc because sometimes we need standard headers,
|
||||
# such as stdarg.h e.g. for variable args, as in printk().
|
||||
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall',
|
||||
'-Werror', '-march=' + gcc_arch_flag],
|
||||
LINKFLAGS = ['-nostdlib', '-T' + linker_lds, '-u_start'],
|
||||
ASFLAGS = ['-D__ASSEMBLY__'],
|
||||
PROGSUFFIX = '.elf', # The suffix to use for final executable
|
||||
ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path
|
||||
# libgcc.a - This is required for division routines.
|
||||
LIBS = ['gcc', 'libl4', 'c-userspace', 'libdev-userspace', 'gcc',
|
||||
'libmem', 'c-userspace'],
|
||||
CPPPATH = ["#include", KERNEL_HEADERS, LIBL4_INCLUDE, LIBDEV_INCLUDE,
|
||||
LIBC_INCLUDE, LIBMEM_INCLUDE, join(builddir, 'include')],
|
||||
LIBPATH = [LIBL4_LIBPATH, LIBDEV_USER_LIBPATH, LIBC_LIBPATH, LIBMEM_LIBPATH],
|
||||
CPPFLAGS = '-include l4/config.h -include l4/macros.h -include l4/types.h')
|
||||
|
||||
src = Glob('*.[cS]')
|
||||
src += Glob('src/*.[cS]')
|
||||
objs = SConscript('SConscript', exports = { 'env' : env },
|
||||
duplicate=0, build_dir = builddir)
|
||||
|
||||
objs = env.Object(src)
|
||||
prog = env.Program('main.elf', objs)
|
||||
Depends(prog, 'include/linker.lds')
|
||||
Depends(objs, join(PROJROOT, CONFIG_H))
|
||||
prog = env.Program(join(builddir, 'main.elf'), objs)
|
||||
Depends(prog, linker_lds)
|
||||
|
||||
11
conts/baremetal/hello_world/SConscript
Normal file
11
conts/baremetal/hello_world/SConscript
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
# Inherit global environment
|
||||
Import('env')
|
||||
|
||||
# The set of source files associated with this SConscript file.
|
||||
src_local = Glob('*.[cS]')
|
||||
src_local += Glob('src/*.[cS]')
|
||||
|
||||
obj = env.Object(src_local)
|
||||
Return('obj')
|
||||
|
||||
@@ -4,64 +4,54 @@
|
||||
#
|
||||
# Copyright © 2009 B Labs Ltd
|
||||
#
|
||||
import os, shelve, sys
|
||||
import os, sys
|
||||
from os.path import *
|
||||
|
||||
PROJRELROOT = '../..'
|
||||
CONTS_XXX = '../..'
|
||||
BAREMETAL_CONTS_XXX = '../../..'
|
||||
sys.path.append(CONTS_XXX)
|
||||
sys.path.append(BAREMETAL_CONTS_XXX)
|
||||
|
||||
sys.path.append(PROJRELROOT)
|
||||
|
||||
from config.projpaths import *
|
||||
from config.configuration import *
|
||||
from scripts.config.projpaths import *
|
||||
from scripts.conts.containers import *
|
||||
from scripts.config.configuration import *
|
||||
|
||||
config = configuration_retrieve()
|
||||
platform = config.platform
|
||||
arch = config.arch
|
||||
gcc_arch_flag = config.gcc_arch_flag
|
||||
|
||||
LIBL4_RELDIR = 'conts/libl4'
|
||||
KERNEL_INCLUDE = join(PROJROOT, 'include')
|
||||
LIBL4_DIR = join(PROJROOT, LIBL4_RELDIR)
|
||||
LIBL4_INCLUDE = join(LIBL4_DIR, 'include')
|
||||
LIBL4_LIBPATH = join(BUILDDIR, LIBL4_RELDIR)
|
||||
cid = int(ARGUMENTS.get('cid', 0))
|
||||
cont = find_container_from_cid(cid)
|
||||
|
||||
# Locally important paths are here
|
||||
LIBC_RELDIR = 'conts/libc'
|
||||
LIBC_DIR = join(PROJROOT, LIBC_RELDIR)
|
||||
LIBC_LIBPATH = join(BUILDDIR, LIBC_RELDIR)
|
||||
LIBC_INCLUDE = [join(LIBC_DIR, 'include'), \
|
||||
join(LIBC_DIR, 'include/arch' + '/' + arch)]
|
||||
builddir = join(join(BUILDDIR, 'cont') + str(cid), cont.name)
|
||||
|
||||
LIBDEV_RELDIR = 'conts/libdev'
|
||||
LIBDEV_DIR = join(PROJROOT, LIBDEV_RELDIR)
|
||||
LIBDEV_LIBPATH = join(join(BUILDDIR, LIBDEV_RELDIR), 'sys-userspace')
|
||||
LIBDEV_INCLUDE = [join(LIBDEV_DIR, 'uart/include')]
|
||||
|
||||
LIBMEM_RELDIR = 'conts/libmem'
|
||||
LIBMEM_DIR = join(PROJROOT, LIBMEM_RELDIR)
|
||||
LIBMEM_LIBPATH = join(BUILDDIR, LIBMEM_RELDIR)
|
||||
LIBMEM_INCLUDE = LIBMEM_DIR
|
||||
# linker.lds is generated either in conts/xxx or build/contx/include
|
||||
if cont.duplicate == 0:
|
||||
linker_lds = join(builddir, 'include/linker.lds')
|
||||
else:
|
||||
linker_lds = 'include/linker.lds'
|
||||
|
||||
env = Environment(CC = config.toolchain_userspace + 'gcc',
|
||||
# We don't use -nostdinc because sometimes we need standard headers,
|
||||
# such as stdarg.h e.g. for variable args, as in printk().
|
||||
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', \
|
||||
'-Werror', '-march=' + gcc_arch_flag],
|
||||
LINKFLAGS = ['-nostdlib', '-T' + "include/linker.lds", "-u_start"],\
|
||||
ASFLAGS = ['-D__ASSEMBLY__'], \
|
||||
PROGSUFFIX = '.elf', # The suffix to use for final executable
|
||||
ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path
|
||||
LIBS = ['gcc', 'libl4', 'c-userspace', 'libdev-userspace', \
|
||||
'libmm', 'libmc', 'libmalloc', 'gcc', 'c-userspace'],
|
||||
# We don't use -nostdinc because sometimes we need standard headers,
|
||||
# such as stdarg.h e.g. for variable args, as in printk().
|
||||
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall',
|
||||
'-Werror', '-march=' + gcc_arch_flag],
|
||||
LINKFLAGS = ['-nostdlib', '-T' + linker_lds, '-u_start'],
|
||||
ASFLAGS = ['-D__ASSEMBLY__'],
|
||||
PROGSUFFIX = '.elf', # The suffix to use for final executable
|
||||
ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path
|
||||
LIBS = ['gcc', 'libl4', 'c-userspace', 'libdev-userspace',
|
||||
'libmem', 'gcc', 'c-userspace'],
|
||||
# libgcc.a - This is required for division routines.
|
||||
CPPPATH = ["#include", KERNEL_INCLUDE, LIBL4_INCLUDE, LIBDEV_INCLUDE, \
|
||||
LIBC_INCLUDE, LIBMEM_INCLUDE],
|
||||
LIBPATH = [LIBL4_LIBPATH, LIBDEV_LIBPATH, LIBC_LIBPATH, LIBMEM_LIBPATH],
|
||||
CPPFLAGS = '-include l4/config.h -include l4/macros.h -include l4/types.h -include l4lib/macros.h')
|
||||
CPPPATH = ["#include", KERNEL_HEADERS, LIBL4_INCLUDE, LIBDEV_INCLUDE,
|
||||
LIBC_INCLUDE, LIBMEM_INCLUDE, join(builddir, 'include')],
|
||||
LIBPATH = [LIBL4_LIBPATH, LIBDEV_USER_LIBPATH, LIBC_LIBPATH, LIBMEM_LIBPATH],
|
||||
CPPFLAGS = '-include l4/config.h -include l4/macros.h \
|
||||
-include l4/types.h -include l4lib/macros.h')
|
||||
|
||||
src = Glob('*.[cS]')
|
||||
src += Glob('src/*.[cS]')
|
||||
objs = SConscript('SConscript', exports = { 'env' : env },
|
||||
duplicate=0, build_dir = builddir)
|
||||
|
||||
objs = env.Object(src)
|
||||
prog = env.Program('main.elf', objs)
|
||||
Depends(prog, 'include/linker.lds')
|
||||
Depends(objs, join(PROJROOT, CONFIG_H))
|
||||
|
||||
prog = env.Program(join(builddir, 'main.elf'), objs)
|
||||
Depends(prog, linker_lds)
|
||||
|
||||
11
conts/baremetal/ipc_demo/SConscript
Normal file
11
conts/baremetal/ipc_demo/SConscript
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
# Inherit global environment
|
||||
Import('env')
|
||||
|
||||
# The set of source files associated with this SConscript file.
|
||||
src_local = Glob('*.[cS]')
|
||||
src_local += Glob('src/*.[cS]')
|
||||
|
||||
obj = env.Object(src_local)
|
||||
Return('obj')
|
||||
|
||||
57
conts/baremetal/ipc_demo/SConstruct
Normal file
57
conts/baremetal/ipc_demo/SConstruct
Normal file
@@ -0,0 +1,57 @@
|
||||
# -*- mode: python; coding: utf-8; -*-
|
||||
#
|
||||
# Codezero -- Virtualization microkernel for embedded systems.
|
||||
#
|
||||
# Copyright © 2009 B Labs Ltd
|
||||
#
|
||||
import os, shelve, sys
|
||||
from os.path import *
|
||||
|
||||
CONTS_XXX = '../..'
|
||||
BAREMETAL_CONTS_XXX = '../../..'
|
||||
sys.path.append(CONTS_XXX)
|
||||
sys.path.append(BAREMETAL_CONTS_XXX)
|
||||
|
||||
from scripts.config.projpaths import *
|
||||
from scripts.conts.containers import *
|
||||
from scripts.config.configuration import *
|
||||
|
||||
config = configuration_retrieve()
|
||||
gcc_arch_flag = config.gcc_arch_flag
|
||||
|
||||
cid = int(ARGUMENTS.get('cid', 0))
|
||||
cont = find_container_from_cid(cid)
|
||||
|
||||
builddir = join(join(BUILDDIR, 'cont') + str(cid), cont.name)
|
||||
|
||||
# linker.lds is generated either in conts/xxx or build/contx/include
|
||||
if cont.duplicate == 0:
|
||||
linker_lds = join(builddir, 'include/linker.lds')
|
||||
else:
|
||||
linker_lds = 'include/linker.lds'
|
||||
|
||||
env = Environment(CC = config.toolchain_userspace + 'gcc',
|
||||
# We don't use -nostdinc because sometimes we need standard headers,
|
||||
# such as stdarg.h e.g. for variable args, as in printk().
|
||||
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall',
|
||||
'-Werror', '-march=' + gcc_arch_flag],
|
||||
LINKFLAGS = ['-nostdlib', '-T' + linker_lds, '-u_start'],
|
||||
ASFLAGS = ['-D__ASSEMBLY__'],
|
||||
PROGSUFFIX = '.elf', # The suffix to use for final executable
|
||||
ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path
|
||||
LIBS = ['gcc', 'libl4', 'c-userspace', 'libdev-userspace',
|
||||
'libmem', 'gcc', 'c-userspace'],
|
||||
# libgcc.a - This is required for division routines.
|
||||
CPPPATH = ["#include", KERNEL_HEADERS, LIBL4_INCLUDE, LIBDEV_INCLUDE,
|
||||
LIBC_INCLUDE, LIBMEM_INCLUDE, join(builddir, 'include')],
|
||||
LIBPATH = [LIBL4_LIBPATH, LIBDEV_USER_LIBPATH, LIBC_LIBPATH, LIBMEM_LIBPATH],
|
||||
CPPFLAGS = '-include l4/config.h -include l4/macros.h \
|
||||
-include l4/types.h -include l4lib/macros.h')
|
||||
|
||||
objs = SConscript('SConscript', exports = { 'env' : env },
|
||||
duplicate=0, build_dir = builddir)
|
||||
|
||||
Depends(objs, join(PROJROOT, CONFIG_H))
|
||||
|
||||
prog = env.Program(join(builddir, 'main.elf'), objs)
|
||||
Depends(prog, linker_lds)
|
||||
@@ -8,7 +8,7 @@ process. It is meant to be the most simple to get on with, therefore if
|
||||
you feel any complications, please reach us on our l4dev.org mailing list
|
||||
on http://lists.l4dev.org/mailman/listinfo/codezero-devel
|
||||
|
||||
You have created a new container called `test_suite0'.
|
||||
You have created a new container called `ipc_demo0'.
|
||||
|
||||
The parameters you have supplied are described in the ".container" file
|
||||
placed at the top-level directory. Note, that this is only an informative
|
||||
@@ -6,8 +6,7 @@
|
||||
|
||||
#include <l4lib/init.h>
|
||||
#include <l4lib/utcb.h>
|
||||
#include <l4lib/lib/thread.h>
|
||||
#include <l4lib/lib/cap.h>
|
||||
|
||||
|
||||
extern void main(void);
|
||||
|
||||
@@ -16,12 +15,6 @@ void __container_init(void)
|
||||
/* Generic L4 initialisation */
|
||||
__l4_init();
|
||||
|
||||
/* Thread library initialisation */
|
||||
__l4_threadlib_init();
|
||||
|
||||
/* Capability library initialization */
|
||||
__l4_capability_init();
|
||||
|
||||
/* Entry to main */
|
||||
main();
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
#define __CONTAINER_H__
|
||||
|
||||
|
||||
#define __CONTAINER_NAME__ "test_suite0"
|
||||
#define __CONTAINER_NAME__ "ipc_demo0"
|
||||
#define __CONTAINER_ID__ 0
|
||||
#define __CONTAINER__ "cont0"
|
||||
|
||||
55
conts/baremetal/ipc_demo/include/linker.lds
Normal file
55
conts/baremetal/ipc_demo/include/linker.lds
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Example working linker script for this container.
|
||||
*
|
||||
* Copyright (C) 2009 B Labs Ltd.
|
||||
*/
|
||||
|
||||
vma_start = 0xa0000000;
|
||||
lma_start = 0x100000;
|
||||
offset = vma_start - lma_start;
|
||||
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(_start)
|
||||
|
||||
PHDRS
|
||||
{
|
||||
rx PT_LOAD;
|
||||
rw PT_LOAD;
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = vma_start;
|
||||
|
||||
/* Put all RX, RO sections here */
|
||||
.text : AT (ADDR(.text) - offset)
|
||||
{
|
||||
*(.text.head) *(.text)
|
||||
} : rx = 0x90909090
|
||||
|
||||
.rodata : AT (ADDR(.rodata) - offset)
|
||||
{
|
||||
*(.rodata)
|
||||
} : rx = 0x90909090
|
||||
|
||||
.rodata1 : AT (ADDR(.rodata1) - offset)
|
||||
{
|
||||
*(.rodata1)
|
||||
} : rx = 0x90909090
|
||||
|
||||
. = ALIGN(4K);
|
||||
|
||||
/* Put all RW sections here */
|
||||
.data : AT (ADDR(.data) - offset)
|
||||
{
|
||||
*(.data)
|
||||
} : rw
|
||||
.bss : AT (ADDR(.bss) - offset)
|
||||
{
|
||||
*(.bss)
|
||||
. += 0x1000;
|
||||
. = ALIGN(8);
|
||||
__stack = .;
|
||||
} : rw
|
||||
__end = .;
|
||||
}
|
||||
13
conts/baremetal/ipc_demo/include/tests.h
Normal file
13
conts/baremetal/ipc_demo/include/tests.h
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
#ifndef __TESTS_H__
|
||||
#define __TESTS_H__
|
||||
|
||||
//#define DEBUG
|
||||
|
||||
#ifdef DEBUG
|
||||
#define dgb_printf printf
|
||||
#else
|
||||
#define dbg_printf(fmt,...)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
29
conts/baremetal/ipc_demo/main.c
Normal file
29
conts/baremetal/ipc_demo/main.c
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Main function for this container
|
||||
*/
|
||||
|
||||
#include <l4lib/macros.h>
|
||||
#include L4LIB_INC_ARCH(syslib.h)
|
||||
#include L4LIB_INC_ARCH(syscalls.h)
|
||||
#include <l4/api/space.h>
|
||||
#include <l4lib/lib/thread.h>
|
||||
#include <l4lib/lib/cap.h>
|
||||
|
||||
#include <memory.h>
|
||||
|
||||
extern int ipc_demo(void);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
|
||||
__l4_threadlib_init();
|
||||
|
||||
__l4_capability_init();
|
||||
|
||||
page_pool_init();
|
||||
|
||||
ipc_demo();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
547
conts/baremetal/ipc_demo/src/ipc.c
Normal file
547
conts/baremetal/ipc_demo/src/ipc.c
Normal file
@@ -0,0 +1,547 @@
|
||||
/*
|
||||
* Test ipc system call.
|
||||
*
|
||||
* Copyright (C) 2010 B Labs Ltd.
|
||||
*
|
||||
* Author: Bahadir Balban
|
||||
*/
|
||||
#include <l4lib/macros.h>
|
||||
#include L4LIB_INC_ARCH(syslib.h)
|
||||
#include L4LIB_INC_ARCH(syscalls.h)
|
||||
#include <l4lib/lib/thread.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include <tests.h>
|
||||
//#include <macros.h>
|
||||
#include <fault.h>
|
||||
#include <memory.h>
|
||||
|
||||
struct ipc_ext_data {
|
||||
void *virtual; /* Virtual address to start ipc from */
|
||||
l4id_t partner; /* Partner to do extended ipc */
|
||||
};
|
||||
|
||||
int ipc_extended_sender(void *arg)
|
||||
{
|
||||
struct ipc_ext_data *data = arg;
|
||||
int err;
|
||||
|
||||
if ((err = l4_send_extended(data->partner, 0,
|
||||
SZ_2K, data->virtual)) < 0) {
|
||||
printf("%s: Extended send failed. err=%d\n",
|
||||
__FUNCTION__, err);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ipc_extended_receiver(void *arg)
|
||||
{
|
||||
struct ipc_ext_data *data = arg;
|
||||
int err;
|
||||
|
||||
if ((err = l4_receive_extended(data->partner, SZ_2K,
|
||||
data->virtual)) < 0) {
|
||||
printf("%s: Extended receive failed. err=%d\n",
|
||||
__FUNCTION__, err);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test the data received
|
||||
*/
|
||||
for (int i = 0; i < SZ_2K; i++) {
|
||||
if (((char *)data->virtual)[i] != 'A' + i)
|
||||
printf("%s: Extended receive buffer has unexpected "
|
||||
"data: Start %p, Offset: %d, "
|
||||
"Data=%d, expected=%d\n", __FUNCTION__,
|
||||
data->virtual, i, ((char *)data->virtual)[i],
|
||||
'A' + i);
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ipc_ext_handle_pfault(struct ipc_ext_data *ipc_data,
|
||||
void **virt, void **phys)
|
||||
{
|
||||
u32 mr[MR_UNUSED_TOTAL];
|
||||
struct fault_data fault;
|
||||
int err;
|
||||
|
||||
/* Read mrs not used by syslib */
|
||||
for (int i = 0; i < MR_UNUSED_TOTAL; i++)
|
||||
mr[i] = read_mr(MR_UNUSED_START + i);
|
||||
|
||||
fault.kdata = (fault_kdata_t *)&mr[0];
|
||||
fault.sender = l4_get_sender();
|
||||
|
||||
/* Convert from arch-specific to generic fault data */
|
||||
set_generic_fault_params(&fault);
|
||||
|
||||
/*
|
||||
* Handle the fault using a basic logic - if a virtual index
|
||||
* is faulted, map the corresponding page at same physical index.
|
||||
*/
|
||||
if (page_align(fault.address) == (unsigned long)virt[0]) {
|
||||
if ((err = l4_map(phys[0], virt[0], 1,
|
||||
MAP_USR_RW, fault.sender)) < 0) {
|
||||
printf("%s: Error: l4_map failed. "
|
||||
"phys=%p, virt=%p\n", __FUNCTION__,
|
||||
phys[0], virt[0]);
|
||||
return err;
|
||||
}
|
||||
} else if (page_align(fault.address) == (unsigned long)virt[1]) {
|
||||
if ((err = l4_map(phys[1], virt[1], 1,
|
||||
MAP_USR_RW, fault.sender)) < 0) {
|
||||
printf("%s: Error: l4_map failed. "
|
||||
"phys=%p, virt=%p\n", __FUNCTION__,
|
||||
phys[1], virt[1]);
|
||||
return err;
|
||||
}
|
||||
} else if (page_align(fault.address) == (unsigned long)virt[2]) {
|
||||
if ((err = l4_map(phys[2], virt[2], 1,
|
||||
MAP_USR_RW, fault.sender)) < 0) {
|
||||
printf("%s: Error: l4_map failed. "
|
||||
"phys=%p, virt=%p\n", __FUNCTION__,
|
||||
phys[2], virt[2]);
|
||||
return err;
|
||||
}
|
||||
} else if (page_align(fault.address) == (unsigned long)virt[3]) {
|
||||
if ((err = l4_map(phys[3], virt[3], 1,
|
||||
MAP_USR_RW, fault.sender)) < 0) {
|
||||
printf("%s: Error: l4_map failed. "
|
||||
"phys=%p, virt=%p\n", __FUNCTION__,
|
||||
phys[3], virt[3]);
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
printf("%s: Error, page fault occured on an unexpected "
|
||||
"address. adress=0x%x\n", __FUNCTION__,
|
||||
fault.address);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Reply back to fault thread and return */
|
||||
return l4_ipc_return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create two threads who will do page-faulting ipc to each other.
|
||||
* Their parent waits and handles the page faults.
|
||||
*
|
||||
* This test allocates 4 virtual page and 4 physical page addresses.
|
||||
* It fills a total of 2KB of payload starting from the 3rd quarter
|
||||
* of the first page and until the 2nd quarter of the 2nd page to
|
||||
* be sent by the sender thread.
|
||||
*
|
||||
* The payload is copied and the pages deliberately unmapped so that
|
||||
* the sender thread will page fault during the send operation.
|
||||
*
|
||||
* The receive pages are also set up same as above, so the receiving
|
||||
* thread also faults during the receive.
|
||||
*
|
||||
* The main thread starts both ipc threads, and starts waiting on
|
||||
* page faults. It handles the faults and the test succeeds if the
|
||||
* data is transfered safely to receiving end, despite all faults.
|
||||
*/
|
||||
int test_ipc_extended(void)
|
||||
{
|
||||
struct task_ids self_ids;
|
||||
struct ipc_ext_data ipc_data[2];
|
||||
struct l4_thread *thread[2];
|
||||
void *virt[4], *phys[4];
|
||||
int err, tag;
|
||||
|
||||
l4_getid(&self_ids);
|
||||
|
||||
/* Get 4 physical pages */
|
||||
for (int i = 0; i < 4; i++)
|
||||
phys[i] = physical_page_new(1);
|
||||
|
||||
/* Get 2 pairs of virtual pages */
|
||||
virt[0] = virtual_page_new(2);
|
||||
virt[1] = virt[0] + PAGE_SIZE;
|
||||
virt[2] = virtual_page_new(2);
|
||||
virt[3] = virt[2] + PAGE_SIZE;
|
||||
|
||||
/* Map sender pages to self */
|
||||
if ((err = l4_map(phys[0], virt[0], 1,
|
||||
MAP_USR_RW, self_ids.tid)) < 0) {
|
||||
printf("Error: Mapping Sender pages failed. phys: 0x%p,"
|
||||
" virt: 0x%p, tid=%d, err=%d\n", phys[0], virt[0],
|
||||
self_ids.tid, err);
|
||||
return err;
|
||||
}
|
||||
if ((err = l4_map(phys[1], virt[1], 1,
|
||||
MAP_USR_RW, self_ids.tid)) < 0) {
|
||||
printf("Error: Mapping Sender pages failed. phys: 0x%p,"
|
||||
" virt: 0x%p, tid=%d, err=%d\n", phys[0], virt[0],
|
||||
self_ids.tid, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill them with values to be sent
|
||||
* Filling in 3rd KB of first page to 2nd KB of second page
|
||||
*/
|
||||
for (int i = 0; i < SZ_2K; i++)
|
||||
((char *)virt[0] + SZ_1K * 3)[i] = 'A' + i;
|
||||
|
||||
/* Unmap the pages */
|
||||
l4_unmap(virt[0], 2, self_ids.tid);
|
||||
|
||||
/* Create ipc threads but don't start. */
|
||||
if ((err = thread_create(ipc_extended_sender,
|
||||
&ipc_data[0],
|
||||
TC_SHARE_SPACE | TC_NOSTART,
|
||||
&thread[0])) < 0) {
|
||||
dbg_printf("Thread create failed. "
|
||||
"err=%d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
dbg_printf("Thread created successfully. "
|
||||
"tid=%d\n", thread[0]->ids.tid);
|
||||
|
||||
if ((err = thread_create(ipc_extended_receiver,
|
||||
&ipc_data[1],
|
||||
TC_SHARE_SPACE | TC_NOSTART,
|
||||
&thread[1])) < 0) {
|
||||
dbg_printf("Thread create failed. "
|
||||
"err=%d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
dbg_printf("Thread created successfully. "
|
||||
"tid=%d\n", thread[1]->ids.tid);
|
||||
|
||||
/*
|
||||
* Set up arguments to sender,
|
||||
* Send offset at 3rd quarter of first page.
|
||||
*/
|
||||
ipc_data[0].virtual = virt[0] + SZ_1K * 3;
|
||||
ipc_data[0].partner = thread[1]->ids.tid;
|
||||
|
||||
/*
|
||||
* Set up arguments to receiver
|
||||
* Receive offset at 3rd quarter of first page.
|
||||
*/
|
||||
ipc_data[1].virtual = virt[1] + SZ_1K * 3;
|
||||
ipc_data[1].partner = thread[0]->ids.tid;
|
||||
|
||||
/* Start the threads */
|
||||
l4_thread_control(THREAD_RUN, &thread[0]->ids);
|
||||
l4_thread_control(THREAD_RUN, &thread[1]->ids);
|
||||
|
||||
/* Expecting 4 faults on 4 pages */
|
||||
for (int i = 0; i < 4; i++) {
|
||||
/* Wait on page fault */
|
||||
if ((err = l4_receive(L4_ANYTHREAD)) < 0) {
|
||||
printf("Error: l4_receive() for page"
|
||||
" fault has failed. err=%d\n",
|
||||
err);
|
||||
}
|
||||
if ((tag = l4_get_tag()) != L4_IPC_TAG_PFAULT) {
|
||||
printf("Error: Parent thread received "
|
||||
"non-page fault ipc tag. tag=%d\n",
|
||||
tag);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Handle fault */
|
||||
if ((err = ipc_ext_handle_pfault(ipc_data, virt, phys)) < 0) {
|
||||
printf("Error: An error occured during ipc "
|
||||
"page fault handling. err=%d\n", err);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for the ipc threads */
|
||||
for (int i = 0; i < 2; i ++)
|
||||
if ((err = thread_wait(thread[i])) < 0) {
|
||||
dbg_printf("THREAD_WAIT failed. "
|
||||
"err=%d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Unmap and release pages */
|
||||
for (int i = 0; i < 4; i++) {
|
||||
l4_unmap(virt[i], 1, self_ids.tid);
|
||||
virtual_page_free(virt[i], 1);
|
||||
physical_page_free(phys[i], 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ipc_full_thread(void *arg)
|
||||
{
|
||||
l4id_t parent = *((l4id_t *)arg);
|
||||
int err;
|
||||
|
||||
/* Do two full send/receives */
|
||||
for (int i = 0; i < 2; i++) {
|
||||
/* Full receive, return positive if error */
|
||||
if ((err = l4_receive_full(parent)) < 0) {
|
||||
dbg_printf("Full receive failed on new "
|
||||
"thread. err=%d", err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Test full utcb received values */
|
||||
for (int i = MR_UNUSED_START; i < MR_TOTAL + MR_REST; i++) {
|
||||
if (read_mr(i) != i) {
|
||||
dbg_printf("IPC full receive on new thread: "
|
||||
"Unexpected message register "
|
||||
"values. MR%d = %d, should be %d\n",
|
||||
i, read_mr(i), i);
|
||||
return 1; /* Exit positive without reply */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset all message registers
|
||||
*/
|
||||
for (int i = MR_UNUSED_START; i < MR_TOTAL + MR_REST; i++)
|
||||
write_mr(i, 0);
|
||||
|
||||
/* Send full return reply */
|
||||
l4_send_full(parent, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ipc_short_thread(void *arg)
|
||||
{
|
||||
l4id_t parent = *((l4id_t *)arg);
|
||||
int err;
|
||||
|
||||
/* Short receive, return positive if error */
|
||||
if ((err = l4_receive(parent)) < 0) {
|
||||
dbg_printf("Short receive failed on new "
|
||||
"thread. err=%d", err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Test received registers */
|
||||
for (int i = MR_UNUSED_START; i < MR_TOTAL; i++) {
|
||||
if (read_mr(i) != i) {
|
||||
dbg_printf("IPC Receive on new thread: "
|
||||
"Unexpected message register "
|
||||
"values.\n"
|
||||
"read = %d, expected = %d\n",
|
||||
read_mr(i), i);
|
||||
l4_print_mrs();
|
||||
return 1; /* Exit positive without reply */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset all message registers
|
||||
*/
|
||||
for (int i = MR_UNUSED_START; i < MR_TOTAL; i++)
|
||||
write_mr(i, 0);
|
||||
|
||||
/*
|
||||
* Send return reply and exit
|
||||
*/
|
||||
return l4_send(parent, 0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create a thread and do a full ipc to it
|
||||
*/
|
||||
int test_ipc_full(void)
|
||||
{
|
||||
struct task_ids self_ids;
|
||||
struct l4_thread *thread;
|
||||
int err;
|
||||
|
||||
l4_getid(&self_ids);
|
||||
|
||||
/*
|
||||
* Create a thread in the same space
|
||||
*/
|
||||
if ((err = thread_create(ipc_full_thread,
|
||||
&self_ids.tid,
|
||||
TC_SHARE_SPACE,
|
||||
&thread)) < 0) {
|
||||
dbg_printf("Thread create failed. "
|
||||
"err=%d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
dbg_printf("Thread created successfully. "
|
||||
"tid=%d\n", thread->ids.tid);
|
||||
|
||||
/*
|
||||
* Try one short and one full send/recv
|
||||
* to test full send/recv occurs on both cases
|
||||
*/
|
||||
|
||||
/*
|
||||
* Write data to full utcb registers
|
||||
*/
|
||||
for (int i = MR_UNUSED_START; i < MR_TOTAL + MR_REST; i++)
|
||||
write_mr(i, i);
|
||||
|
||||
/*
|
||||
* First, do a full ipc send/recv
|
||||
*/
|
||||
if ((err = l4_sendrecv_full(thread->ids.tid,
|
||||
thread->ids.tid,
|
||||
0)) < 0) {
|
||||
dbg_printf("Full IPC send/recv failed. "
|
||||
"err=%d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that payload registers are modified to 0
|
||||
*/
|
||||
dbg_printf("%s: After send/recv:\n", __FUNCTION__);
|
||||
for (int i = MR_UNUSED_START; i < MR_TOTAL + MR_REST; i++) {
|
||||
if (read_mr(i) != 0) {
|
||||
dbg_printf("Full IPC send/recv: "
|
||||
"Received payload is not "
|
||||
"as expected.\n "
|
||||
"MR%d = %d, should be %d\n",
|
||||
i, read_mr(i), 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Write data to full utcb registers
|
||||
*/
|
||||
for (int i = MR_UNUSED_START; i < MR_TOTAL + MR_REST; i++)
|
||||
write_mr(i, i);
|
||||
|
||||
/*
|
||||
* Try a short ipc send/recv. This should still result
|
||||
* in full ipc since the other side is doing full send/recv.
|
||||
*/
|
||||
if ((err = l4_sendrecv(thread->ids.tid,
|
||||
thread->ids.tid,
|
||||
0)) < 0) {
|
||||
dbg_printf("Full IPC send/recv failed. "
|
||||
"err=%d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that payload registers are modified to 0
|
||||
*/
|
||||
// dbg_printf("%s: After send/recv:\n", __FUNCTION__);
|
||||
for (int i = MR_UNUSED_START; i < MR_TOTAL + MR_REST; i++) {
|
||||
// dbg_printf("MR%d: %d\n", i, read_mr(i));
|
||||
if (read_mr(i) != 0) {
|
||||
dbg_printf("Full IPC send/recv: "
|
||||
"Received payload is not "
|
||||
"as expected.\n "
|
||||
"MR%d = %d, should be %d\n",
|
||||
i, read_mr(i), 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for the ipc thread to die */
|
||||
if ((err = thread_wait(thread)) < 0) {
|
||||
dbg_printf("THREAD_WAIT failed. "
|
||||
"err=%d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
dbg_printf("Full IPC send/recv successful.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a thread and do a short ipc to it
|
||||
*/
|
||||
int test_ipc_short(void)
|
||||
{
|
||||
struct task_ids self_ids;
|
||||
struct l4_thread *thread;
|
||||
int err;
|
||||
|
||||
l4_getid(&self_ids);
|
||||
|
||||
/*
|
||||
* Create a thread in the same space
|
||||
*/
|
||||
if ((err = thread_create(ipc_short_thread,
|
||||
&self_ids.tid,
|
||||
TC_SHARE_SPACE,
|
||||
&thread)) < 0) {
|
||||
dbg_printf("Thread create failed. "
|
||||
"err=%d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
dbg_printf("Thread created successfully. "
|
||||
"tid=%d\n", thread->ids.tid);
|
||||
|
||||
/*
|
||||
* Write data to short ipc registers
|
||||
*/
|
||||
for (int i = MR_UNUSED_START; i < MR_TOTAL; i++)
|
||||
write_mr(i, i);
|
||||
|
||||
/*
|
||||
* Do short ipc send/recv and check data is reset
|
||||
*/
|
||||
if ((err = l4_sendrecv(thread->ids.tid,
|
||||
thread->ids.tid,
|
||||
0)) < 0) {
|
||||
dbg_printf("Short IPC send/recv failed. "
|
||||
"err=%d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that payload registers are reset
|
||||
*/
|
||||
for (int i = MR_UNUSED_START; i < MR_TOTAL; i++) {
|
||||
if (read_mr(i) != 0) {
|
||||
dbg_printf("Short IPC send/recv: "
|
||||
"Received payload is incorrect."
|
||||
"read = %d, expected=%d\n",
|
||||
read_mr(i), 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for the ipc thread */
|
||||
if ((err = thread_wait(thread)) < 0) {
|
||||
dbg_printf("THREAD_WAIT failed. "
|
||||
"err=%d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
dbg_printf("Short IPC send/recv successful.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ipc_demo(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
if ((err = test_ipc_extended()) < 0)
|
||||
goto out_err;
|
||||
|
||||
if ((err = test_ipc_short()) < 0)
|
||||
goto out_err;
|
||||
|
||||
if ((err = test_ipc_full()) < 0)
|
||||
goto out_err;
|
||||
|
||||
printf("IPC: -- PASSED --\n");
|
||||
return 0;
|
||||
|
||||
out_err:
|
||||
printf("IPC: -- FAILED --\n");
|
||||
return err;
|
||||
|
||||
}
|
||||
|
||||
74
conts/baremetal/ipc_demo/src/mm.c
Normal file
74
conts/baremetal/ipc_demo/src/mm.c
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* ARMv7 specific functions
|
||||
*
|
||||
* Copyright (C) 2008 - 2010 B Labs Ltd.
|
||||
*/
|
||||
#include <l4lib/exregs.h>
|
||||
#include <fault.h>
|
||||
#include INC_SUBARCH(mm.h)
|
||||
#include INC_SUBARCH(exception.h)
|
||||
|
||||
/* Get simplified access permissions */
|
||||
int pte_get_access_simple(pte_t pte)
|
||||
{
|
||||
/* Place AP[2] and AP[1] in [1:0] positions and return */
|
||||
return (((pte >> PTE_AP2_BIT) & 1) << 1)
|
||||
| ((pte >> PTE_AP1_BIT) & 1);
|
||||
}
|
||||
|
||||
int is_translation_fault(u32 fsr)
|
||||
{
|
||||
return (fsr & FSR_FS_MASK) == ABORT_TRANSLATION_PAGE;
|
||||
}
|
||||
|
||||
unsigned int vm_prot_flags(pte_t pte, u32 fsr)
|
||||
{
|
||||
unsigned int pte_prot_flags = 0;
|
||||
|
||||
/* Translation fault means no permissions */
|
||||
if (is_translation_fault(fsr))
|
||||
return VM_NONE;
|
||||
|
||||
/* Check simplified permission bits */
|
||||
switch (pte_get_access_simple(pte)) {
|
||||
case AP_SIMPLE_USER_RW_KERN_RW:
|
||||
pte_prot_flags |= VM_WRITE;
|
||||
case AP_SIMPLE_USER_RO_KERN_RO:
|
||||
pte_prot_flags |= VM_READ;
|
||||
|
||||
/* Also, check exec never bit */
|
||||
if (!(pte & (1 << PTE_XN_BIT)))
|
||||
pte_prot_flags |= VM_EXEC;
|
||||
break;
|
||||
case AP_SIMPLE_USER_NONE_KERN_RW:
|
||||
case AP_SIMPLE_USER_NONE_KERN_RO:
|
||||
default:
|
||||
pte_prot_flags = VM_NONE;
|
||||
break;
|
||||
}
|
||||
|
||||
return pte_prot_flags;
|
||||
}
|
||||
|
||||
void set_generic_fault_params(struct fault_data *fault)
|
||||
{
|
||||
fault->pte_flags = vm_prot_flags(fault->kdata->pte, fault->kdata->fsr);
|
||||
fault->reason = 0;
|
||||
|
||||
/*
|
||||
* Prefetch fault denotes exec fault.
|
||||
*/
|
||||
if (is_prefetch_abort(fault->kdata->fsr)) {
|
||||
fault->reason |= VM_EXEC;
|
||||
fault->address = fault->kdata->faulty_pc;
|
||||
} else {
|
||||
fault->address = fault->kdata->far;
|
||||
|
||||
/* Write-not-read bit determines fault */
|
||||
if (fault->kdata->fsr & (1 << DFSR_WNR_BIT))
|
||||
fault->reason |= VM_WRITE;
|
||||
else
|
||||
fault->reason |= VM_READ;
|
||||
}
|
||||
}
|
||||
|
||||
12
conts/baremetal/kmi_service/SConscript
Normal file
12
conts/baremetal/kmi_service/SConscript
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
# Inherit global environment
|
||||
Import('env')
|
||||
|
||||
# The set of source files associated with this SConscript file.
|
||||
src_local = Glob('*.[cS]')
|
||||
src_local += Glob('src/*.[cS]')
|
||||
src_local += Glob('src/arch/*.[cS]')
|
||||
|
||||
obj = env.Object(src_local)
|
||||
Return('obj')
|
||||
|
||||
@@ -7,64 +7,51 @@
|
||||
import os, shelve, sys
|
||||
from os.path import *
|
||||
|
||||
PROJRELROOT = '../..'
|
||||
CONTS_XXX = '../..'
|
||||
BAREMETAL_CONTS_XXX = '../../..'
|
||||
sys.path.append(CONTS_XXX)
|
||||
sys.path.append(BAREMETAL_CONTS_XXX)
|
||||
|
||||
sys.path.append(PROJRELROOT)
|
||||
|
||||
from config.projpaths import *
|
||||
from config.configuration import *
|
||||
from configure import *
|
||||
from scripts.config.projpaths import *
|
||||
from scripts.config.configuration import *
|
||||
from scripts.conts.containers import *
|
||||
from scripts.config.config_invoke import *
|
||||
|
||||
config = configuration_retrieve()
|
||||
arch = config.arch
|
||||
platform = config.platform
|
||||
gcc_arch_flag = config.gcc_arch_flag
|
||||
|
||||
# Wrapper library for system calls
|
||||
LIBL4_RELDIR = 'conts/libl4'
|
||||
KERNEL_INCLUDE = join(PROJROOT, 'include')
|
||||
LIBL4_DIR = join(PROJROOT, LIBL4_RELDIR)
|
||||
LIBL4_INCLUDE = join(LIBL4_DIR, 'include')
|
||||
LIBL4_LIBPATH = join(BUILDDIR, LIBL4_RELDIR)
|
||||
cid = int(ARGUMENTS.get('cid', 0))
|
||||
cont = find_container_from_cid(cid)
|
||||
|
||||
# Some user-space libraries
|
||||
LIBC_RELDIR = 'conts/libc'
|
||||
LIBC_DIR = join(PROJROOT, LIBC_RELDIR)
|
||||
LIBC_LIBPATH = join(BUILDDIR, LIBC_RELDIR)
|
||||
LIBC_INCLUDE = [join(LIBC_DIR, 'include'), \
|
||||
join(LIBC_DIR, 'include/arch' + '/' + arch)]
|
||||
builddir = join(join(BUILDDIR, 'cont') + str(cid), cont.name)
|
||||
|
||||
LIBDEV_RELDIR = 'conts/libdev'
|
||||
LIBDEV_DIR = join(PROJROOT, LIBDEV_RELDIR)
|
||||
LIBDEV_LIBPATH = join(join(BUILDDIR, LIBDEV_RELDIR), 'sys-userspace')
|
||||
LIBDEV_INCLUDE = join(LIBDEV_DIR, 'include')
|
||||
|
||||
LIBMEM_RELDIR = 'conts/libmem'
|
||||
LIBMEM_DIR = join(PROJROOT, LIBMEM_RELDIR)
|
||||
LIBMEM_LIBPATH = join(BUILDDIR, LIBMEM_RELDIR)
|
||||
LIBMEM_INCLUDE = LIBMEM_DIR
|
||||
# linker.lds is generated either in conts/xxx or build/contx/include
|
||||
if cont.duplicate == 0:
|
||||
linker_lds = join(builddir, 'include/linker.lds')
|
||||
else:
|
||||
linker_lds = 'include/linker.lds'
|
||||
|
||||
env = Environment(CC = config.toolchain_userspace + 'gcc',
|
||||
# We don't use -nostdinc because sometimes we need standard headers,
|
||||
# such as stdarg.h e.g. for variable args, as in printk().
|
||||
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', \
|
||||
'-Werror', '-march=' + gcc_arch_flag], \
|
||||
LINKFLAGS = ['-nostdlib', '-T' + "include/linker.lds", "-u_start"],\
|
||||
ASFLAGS = ['-D__ASSEMBLY__'], \
|
||||
PROGSUFFIX = '.elf', # The suffix to use for final executable
|
||||
ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path
|
||||
LIBS = ['gcc', 'libl4', 'c-userspace', 'libdev-userspace', \
|
||||
'libmm', 'libmc', 'libmalloc', 'gcc', 'c-userspace'],
|
||||
# libgcc.a - This is required for division routines.
|
||||
CPPPATH = ["#include", KERNEL_INCLUDE, LIBL4_INCLUDE, LIBDEV_INCLUDE, \
|
||||
LIBC_INCLUDE, LIBMEM_INCLUDE],
|
||||
LIBPATH = [LIBL4_LIBPATH, LIBDEV_LIBPATH, LIBC_LIBPATH, LIBMEM_LIBPATH],
|
||||
CPPFLAGS = '-include l4/config.h -include l4/macros.h -include l4/types.h')
|
||||
# We don't use -nostdinc because sometimes we need standard headers,
|
||||
# such as stdarg.h e.g. for variable args, as in printk().
|
||||
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall',
|
||||
'-Werror', '-march=' + gcc_arch_flag],
|
||||
LINKFLAGS = ['-nostdlib', '-T' + linker_lds, '-u_start'],
|
||||
ASFLAGS = ['-D__ASSEMBLY__'],
|
||||
PROGSUFFIX = '.elf', # The suffix to use for final executable
|
||||
ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path
|
||||
LIBS = ['gcc', 'libl4', 'c-userspace', 'libdev-userspace',
|
||||
'libmem', 'gcc', 'c-userspace'],
|
||||
# libgcc.a - This is required for division routines.
|
||||
CPPPATH = ["#include", KERNEL_HEADERS, LIBL4_INCLUDE, LIBDEV_INCLUDE,
|
||||
LIBC_INCLUDE, LIBMEM_INCLUDE, join(builddir, 'include')],
|
||||
LIBPATH = [LIBL4_LIBPATH, LIBDEV_USER_LIBPATH, LIBC_LIBPATH, LIBMEM_LIBPATH],
|
||||
CPPFLAGS = '-include l4/config.h -include l4/macros.h -include l4/types.h')
|
||||
|
||||
src = Glob('*.[cS]')
|
||||
src += Glob('src/*.[cS]')
|
||||
src += Glob('src/arch/*.[cS]')
|
||||
objs = SConscript('SConscript', exports = { 'env' : env },
|
||||
duplicate=0, build_dir = builddir)
|
||||
|
||||
objs = env.Object(src)
|
||||
prog = env.Program('main.elf', objs)
|
||||
Depends(prog, 'include/linker.lds')
|
||||
Depends(objs, join(PROJROOT, CONFIG_H))
|
||||
|
||||
prog = env.Program(join(builddir, 'main.elf'), objs)
|
||||
Depends(prog, linker_lds)
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <l4lib/init.h>
|
||||
#include <l4lib/utcb.h>
|
||||
#include <l4lib/lib/thread.h>
|
||||
#include <l4lib/lib/cap.h>
|
||||
|
||||
void main(void);
|
||||
|
||||
@@ -18,6 +19,8 @@ void __container_init(void)
|
||||
/* Thread library initialisation */
|
||||
__l4_threadlib_init();
|
||||
|
||||
__l4_capability_init();
|
||||
|
||||
/* Entry to main */
|
||||
main();
|
||||
}
|
||||
|
||||
@@ -4,15 +4,16 @@
|
||||
#ifndef __KEYBOARD_H__
|
||||
#define __KEYBOARD_H__
|
||||
|
||||
#include <libdev/kmi.h>
|
||||
#include <dev/kmi.h>
|
||||
|
||||
/*
|
||||
* Keyboard structure
|
||||
*/
|
||||
struct keyboard {
|
||||
unsigned long base; /* Virtual base address */
|
||||
struct capability cap; /* Capability describing keyboard */
|
||||
struct keyboard_state state;
|
||||
unsigned long phys_base; /* Physical address of device */
|
||||
int irq_no; /* IRQ number of device */
|
||||
};
|
||||
|
||||
#endif /* __KEYBOARD_H__ */
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
*/
|
||||
struct mouse {
|
||||
unsigned long base; /* Virtual base address */
|
||||
struct capability cap; /* Capability describing keyboard */
|
||||
unsigned long phys_base; /* Physical address of device */
|
||||
int irq_no; /* IRQ number of device */
|
||||
};
|
||||
|
||||
#endif /* __MOUSE_H__ */
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
*/
|
||||
#include <l4lib/lib/addr.h>
|
||||
#include <l4lib/lib/thread.h>
|
||||
#include <l4lib/lib/cap.h>
|
||||
#include <l4lib/irq.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include <l4/api/errno.h>
|
||||
@@ -10,47 +11,22 @@
|
||||
#include <l4/api/capability.h>
|
||||
#include <l4/generic/cap-types.h>
|
||||
#include <l4/api/space.h>
|
||||
#include <malloc/malloc.h>
|
||||
#include <mem/malloc.h>
|
||||
#include <container.h>
|
||||
#include <linker.h>
|
||||
#include <keyboard.h>
|
||||
#include <mouse.h>
|
||||
#include <dev/platform.h>
|
||||
|
||||
#define KEYBOARDS_TOTAL 1
|
||||
#define MOUSE_TOTAL 1
|
||||
|
||||
static struct capability caparray[32];
|
||||
static struct capability *caparray;
|
||||
static int total_caps = 0;
|
||||
|
||||
struct keyboard kbd[KEYBOARDS_TOTAL];
|
||||
struct mouse mouse[MOUSE_TOTAL];
|
||||
|
||||
int cap_read_all()
|
||||
{
|
||||
int ncaps;
|
||||
int err;
|
||||
|
||||
/* Read number of capabilities */
|
||||
if ((err = l4_capability_control(CAP_CONTROL_NCAPS,
|
||||
0, &ncaps)) < 0) {
|
||||
printf("l4_capability_control() reading # of"
|
||||
" capabilities failed.\n Could not "
|
||||
"complete CAP_CONTROL_NCAPS request.\n");
|
||||
BUG();
|
||||
}
|
||||
total_caps = ncaps;
|
||||
|
||||
/* Read all capabilities */
|
||||
if ((err = l4_capability_control(CAP_CONTROL_READ,
|
||||
0, caparray)) < 0) {
|
||||
printf("l4_capability_control() reading of "
|
||||
"capabilities failed.\n Could not "
|
||||
"complete CAP_CONTROL_READ_CAPS request.\n");
|
||||
BUG();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cap_share_all_with_space()
|
||||
{
|
||||
int err;
|
||||
@@ -68,47 +44,6 @@ int cap_share_all_with_space()
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Scans for up to KEYBOARDS_TOTAL
|
||||
* keyboard devices and MOUSE_TOTAL mouse
|
||||
* in capabilities.
|
||||
*/
|
||||
int kmi_probe_devices(void)
|
||||
{
|
||||
int keyboards = 0, nmouse = 0;
|
||||
|
||||
/* Scan for timer devices */
|
||||
for (int i = 0; i < total_caps; i++) {
|
||||
/* Match device type */
|
||||
if (cap_devtype(&caparray[i]) == CAP_DEVTYPE_KEYBOARD) {
|
||||
/* Copy to correct device index */
|
||||
memcpy(&kbd[cap_devnum(&caparray[i])].cap,
|
||||
&caparray[i], sizeof(kbd[0].cap));
|
||||
keyboards++;
|
||||
}
|
||||
if (cap_devtype(&caparray[i]) == CAP_DEVTYPE_MOUSE) {
|
||||
/* Copy to correct device index */
|
||||
memcpy(&mouse[cap_devnum(&caparray[i])].cap,
|
||||
&caparray[i], sizeof(mouse[0].cap));
|
||||
nmouse++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (keyboards != KEYBOARDS_TOTAL) {
|
||||
printf("%s: Error, not all keyboards could be found. "
|
||||
"keyboards=%d\n", __CONTAINER_NAME__, keyboards);
|
||||
return -ENODEV;
|
||||
}
|
||||
if (nmouse != MOUSE_TOTAL) {
|
||||
printf("%s: Error, not all mouse could be found. "
|
||||
"mouse=%d\n", __CONTAINER_NAME__, nmouse);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int keyboard_irq_handler(void *arg)
|
||||
{
|
||||
int err;
|
||||
@@ -125,7 +60,7 @@ int keyboard_irq_handler(void *arg)
|
||||
|
||||
/* Register self for timer irq, using notify slot 0 */
|
||||
if ((err = l4_irq_control(IRQ_CONTROL_REGISTER, slot,
|
||||
keyboard->cap.irq)) < 0) {
|
||||
keyboard->irq_no)) < 0) {
|
||||
printf("%s: FATAL: Keyboard irq could not be registered. "
|
||||
"err=%d\n", __FUNCTION__, err);
|
||||
BUG();
|
||||
@@ -136,7 +71,7 @@ int keyboard_irq_handler(void *arg)
|
||||
char c;
|
||||
|
||||
/* Block on irq */
|
||||
int data = l4_irq_wait(slot, keyboard->cap.irq);
|
||||
int data = l4_irq_wait(slot, keyboard->irq_no);
|
||||
while (data--)
|
||||
if ((c = kmi_keyboard_read(keyboard->base, &keyboard->state)))
|
||||
printf("%c", c);
|
||||
@@ -165,7 +100,7 @@ int mouse_irq_handler(void *arg)
|
||||
|
||||
/* Register self for timer irq, using notify slot 0 */
|
||||
if ((err = l4_irq_control(IRQ_CONTROL_REGISTER, slot,
|
||||
mouse->cap.irq)) < 0) {
|
||||
mouse->irq_no)) < 0) {
|
||||
printf("%s: FATAL: Mouse irq could not be registered. "
|
||||
"err=%d\n", __FUNCTION__, err);
|
||||
BUG();
|
||||
@@ -176,7 +111,7 @@ int mouse_irq_handler(void *arg)
|
||||
int c;
|
||||
|
||||
/* Block on irq */
|
||||
int data = l4_irq_wait(slot, mouse->cap.irq);
|
||||
int data = l4_irq_wait(slot, mouse->irq_no);
|
||||
while (data--)
|
||||
if ((c = kmi_data_read(mouse->base)))
|
||||
printf("mouse data: %d\n", c);
|
||||
@@ -195,6 +130,9 @@ int kmi_setup_devices(void)
|
||||
struct l4_thread *tptr = &thread;
|
||||
int err;
|
||||
|
||||
kbd[0].phys_base = PLATFORM_KEYBOARD0_BASE;
|
||||
kbd[0].irq_no = IRQ_KEYBOARD0;
|
||||
|
||||
for (int i = 0; i < KEYBOARDS_TOTAL; i++) {
|
||||
/* Get one page from address pool */
|
||||
kbd[i].base = (unsigned long)l4_new_virtual(1);
|
||||
@@ -203,13 +141,12 @@ int kmi_setup_devices(void)
|
||||
kbd[i].state.keyup = 0;
|
||||
|
||||
/* Map timer to a virtual address region */
|
||||
if (IS_ERR(l4_map((void *)__pfn_to_addr(kbd[i].cap.start),
|
||||
(void *)kbd[i].base, kbd[i].cap.size,
|
||||
if (IS_ERR(l4_map((void *)kbd[i].phys_base,
|
||||
(void *)kbd[i].base, 1,
|
||||
MAP_USR_IO, self_tid()))) {
|
||||
printf("%s: FATAL: Failed to map Keyboard device "
|
||||
"%d to a virtual address\n",
|
||||
__CONTAINER_NAME__,
|
||||
cap_devnum(&kbd[i].cap));
|
||||
"to a virtual address\n",
|
||||
__CONTAINER_NAME__);
|
||||
BUG();
|
||||
}
|
||||
|
||||
@@ -229,17 +166,20 @@ int kmi_setup_devices(void)
|
||||
}
|
||||
}
|
||||
|
||||
mouse[0].phys_base = PLATFORM_MOUSE0_BASE;
|
||||
mouse[0].irq_no = IRQ_MOUSE0;
|
||||
|
||||
for (int i = 0; i < MOUSE_TOTAL; i++) {
|
||||
/* Get one page from address pool */
|
||||
mouse[i].base = (unsigned long)l4_new_virtual(1);
|
||||
|
||||
/* Map timer to a virtual address region */
|
||||
if (IS_ERR(l4_map((void *)__pfn_to_addr(mouse[i].cap.start),
|
||||
(void *)mouse[i].base, mouse[i].cap.size,
|
||||
if (IS_ERR(l4_map((void *)mouse[i].phys_base,
|
||||
(void *)mouse[i].base, 1,
|
||||
MAP_USR_IO, self_tid()))) {
|
||||
printf("%s: FATAL: Failed to map Mouse device "
|
||||
"%d to a virtual address\n",
|
||||
__CONTAINER_NAME__, cap_devnum(&mouse[i].cap));
|
||||
"to a virtual address\n",
|
||||
__CONTAINER_NAME__);
|
||||
BUG();
|
||||
}
|
||||
|
||||
@@ -368,64 +308,20 @@ void handle_requests(void)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* UTCB-size aligned utcb.
|
||||
*
|
||||
* BIG WARNING NOTE: This declaration is legal if we are
|
||||
* running in a disjoint virtual address space, where the
|
||||
* utcb declaration lies in a unique virtual address in
|
||||
* the system.
|
||||
*/
|
||||
#define DECLARE_UTCB(name) \
|
||||
struct utcb name ALIGN(sizeof(struct utcb))
|
||||
|
||||
DECLARE_UTCB(utcb);
|
||||
|
||||
/* Set up own utcb for ipc */
|
||||
int l4_utcb_setup(void *utcb_address)
|
||||
{
|
||||
struct task_ids ids;
|
||||
struct exregs_data exregs;
|
||||
int err;
|
||||
|
||||
l4_getid(&ids);
|
||||
|
||||
/* Clear utcb */
|
||||
memset(utcb_address, 0, sizeof(struct utcb));
|
||||
|
||||
/* Setup exregs for utcb request */
|
||||
memset(&exregs, 0, sizeof(exregs));
|
||||
exregs_set_utcb(&exregs, (unsigned long)utcb_address);
|
||||
|
||||
if ((err = l4_exchange_registers(&exregs, ids.tid)) < 0)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* Read all capabilities */
|
||||
cap_read_all();
|
||||
caps_read_all();
|
||||
|
||||
total_caps = cap_get_count();
|
||||
caparray = cap_get_all();
|
||||
|
||||
/* Share all with space */
|
||||
cap_share_all_with_space();
|
||||
|
||||
/* Scan for keyboard devices in capabilities */
|
||||
kmi_probe_devices();
|
||||
|
||||
/* Initialize virtual address pool for timers */
|
||||
init_vaddr_pool();
|
||||
|
||||
/* Setup own static utcb */
|
||||
if ((err = l4_utcb_setup(&utcb)) < 0) {
|
||||
printf("FATAL: Could not set up own utcb. "
|
||||
"err=%d\n", err);
|
||||
BUG();
|
||||
}
|
||||
|
||||
/* Map and initialize keyboard devices */
|
||||
kmi_setup_devices();
|
||||
|
||||
|
||||
11
conts/baremetal/mutex_demo/SConscript
Normal file
11
conts/baremetal/mutex_demo/SConscript
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
# Inherit global environment
|
||||
Import('env')
|
||||
|
||||
# The set of source files associated with this SConscript file.
|
||||
src_local = Glob('*.[cS]')
|
||||
src_local += Glob('src/*.[cS]')
|
||||
|
||||
obj = env.Object(src_local)
|
||||
Return('obj')
|
||||
|
||||
57
conts/baremetal/mutex_demo/SConstruct
Normal file
57
conts/baremetal/mutex_demo/SConstruct
Normal file
@@ -0,0 +1,57 @@
|
||||
# -*- mode: python; coding: utf-8; -*-
|
||||
#
|
||||
# Codezero -- Virtualization microkernel for embedded systems.
|
||||
#
|
||||
# Copyright © 2009 B Labs Ltd
|
||||
#
|
||||
import os, shelve, sys
|
||||
from os.path import *
|
||||
|
||||
CONTS_XXX = '../..'
|
||||
BAREMETAL_CONTS_XXX = '../../..'
|
||||
sys.path.append(CONTS_XXX)
|
||||
sys.path.append(BAREMETAL_CONTS_XXX)
|
||||
|
||||
from scripts.config.projpaths import *
|
||||
from scripts.conts.containers import *
|
||||
from scripts.config.configuration import *
|
||||
|
||||
config = configuration_retrieve()
|
||||
gcc_arch_flag = config.gcc_arch_flag
|
||||
|
||||
cid = int(ARGUMENTS.get('cid', 0))
|
||||
cont = find_container_from_cid(cid)
|
||||
|
||||
builddir = join(join(BUILDDIR, 'cont') + str(cid), cont.name)
|
||||
|
||||
# linker.lds is generated either in conts/xxx or build/contx/include
|
||||
if cont.duplicate == 0:
|
||||
linker_lds = join(builddir, 'include/linker.lds')
|
||||
else:
|
||||
linker_lds = 'include/linker.lds'
|
||||
|
||||
env = Environment(CC = config.toolchain_userspace + 'gcc',
|
||||
# We don't use -nostdinc because sometimes we need standard headers,
|
||||
# such as stdarg.h e.g. for variable args, as in printk().
|
||||
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall',
|
||||
'-Werror', '-march=' + gcc_arch_flag],
|
||||
LINKFLAGS = ['-nostdlib', '-T' + linker_lds, '-u_start'],
|
||||
ASFLAGS = ['-D__ASSEMBLY__'],
|
||||
PROGSUFFIX = '.elf', # The suffix to use for final executable
|
||||
ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path
|
||||
LIBS = ['gcc', 'libl4', 'c-userspace', 'libdev-userspace',
|
||||
'libmem', 'gcc', 'c-userspace'],
|
||||
# libgcc.a - This is required for division routines.
|
||||
CPPPATH = ["#include", KERNEL_HEADERS, LIBL4_INCLUDE, LIBDEV_INCLUDE,
|
||||
LIBC_INCLUDE, LIBMEM_INCLUDE, join(builddir, 'include')],
|
||||
LIBPATH = [LIBL4_LIBPATH, LIBDEV_USER_LIBPATH, LIBC_LIBPATH, LIBMEM_LIBPATH],
|
||||
CPPFLAGS = '-include l4/config.h -include l4/macros.h \
|
||||
-include l4/types.h -include l4lib/macros.h')
|
||||
|
||||
objs = SConscript('SConscript', exports = { 'env' : env },
|
||||
duplicate=0, build_dir = builddir)
|
||||
|
||||
Depends(objs, join(PROJROOT, CONFIG_H))
|
||||
|
||||
prog = env.Program(join(builddir, 'main.elf'), objs)
|
||||
Depends(prog, linker_lds)
|
||||
21
conts/baremetal/mutex_demo/container.c
Normal file
21
conts/baremetal/mutex_demo/container.c
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Container entry point for pager
|
||||
*
|
||||
* Copyright (C) 2007-2009 B Labs Ltd.
|
||||
*/
|
||||
|
||||
#include <l4lib/init.h>
|
||||
#include <l4lib/utcb.h>
|
||||
|
||||
|
||||
extern void main(void);
|
||||
|
||||
void __container_init(void)
|
||||
{
|
||||
/* Generic L4 initialisation */
|
||||
__l4_init();
|
||||
|
||||
/* Entry to main */
|
||||
main();
|
||||
}
|
||||
|
||||
13
conts/baremetal/mutex_demo/include/tests.h
Normal file
13
conts/baremetal/mutex_demo/include/tests.h
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
#ifndef __TESTS_H__
|
||||
#define __TESTS_H__
|
||||
|
||||
//#define DEBUG
|
||||
|
||||
#ifdef DEBUG
|
||||
#define dgb_printf printf
|
||||
#else
|
||||
#define dbg_printf(fmt,...)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
18
conts/baremetal/mutex_demo/main.c
Normal file
18
conts/baremetal/mutex_demo/main.c
Normal file
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Main function for this container
|
||||
*/
|
||||
|
||||
#include <l4lib/macros.h>
|
||||
#include L4LIB_INC_ARCH(syslib.h)
|
||||
#include L4LIB_INC_ARCH(syscalls.h)
|
||||
#include <l4/api/space.h>
|
||||
|
||||
extern int test_api_mutexctrl(void);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
test_api_mutexctrl();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
23
conts/baremetal/test_suite/SConscript
Normal file
23
conts/baremetal/test_suite/SConscript
Normal file
@@ -0,0 +1,23 @@
|
||||
|
||||
# Inherit global environment
|
||||
Import('env')
|
||||
|
||||
from scripts.config.configuration import *
|
||||
|
||||
config = configuration_retrieve()
|
||||
arch = config.arch
|
||||
subarch = config.subarch
|
||||
|
||||
# The set of source files associated with this SConscript file.
|
||||
src_local = Glob('*.[cS]')
|
||||
src_local += Glob('src/*.[cS]')
|
||||
src_local += Glob('src/arch/' + arch + '/*.[cS]')
|
||||
src_local += Glob('src/api/*.c');
|
||||
src_local += Glob('src/perf/*.c');
|
||||
src_local += Glob('src/cli_serv/*.c');
|
||||
src_local += Glob('src/mthread/*.c');
|
||||
src_local += Glob('src/arch/' + arch + '/' + subarch + '/*.[cS]')
|
||||
|
||||
obj = env.Object(src_local)
|
||||
Return('obj')
|
||||
|
||||
@@ -7,61 +7,49 @@
|
||||
import os, shelve, sys
|
||||
from os.path import *
|
||||
|
||||
PROJRELROOT = '../..'
|
||||
CONTS_XXX = '../..'
|
||||
BAREMETAL_CONTS_XXX = '../../..'
|
||||
sys.path.append(CONTS_XXX)
|
||||
sys.path.append(BAREMETAL_CONTS_XXX)
|
||||
|
||||
sys.path.append(PROJRELROOT)
|
||||
|
||||
from config.projpaths import *
|
||||
from config.configuration import *
|
||||
from config.lib import *
|
||||
from scripts.config.projpaths import *
|
||||
from scripts.conts.containers import *
|
||||
from scripts.config.configuration import *
|
||||
|
||||
config = configuration_retrieve()
|
||||
arch = config.arch
|
||||
platform = config.platform
|
||||
gcc_arch_flag = config.gcc_arch_flag
|
||||
|
||||
LIBL4_RELDIR = 'conts/libl4'
|
||||
KERNEL_INCLUDE = join(PROJROOT, 'include')
|
||||
LIBL4_DIR = join(PROJROOT, LIBL4_RELDIR)
|
||||
LIBL4_INCLUDE = join(LIBL4_DIR, 'include')
|
||||
LIBL4_LIBPATH = join(BUILDDIR, LIBL4_RELDIR)
|
||||
cid = int(ARGUMENTS.get('cid', 0))
|
||||
cont = find_container_from_cid(cid)
|
||||
|
||||
# Locally important paths are here
|
||||
LIBC_RELDIR = 'conts/libc'
|
||||
LIBC_DIR = join(PROJROOT, LIBC_RELDIR)
|
||||
LIBC_LIBPATH = join(BUILDDIR, LIBC_RELDIR)
|
||||
LIBC_INCLUDE = [join(LIBC_DIR, 'include'), \
|
||||
join(LIBC_DIR, 'include/arch' + '/' + arch)]
|
||||
builddir = join(join(BUILDDIR, 'cont') + str(cid), cont.name)
|
||||
|
||||
LIBDEV_RELDIR = 'conts/libdev'
|
||||
LIBDEV_DIR = join(PROJROOT, LIBDEV_RELDIR)
|
||||
LIBDEV_LIBPATH = join(join(BUILDDIR, LIBDEV_RELDIR), 'sys-userspace')
|
||||
LIBDEV_INCLUDE = [join(LIBDEV_DIR, 'uart/include')]
|
||||
|
||||
LIBMEM_RELDIR = 'conts/libmem'
|
||||
LIBMEM_DIR = join(PROJROOT, LIBMEM_RELDIR)
|
||||
LIBMEM_LIBPATH = join(BUILDDIR, LIBMEM_RELDIR)
|
||||
LIBMEM_INCLUDE = LIBMEM_DIR
|
||||
# linker.lds is generated either in conts/xxx or build/contx/include
|
||||
if cont.duplicate == 0:
|
||||
linker_lds = join(builddir, 'include/linker.lds')
|
||||
else:
|
||||
linker_lds = 'include/linker.lds'
|
||||
|
||||
env = Environment(CC = config.toolchain_userspace + 'gcc',
|
||||
# We don't use -nostdinc because sometimes we need standard headers,
|
||||
# such as stdarg.h e.g. for variable args, as in printk().
|
||||
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', \
|
||||
'-Werror', '-march=' + gcc_arch_flag],
|
||||
LINKFLAGS = ['-nostdlib', '-T' + "include/linker.lds", "-u_start"],\
|
||||
ASFLAGS = ['-D__ASSEMBLY__'], \
|
||||
PROGSUFFIX = '.elf', # The suffix to use for final executable\
|
||||
ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path\
|
||||
LIBS = ['gcc', 'libl4', 'c-userspace', 'libdev-userspace', 'gcc', 'libmalloc',
|
||||
'c-userspace'], # libgcc.a - This is required for division routines.
|
||||
CPPPATH = ["#include", KERNEL_INCLUDE, LIBL4_INCLUDE, LIBDEV_INCLUDE, LIBC_INCLUDE, LIBMEM_INCLUDE],
|
||||
LIBPATH = [LIBL4_LIBPATH, LIBDEV_LIBPATH, LIBC_LIBPATH, LIBMEM_LIBPATH],
|
||||
CPPFLAGS = '-include l4/config.h -include l4/macros.h -include l4/types.h')
|
||||
# We don't use -nostdinc because sometimes we need standard headers,
|
||||
# such as stdarg.h e.g. for variable args, as in printk().
|
||||
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall',
|
||||
'-march=' + gcc_arch_flag],
|
||||
LINKFLAGS = ['-nostdlib', '-T' + linker_lds, '-u_start'],
|
||||
ASFLAGS = ['-D__ASSEMBLY__'],
|
||||
PROGSUFFIX = '.elf',
|
||||
ENV = {'PATH' : os.environ['PATH']},
|
||||
LIBS = ['gcc', 'libl4', 'libmem', 'c-userspace', 'libdev-userspace',
|
||||
'gcc', 'c-userspace'],
|
||||
# libgcc.a - This is required for division routines.
|
||||
CPPPATH = ["#include", KERNEL_HEADERS, LIBL4_INCLUDE, LIBDEV_INCLUDE,
|
||||
LIBC_INCLUDE, LIBMEM_INCLUDE, join(builddir, 'include')],
|
||||
LIBPATH = [LIBL4_LIBPATH, LIBDEV_USER_LIBPATH, LIBC_LIBPATH, LIBMEM_LIBPATH],
|
||||
CPPFLAGS = '-include l4/config.h -include l4/macros.h -include l4/types.h')
|
||||
|
||||
src = Glob('*.[cS]')
|
||||
src += Glob('src/*.[cS]')
|
||||
src += Glob('src/arch/*.[cS]')
|
||||
objs = SConscript('SConscript', exports = { 'env' : env },
|
||||
duplicate=0, build_dir = builddir)
|
||||
|
||||
objs = env.Object(src)
|
||||
prog = env.Program('main.elf', objs)
|
||||
Depends(prog, 'include/linker.lds')
|
||||
Depends(objs, join(PROJROOT, CONFIG_H))
|
||||
prog = env.Program(join(builddir, 'main.elf'), objs)
|
||||
Depends(prog, linker_lds)
|
||||
|
||||
257
conts/baremetal/test_suite/TAGS
Normal file
257
conts/baremetal/test_suite/TAGS
Normal file
@@ -0,0 +1,257 @@
|
||||
|
||||
main.c,65
|
||||
void run_tests(void)run_tests16,287
|
||||
int main(void)main38,770
|
||||
|
||||
src/capability.c,0
|
||||
|
||||
src/example.c,0
|
||||
|
||||
src/cli_serv/cli_serv.c,45
|
||||
int test_cli_serv(void)test_cli_serv21,536
|
||||
|
||||
src/api/cap.c,192
|
||||
#define TOTAL_CAPS TOTAL_CAPS12,202
|
||||
struct capability cap_array[TOTAL_CAPS];cap_array14,228
|
||||
int test_cap_read(void)test_cap_read19,308
|
||||
int test_api_capctrl(void)test_api_capctrl47,968
|
||||
|
||||
src/api/exregs.c,113
|
||||
int test_exregs_read_write(void)test_exregs_read_write15,229
|
||||
int test_api_exregs(void)test_api_exregs76,1453
|
||||
|
||||
src/api/memory.c,771
|
||||
#define DECLARE_IDPOOL(DECLARE_IDPOOL23,461
|
||||
struct address_pool virtual_page_pool, physical_page_pool;virtual_page_pool26,558
|
||||
struct address_pool virtual_page_pool, physical_page_pool;physical_page_pool26,558
|
||||
#define PAGE_POOL_SIZE PAGE_POOL_SIZE28,618
|
||||
#define virt_to_phys(virt_to_phys33,750
|
||||
#define phys_to_virt(phys_to_virt34,833
|
||||
#define TEST_POOL_TOTAL TEST_POOL_TOTAL37,920
|
||||
void test_page_pool(void)test_page_pool41,972
|
||||
void page_pool_init(void)page_pool_init106,2602
|
||||
void *virtual_page_new(int npages)virtual_page_new177,4779
|
||||
void *physical_page_new(int npages)physical_page_new182,4879
|
||||
void virtual_page_free(void *address, int npages)virtual_page_free187,4981
|
||||
void physical_page_free(void *address, int npages)physical_page_free193,5104
|
||||
|
||||
src/api/cache.c,158
|
||||
int test_cctrl_basic(void)test_cctrl_basic18,348
|
||||
int test_cctrl_sync_caches()test_cctrl_sync_caches43,971
|
||||
int test_api_cctrl(void)test_api_cctrl64,1314
|
||||
|
||||
src/api/thread.c,517
|
||||
int new_thread_func(void *args)new_thread_func18,285
|
||||
int delayed_exit_func(void *args)delayed_exit_func32,614
|
||||
int imm_exit_func(void *args)imm_exit_func54,1031
|
||||
struct l4_thread *test_thread_create()test_thread_create62,1132
|
||||
int test_thread_actions(struct l4_thread *thread)test_thread_actions92,1698
|
||||
int test_thread_destroy(struct l4_thread *thread)test_thread_destroy126,2347
|
||||
int test_thread_invalid(struct l4_thread *thread)test_thread_invalid214,4305
|
||||
int test_api_tctrl(void)test_api_tctrl219,4371
|
||||
|
||||
src/api/api.c,35
|
||||
int test_api(void)test_api15,214
|
||||
|
||||
src/api/irq.c,50
|
||||
int test_api_irqctrl(void)test_api_irqctrl8,105
|
||||
|
||||
src/api/ipc.c,705
|
||||
struct ipc_ext_data {ipc_ext_data18,330
|
||||
void *virtual; /* Virtual address to start ipc from */virtual19,352
|
||||
l4id_t partner; /* Partner to do extended ipc */partner20,408
|
||||
int ipc_extended_sender(void *arg)ipc_extended_sender23,462
|
||||
int ipc_extended_receiver(void *arg)ipc_extended_receiver36,722
|
||||
int ipc_ext_handle_pfault(struct ipc_ext_data *ipc_data,ipc_ext_handle_pfault63,1348
|
||||
int test_ipc_extended(void)test_ipc_extended146,4092
|
||||
int ipc_full_thread(void *arg)ipc_full_thread276,7400
|
||||
int ipc_short_thread(void *arg)ipc_short_thread313,8275
|
||||
int test_ipc_full(void)test_ipc_full354,9106
|
||||
int test_ipc_short(void)test_ipc_short462,11483
|
||||
int test_api_ipc(void)test_api_ipc526,12763
|
||||
|
||||
src/api/map.c,305
|
||||
#define KERNEL_PAGE KERNEL_PAGE15,277
|
||||
#define KIP_PAGE KIP_PAGE16,311
|
||||
#define SYSCALL_PAGE SYSCALL_PAGE17,342
|
||||
#define VECTOR_PAGE VECTOR_PAGE18,377
|
||||
int test_api_map(void)test_api_map20,412
|
||||
int test_api_unmap(void)test_api_unmap259,6043
|
||||
int test_api_map_unmap(void)test_api_map_unmap347,8064
|
||||
|
||||
src/api/getid.c,167
|
||||
int thread_getid_nullptr(void *arg)thread_getid_nullptr15,250
|
||||
int test_getid_nullptr(void)test_getid_nullptr27,479
|
||||
int test_api_getid(void)test_api_getid84,1734
|
||||
|
||||
src/api/smp.c,299
|
||||
static int new_thread_func(void *args)new_thread_func14,232
|
||||
int test_smp_two_threads(void)test_smp_two_threads48,945
|
||||
int test_smp_two_spaces(void)test_smp_two_spaces113,2491
|
||||
int test_smp_ipc(void)test_smp_ipc118,2537
|
||||
int test_smp(void)test_smp124,2601
|
||||
int test_smp(void)test_smp141,2833
|
||||
|
||||
src/api/mutex.c,652
|
||||
#define MUTEX_NTHREADS MUTEX_NTHREADS16,283
|
||||
#define MUTEX_INCREMENTS MUTEX_INCREMENTS17,310
|
||||
#define MUTEX_VALUE_TOTAL MUTEX_VALUE_TOTAL18,340
|
||||
struct mutex_test_data {mutex_test_data20,404
|
||||
struct l4_mutex lock;lock21,429
|
||||
int val;val22,452
|
||||
static struct mutex_test_data tdata;tdata25,466
|
||||
static void init_test_data(struct mutex_test_data *tdata)init_test_data27,504
|
||||
int mutex_thread_non_contending(void *arg)mutex_thread_non_contending34,615
|
||||
int mutex_thread_contending(void *arg)mutex_thread_contending67,1270
|
||||
int test_mutex(int (*mutex_thread)(void *))test_mutex106,2054
|
||||
int test_api_mutexctrl(void)test_api_mutexctrl187,3891
|
||||
|
||||
src/captest.c,178
|
||||
int simple_pager_thread(void *arg)simple_pager_thread10,204
|
||||
int wait_check_test(struct task_ids *ids)wait_check_test57,1151
|
||||
int capability_test(void)capability_test74,1490
|
||||
|
||||
src/perf/tctrl.c,174
|
||||
struct perfmon_cycles tctrl_cycles;tctrl_cycles18,324
|
||||
#define PERFTEST_THREAD_CREATE PERFTEST_THREAD_CREATE20,361
|
||||
void perf_measure_tctrl(void)perf_measure_tctrl22,399
|
||||
|
||||
src/perf/exregs.c,181
|
||||
struct perfmon_cycles l4_exregs_cycles;l4_exregs_cycles19,372
|
||||
#define PERFTEST_EXREGS_COUNT PERFTEST_EXREGS_COUNT21,413
|
||||
int perf_measure_exregs(void)perf_measure_exregs23,449
|
||||
|
||||
src/perf/tswitch.c,472
|
||||
struct perfmon_cycles thread_switch_cycles;thread_switch_cycles18,324
|
||||
struct perfmon_cycles space_switch_cycles;space_switch_cycles19,368
|
||||
static int indicate_switch = 0;indicate_switch21,412
|
||||
void thread_switcher_thread(void *arg)thread_switcher_thread23,445
|
||||
void perf_measure_thread_switch(void)perf_measure_thread_switch39,799
|
||||
void perf_measure_space_switch(void)perf_measure_space_switch102,2328
|
||||
void perf_measure_tswitch(void)perf_measure_tswitch108,2372
|
||||
|
||||
src/perf/perf.c,51
|
||||
int test_performance(void)test_performance15,204
|
||||
|
||||
src/perf/simple.c,168
|
||||
struct perfmon_cycles simple_cycles;simple_cycles17,314
|
||||
#define PERFTEST_SIMPLE_LOOP PERFTEST_SIMPLE_LOOP19,352
|
||||
void perf_test_simple(void)perf_test_simple21,387
|
||||
|
||||
src/perf/ipc.c,51
|
||||
void perf_measure_ipc(void)perf_measure_ipc9,102
|
||||
|
||||
src/perf/map.c,107
|
||||
void perf_measure_map(void)perf_measure_map9,111
|
||||
void perf_measure_unmap(void)perf_measure_unmap14,145
|
||||
|
||||
src/perf/getid.c,245
|
||||
struct perfmon_cycles l4_getid_cycles;l4_getid_cycles18,333
|
||||
#define PERFTEST_GETID_COUNT PERFTEST_GETID_COUNT20,373
|
||||
void perf_measure_getid_ticks(void)perf_measure_getid_ticks25,450
|
||||
void perf_measure_getid(void)perf_measure_getid67,1461
|
||||
|
||||
src/perf/timer.c,150
|
||||
#define TIMER_PHYSICAL_BASE TIMER_PHYSICAL_BASE15,298
|
||||
unsigned long timer_base;timer_base17,339
|
||||
void perf_timer_init(void)perf_timer_init19,366
|
||||
|
||||
src/perf/mutex.c,55
|
||||
void perf_measure_mutex(void)perf_measure_mutex9,104
|
||||
|
||||
src/perf/cycles.c,70
|
||||
void platform_measure_cpu_cycles()platform_measure_cpu_cycles20,354
|
||||
|
||||
src/mthread/mthread.c,43
|
||||
int test_mthread(void)test_mthread22,547
|
||||
|
||||
src/arch/arm/v7/mm.c,285
|
||||
int pte_get_access_simple(pte_t pte)pte_get_access_simple13,246
|
||||
int is_translation_fault(u32 fsr)is_translation_fault20,427
|
||||
unsigned int vm_prot_flags(pte_t pte, u32 fsr)vm_prot_flags25,521
|
||||
void set_generic_fault_params(struct fault_data *fault)set_generic_fault_params54,1163
|
||||
|
||||
src/arch/arm/v5/mm.c,147
|
||||
unsigned int vm_prot_flags(pte_t pte)vm_prot_flags12,242
|
||||
void set_generic_fault_params(struct fault_data *fault)set_generic_fault_params42,960
|
||||
|
||||
container.c,52
|
||||
void __container_init(void)__container_init14,216
|
||||
|
||||
include/capability.h,47
|
||||
#define __CAPABILITY_H____CAPABILITY_H__2,25
|
||||
|
||||
include/thread.h,121
|
||||
#define __THREAD_H____THREAD_H__2,21
|
||||
#define STACK_SIZE STACK_SIZE15,318
|
||||
#define THREADS_TOTAL THREADS_TOTAL17,345
|
||||
|
||||
include/memory.h,59
|
||||
#define __TESTSUITE_MEMORY_H____TESTSUITE_MEMORY_H__2,31
|
||||
|
||||
include/fault.h,840
|
||||
#define __FAULT_H____FAULT_H__2,20
|
||||
#define VM_NONE VM_NONE10,169
|
||||
#define VM_READ VM_READ11,197
|
||||
#define VM_EXEC VM_EXEC12,225
|
||||
#define VM_WRITE VM_WRITE13,253
|
||||
#define VM_PROT_MASK VM_PROT_MASK14,281
|
||||
#define VMA_SHARED VMA_SHARED17,364
|
||||
#define VMA_ANONYMOUS VMA_ANONYMOUS19,459
|
||||
#define VMA_PRIVATE VMA_PRIVATE21,521
|
||||
#define VMA_FIXED VMA_FIXED23,574
|
||||
#define VMA_GROWSDOWN VMA_GROWSDOWN25,651
|
||||
#define VM_DIRTY VM_DIRTY28,751
|
||||
struct fault_data {fault_data31,842
|
||||
fault_kdata_t *kdata; /* Generic data forged by the kernel */kdata32,862
|
||||
unsigned int reason; /* Generic fault reason flags */reason33,926
|
||||
unsigned int address; /* Aborted address */address34,982
|
||||
unsigned int pte_flags; /* Generic protection flags on pte */pte_flags35,1028
|
||||
l4id_t sender; /* Inittask-related fault data */sender36,1092
|
||||
|
||||
include/macros.h,201
|
||||
#define __TEST_MACROS_H____TEST_MACROS_H__2,26
|
||||
#define __INC_ARCH(__INC_ARCH4,53
|
||||
#define __INC_SUBARCH(__INC_SUBARCH5,94
|
||||
#define __INC_PLAT(__INC_PLAT6,149
|
||||
#define __INC_GLUE(__INC_GLUE7,198
|
||||
|
||||
include/timer.h,59
|
||||
#define __PERF_TESTS_TIMER_H____PERF_TESTS_TIMER_H__2,31
|
||||
|
||||
include/perf.h,740
|
||||
#define __PERF_TESTS_H____PERF_TESTS_H__2,25
|
||||
struct perfmon_cycles {perfmon_cycles9,192
|
||||
u64 last; /* Last op cycles */last10,216
|
||||
u64 min; /* Minimum cycles */min11,248
|
||||
u64 max; /* Max cycles */max12,279
|
||||
u64 avg; /* Average cycles */avg13,306
|
||||
u64 total; /* Total cycles */total14,337
|
||||
u64 ops; /* Total ops */ops15,368
|
||||
#define CORTEXA9_400MHZ_USEC CORTEXA9_400MHZ_USEC26,614
|
||||
#define CORTEXA9_400MHZ_MSEC CORTEXA9_400MHZ_MSEC27,654
|
||||
#define USEC_MULTIPLIER USEC_MULTIPLIER28,697
|
||||
#define MSEC_MULTIPLIER MSEC_MULTIPLIER29,743
|
||||
#define perfmon_record_cycles(perfmon_record_cycles34,832
|
||||
#define perfmon_record_cycles(perfmon_record_cycles38,919
|
||||
#define perfmon_checkpoint_cycles(perfmon_checkpoint_cycles50,1261
|
||||
|
||||
include/api/api.h,55
|
||||
#define __TEST_SUITE_API_H____TEST_SUITE_API_H__2,29
|
||||
|
||||
include/debug.h,432
|
||||
#define __ARCH_DEBUG_H____ARCH_DEBUG_H__7,111
|
||||
static inline u32 perfmon_read_cyccnt() { return 0; }perfmon_read_cyccnt14,250
|
||||
static inline void perfmon_reset_start_cyccnt() { }perfmon_reset_start_cyccnt16,305
|
||||
static inline u32 perfmon_read_reset_start_cyccnt() { return 0; }perfmon_read_reset_start_cyccnt17,357
|
||||
#define debug_record_cycles(debug_record_cycles19,424
|
||||
#define debug_record_cycles(debug_record_cycles33,763
|
||||
|
||||
include/tests.h,149
|
||||
#define __TESTS_H____TESTS_H__2,20
|
||||
#define DEBUG_TESTS DEBUG_TESTS5,74
|
||||
#define dbg_printf(dbg_printf7,112
|
||||
#define dbg_printf(dbg_printf9,162
|
||||
|
||||
include/linker.h,61
|
||||
#define __TEST_SUITE_LINKER_H____TEST_SUITE_LINKER_H__2,32
|
||||
@@ -6,7 +6,8 @@
|
||||
|
||||
#include <l4lib/init.h>
|
||||
#include <l4lib/utcb.h>
|
||||
|
||||
#include <l4lib/lib/thread.h>
|
||||
#include <l4lib/lib/cap.h>
|
||||
|
||||
extern void main(void);
|
||||
|
||||
@@ -15,6 +16,12 @@ void __container_init(void)
|
||||
/* Generic L4 initialisation */
|
||||
__l4_init();
|
||||
|
||||
/* Thread library initialisation */
|
||||
__l4_threadlib_init();
|
||||
|
||||
/* Capability library initialization */
|
||||
__l4_capability_init();
|
||||
|
||||
/* Entry to main */
|
||||
main();
|
||||
}
|
||||
|
||||
44
conts/baremetal/test_suite/include/fault.h
Normal file
44
conts/baremetal/test_suite/include/fault.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#ifndef __FAULT_H__
|
||||
#define __FAULT_H__
|
||||
|
||||
#include <l4/macros.h>
|
||||
#include <l4/types.h>
|
||||
#include INC_GLUE(memory.h)
|
||||
#include INC_ARCH(exception.h)
|
||||
|
||||
/* Protection flags */
|
||||
#define VM_NONE (1 << 0)
|
||||
#define VM_READ (1 << 1)
|
||||
#define VM_EXEC (1 << 2)
|
||||
#define VM_WRITE (1 << 3)
|
||||
#define VM_PROT_MASK (VM_READ | VM_WRITE | VM_EXEC)
|
||||
|
||||
/* Shared copy of a file */
|
||||
#define VMA_SHARED (1 << 4)
|
||||
/* VMA that's not file-backed, always maps devzero as VMA_COW */
|
||||
#define VMA_ANONYMOUS (1 << 5)
|
||||
/* Private copy of a file */
|
||||
#define VMA_PRIVATE (1 << 6)
|
||||
/* For wired pages */
|
||||
#define VMA_FIXED (1 << 7)
|
||||
/* For stack, where mmap returns end address */
|
||||
#define VMA_GROWSDOWN (1 << 8)
|
||||
|
||||
/* Set when the page is dirty in cache but not written to disk */
|
||||
#define VM_DIRTY (1 << 9)
|
||||
|
||||
/* Fault data specific to this task + ptr to kernel's data */
|
||||
struct fault_data {
|
||||
fault_kdata_t *kdata; /* Generic data forged by the kernel */
|
||||
unsigned int reason; /* Generic fault reason flags */
|
||||
unsigned int address; /* Aborted address */
|
||||
unsigned int pte_flags; /* Generic protection flags on pte */
|
||||
l4id_t sender; /* Inittask-related fault data */
|
||||
};
|
||||
|
||||
|
||||
void set_generic_fault_params(struct fault_data *fault);
|
||||
void arch_print_fault_params(struct fault_data *fault);
|
||||
void fault_handle_error(struct fault_data *fault);
|
||||
|
||||
#endif /* __FAULT_H__ */
|
||||
16
conts/baremetal/test_suite/include/linker.h
Normal file
16
conts/baremetal/test_suite/include/linker.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef __TEST_SUITE_LINKER_H__
|
||||
#define __TEST_SUITE_LINKER_H__
|
||||
|
||||
extern unsigned char __stack[];
|
||||
extern unsigned char __end[];
|
||||
extern unsigned char vma_start[];
|
||||
extern unsigned char lma_start[];
|
||||
extern unsigned char offset[];
|
||||
extern unsigned char __data_start[];
|
||||
extern unsigned char __data_end[];
|
||||
extern unsigned char __bss_start[];
|
||||
extern unsigned char __bss_end[];
|
||||
extern unsigned char __stack_start[];
|
||||
extern unsigned char __stack_end[];
|
||||
|
||||
#endif /* __LINKER_H__ */
|
||||
12
conts/baremetal/test_suite/include/memory.h
Normal file
12
conts/baremetal/test_suite/include/memory.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef __TESTSUITE_MEMORY_H__
|
||||
#define __TESTSUITE_MEMORY_H__
|
||||
|
||||
|
||||
|
||||
void *virtual_page_new(int npages);
|
||||
void *physical_page_new(int npages);
|
||||
void virtual_page_free(void *address, int npages);
|
||||
void physical_page_free(void *address, int npages);
|
||||
|
||||
void page_pool_init(void);
|
||||
#endif /* __TESTSUITE_MEMORY_H__ */
|
||||
@@ -1,7 +1,18 @@
|
||||
#ifndef __TESTS_H__
|
||||
#define __TESTS_H__
|
||||
|
||||
/* Abort debugging conditions */
|
||||
#define DEBUG_TESTS 0
|
||||
#if DEBUG_TESTS
|
||||
#define dbg_printf(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define dbg_printf(...)
|
||||
#endif
|
||||
|
||||
int capability_test(void);
|
||||
int test_smp();
|
||||
int test_performance();
|
||||
int test_api();
|
||||
int test_cli_serv();
|
||||
int test_mthread();
|
||||
|
||||
#endif /* __TESTS_H__ */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __PERF_TESTS_TIMER_H__
|
||||
#define __PERF_TESTS_TIMER_H__
|
||||
|
||||
#include <libdev/timer.h>
|
||||
#include <dev/timer.h>
|
||||
|
||||
extern unsigned long timer_base;
|
||||
void perf_timer_init(void);
|
||||
@@ -3,62 +3,41 @@
|
||||
*
|
||||
* Copyright (C) 2009 B Labs Ltd.
|
||||
*/
|
||||
#include <l4/api/errno.h>
|
||||
#include <container.h>
|
||||
#include <thread.h>
|
||||
#include <tests.h>
|
||||
#include <l4lib/macros.h>
|
||||
#include L4LIB_INC_ARCH(syslib.h)
|
||||
#include L4LIB_INC_ARCH(syscalls.h)
|
||||
#include <tests.h>
|
||||
#include <thread.h>
|
||||
#include <container.h>
|
||||
#include <l4/api/space.h>
|
||||
#include <l4/api/errno.h>
|
||||
|
||||
|
||||
int exit_test_thread(void *arg)
|
||||
void run_tests(void)
|
||||
{
|
||||
while (1)
|
||||
;
|
||||
//l4_thread_switch(0);
|
||||
//l4_exit(5);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int exit_test(void)
|
||||
{
|
||||
int ret;
|
||||
struct task_ids ids;
|
||||
|
||||
/* Create and run a new thread */
|
||||
if ((ret = thread_create(exit_test_thread, 0,
|
||||
TC_SHARE_SPACE | TC_AS_PAGER,
|
||||
&ids)) < 0) {
|
||||
printf("Top-level simple_pager creation failed.\n");
|
||||
goto out_err;
|
||||
} else
|
||||
printf("Thread (%d) created successfully.\n", ids.tid);
|
||||
|
||||
// l4_thread_switch(0);
|
||||
|
||||
/* Kill it */
|
||||
printf("Killing Thread (%d).\n", ids.tid);
|
||||
if ((ret = l4_thread_control(THREAD_DESTROY, &ids)) < 0)
|
||||
printf("Error: Killing Thread (%d), err = %d\n", ids.tid, ret);
|
||||
else
|
||||
printf("Success: Killed Thread (%d)\n", ids.tid);
|
||||
|
||||
|
||||
#if 0
|
||||
/* Wait on it */
|
||||
printf("Waiting on Thread (%d) to exit.\n", ids.tid);
|
||||
if ((ret = l4_thread_control(THREAD_WAIT, &ids)) >= 0)
|
||||
printf("Success. Paged child returned %d\n", ret);
|
||||
else
|
||||
printf("Error. Wait on (%d) failed. err = %d\n",
|
||||
ids.tid, ret);
|
||||
|
||||
/* Performance tests */
|
||||
if (test_performance() < 0)
|
||||
printf("Performance tests failed.\n");
|
||||
#endif
|
||||
return 0;
|
||||
out_err:
|
||||
BUG();
|
||||
if (test_smp() < 0)
|
||||
printf("SMP tests failed.\n");
|
||||
|
||||
/* API Tests */
|
||||
if (test_api() < 0)
|
||||
printf("API tests failed.\n");
|
||||
|
||||
/* Container client/server setup test */
|
||||
if (test_cli_serv() < 0)
|
||||
printf("Client/server tests failed.\n");
|
||||
|
||||
/* Container multithreaded/standalone setup test */
|
||||
if (test_mthread() < 0)
|
||||
printf("Multi-threaded tests failed.\n");
|
||||
|
||||
/* Parent quits */
|
||||
printf("Test parent thread exiting...\n");
|
||||
thread_exit(0);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
@@ -66,15 +45,7 @@ int main(void)
|
||||
printf("%s: Container %s started\n",
|
||||
__CONTAINER__, __CONTAINER_NAME__);
|
||||
|
||||
capability_test();
|
||||
|
||||
//exit_test();
|
||||
|
||||
/* Now quit to demo self-paging quit */
|
||||
//l4_exit(0);
|
||||
|
||||
/* Now quit by null pointer */
|
||||
// *((int *)0) = 5;
|
||||
run_tests();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -27,8 +27,8 @@ int test_api_map(void)
|
||||
* Make a valid mapping, a few pages below
|
||||
* the end of physical and virtual marks
|
||||
*/
|
||||
if ((err = l4_map((void *)CONFIG_CONT0_PHYS0_END - PAGE_SIZE * 5,
|
||||
(void *)CONFIG_CONT0_VIRT0_END - PAGE_SIZE * 5,
|
||||
if ((err = l4_map((void *)CONFIG_CONT0_PAGER_PHYS0_END - PAGE_SIZE * 5,
|
||||
(void *)CONFIG_CONT0_PAGER_VIRT0_END - PAGE_SIZE * 5,
|
||||
1,
|
||||
MAP_USR_RW,
|
||||
self)) < 0) {
|
||||
@@ -40,8 +40,8 @@ int test_api_map(void)
|
||||
/*
|
||||
* Redo the same mapping. This should be valid.
|
||||
*/
|
||||
if ((err = l4_map((void *)CONFIG_CONT0_PHYS0_END - PAGE_SIZE * 5,
|
||||
(void *)CONFIG_CONT0_VIRT0_END - PAGE_SIZE * 5,
|
||||
if ((err = l4_map((void *)CONFIG_CONT0_PAGER_PHYS0_END - PAGE_SIZE * 5,
|
||||
(void *)CONFIG_CONT0_PAGER_VIRT0_END - PAGE_SIZE * 5,
|
||||
1,
|
||||
MAP_USR_RW,
|
||||
self)) < 0) {
|
||||
@@ -53,8 +53,8 @@ int test_api_map(void)
|
||||
/*
|
||||
* Try mapping outside the virtual range
|
||||
*/
|
||||
if ((err = l4_map((void *)CONFIG_CONT0_PHYS0_END - PAGE_SIZE * 5,
|
||||
(void *)CONFIG_CONT0_VIRT0_END,
|
||||
if ((err = l4_map((void *)CONFIG_CONT0_PAGER_PHYS0_END - PAGE_SIZE * 5,
|
||||
(void *)CONFIG_CONT0_PAGER_VIRT0_END,
|
||||
1,
|
||||
MAP_USR_RW,
|
||||
self)) == 0) {
|
||||
@@ -66,8 +66,8 @@ int test_api_map(void)
|
||||
/*
|
||||
* Try mapping outside the physical range
|
||||
*/
|
||||
if ((err = l4_map((void *)CONFIG_CONT0_PHYS0_END,
|
||||
(void *)CONFIG_CONT0_VIRT0_END - PAGE_SIZE * 5,
|
||||
if ((err = l4_map((void *)CONFIG_CONT0_PAGER_PHYS0_END,
|
||||
(void *)CONFIG_CONT0_PAGER_VIRT0_END - PAGE_SIZE * 5,
|
||||
1,
|
||||
MAP_USR_RW,
|
||||
self)) == 0) {
|
||||
@@ -79,8 +79,8 @@ int test_api_map(void)
|
||||
/*
|
||||
* Try having them both out of range
|
||||
*/
|
||||
if ((err = l4_map((void *)CONFIG_CONT0_PHYS0_END,
|
||||
(void *)CONFIG_CONT0_VIRT0_END,
|
||||
if ((err = l4_map((void *)CONFIG_CONT0_PAGER_PHYS0_END,
|
||||
(void *)CONFIG_CONT0_PAGER_VIRT0_END,
|
||||
1,
|
||||
MAP_USR_RW,
|
||||
self)) == 0) {
|
||||
@@ -93,8 +93,8 @@ int test_api_map(void)
|
||||
/*
|
||||
* Try out of range by off-by-one page size excess
|
||||
*/
|
||||
if ((err = l4_map((void *)CONFIG_CONT0_PHYS0_END - PAGE_SIZE * 5,
|
||||
(void *)CONFIG_CONT0_VIRT0_END - PAGE_SIZE * 5,
|
||||
if ((err = l4_map((void *)CONFIG_CONT0_PAGER_PHYS0_END - PAGE_SIZE * 5,
|
||||
(void *)CONFIG_CONT0_PAGER_VIRT0_END - PAGE_SIZE * 5,
|
||||
6,
|
||||
MAP_USR_RW,
|
||||
self)) == 0) {
|
||||
@@ -108,8 +108,8 @@ int test_api_map(void)
|
||||
/*
|
||||
* Try invalid page size
|
||||
*/
|
||||
if ((err = l4_map((void *)CONFIG_CONT0_PHYS0_END - PAGE_SIZE * 5,
|
||||
(void *)CONFIG_CONT0_VIRT0_END - PAGE_SIZE * 5,
|
||||
if ((err = l4_map((void *)CONFIG_CONT0_PAGER_PHYS0_END - PAGE_SIZE * 5,
|
||||
(void *)CONFIG_CONT0_PAGER_VIRT0_END - PAGE_SIZE * 5,
|
||||
0xFFFFFFFF,
|
||||
MAP_USR_RW,
|
||||
self)) == 0) {
|
||||
@@ -122,8 +122,8 @@ int test_api_map(void)
|
||||
* Try invalid flags
|
||||
*/
|
||||
flags = 0;
|
||||
if ((err = l4_map((void *)CONFIG_CONT0_PHYS0_END - PAGE_SIZE * 5,
|
||||
(void *)CONFIG_CONT0_VIRT0_END - PAGE_SIZE * 5,
|
||||
if ((err = l4_map((void *)CONFIG_CONT0_PAGER_PHYS0_END - PAGE_SIZE * 5,
|
||||
(void *)CONFIG_CONT0_PAGER_VIRT0_END - PAGE_SIZE * 5,
|
||||
1,
|
||||
flags,
|
||||
self)) == 0) {
|
||||
@@ -132,8 +132,8 @@ int test_api_map(void)
|
||||
return -1;
|
||||
}
|
||||
flags = MAP_KERN_RWX;
|
||||
if ((err = l4_map((void *)CONFIG_CONT0_PHYS0_END - PAGE_SIZE * 5,
|
||||
(void *)CONFIG_CONT0_VIRT0_END - PAGE_SIZE * 5,
|
||||
if ((err = l4_map((void *)CONFIG_CONT0_PAGER_PHYS0_END - PAGE_SIZE * 5,
|
||||
(void *)CONFIG_CONT0_PAGER_VIRT0_END - PAGE_SIZE * 5,
|
||||
1,
|
||||
0,
|
||||
self)) == 0) {
|
||||
@@ -142,8 +142,8 @@ int test_api_map(void)
|
||||
return -1;
|
||||
}
|
||||
flags = MAP_KERN_IO;
|
||||
if ((err = l4_map((void *)CONFIG_CONT0_PHYS0_END - PAGE_SIZE * 5,
|
||||
(void *)CONFIG_CONT0_VIRT0_END - PAGE_SIZE * 5,
|
||||
if ((err = l4_map((void *)CONFIG_CONT0_PAGER_PHYS0_END - PAGE_SIZE * 5,
|
||||
(void *)CONFIG_CONT0_PAGER_VIRT0_END - PAGE_SIZE * 5,
|
||||
1,
|
||||
0,
|
||||
self)) == 0) {
|
||||
@@ -153,8 +153,8 @@ int test_api_map(void)
|
||||
}
|
||||
|
||||
flags = MAP_KERN_RX;
|
||||
if ((err = l4_map((void *)CONFIG_CONT0_PHYS0_END - PAGE_SIZE * 5,
|
||||
(void *)CONFIG_CONT0_VIRT0_END - PAGE_SIZE * 5,
|
||||
if ((err = l4_map((void *)CONFIG_CONT0_PAGER_PHYS0_END - PAGE_SIZE * 5,
|
||||
(void *)CONFIG_CONT0_PAGER_VIRT0_END - PAGE_SIZE * 5,
|
||||
1,
|
||||
0,
|
||||
self)) == 0) {
|
||||
@@ -164,8 +164,8 @@ int test_api_map(void)
|
||||
}
|
||||
|
||||
flags = 0xF0F0F01;
|
||||
if ((err = l4_map((void *)CONFIG_CONT0_PHYS0_END - PAGE_SIZE * 5,
|
||||
(void *)CONFIG_CONT0_VIRT0_END - PAGE_SIZE * 5,
|
||||
if ((err = l4_map((void *)CONFIG_CONT0_PAGER_PHYS0_END - PAGE_SIZE * 5,
|
||||
(void *)CONFIG_CONT0_PAGER_VIRT0_END - PAGE_SIZE * 5,
|
||||
1,
|
||||
0,
|
||||
self)) == 0) {
|
||||
@@ -178,7 +178,7 @@ int test_api_map(void)
|
||||
* Try passing wraparound values
|
||||
*/
|
||||
if ((err = l4_map((void *)0xFFFFFFFF,
|
||||
(void *)CONFIG_CONT0_VIRT0_END - PAGE_SIZE * 5,
|
||||
(void *)CONFIG_CONT0_PAGER_VIRT0_END - PAGE_SIZE * 5,
|
||||
1,
|
||||
MAP_USR_RW,
|
||||
self)) == 0) {
|
||||
@@ -190,7 +190,7 @@ int test_api_map(void)
|
||||
/*
|
||||
* Try passing wraparound values
|
||||
*/
|
||||
if ((err = l4_map((void *)CONFIG_CONT0_PHYS0_END - PAGE_SIZE * 5,
|
||||
if ((err = l4_map((void *)CONFIG_CONT0_PAGER_PHYS0_END - PAGE_SIZE * 5,
|
||||
(void *)0xFFFFF000,
|
||||
2,
|
||||
MAP_USR_RW,
|
||||
@@ -203,7 +203,7 @@ int test_api_map(void)
|
||||
/*
|
||||
* Try mapping onto kernel
|
||||
*/
|
||||
if ((err = l4_map((void *)CONFIG_CONT0_PHYS0_END - PAGE_SIZE * 5,
|
||||
if ((err = l4_map((void *)CONFIG_CONT0_PAGER_PHYS0_END - PAGE_SIZE * 5,
|
||||
(void *)0xF0000000,
|
||||
1,
|
||||
MAP_USR_RW,
|
||||
@@ -216,7 +216,7 @@ int test_api_map(void)
|
||||
/*
|
||||
* Try mapping to vector page
|
||||
*/
|
||||
if ((err = l4_map((void *)CONFIG_CONT0_PHYS0_END - PAGE_SIZE * 5,
|
||||
if ((err = l4_map((void *)CONFIG_CONT0_PAGER_PHYS0_END - PAGE_SIZE * 5,
|
||||
(void *)0xFFFF0000,
|
||||
1,
|
||||
MAP_USR_RW,
|
||||
@@ -229,7 +229,7 @@ int test_api_map(void)
|
||||
/*
|
||||
* Try mapping to kip
|
||||
*/
|
||||
if ((err = l4_map((void *)CONFIG_CONT0_PHYS0_END - PAGE_SIZE * 5,
|
||||
if ((err = l4_map((void *)CONFIG_CONT0_PAGER_PHYS0_END - PAGE_SIZE * 5,
|
||||
(void *)0xFF000000,
|
||||
1,
|
||||
MAP_USR_RW,
|
||||
@@ -242,7 +242,7 @@ int test_api_map(void)
|
||||
/*
|
||||
* Try mapping to syscall page
|
||||
*/
|
||||
if ((err = l4_map((void *)CONFIG_CONT0_PHYS0_END - PAGE_SIZE * 5,
|
||||
if ((err = l4_map((void *)CONFIG_CONT0_PAGER_PHYS0_END - PAGE_SIZE * 5,
|
||||
(void *)0xFFFFF000,
|
||||
1,
|
||||
MAP_USR_RW,
|
||||
@@ -264,7 +264,7 @@ int test_api_unmap(void)
|
||||
/*
|
||||
* Try a valid unmap
|
||||
*/
|
||||
if ((err = l4_unmap((void *)CONFIG_CONT0_VIRT0_END - PAGE_SIZE * 5,
|
||||
if ((err = l4_unmap((void *)CONFIG_CONT0_PAGER_VIRT0_END - PAGE_SIZE * 5,
|
||||
1,
|
||||
self)) < 0) {
|
||||
dbg_printf("sys_unmap failed on valid request. err=%d\n",
|
||||
@@ -275,7 +275,7 @@ int test_api_unmap(void)
|
||||
/*
|
||||
* Try the same unmap, should return ENOMAP
|
||||
*/
|
||||
if ((err = l4_unmap((void *)CONFIG_CONT0_VIRT0_END - PAGE_SIZE * 5,
|
||||
if ((err = l4_unmap((void *)CONFIG_CONT0_PAGER_VIRT0_END - PAGE_SIZE * 5,
|
||||
1,
|
||||
self)) != -ENOMAP) {
|
||||
dbg_printf("sys_unmap did not return ENOMAP "
|
||||
@@ -314,7 +314,7 @@ int test_api_unmap(void)
|
||||
"unmap region. err=%d\n", err);
|
||||
return -1;
|
||||
}
|
||||
if ((err = l4_unmap((void *)CONFIG_CONT0_VIRT0_END - PAGE_SIZE * 5,
|
||||
if ((err = l4_unmap((void *)CONFIG_CONT0_PAGER_VIRT0_END - PAGE_SIZE * 5,
|
||||
0xFFFFFFFF, self)) == 0) {
|
||||
dbg_printf("sys_unmap succeeded on invalid "
|
||||
"unmap region. err=%d\n", err);
|
||||
@@ -324,7 +324,7 @@ int test_api_unmap(void)
|
||||
/*
|
||||
* Try unmapping zero pages
|
||||
*/
|
||||
if ((err = l4_unmap((void *)CONFIG_CONT0_VIRT0_END - PAGE_SIZE * 5,
|
||||
if ((err = l4_unmap((void *)CONFIG_CONT0_PAGER_VIRT0_END - PAGE_SIZE * 5,
|
||||
0, self)) == 0) {
|
||||
dbg_printf("sys_unmap succeeded on invalid "
|
||||
"unmap region. err=%d\n", err);
|
||||
@@ -334,7 +334,7 @@ int test_api_unmap(void)
|
||||
/*
|
||||
* Try unmapping with invalid id
|
||||
*/
|
||||
if ((err = l4_unmap((void *)CONFIG_CONT0_VIRT0_END - PAGE_SIZE * 5,
|
||||
if ((err = l4_unmap((void *)CONFIG_CONT0_PAGER_VIRT0_END - PAGE_SIZE * 5,
|
||||
1, 0xFFFFFFFF)) == 0) {
|
||||
dbg_printf("sys_unmap succeeded on invalid "
|
||||
"unmap region. err=%d\n", err);
|
||||
198
conts/baremetal/test_suite/src/api/memory.c
Normal file
198
conts/baremetal/test_suite/src/api/memory.c
Normal file
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Empty virtual and physical pages for
|
||||
* creating test scenarios
|
||||
*
|
||||
* Copyright (C) 2010 B Labs Ltd.
|
||||
*
|
||||
* Author: Bahadir Balban
|
||||
*/
|
||||
#include <l4lib/lib/addr.h>
|
||||
#include INC_GLUE(memory.h)
|
||||
#include <l4/generic/cap-types.h>
|
||||
#include <l4lib/lib/cap.h>
|
||||
#include <l4/lib/math.h>
|
||||
#include <stdio.h>
|
||||
#include <memory.h>
|
||||
#include <linker.h>
|
||||
#include <tests.h>
|
||||
|
||||
/*
|
||||
* Declare a statically allocated char buffer
|
||||
* with enough bitmap size to cover given size
|
||||
*/
|
||||
#define DECLARE_IDPOOL(name, size) \
|
||||
char name[(sizeof(struct id_pool) + ((size >> 12) >> 3))]
|
||||
|
||||
struct address_pool virtual_page_pool, physical_page_pool;
|
||||
|
||||
#define PAGE_POOL_SIZE SZ_16MB
|
||||
|
||||
DECLARE_IDPOOL(virtual_idpool, PAGE_POOL_SIZE);
|
||||
DECLARE_IDPOOL(physical_idpool, PAGE_POOL_SIZE);
|
||||
|
||||
#define virt_to_phys(virtual) ((unsigned long)(virtual) - (unsigned long)(offset))
|
||||
#define phys_to_virt(physical) ((unsigned long)(physical) + (unsigned long)(offset))
|
||||
|
||||
|
||||
#define TEST_POOL_TOTAL 5
|
||||
/*
|
||||
* Test page pool
|
||||
*/
|
||||
void test_page_pool(void)
|
||||
{
|
||||
void *p[TEST_POOL_TOTAL], *v[TEST_POOL_TOTAL];
|
||||
|
||||
/* Allocate test pages */
|
||||
for (int i = 0; i < TEST_POOL_TOTAL; i++) {
|
||||
v[i] = virtual_page_new(1);
|
||||
p[i] = physical_page_new(1);
|
||||
dbg_printf("Test allocated: Virtual%d: 0x%p, "
|
||||
"Physical%d, 0x%p\n",
|
||||
i, v[i], i, p[i]);
|
||||
}
|
||||
|
||||
/* Free test pages */
|
||||
for (int i = 0; i < TEST_POOL_TOTAL; i++) {
|
||||
virtual_page_free(v[i], 1);
|
||||
physical_page_free(p[i], 1);
|
||||
}
|
||||
|
||||
/* Re-allocate test pages */
|
||||
for (int i = 0; i < TEST_POOL_TOTAL; i++) {
|
||||
v[i] = virtual_page_new(1);
|
||||
p[i] = physical_page_new(1);
|
||||
dbg_printf("Test allocated: Virtual%d: 0x%p, "
|
||||
"Physical%d, 0x%p\n",
|
||||
i, v[i], i, p[i]);
|
||||
}
|
||||
|
||||
/* Free test pages */
|
||||
for (int i = 0; i < TEST_POOL_TOTAL; i++) {
|
||||
virtual_page_free(v[i], 1);
|
||||
physical_page_free(p[i], 1);
|
||||
}
|
||||
|
||||
/* Allocate in different lengths */
|
||||
for (int i = 0; i < TEST_POOL_TOTAL; i++) {
|
||||
v[i] = virtual_page_new(i);
|
||||
p[i] = physical_page_new(i);
|
||||
dbg_printf("Test allocated: Virtual%d: 0x%p, "
|
||||
"Physical%d, 0x%p\n",
|
||||
i, v[i], i, p[i]);
|
||||
}
|
||||
|
||||
/* Free test pages in different order */
|
||||
for (int i = TEST_POOL_TOTAL - 1; i >= 0; i--) {
|
||||
virtual_page_free(v[i], 1);
|
||||
physical_page_free(p[i], 1);
|
||||
}
|
||||
|
||||
/* Allocate in different lengths */
|
||||
for (int i = 0; i < TEST_POOL_TOTAL; i++) {
|
||||
v[i] = virtual_page_new(i);
|
||||
p[i] = physical_page_new(i);
|
||||
dbg_printf("Test allocated: Virtual%d: 0x%p, "
|
||||
"Physical%d, 0x%p\n",
|
||||
i, v[i], i, p[i]);
|
||||
}
|
||||
|
||||
/* Free test pages in normal order */
|
||||
for (int i = 0; i < TEST_POOL_TOTAL; i++) {
|
||||
virtual_page_free(v[i], 1);
|
||||
physical_page_free(p[i], 1);
|
||||
}
|
||||
}
|
||||
|
||||
void page_pool_init(void)
|
||||
{
|
||||
struct capability *physcap, *virtcap;
|
||||
unsigned long phys_start, phys_end;
|
||||
unsigned long virt_start, virt_end;
|
||||
|
||||
/*
|
||||
* Get physmem capability (Must be only one)
|
||||
*/
|
||||
if (!(physcap = cap_get_physmem(CAP_TYPE_MAP_PHYSMEM))) {
|
||||
printf("FATAL: Could not find a physical memory"
|
||||
"capability to use as a page pool.\n");
|
||||
BUG();
|
||||
}
|
||||
|
||||
/*
|
||||
* Get virtmem capability (Must be only one)
|
||||
*/
|
||||
if (!(virtcap = cap_get_by_type(CAP_TYPE_MAP_VIRTMEM))) {
|
||||
printf("FATAL: Could not find a virtual memory"
|
||||
"capability to use as a page pool.\n");
|
||||
BUG();
|
||||
}
|
||||
|
||||
/*
|
||||
* Now initialize physical and virtual page marks
|
||||
* from unused pages. Linker script will help us
|
||||
* on this.
|
||||
*/
|
||||
/*
|
||||
printf("__data_start symbol: %lx\n", (unsigned long)__data_start);
|
||||
printf("__data_end symbol: %lx\n", (unsigned long)__data_end);
|
||||
printf("__bss_start symbol: %lx\n", (unsigned long)__bss_start);
|
||||
printf("__bss_end symbol: %lx\n", (unsigned long)__bss_end);
|
||||
printf("__stack_start symbol: %lx\n", (unsigned long)__stack_start);
|
||||
printf("__stack_end symbol: %lx\n", (unsigned long)__stack_end);
|
||||
printf("__end symbol: %lx\n", (unsigned long)__end);
|
||||
*/
|
||||
|
||||
phys_start = page_align_up(virt_to_phys(__end) +
|
||||
(unsigned long)lma_start);
|
||||
phys_end = __pfn_to_addr(physcap->end);
|
||||
|
||||
dbg_printf("%s: Initializing physical range 0x%lx - 0x%lx\n",
|
||||
__FUNCTION__, phys_start, phys_end);
|
||||
|
||||
virt_start = page_align_up(__end) + (unsigned long)lma_start;
|
||||
virt_end = __pfn_to_addr(virtcap->end);
|
||||
|
||||
dbg_printf("%s: Initializing virtual range 0x%lx - 0x%lx\n",
|
||||
__FUNCTION__, virt_start, virt_end);
|
||||
|
||||
/* Initialize pools, maximum of PAGE_POOL_SIZE size */
|
||||
address_pool_init(&virtual_page_pool,
|
||||
(struct id_pool *)&virtual_idpool,
|
||||
virt_start, min(virt_end,
|
||||
virt_start + PAGE_POOL_SIZE));
|
||||
address_pool_init(&physical_page_pool,
|
||||
(struct id_pool *)&physical_idpool,
|
||||
phys_start, min(phys_end,
|
||||
phys_start + PAGE_POOL_SIZE));
|
||||
|
||||
// test_page_pool();
|
||||
}
|
||||
|
||||
/*
|
||||
* Some tests require page-faulting virtual addresses or
|
||||
* differing virtual addresses that map onto the same
|
||||
* physical page. These functions provide these pages.
|
||||
*/
|
||||
|
||||
void *virtual_page_new(int npages)
|
||||
{
|
||||
return address_new(&virtual_page_pool, npages, PAGE_SIZE);
|
||||
}
|
||||
|
||||
void *physical_page_new(int npages)
|
||||
{
|
||||
return address_new(&physical_page_pool, npages, PAGE_SIZE);
|
||||
}
|
||||
|
||||
void virtual_page_free(void *address, int npages)
|
||||
{
|
||||
address_del(&virtual_page_pool, address,
|
||||
npages, PAGE_SIZE);
|
||||
}
|
||||
|
||||
void physical_page_free(void *address, int npages)
|
||||
{
|
||||
address_del(&physical_page_pool, address,
|
||||
npages, PAGE_SIZE);
|
||||
}
|
||||
|
||||
204
conts/baremetal/test_suite/src/api/mutex.c
Normal file
204
conts/baremetal/test_suite/src/api/mutex.c
Normal file
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Test l4_mutex_control system call.
|
||||
*
|
||||
* Copyright (C) 2010 B Labs Ltd.
|
||||
*
|
||||
* Author: Bahadir Balban
|
||||
*/
|
||||
|
||||
#include <l4lib/macros.h>
|
||||
#include L4LIB_INC_ARCH(syslib.h)
|
||||
#include L4LIB_INC_ARCH(syscalls.h)
|
||||
#include <l4lib/lib/thread.h>
|
||||
#include <l4lib/mutex.h>
|
||||
#include <tests.h>
|
||||
|
||||
#define MUTEX_NTHREADS 8
|
||||
#define MUTEX_INCREMENTS 200
|
||||
#define MUTEX_VALUE_TOTAL (MUTEX_NTHREADS * MUTEX_INCREMENTS)
|
||||
|
||||
struct mutex_test_data {
|
||||
struct l4_mutex lock;
|
||||
int val;
|
||||
};
|
||||
|
||||
static struct mutex_test_data tdata;
|
||||
|
||||
static void init_test_data(struct mutex_test_data *tdata)
|
||||
{
|
||||
l4_mutex_init(&tdata->lock);
|
||||
tdata->val = 0;
|
||||
}
|
||||
|
||||
|
||||
int mutex_thread_non_contending(void *arg)
|
||||
{
|
||||
struct mutex_test_data *data =
|
||||
(struct mutex_test_data *)arg;
|
||||
l4id_t tid = self_tid();
|
||||
int err = tid;
|
||||
|
||||
for (int i = 0; i < MUTEX_INCREMENTS; i++) {
|
||||
/* Lock the data structure */
|
||||
if ((err = l4_mutex_lock(&data->lock)) < 0) {
|
||||
dbg_printf("Thread %d: Acquiring mutex failed. "
|
||||
"err = %d\n", tid, err);
|
||||
return -err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Increment and release lock
|
||||
*/
|
||||
data->val++;
|
||||
|
||||
/* Unlock the data structure */
|
||||
if ((err = l4_mutex_unlock(&data->lock)) < 0) {
|
||||
dbg_printf("Thread %d: Releasing the mutex failed. "
|
||||
"err = %d\n", tid, err);
|
||||
return -err;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int mutex_thread_contending(void *arg)
|
||||
{
|
||||
struct mutex_test_data *data =
|
||||
(struct mutex_test_data *)arg;
|
||||
l4id_t tid = self_tid();
|
||||
int err = tid;
|
||||
|
||||
for (int i = 0; i < MUTEX_INCREMENTS; i++) {
|
||||
/* Lock the data structure */
|
||||
if ((err = l4_mutex_lock(&data->lock)) < 0) {
|
||||
dbg_printf("Thread %d: Acquiring mutex failed. "
|
||||
"err = %d\n", tid, err);
|
||||
return -err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sleep some time to have some
|
||||
* threads blocked on the mutex
|
||||
*/
|
||||
for (int j = 0; j < 3; j++)
|
||||
l4_thread_switch(0);
|
||||
|
||||
/*
|
||||
* Increment and release lock
|
||||
*/
|
||||
data->val++;
|
||||
|
||||
/* Unlock the data structure */
|
||||
if ((err = l4_mutex_unlock(&data->lock)) < 0) {
|
||||
dbg_printf("Thread %d: Releasing the mutex failed. "
|
||||
"err = %d\n", tid, err);
|
||||
return -err;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int test_mutex(int (*mutex_thread)(void *))
|
||||
{
|
||||
struct l4_thread *thread[MUTEX_NTHREADS];
|
||||
int err;
|
||||
|
||||
/* Init mutex data */
|
||||
init_test_data(&tdata);
|
||||
|
||||
/*
|
||||
* Lock the mutex so nobody starts working
|
||||
*/
|
||||
if ((err = l4_mutex_lock(&tdata.lock)) < 0) {
|
||||
dbg_printf("Acquiring mutex failed. "
|
||||
"err = %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Create threads */
|
||||
for (int i = 0; i < MUTEX_NTHREADS; i++) {
|
||||
if ((err = thread_create(mutex_thread,
|
||||
&tdata,
|
||||
TC_SHARE_SPACE,
|
||||
&thread[i])) < 0) {
|
||||
dbg_printf("Thread create failed. "
|
||||
"err=%d\n", err);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
/* Unlock the mutex and initiate all workers */
|
||||
if ((err = l4_mutex_unlock(&tdata.lock)) < 0) {
|
||||
dbg_printf("Releasing the mutex failed. "
|
||||
"err = %d\n", err);
|
||||
return -err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for all threads to exit successfully
|
||||
*/
|
||||
for (int i = 0; i < MUTEX_NTHREADS; i++) {
|
||||
if ((err = thread_wait(thread[i])) < 0) {
|
||||
dbg_printf("THREAD_WAIT failed. "
|
||||
"err=%d\n", err);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Test that lock is in correct state
|
||||
*/
|
||||
if (tdata.lock.lock != L4_MUTEX_UNLOCKED) {
|
||||
dbg_printf("MUTEX is not in unlocked condition "
|
||||
"after tests. lockval = %d, expected = %d\n",
|
||||
tdata.lock.lock, L4_MUTEX_UNLOCKED);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test that increments have occured correctly
|
||||
*/
|
||||
if (tdata.val != MUTEX_VALUE_TOTAL) {
|
||||
dbg_printf("Lock-protected value incremented incorrectly "
|
||||
"after mutex worker threads.\n"
|
||||
"val = %d, expected = %d\n",
|
||||
tdata.val,
|
||||
MUTEX_VALUE_TOTAL);
|
||||
return -1;
|
||||
}
|
||||
if (tdata.val != MUTEX_VALUE_TOTAL) {
|
||||
dbg_printf("Lock-protected value incremented incorrectly "
|
||||
"after mutex worker threads.\n"
|
||||
"val = %d, expected = %d\n",
|
||||
tdata.val,
|
||||
MUTEX_VALUE_TOTAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
dbg_printf("Mutex test successful.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_api_mutexctrl(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
if ((err = test_mutex(mutex_thread_contending)) < 0)
|
||||
goto out_err;
|
||||
|
||||
if ((err = test_mutex(mutex_thread_non_contending)) < 0)
|
||||
goto out_err;
|
||||
|
||||
printf("USERSPACE MUTEX: -- PASSED --\n");
|
||||
return 0;
|
||||
|
||||
out_err:
|
||||
printf("USERSPACE MUTEX: -- FAILED --\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
arch-arm
|
||||
@@ -3,10 +3,11 @@
|
||||
*
|
||||
* Copyright (C) 2008 - 2010 B Labs Ltd.
|
||||
*/
|
||||
#include <task.h>
|
||||
#include <vm_area.h>
|
||||
#include <macros.h>
|
||||
#include <l4lib/exregs.h>
|
||||
#include __INC_ARCH(mm.h)
|
||||
#include <fault.h>
|
||||
#include INC_SUBARCH(mm.h)
|
||||
#include INC_SUBARCH(exception.h)
|
||||
|
||||
/* Extracts generic protection flags from architecture-specific pte */
|
||||
unsigned int vm_prot_flags(pte_t pte)
|
||||
@@ -60,6 +61,6 @@ void set_generic_fault_params(struct fault_data *fault)
|
||||
else
|
||||
BUG();
|
||||
}
|
||||
arch_print_fault_params(fault);
|
||||
// arch_print_fault_params(fault);
|
||||
}
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
* Copyright (C) 2009 B Labs Ltd.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <l4lib/capability/cap_print.h>
|
||||
#include <l4lib/lib/cap.h>
|
||||
#include <l4lib/macros.h>
|
||||
#include L4LIB_INC_ARCH(syscalls.h)
|
||||
|
||||
#if 0
|
||||
static struct capability cap_array[30];
|
||||
|
||||
#if 0
|
||||
struct cap_group {
|
||||
struct cap_list virtmem;
|
||||
struct cap_list physmem;
|
||||
@@ -75,7 +75,6 @@ void cap_grant_single(struct capability *orig, struct capability *share, l4id_t
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int caps_read_all(void)
|
||||
{
|
||||
@@ -104,3 +103,4 @@ int caps_read_all(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -19,8 +19,7 @@ int simple_pager_thread(void *arg)
|
||||
printf("Thread spawned from pager, \
|
||||
trying to create new thread.\n");
|
||||
err = l4_thread_control(THREAD_CREATE |
|
||||
TC_SHARE_SPACE |
|
||||
TC_AS_PAGER, &ids);
|
||||
TC_SHARE_SPACE, &ids);
|
||||
|
||||
if (res == 0)
|
||||
if (err == -ENOCAP ||
|
||||
|
||||
@@ -39,7 +39,6 @@ void perf_measure_getid_ticks(void)
|
||||
timer_load(timer_ldval, timer_base);
|
||||
|
||||
/* Start the timer */
|
||||
printf("Starting the l4_getid timer tick test.\n");
|
||||
timer_start(timer_base);
|
||||
|
||||
/* Do the operation */
|
||||
@@ -56,7 +55,7 @@ void perf_measure_getid_ticks(void)
|
||||
total += last;
|
||||
}
|
||||
|
||||
printf("TIMER: l4_getid took each %u min, %u max, %u avg,\n"
|
||||
printf("L4_GETID(timer) took each %u min, %u max, %u avg, "
|
||||
"%u total microseconds, and %u total ops\n", min,
|
||||
max, total/ops, total, ops);
|
||||
}
|
||||
@@ -77,7 +76,6 @@ void perf_measure_getid(void)
|
||||
/*
|
||||
* Do the test
|
||||
*/
|
||||
printf("Starting the l4_getid cycle counter test.\n");
|
||||
for (int i = 0; i < PERFTEST_GETID_COUNT; i++) {
|
||||
perfmon_reset_start_cyccnt();
|
||||
l4_getid(&ids);
|
||||
@@ -93,9 +91,9 @@ void perf_measure_getid(void)
|
||||
/*
|
||||
* Print results
|
||||
*/
|
||||
printf("PERFMON: %s took %llu min, %llu max, %llu avg, "
|
||||
printf("L4_GETID (cycle counter): took %llu cycles, %llu min, %llu max, %llu avg, "
|
||||
"%llu total microseconds in %llu ops.\n",
|
||||
"l4_getid()",
|
||||
l4_getid_cycles.min,
|
||||
l4_getid_cycles.min * USEC_MULTIPLIER,
|
||||
l4_getid_cycles.max * USEC_MULTIPLIER,
|
||||
l4_getid_cycles.avg * USEC_MULTIPLIER,
|
||||
@@ -8,4 +8,5 @@
|
||||
|
||||
void perf_measure_mutex(void)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -20,6 +20,7 @@ int test_performance(void)
|
||||
|
||||
perf_measure_getid_ticks();
|
||||
perf_measure_getid();
|
||||
perf_measure_tswitch();
|
||||
perf_measure_tctrl();
|
||||
perf_measure_exregs();
|
||||
perf_measure_ipc();
|
||||
@@ -51,8 +51,9 @@ void perf_measure_tctrl(void)
|
||||
/*
|
||||
* Print results
|
||||
*/
|
||||
printf("%s took %llu min, %llu max, %llu avg, in %llu ops.\n",
|
||||
printf("%s took %llu cycles, %llu min, %llu max, %llu avg, in %llu ops.\n",
|
||||
"THREAD_CREATE",
|
||||
tctrl_cycles.min,
|
||||
tctrl_cycles.min * USEC_MULTIPLIER,
|
||||
tctrl_cycles.max * USEC_MULTIPLIER,
|
||||
tctrl_cycles.avg * USEC_MULTIPLIER,
|
||||
@@ -11,7 +11,6 @@
|
||||
#include L4LIB_INC_ARCH(syslib.h)
|
||||
#include L4LIB_INC_ARCH(syscalls.h)
|
||||
|
||||
/* Note this must be obtained from the capability */
|
||||
#define TIMER_PHYSICAL_BASE 0x10012000
|
||||
|
||||
unsigned long timer_base;
|
||||
150
conts/baremetal/test_suite/src/perf/tswitch.c
Normal file
150
conts/baremetal/test_suite/src/perf/tswitch.c
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright (C) 2010 B Labs Ltd.
|
||||
*
|
||||
* l4_thread_control performance tests
|
||||
*
|
||||
* Author: Bahadir Balban
|
||||
*/
|
||||
|
||||
#include <l4lib/macros.h>
|
||||
#include L4LIB_INC_ARCH(syslib.h)
|
||||
#include L4LIB_INC_ARCH(syscalls.h)
|
||||
#include <l4lib/lib/thread.h>
|
||||
#include <l4lib/perfmon.h>
|
||||
#include <perf.h>
|
||||
#include <tests.h>
|
||||
#include <string.h>
|
||||
|
||||
struct perfmon_cycles thread_switch_cycles;
|
||||
struct perfmon_cycles space_switch_cycles;
|
||||
|
||||
static int indicate_switch = 0;
|
||||
|
||||
void thread_switcher_thread(void *arg)
|
||||
{
|
||||
l4id_t parent = ((struct task_ids *)arg)->tid;
|
||||
|
||||
printf("%s: Running\n", __FUNCTION__);
|
||||
/* Wait until parent signals us to switch */
|
||||
while (!indicate_switch)
|
||||
l4_thread_switch(parent);
|
||||
|
||||
/*
|
||||
* Now do one last switch, which will
|
||||
* be used in the actual switch measurement
|
||||
*/
|
||||
l4_thread_switch(parent);
|
||||
}
|
||||
|
||||
void perf_measure_thread_switch_simple(void)
|
||||
{
|
||||
struct task_ids thread_switcher;
|
||||
struct task_ids selfid;
|
||||
l4_getid(&selfid);
|
||||
|
||||
/*
|
||||
* Initialize structures
|
||||
*/
|
||||
memset(&thread_switch_cycles, 0, sizeof (struct perfmon_cycles));
|
||||
thread_switch_cycles.min = ~0; /* Init as maximum possible */
|
||||
|
||||
/* Start the counter */
|
||||
perfmon_reset_start_cyccnt();
|
||||
|
||||
l4_thread_switch(0);
|
||||
|
||||
perfmon_record_cycles(&thread_switch_cycles, "THREAD_SWITCH");
|
||||
|
||||
/*
|
||||
* Calculate average
|
||||
*/
|
||||
thread_switch_cycles.avg =
|
||||
thread_switch_cycles.total / thread_switch_cycles.ops;
|
||||
|
||||
/*
|
||||
* Print results
|
||||
*/
|
||||
printf("%s took %llu cycles, %llu min, %llu max, %llu avg, in %llu ops.\n",
|
||||
"THREAD_SWITCH",
|
||||
thread_switch_cycles.min,
|
||||
thread_switch_cycles.min * USEC_MULTIPLIER,
|
||||
thread_switch_cycles.max * USEC_MULTIPLIER,
|
||||
thread_switch_cycles.avg * USEC_MULTIPLIER,
|
||||
thread_switch_cycles.ops);
|
||||
}
|
||||
|
||||
void perf_measure_thread_switch(void)
|
||||
{
|
||||
struct task_ids thread_switcher;
|
||||
struct task_ids selfid;
|
||||
l4_getid(&selfid);
|
||||
|
||||
/*
|
||||
* Initialize structures
|
||||
*/
|
||||
memset(&thread_switch_cycles, 0, sizeof (struct perfmon_cycles));
|
||||
thread_switch_cycles.min = ~0; /* Init as maximum possible */
|
||||
|
||||
/* Create switcher thread */
|
||||
l4_thread_control(THREAD_CREATE | TC_SHARE_SPACE, &selfid);
|
||||
|
||||
/* Copy ids of created task */
|
||||
memcpy(&thread_switcher, &selfid, sizeof(struct task_ids));
|
||||
|
||||
/* Switch to the thread to ensure it runs at least once */
|
||||
l4_thread_switch(thread_switcher.tid);
|
||||
|
||||
/* Start the counter */
|
||||
perfmon_reset_start_cyccnt();
|
||||
|
||||
/* Set the switch indicator */
|
||||
indicate_switch = 1;
|
||||
|
||||
/*
|
||||
* Switch to thread.
|
||||
*
|
||||
* We should be in full control here, because
|
||||
* the thread must have run out of its time slices.
|
||||
*/
|
||||
l4_thread_switch(thread_switcher.tid);
|
||||
|
||||
/*
|
||||
* By this time, the switcher thread must have done a
|
||||
* thread switch back to us
|
||||
*/
|
||||
perfmon_record_cycles(&thread_switch_cycles, "THREAD_SWITCH");
|
||||
|
||||
/*
|
||||
* Calculate average
|
||||
*/
|
||||
thread_switch_cycles.avg =
|
||||
thread_switch_cycles.total / thread_switch_cycles.ops;
|
||||
|
||||
/*
|
||||
* Print results
|
||||
*/
|
||||
printf("%s took %llu cycles, %llu min, %llu max, %llu avg, in %llu ops.\n",
|
||||
"THREAD_SWITCH",
|
||||
thread_switch_cycles.min,
|
||||
thread_switch_cycles.min * USEC_MULTIPLIER,
|
||||
thread_switch_cycles.max * USEC_MULTIPLIER,
|
||||
thread_switch_cycles.avg * USEC_MULTIPLIER,
|
||||
thread_switch_cycles.ops);
|
||||
|
||||
|
||||
/* Destroy the thread */
|
||||
l4_thread_control(THREAD_DESTROY, &thread_switcher);
|
||||
}
|
||||
|
||||
|
||||
void perf_measure_space_switch(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void perf_measure_tswitch(void)
|
||||
{
|
||||
perf_measure_thread_switch_simple();
|
||||
perf_measure_space_switch();
|
||||
}
|
||||
11
conts/baremetal/threads_demo/SConscript
Normal file
11
conts/baremetal/threads_demo/SConscript
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
# Inherit global environment
|
||||
Import('env')
|
||||
|
||||
# The set of source files associated with this SConscript file.
|
||||
src_local = Glob('*.[cS]')
|
||||
src_local += Glob('src/*.[cS]')
|
||||
|
||||
obj = env.Object(src_local)
|
||||
Return('obj')
|
||||
|
||||
@@ -4,62 +4,54 @@
|
||||
#
|
||||
# Copyright © 2009 B Labs Ltd
|
||||
#
|
||||
import os, shelve, sys
|
||||
import os, sys
|
||||
from os.path import *
|
||||
|
||||
PROJRELROOT = '../..'
|
||||
CONTS_XXX = '../..'
|
||||
BAREMETAL_CONTS_XXX = '../../..'
|
||||
sys.path.append(CONTS_XXX)
|
||||
sys.path.append(BAREMETAL_CONTS_XXX)
|
||||
|
||||
sys.path.append(PROJRELROOT)
|
||||
|
||||
from config.projpaths import *
|
||||
from config.configuration import *
|
||||
from scripts.config.projpaths import *
|
||||
from scripts.conts.containers import *
|
||||
from scripts.config.configuration import *
|
||||
|
||||
config = configuration_retrieve()
|
||||
platform = config.platform
|
||||
arch = config.arch
|
||||
gcc_arch_flag = config.gcc_arch_flag
|
||||
|
||||
LIBL4_RELDIR = 'conts/libl4'
|
||||
KERNEL_INCLUDE = join(PROJROOT, 'include')
|
||||
LIBL4_DIR = join(PROJROOT, LIBL4_RELDIR)
|
||||
LIBL4_INCLUDE = join(LIBL4_DIR, 'include')
|
||||
LIBL4_LIBPATH = join(BUILDDIR, LIBL4_RELDIR)
|
||||
cid = int(ARGUMENTS.get('cid', 0))
|
||||
cont = find_container_from_cid(cid)
|
||||
|
||||
# Locally important paths are here
|
||||
LIBC_RELDIR = 'conts/libc'
|
||||
LIBC_DIR = join(PROJROOT, LIBC_RELDIR)
|
||||
LIBC_LIBPATH = join(BUILDDIR, LIBC_RELDIR)
|
||||
LIBC_INCLUDE = [join(LIBC_DIR, 'include'), \
|
||||
join(LIBC_DIR, 'include/arch' + '/' + arch)]
|
||||
builddir = join(join(BUILDDIR, 'cont') + str(cid), cont.name)
|
||||
|
||||
LIBDEV_RELDIR = 'conts/libdev'
|
||||
LIBDEV_DIR = join(PROJROOT, LIBDEV_RELDIR)
|
||||
LIBDEV_LIBPATH = join(join(BUILDDIR, LIBDEV_RELDIR), 'sys-userspace')
|
||||
LIBDEV_INCLUDE = [join(LIBDEV_DIR, 'uart/include')]
|
||||
|
||||
LIBMEM_RELDIR = 'conts/libmem'
|
||||
LIBMEM_DIR = join(PROJROOT, LIBMEM_RELDIR)
|
||||
LIBMEM_LIBPATH = join(BUILDDIR, LIBMEM_RELDIR)
|
||||
LIBMEM_INCLUDE = LIBMEM_DIR
|
||||
# linker.lds is generated either in conts/xxx or build/contx/include
|
||||
if cont.duplicate == 0:
|
||||
linker_lds = join(builddir, 'include/linker.lds')
|
||||
else:
|
||||
linker_lds = 'include/linker.lds'
|
||||
|
||||
env = Environment(CC = config.toolchain_userspace + 'gcc',
|
||||
# We don't use -nostdinc because sometimes we need standard headers,
|
||||
# such as stdarg.h e.g. for variable args, as in printk().
|
||||
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', \
|
||||
'-Werror', '-march=' + gcc_arch_flag],
|
||||
LINKFLAGS = ['-nostdlib', '-T' + "include/linker.lds", "-u_start"],
|
||||
ASFLAGS = ['-D__ASSEMBLY__'],
|
||||
# We don't use -nostdinc because sometimes we need standard headers,
|
||||
# such as stdarg.h e.g. for variable args, as in printk().
|
||||
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall',
|
||||
'-Werror', '-march=' + gcc_arch_flag],
|
||||
LINKFLAGS = ['-nostdlib', '-T' + linker_lds, '-u_start'],
|
||||
ASFLAGS = ['-D__ASSEMBLY__'],
|
||||
PROGSUFFIX = '.elf', # The suffix to use for final executable
|
||||
ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path
|
||||
LIBS = ['libl4', 'libmalloc', 'c-userspace', 'libdev-userspace', \
|
||||
'gcc', 'c-userspace'], # libgcc.a - This is required for division routines.
|
||||
CPPPATH = ["#include", KERNEL_INCLUDE, LIBL4_INCLUDE, LIBDEV_INCLUDE, LIBC_INCLUDE],
|
||||
LIBPATH = [LIBL4_LIBPATH, LIBDEV_LIBPATH, LIBC_LIBPATH, LIBMEM_LIBPATH],
|
||||
CPPFLAGS = '-include l4/config.h -include l4/macros.h -include l4/types.h')
|
||||
LIBS = ['gcc', 'libl4', 'c-userspace', 'libdev-userspace',
|
||||
'libmem', 'gcc', 'c-userspace'],
|
||||
# libgcc.a - This is required for division routines.
|
||||
CPPPATH = ["#include", KERNEL_HEADERS, LIBL4_INCLUDE, LIBDEV_INCLUDE,
|
||||
LIBC_INCLUDE, LIBMEM_INCLUDE, join(builddir, 'include')],
|
||||
LIBPATH = [LIBL4_LIBPATH, LIBDEV_USER_LIBPATH, LIBC_LIBPATH, LIBMEM_LIBPATH],
|
||||
CPPFLAGS = '-include l4/config.h -include l4/macros.h \
|
||||
-include l4/types.h -include l4lib/macros.h')
|
||||
|
||||
src = Glob('*.[cS]')
|
||||
src += Glob('src/*.[cS]')
|
||||
objs = SConscript('SConscript', exports = { 'env' : env },
|
||||
duplicate=0, build_dir = builddir)
|
||||
|
||||
objs = env.Object(src)
|
||||
prog = env.Program('main.elf', objs)
|
||||
Depends(prog, 'include/linker.lds')
|
||||
Depends(objs, join(PROJROOT, CONFIG_H))
|
||||
|
||||
prog = env.Program(join(builddir, 'main.elf'), objs)
|
||||
Depends(prog, linker_lds)
|
||||
|
||||
108
conts/baremetal/threads_demo/thread.c
Normal file
108
conts/baremetal/threads_demo/thread.c
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Test l4_mutex_control system call.
|
||||
*
|
||||
* Copyright (C) 2010 B Labs Ltd.
|
||||
*
|
||||
* Author: Bahadir Balban
|
||||
*/
|
||||
|
||||
#include <l4lib/macros.h>
|
||||
#include L4LIB_INC_ARCH(syslib.h)
|
||||
#include L4LIB_INC_ARCH(syscalls.h)
|
||||
#include <l4lib/lib/thread.h>
|
||||
|
||||
#define NTHREADS 6
|
||||
#define dbg_printf printf
|
||||
|
||||
int thread_test_func1(void *arg)
|
||||
{
|
||||
l4id_t tid = self_tid();
|
||||
|
||||
printf("tid = %d is called.\n", tid);
|
||||
|
||||
/* Wait for a while before exiting */
|
||||
int j = 0x400000;
|
||||
while (j--)
|
||||
;
|
||||
|
||||
return tid;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int thread_test_func2(void *arg)
|
||||
{
|
||||
l4id_t tid = self_tid();
|
||||
|
||||
printf("tid = %d is called.\n", tid);
|
||||
|
||||
/* Wait for a while before exiting */
|
||||
int j = 0x400000;
|
||||
while (j--)
|
||||
;
|
||||
|
||||
thread_exit(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int thread_demo()
|
||||
{
|
||||
struct l4_thread *thread[NTHREADS];
|
||||
int err;
|
||||
|
||||
/* Create threads */
|
||||
for (int i = 0; i < NTHREADS; i++) {
|
||||
if (i % 2 ) {
|
||||
err = thread_create(thread_test_func1, 0,
|
||||
TC_SHARE_SPACE, &thread[i]);
|
||||
|
||||
if (err < 0) {
|
||||
dbg_printf("Thread create failed. "
|
||||
"err=%d i= %d\n", err, i);
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
err = thread_create(thread_test_func2, 0,
|
||||
TC_SHARE_SPACE, &thread[i]);
|
||||
if (err < 0) {
|
||||
dbg_printf("Thread create failed. "
|
||||
"err=%d i= %d\n", err, i);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for all threads to exit successfully
|
||||
*/
|
||||
for (int i = 0; i < NTHREADS; i++) {
|
||||
if ((err = thread_wait(thread[i])) < 0) {
|
||||
dbg_printf("THREAD_WAIT failed. "
|
||||
"err=%d\n", err);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
dbg_printf("Thread test successful.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
__l4_threadlib_init();
|
||||
|
||||
if ((err = thread_demo()) < 0)
|
||||
goto out_err;
|
||||
|
||||
printf("THREAD DEMO: -- PASSED --\n");
|
||||
return 0;
|
||||
|
||||
out_err:
|
||||
printf("THREAD DEMO: -- FAILED --\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
12
conts/baremetal/timer_service/SConscript
Normal file
12
conts/baremetal/timer_service/SConscript
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
# Inherit global environment
|
||||
Import('env')
|
||||
|
||||
# The set of source files associated with this SConscript file.
|
||||
src_local = Glob('*.[cS]')
|
||||
src_local += Glob('src/*.[cS]')
|
||||
src_local += Glob('src/arch/*.[cS]')
|
||||
|
||||
obj = env.Object(src_local)
|
||||
Return('obj')
|
||||
|
||||
@@ -7,64 +7,51 @@
|
||||
import os, shelve, sys
|
||||
from os.path import *
|
||||
|
||||
PROJRELROOT = '../..'
|
||||
CONTS_XXX = '../..'
|
||||
BAREMETAL_CONTS_XXX = '../../..'
|
||||
sys.path.append(CONTS_XXX)
|
||||
sys.path.append(BAREMETAL_CONTS_XXX)
|
||||
|
||||
sys.path.append(PROJRELROOT)
|
||||
|
||||
from config.projpaths import *
|
||||
from config.configuration import *
|
||||
from configure import *
|
||||
from scripts.config.projpaths import *
|
||||
from scripts.config.configuration import *
|
||||
from scripts.conts.containers import *
|
||||
from scripts.config.config_invoke import *
|
||||
|
||||
config = configuration_retrieve()
|
||||
arch = config.arch
|
||||
platform = config.platform
|
||||
gcc_arch_flag = config.gcc_arch_flag
|
||||
|
||||
# Wrapper library for system calls
|
||||
LIBL4_RELDIR = 'conts/libl4'
|
||||
KERNEL_INCLUDE = join(PROJROOT, 'include')
|
||||
LIBL4_DIR = join(PROJROOT, LIBL4_RELDIR)
|
||||
LIBL4_INCLUDE = join(LIBL4_DIR, 'include')
|
||||
LIBL4_LIBPATH = join(BUILDDIR, LIBL4_RELDIR)
|
||||
cid = int(ARGUMENTS.get('cid', 0))
|
||||
cont = find_container_from_cid(cid)
|
||||
|
||||
# Some user-space libraries
|
||||
LIBC_RELDIR = 'conts/libc'
|
||||
LIBC_DIR = join(PROJROOT, LIBC_RELDIR)
|
||||
LIBC_LIBPATH = join(BUILDDIR, LIBC_RELDIR)
|
||||
LIBC_INCLUDE = [join(LIBC_DIR, 'include'), \
|
||||
join(LIBC_DIR, 'include/arch' + '/' + arch)]
|
||||
builddir = join(join(BUILDDIR, 'cont') + str(cid), cont.name)
|
||||
|
||||
LIBDEV_RELDIR = 'conts/libdev'
|
||||
LIBDEV_DIR = join(PROJROOT, LIBDEV_RELDIR)
|
||||
LIBDEV_LIBPATH = join(join(BUILDDIR, LIBDEV_RELDIR), 'sys-userspace')
|
||||
LIBDEV_INCLUDE = join(LIBDEV_DIR, 'include')
|
||||
|
||||
LIBMEM_RELDIR = 'conts/libmem'
|
||||
LIBMEM_DIR = join(PROJROOT, LIBMEM_RELDIR)
|
||||
LIBMEM_LIBPATH = join(BUILDDIR, LIBMEM_RELDIR)
|
||||
LIBMEM_INCLUDE = LIBMEM_DIR
|
||||
# linker.lds is generated either in conts/xxx or build/contx/include
|
||||
if cont.duplicate == 0:
|
||||
linker_lds = join(builddir, 'include/linker.lds')
|
||||
else:
|
||||
linker_lds = 'include/linker.lds'
|
||||
|
||||
env = Environment(CC = config.toolchain_userspace + 'gcc',
|
||||
# We don't use -nostdinc because sometimes we need standard headers,
|
||||
# such as stdarg.h e.g. for variable args, as in printk().
|
||||
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', \
|
||||
'-Werror', '-march=' + gcc_arch_flag], \
|
||||
LINKFLAGS = ['-nostdlib', '-T' + "include/linker.lds", "-u_start"],\
|
||||
ASFLAGS = ['-D__ASSEMBLY__'], \
|
||||
PROGSUFFIX = '.elf', # The suffix to use for final executable
|
||||
ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path
|
||||
LIBS = ['gcc', 'libl4', 'c-userspace', 'libdev-userspace', \
|
||||
'libmm', 'libmc', 'libmalloc', 'gcc', 'c-userspace'],
|
||||
# libgcc.a - This is required for division routines.
|
||||
CPPPATH = ["#include", KERNEL_INCLUDE, LIBL4_INCLUDE, LIBDEV_INCLUDE, \
|
||||
LIBC_INCLUDE, LIBMEM_INCLUDE],
|
||||
LIBPATH = [LIBL4_LIBPATH, LIBDEV_LIBPATH, LIBC_LIBPATH, LIBMEM_LIBPATH],
|
||||
CPPFLAGS = '-include l4/config.h -include l4/macros.h -include l4/types.h')
|
||||
# We don't use -nostdinc because sometimes we need standard headers,
|
||||
# such as stdarg.h e.g. for variable args, as in printk().
|
||||
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall',
|
||||
'-Werror', '-march=' + gcc_arch_flag],
|
||||
LINKFLAGS = ['-nostdlib', '-T' + linker_lds, '-u_start'],
|
||||
ASFLAGS = ['-D__ASSEMBLY__'],
|
||||
PROGSUFFIX = '.elf', # The suffix to use for final executable
|
||||
ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path
|
||||
LIBS = ['gcc', 'libl4', 'c-userspace', 'libdev-userspace',
|
||||
'libmem', 'gcc', 'c-userspace'],
|
||||
# libgcc.a - This is required for division routines.
|
||||
CPPPATH = ["#include", KERNEL_HEADERS, LIBL4_INCLUDE, LIBDEV_INCLUDE,
|
||||
LIBC_INCLUDE, LIBMEM_INCLUDE, join(builddir, 'include')],
|
||||
LIBPATH = [LIBL4_LIBPATH, LIBDEV_USER_LIBPATH, LIBC_LIBPATH, LIBMEM_LIBPATH],
|
||||
CPPFLAGS = '-include l4/config.h -include l4/macros.h -include l4/types.h')
|
||||
|
||||
src = Glob('*.[cS]')
|
||||
src += Glob('src/*.[cS]')
|
||||
src += Glob('src/arch/*.[cS]')
|
||||
objs = SConscript('SConscript', exports = { 'env' : env },
|
||||
duplicate=0, build_dir = builddir)
|
||||
|
||||
objs = env.Object(src)
|
||||
prog = env.Program('main.elf', objs)
|
||||
Depends(prog, 'include/linker.lds')
|
||||
Depends(objs, join(PROJROOT, CONFIG_H))
|
||||
|
||||
prog = env.Program(join(builddir, 'main.elf'), objs)
|
||||
Depends(prog, linker_lds)
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <l4lib/init.h>
|
||||
#include <l4lib/utcb.h>
|
||||
#include <l4lib/lib/thread.h>
|
||||
#include <l4lib/lib/cap.h>
|
||||
|
||||
void main(void);
|
||||
|
||||
@@ -18,6 +19,8 @@ void __container_init(void)
|
||||
/* Thread library initialisation */
|
||||
__l4_threadlib_init();
|
||||
|
||||
__l4_capability_init();
|
||||
|
||||
/* Entry to main */
|
||||
main();
|
||||
}
|
||||
|
||||
@@ -78,7 +78,8 @@ struct timer {
|
||||
unsigned int count; /* Counter/jiffies */
|
||||
struct sleeper_task_bucket task_list; /* List of sleeping tasks */
|
||||
struct l4_mutex task_list_lock; /* Lock for sleeper_task_bucket */
|
||||
struct capability cap; /* Capability describing timer */
|
||||
unsigned long phys_base; /* Physical address of Device */
|
||||
int irq_no; /* IRQ number of device */
|
||||
};
|
||||
|
||||
#endif /* __TIMER_H__ */
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* Timer service for userspace
|
||||
*/
|
||||
#include <l4lib/lib/addr.h>
|
||||
#include <l4lib/lib/cap.h>
|
||||
#include <l4lib/irq.h>
|
||||
#include <l4lib/lib/thread.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
@@ -10,14 +11,15 @@
|
||||
#include <l4/api/capability.h>
|
||||
#include <l4/generic/cap-types.h>
|
||||
#include <l4/api/space.h>
|
||||
#include <malloc/malloc.h>
|
||||
#include <mem/malloc.h>
|
||||
#include <container.h>
|
||||
#include <linker.h>
|
||||
#include <timer.h>
|
||||
#include <libdev/timer.h>
|
||||
#include <dev/timer.h>
|
||||
#include <dev/platform.h>
|
||||
|
||||
/* Capabilities of this service */
|
||||
static struct capability caparray[32];
|
||||
static struct capability *caparray;
|
||||
static int total_caps = 0;
|
||||
|
||||
/* Total number of timer chips being handled by us */
|
||||
@@ -33,33 +35,6 @@ struct wake_task_list wake_tasks;
|
||||
/* tid of handle_request thread */
|
||||
l4id_t tid_ipc_handler;
|
||||
|
||||
int cap_read_all()
|
||||
{
|
||||
int ncaps;
|
||||
int err;
|
||||
|
||||
/* Read number of capabilities */
|
||||
if ((err = l4_capability_control(CAP_CONTROL_NCAPS,
|
||||
0, &ncaps)) < 0) {
|
||||
printf("l4_capability_control() reading # of"
|
||||
" capabilities failed.\n Could not "
|
||||
"complete CAP_CONTROL_NCAPS request.\n");
|
||||
BUG();
|
||||
}
|
||||
total_caps = ncaps;
|
||||
|
||||
/* Read all capabilities */
|
||||
if ((err = l4_capability_control(CAP_CONTROL_READ,
|
||||
0, caparray)) < 0) {
|
||||
printf("l4_capability_control() reading of "
|
||||
"capabilities failed.\n Could not "
|
||||
"complete CAP_CONTROL_READ_CAPS request.\n");
|
||||
BUG();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cap_share_all_with_space()
|
||||
{
|
||||
int err;
|
||||
@@ -160,32 +135,6 @@ struct link* find_bucket_list(unsigned long seconds)
|
||||
return vector;
|
||||
}
|
||||
|
||||
/*
|
||||
* Scans for up to TIMERS_TOTAL timer devices in capabilities.
|
||||
*/
|
||||
int timer_probe_devices(void)
|
||||
{
|
||||
int timers = 0;
|
||||
|
||||
/* Scan for timer devices */
|
||||
for (int i = 0; i < total_caps; i++) {
|
||||
/* Match device type */
|
||||
if (cap_devtype(&caparray[i]) == CAP_DEVTYPE_TIMER) {
|
||||
/* Copy to correct device index */
|
||||
memcpy(&global_timer[cap_devnum(&caparray[i]) - 1].cap,
|
||||
&caparray[i], sizeof(global_timer[0].cap));
|
||||
timers++;
|
||||
}
|
||||
}
|
||||
|
||||
if (timers != TIMERS_TOTAL) {
|
||||
printf("%s: Error, not all timers could be found. "
|
||||
"timers=%d\n", __CONTAINER_NAME__, timers);
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Irq handler for timer interrupts
|
||||
*/
|
||||
@@ -204,7 +153,7 @@ int timer_irq_handler(void *arg)
|
||||
|
||||
/* Register self for timer irq, using notify slot 0 */
|
||||
if ((err = l4_irq_control(IRQ_CONTROL_REGISTER, slot,
|
||||
timer->cap.irq)) < 0) {
|
||||
timer->irq_no)) < 0) {
|
||||
printf("%s: FATAL: Timer irq could not be registered. "
|
||||
"err=%d\n", __FUNCTION__, err);
|
||||
BUG();
|
||||
@@ -219,7 +168,7 @@ int timer_irq_handler(void *arg)
|
||||
struct link *task_list;
|
||||
|
||||
/* Block on irq */
|
||||
if((count = l4_irq_wait(slot, timer->cap.irq)) < 0) {
|
||||
if((count = l4_irq_wait(slot, timer->irq_no)) < 0) {
|
||||
printf("l4_irq_wait() returned with negative value\n");
|
||||
BUG();
|
||||
}
|
||||
@@ -234,6 +183,7 @@ int timer_irq_handler(void *arg)
|
||||
|
||||
/* find bucket list of taks to be woken for current count */
|
||||
vector = find_bucket_list(timer->count);
|
||||
l4_send(tid_ipc_handler,L4_IPC_TAG_TIMER_WAKE_THREADS);
|
||||
|
||||
if (!list_empty(vector)) {
|
||||
/* Removing tasks from sleeper list */
|
||||
@@ -300,19 +250,21 @@ int timer_setup_devices(void)
|
||||
struct l4_thread *tptr = &thread;
|
||||
int err;
|
||||
|
||||
global_timer[0].phys_base = PLATFORM_TIMER1_BASE;
|
||||
global_timer[0].irq_no = IRQ_TIMER1;
|
||||
|
||||
for (int i = 0; i < TIMERS_TOTAL; i++) {
|
||||
/* initialize timer */
|
||||
timer_struct_init(&global_timer[i],(unsigned long)l4_new_virtual(1) );
|
||||
|
||||
/* Map timer to a virtual address region */
|
||||
if (IS_ERR(l4_map((void *)__pfn_to_addr(global_timer[i].cap.start),
|
||||
(void *)global_timer[i].base, global_timer[i].cap.size,
|
||||
MAP_USR_IO,
|
||||
self_tid()))) {
|
||||
printf("%s: FATAL: Failed to map TIMER device "
|
||||
"%d to a virtual address\n",
|
||||
__CONTAINER_NAME__,
|
||||
cap_devnum(&global_timer[i].cap));
|
||||
if (IS_ERR(l4_map((void *)global_timer[i].phys_base,
|
||||
(void *)global_timer[i].base, 1,
|
||||
MAP_USR_IO, self_tid()))) {
|
||||
printf("%s: FATAL: Failed to map TIMER device from 0x%lx"
|
||||
" to 0x%lx\n", __CONTAINER_NAME__,
|
||||
global_timer[i].phys_base,
|
||||
global_timer[i].base);
|
||||
BUG();
|
||||
}
|
||||
|
||||
@@ -502,64 +454,20 @@ void handle_requests(void)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* UTCB-size aligned utcb.
|
||||
*
|
||||
* BIG WARNING NOTE: This declaration is legal if we are
|
||||
* running in a disjoint virtual address space, where the
|
||||
* utcb declaration lies in a unique virtual address in
|
||||
* the system.
|
||||
*/
|
||||
#define DECLARE_UTCB(name) \
|
||||
struct utcb name ALIGN(sizeof(struct utcb))
|
||||
|
||||
DECLARE_UTCB(utcb);
|
||||
|
||||
/* Set up own utcb for ipc */
|
||||
int l4_utcb_setup(void *utcb_address)
|
||||
{
|
||||
struct task_ids ids;
|
||||
struct exregs_data exregs;
|
||||
int err;
|
||||
|
||||
l4_getid(&ids);
|
||||
|
||||
/* Clear utcb */
|
||||
memset(utcb_address, 0, sizeof(struct utcb));
|
||||
|
||||
/* Setup exregs for utcb request */
|
||||
memset(&exregs, 0, sizeof(exregs));
|
||||
exregs_set_utcb(&exregs, (unsigned long)utcb_address);
|
||||
|
||||
if ((err = l4_exchange_registers(&exregs, ids.tid)) < 0)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* Read all capabilities */
|
||||
cap_read_all();
|
||||
caps_read_all();
|
||||
|
||||
total_caps = cap_get_count();
|
||||
caparray = cap_get_all();
|
||||
|
||||
/* Share all with space */
|
||||
cap_share_all_with_space();
|
||||
|
||||
/* Scan for timer devices in capabilities */
|
||||
timer_probe_devices();
|
||||
|
||||
/* Initialize virtual address pool for timers */
|
||||
init_vaddr_pool();
|
||||
|
||||
/* Setup own static utcb */
|
||||
if ((err = l4_utcb_setup(&utcb)) < 0) {
|
||||
printf("FATAL: Could not set up own utcb. "
|
||||
"err=%d\n", err);
|
||||
BUG();
|
||||
}
|
||||
|
||||
/* initialise timed_out_task list */
|
||||
wake_task_list_init();
|
||||
|
||||
|
||||
11
conts/baremetal/uart_service/SConscript
Normal file
11
conts/baremetal/uart_service/SConscript
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
# Inherit global environment
|
||||
Import('env')
|
||||
|
||||
# The set of source files associated with this SConscript file.
|
||||
src_local = Glob('*.[cS]')
|
||||
src_local += Glob('src/*.[cS]')
|
||||
|
||||
obj = env.Object(src_local)
|
||||
Return('obj')
|
||||
|
||||
@@ -7,60 +7,50 @@
|
||||
import os, shelve, sys
|
||||
from os.path import *
|
||||
|
||||
PROJRELROOT = '../..'
|
||||
CONTS_XXX = '../..'
|
||||
BAREMETAL_CONTS_XXX = '../../..'
|
||||
sys.path.append(CONTS_XXX)
|
||||
sys.path.append(BAREMETAL_CONTS_XXX)
|
||||
|
||||
sys.path.append(PROJRELROOT)
|
||||
|
||||
from config.projpaths import *
|
||||
from config.configuration import *
|
||||
from scripts.config.projpaths import *
|
||||
from scripts.conts.containers import *
|
||||
from scripts.config.configuration import *
|
||||
|
||||
config = configuration_retrieve()
|
||||
platform = config.platform
|
||||
arch = config.arch
|
||||
gcc_arch_flag = config.gcc_arch_flag
|
||||
|
||||
LIBL4_RELDIR = 'conts/libl4'
|
||||
KERNEL_INCLUDE = join(PROJROOT, 'include')
|
||||
LIBL4_DIR = join(PROJROOT, LIBL4_RELDIR)
|
||||
LIBL4_INCLUDE = join(LIBL4_DIR, 'include')
|
||||
LIBL4_LIBPATH = join(BUILDDIR, LIBL4_RELDIR)
|
||||
cid = int(ARGUMENTS.get('cid', 0))
|
||||
cont = find_container_from_cid(cid)
|
||||
|
||||
# Locally important paths are here
|
||||
LIBC_RELDIR = 'conts/libc'
|
||||
LIBC_DIR = join(PROJROOT, LIBC_RELDIR)
|
||||
LIBC_LIBPATH = join(BUILDDIR, LIBC_RELDIR)
|
||||
LIBC_INCLUDE = [join(LIBC_DIR, 'include'), \
|
||||
join(LIBC_DIR, 'include/arch' + '/' + arch)]
|
||||
builddir = join(join(BUILDDIR, 'cont') + str(cid), cont.name)
|
||||
|
||||
LIBDEV_RELDIR = 'conts/libdev'
|
||||
LIBDEV_DIR = join(PROJROOT, LIBDEV_RELDIR)
|
||||
LIBDEV_LIBPATH = join(join(BUILDDIR, LIBDEV_RELDIR), 'sys-userspace')
|
||||
LIBDEV_INCLUDE = join(LIBDEV_DIR, 'include')
|
||||
|
||||
# FIXME: Add these to autogenerated SConstruct !!!
|
||||
LIBMEM_RELDIR = 'conts/libmem'
|
||||
LIBMEM_DIR = join(PROJROOT, LIBMEM_RELDIR)
|
||||
LIBMEM_LIBPATH = join(BUILDDIR, LIBMEM_RELDIR)
|
||||
LIBMEM_INCLUDE = LIBMEM_DIR
|
||||
# linker.lds is generated either in conts/xxx or build/contx/include
|
||||
if cont.duplicate == 0:
|
||||
linker_lds = join(builddir, 'include/linker.lds')
|
||||
else:
|
||||
linker_lds = 'include/linker.lds'
|
||||
|
||||
env = Environment(CC = config.toolchain_userspace + 'gcc',
|
||||
# We don't use -nostdinc because sometimes we need standard headers,
|
||||
# such as stdarg.h e.g. for variable args, as in printk().
|
||||
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', \
|
||||
'-Werror', '-march=' + gcc_arch_flag],
|
||||
LINKFLAGS = ['-nostdlib', '-T' + "include/linker.lds", "-u_start"],
|
||||
ASFLAGS = ['-D__ASSEMBLY__'], \
|
||||
PROGSUFFIX = '.elf', # The suffix to use for final executable\
|
||||
ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path\
|
||||
LIBS = ['gcc', 'libl4', 'libmalloc', 'c-userspace', 'libdev-userspace',
|
||||
'gcc', 'c-userspace'], # libgcc.a - This is required for division routines.
|
||||
CPPPATH = ["#include", KERNEL_INCLUDE, LIBL4_INCLUDE, LIBDEV_INCLUDE, LIBC_INCLUDE, LIBMEM_INCLUDE],
|
||||
LIBPATH = [LIBL4_LIBPATH, LIBDEV_LIBPATH, LIBC_LIBPATH, LIBMEM_LIBPATH],
|
||||
CPPFLAGS = '-include l4/config.h -include l4/macros.h -include l4/types.h')
|
||||
# We don't use -nostdinc because sometimes we need standard headers,
|
||||
# such as stdarg.h e.g. for variable args, as in printk().
|
||||
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall',
|
||||
'-Werror', '-march=' + gcc_arch_flag],
|
||||
LINKFLAGS = ['-nostdlib', '-T' + linker_lds, '-u_start'],
|
||||
ASFLAGS = ['-D__ASSEMBLY__'],
|
||||
PROGSUFFIX = '.elf',
|
||||
ENV = {'PATH' : os.environ['PATH']},
|
||||
LIBS = ['gcc', 'libl4', 'c-userspace', 'libdev-userspace',
|
||||
'libmem', 'gcc', 'c-userspace'],
|
||||
# libgcc.a - This is required for division routines.
|
||||
CPPPATH = ["#include", KERNEL_HEADERS, LIBL4_INCLUDE, LIBDEV_INCLUDE,
|
||||
LIBC_INCLUDE, LIBMEM_INCLUDE, join(builddir, 'include')],
|
||||
LIBPATH = [LIBL4_LIBPATH, LIBDEV_USER_LIBPATH, LIBC_LIBPATH, LIBMEM_LIBPATH],
|
||||
CPPFLAGS = '-include l4/config.h -include l4/macros.h -include l4/types.h')
|
||||
|
||||
src = Glob('*.[cS]')
|
||||
src += Glob('src/*.[cS]')
|
||||
objs = SConscript('SConscript', exports = { 'env' : env },
|
||||
duplicate=0, build_dir = builddir)
|
||||
|
||||
objs = env.Object(src)
|
||||
prog = env.Program('main.elf', objs)
|
||||
Depends(prog, 'include/linker.lds')
|
||||
Depends(objs, join(PROJROOT, CONFIG_H))
|
||||
|
||||
prog = env.Program(join(builddir, 'main.elf'), objs)
|
||||
Depends(prog, linker_lds)
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
|
||||
#include <l4lib/init.h>
|
||||
#include <l4lib/utcb.h>
|
||||
|
||||
#include <l4lib/lib/thread.h>
|
||||
#include <l4lib/lib/cap.h>
|
||||
|
||||
extern void main(void);
|
||||
|
||||
@@ -15,6 +16,11 @@ void __container_init(void)
|
||||
/* Generic L4 initialisation */
|
||||
__l4_init();
|
||||
|
||||
/* Thread library initialisation */
|
||||
__l4_threadlib_init();
|
||||
|
||||
__l4_capability_init();
|
||||
|
||||
/* Entry to main */
|
||||
main();
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
*/
|
||||
struct uart {
|
||||
unsigned long base; /* VMA where uart will be mapped */
|
||||
struct capability cap; /* Capability describing uart */
|
||||
unsigned long phys_base;
|
||||
};
|
||||
|
||||
#endif /* __UART_SERVICE_H__ */
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include L4LIB_INC_ARCH(syscalls.h)
|
||||
#include <l4lib/exregs.h>
|
||||
#include <l4lib/lib/addr.h>
|
||||
#include <l4lib/lib/cap.h>
|
||||
#include <l4lib/ipcdefs.h>
|
||||
#include <l4/api/errno.h>
|
||||
#include <l4/api/capability.h>
|
||||
@@ -14,43 +15,17 @@
|
||||
#include <container.h>
|
||||
#include <linker.h>
|
||||
#include <uart.h>
|
||||
#include <libdev/uart.h>
|
||||
#include <dev/uart.h>
|
||||
#include <dev/platform.h>
|
||||
|
||||
/* Capabilities of this service */
|
||||
static struct capability caparray[32];
|
||||
static struct capability *caparray;
|
||||
static int total_caps = 0;
|
||||
|
||||
/* Number of UARTS to be managed by this service */
|
||||
#define UARTS_TOTAL 1
|
||||
static struct uart uart[UARTS_TOTAL];
|
||||
|
||||
int cap_read_all()
|
||||
{
|
||||
int ncaps;
|
||||
int err;
|
||||
|
||||
/* Read number of capabilities */
|
||||
if ((err = l4_capability_control(CAP_CONTROL_NCAPS,
|
||||
0, &ncaps)) < 0) {
|
||||
printf("l4_capability_control() reading # of"
|
||||
" capabilities failed.\n Could not "
|
||||
"complete CAP_CONTROL_NCAPS request.\n");
|
||||
BUG();
|
||||
}
|
||||
total_caps = ncaps;
|
||||
|
||||
/* Read all capabilities */
|
||||
if ((err = l4_capability_control(CAP_CONTROL_READ,
|
||||
0, caparray)) < 0) {
|
||||
printf("l4_capability_control() reading of "
|
||||
"capabilities failed.\n Could not "
|
||||
"complete CAP_CONTROL_READ_CAPS request.\n");
|
||||
BUG();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cap_share_all_with_space()
|
||||
{
|
||||
int err;
|
||||
@@ -66,48 +41,23 @@ int cap_share_all_with_space()
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Scans for up to UARTS_TOTAL uart devices in capabilities.
|
||||
*/
|
||||
int uart_probe_devices(void)
|
||||
{
|
||||
int uarts = 0;
|
||||
|
||||
/* Scan for uart devices */
|
||||
for (int i = 0; i < total_caps; i++) {
|
||||
/* Match device type */
|
||||
if (cap_devtype(&caparray[i]) == CAP_DEVTYPE_UART) {
|
||||
/* Copy to correct device index */
|
||||
memcpy(&uart[cap_devnum(&caparray[i]) - 1].cap,
|
||||
&caparray[i], sizeof(uart[0].cap));
|
||||
uarts++;
|
||||
}
|
||||
}
|
||||
|
||||
if (uarts != UARTS_TOTAL) {
|
||||
printf("%s: Error, not all uarts could be found. "
|
||||
"total uarts=%d\n", __CONTAINER_NAME__, uarts);
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct uart uart[UARTS_TOTAL];
|
||||
|
||||
int uart_setup_devices(void)
|
||||
{
|
||||
uart[0].phys_base = PLATFORM_UART1_BASE;
|
||||
|
||||
for (int i = 0; i < UARTS_TOTAL; i++) {
|
||||
/* Get one page from address pool */
|
||||
uart[i].base = (unsigned long)l4_new_virtual(1);
|
||||
|
||||
/* Map uart to a virtual address region */
|
||||
if (IS_ERR(l4_map((void *)__pfn_to_addr(uart[i].cap.start),
|
||||
(void *)uart[i].base, uart[i].cap.size,
|
||||
if (IS_ERR(l4_map((void *)uart[i].phys_base,
|
||||
(void *)uart[i].base, 1,
|
||||
MAP_USR_IO, self_tid()))) {
|
||||
printf("%s: FATAL: Failed to map UART device "
|
||||
"%d to a virtual address\n",
|
||||
__CONTAINER_NAME__,
|
||||
cap_devnum(&uart[i].cap));
|
||||
"to a virtual address\n",
|
||||
__CONTAINER_NAME__);
|
||||
BUG();
|
||||
}
|
||||
|
||||
@@ -246,68 +196,23 @@ void handle_requests(void)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* UTCB-size aligned utcb.
|
||||
*
|
||||
* BIG WARNING NOTE:
|
||||
* This in-place declaration is legal if we are running
|
||||
* in a disjoint virtual address space, where the utcb
|
||||
* declaration lies in a unique virtual address in
|
||||
* the system.
|
||||
*/
|
||||
#define DECLARE_UTCB(name) \
|
||||
struct utcb name ALIGN(sizeof(struct utcb))
|
||||
|
||||
DECLARE_UTCB(utcb);
|
||||
|
||||
/* Set up own utcb for ipc */
|
||||
int l4_utcb_setup(void *utcb_address)
|
||||
{
|
||||
struct task_ids ids;
|
||||
struct exregs_data exregs;
|
||||
int err;
|
||||
|
||||
l4_getid(&ids);
|
||||
|
||||
/* Clear utcb */
|
||||
memset(utcb_address, 0, sizeof(struct utcb));
|
||||
|
||||
/* Setup exregs for utcb request */
|
||||
memset(&exregs, 0, sizeof(exregs));
|
||||
exregs_set_utcb(&exregs, (unsigned long)utcb_address);
|
||||
|
||||
if ((err = l4_exchange_registers(&exregs, ids.tid)) < 0)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* Read all capabilities */
|
||||
cap_read_all();
|
||||
caps_read_all();
|
||||
|
||||
total_caps = cap_get_count();
|
||||
caparray = cap_get_all();
|
||||
|
||||
/* Share all with space */
|
||||
cap_share_all_with_space();
|
||||
|
||||
/* Scan for uart devices in capabilities */
|
||||
uart_probe_devices();
|
||||
|
||||
/* Initialize virtual address pool for uarts */
|
||||
init_vaddr_pool();
|
||||
|
||||
/* Map and initialize uart devices */
|
||||
uart_setup_devices();
|
||||
|
||||
/* Setup own utcb */
|
||||
if ((err = l4_utcb_setup(&utcb)) < 0) {
|
||||
printf("FATAL: Could not set up own utcb. "
|
||||
"err=%d\n", err);
|
||||
BUG();
|
||||
}
|
||||
|
||||
/* Listen for uart requests */
|
||||
while (1)
|
||||
handle_requests();
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
# -*- mode: python; coding: utf-8; -*-
|
||||
#
|
||||
# Codezero -- Virtualization microkernel for embedded systems.
|
||||
#
|
||||
# Copyright © 2009 B Labs Ltd
|
||||
|
||||
import os, sys, shelve
|
||||
from os.path import join
|
||||
|
||||
# Get global paths
|
||||
PROJRELROOT = '../../../'
|
||||
|
||||
sys.path.append(PROJRELROOT)
|
||||
|
||||
from config.configuration import *
|
||||
from config.projpaths import *
|
||||
|
||||
Import('env', 'arch', 'type')
|
||||
variant = type
|
||||
|
||||
# Needed by fputc(), for declaration of uart_tx()
|
||||
LIBDEV_RELDIR = 'conts/libdev'
|
||||
LIBDEV_DIR = join(PROJROOT, LIBDEV_RELDIR)
|
||||
LIBDEV_INC = join(LIBDEV_DIR, 'include')
|
||||
|
||||
e = env.Clone()
|
||||
e.Append(CPPPATH = ['include', 'include/sys-' + variant + \
|
||||
'/arch-' + arch, LIBDEV_INC],
|
||||
CCFLAGS = ['-nostdinc'])
|
||||
|
||||
source = \
|
||||
Glob('src/*.[cS]') + \
|
||||
Glob('src/sys-' + variant + '/*.c') + \
|
||||
Glob('src/sys-' + variant + '/arch-' + arch + '/*.c') + \
|
||||
Glob('src/arch-' + arch + '/*.c') + \
|
||||
Glob('src/arch-' + arch + '/*.S') + \
|
||||
Glob('crt/sys-' + variant + '/arch-' + arch + '/*.[cS]')
|
||||
|
||||
objects = e.StaticObject(source)
|
||||
library = e.StaticLibrary('c-' + variant, objects)
|
||||
|
||||
Return('library')
|
||||
@@ -1,50 +0,0 @@
|
||||
# -*- mode: python; coding: utf-8; -*-
|
||||
#
|
||||
# Codezero -- a microkernel for embedded systems.
|
||||
#
|
||||
# Copyright © 2009 B Labs Ltd
|
||||
#
|
||||
import os, sys
|
||||
|
||||
PROJRELROOT = '../..'
|
||||
|
||||
sys.path.append(PROJRELROOT)
|
||||
|
||||
from config.projpaths import *
|
||||
from config.configuration import *
|
||||
|
||||
config = configuration_retrieve()
|
||||
gcc_arch_flag = config.gcc_arch_flag
|
||||
arch = config.arch
|
||||
|
||||
# We assume we are compiling for userspace.
|
||||
# variant can be specified from cmdline using
|
||||
# scons variant=xxx
|
||||
variant = ARGUMENTS.get('variant', 'userspace')
|
||||
print '\nCompiling for variant: ' + variant + '\n'
|
||||
|
||||
# Needed by fputc(), for declaration of uart_tx()
|
||||
LIBDEV_RELDIR = 'conts/libdev'
|
||||
LIBDEV_DIR = join(PROJROOT, LIBDEV_RELDIR)
|
||||
LIBDEV_INC = join(LIBDEV_DIR, 'include')
|
||||
|
||||
env = Environment(CC = config.toolchain_userspace + 'gcc',
|
||||
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', \
|
||||
'-nostdinc', '-Wall', '-Werror', '-march=' + gcc_arch_flag],
|
||||
LINKFLAGS = ['-nostdlib'],
|
||||
ASFLAGS = ['-D__ASSEMBLY__'],
|
||||
ENV = {'PATH' : os.environ['PATH']},
|
||||
CPPPATH = ['include', LIBDEV_INC, join(PROJROOT,'include'), \
|
||||
'include/sys-' + variant + '/arch-' + arch])
|
||||
|
||||
source = \
|
||||
Glob('src/*.[cS]') + \
|
||||
Glob('src/sys-' + variant + '/*.c') + \
|
||||
Glob('src/sys-' + variant + '/arch-' + arch + '/*.c') + \
|
||||
Glob('src/arch-' + arch + '/*.c') + \
|
||||
Glob('src/arch-' + arch + '/*.S') + \
|
||||
Glob('crt/sys-' + variant + '/arch-' + arch + '/*.[cS]')
|
||||
|
||||
objects = env.StaticObject(source)
|
||||
library = env.StaticLibrary('c-' + variant, objects)
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
# -*- mode: python; coding: utf-8; -*-
|
||||
#
|
||||
# Codezero -- Virtualization microkernel for embedded systems.
|
||||
#
|
||||
# Copyright © 2009 B Labs Ltd
|
||||
|
||||
import os, sys, shelve
|
||||
from os.path import join
|
||||
|
||||
# Get global paths
|
||||
PROJRELROOT = '../../../'
|
||||
|
||||
sys.path.append(PROJRELROOT)
|
||||
|
||||
from config.configuration import *
|
||||
from config.projpaths import *
|
||||
|
||||
Import('env', 'platform', 'type')
|
||||
variant = type
|
||||
|
||||
# To include setbit/clrbit functions
|
||||
LIBL4_RELDIR = 'conts/libl4'
|
||||
LIBL4_DIR = join(PROJROOT, LIBL4_RELDIR)
|
||||
LIBL4_INC = join(LIBL4_DIR, 'include')
|
||||
|
||||
LIBC_RELDIR = 'conts/libc'
|
||||
LIBC_DIR = join(PROJROOT, LIBC_RELDIR)
|
||||
LIBC_INC = join(LIBC_DIR, 'include')
|
||||
|
||||
e = env.Clone()
|
||||
e.Append(CPPPATH = ['#conts/libdev/include', LIBC_INC, LIBL4_INC],
|
||||
CCFLAGS = ['-DVARIANT_' + variant.upper()])
|
||||
|
||||
objects = []
|
||||
objects += SConscript('uart/pl011/SConscript', duplicate=0, \
|
||||
exports = {'platform' : platform, 'env' : e})
|
||||
objects += SConscript('timer/sp804/SConscript', duplicate=0, \
|
||||
exports = {'platform' : platform, 'env' : e})
|
||||
objects += SConscript('kmi/pl050/SConscript', duplicate=0, \
|
||||
exports = {'platform' : platform, 'env' : e})
|
||||
objects += SConscript('clcd/pl110/SConscript', duplicate=0, \
|
||||
exports = {'platform' : platform, 'env' : e})
|
||||
|
||||
objects += SConscript('uart/omap/SConscript', duplicate=0, \
|
||||
exports = {'platform' : platform, 'env' : e})
|
||||
objects += SConscript('timer/omap/SConscript', duplicate=0, \
|
||||
exports = {'platform' : platform, 'env' : e})
|
||||
|
||||
library = e.StaticLibrary('libdev-' + variant, objects)
|
||||
Return('library')
|
||||
@@ -1,59 +0,0 @@
|
||||
# -*- mode: python; coding: utf-8; -*-
|
||||
#
|
||||
# Codezero -- a microkernel for embedded systems.
|
||||
#
|
||||
# Copyright © 2009 B Labs Ltd
|
||||
#
|
||||
import os, sys
|
||||
|
||||
PROJRELROOT = '../..'
|
||||
|
||||
sys.path.append(PROJRELROOT)
|
||||
|
||||
from config.projpaths import *
|
||||
from config.configuration import *
|
||||
|
||||
config = configuration_retrieve()
|
||||
gcc_arch_flag = config.gcc_arch_flag
|
||||
platform = config.platform
|
||||
|
||||
# We assume we are compiling for userspace.
|
||||
# variant can be specified from cmdline using
|
||||
# scons variant=xxx
|
||||
variant = ARGUMENTS.get('variant', 'userspace')
|
||||
print '\nCompiling for variant: ' + variant + '\n'
|
||||
|
||||
# To include setbit/clrbit functions
|
||||
LIBL4_RELDIR = 'conts/libl4'
|
||||
LIBL4_DIR = join(PROJROOT, LIBL4_RELDIR)
|
||||
LIBL4_INC = join(LIBL4_DIR, 'include')
|
||||
|
||||
LIBC_RELDIR = 'conts/libc'
|
||||
LIBC_DIR = join(PROJROOT, LIBC_RELDIR)
|
||||
LIBC_INC = join(LIBC_DIR, 'include')
|
||||
|
||||
env = Environment(CC = config.toolchain_userspace + 'gcc',
|
||||
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', \
|
||||
'-nostdinc', '-Wall', '-DVARIANT_' + variant.upper(), \
|
||||
'-march=' + gcc_arch_flag, '-Werror'],
|
||||
LINKFLAGS = ['-nostdlib'],
|
||||
ASFLAGS = ['-D__ASSEMBLY__'],
|
||||
ENV = {'PATH' : os.environ['PATH']},
|
||||
CPPPATH = ['#include', LIBC_INC, LIBL4_INC, join(PROJROOT,'include')])
|
||||
|
||||
objects = []
|
||||
objects += SConscript('uart/pl011/SConscript', duplicate=0, \
|
||||
exports = {'platform' : platform, 'env' : env})
|
||||
objects += SConscript('timer/sp804/SConscript', duplicate=0, \
|
||||
exports = {'platform' : platform, 'env' : env})
|
||||
objects += SConscript('kmi/pl050/SConscript', duplicate=0, \
|
||||
exports = {'platform' : platform, 'env' : env})
|
||||
objects += SConscript('clcd/pl110/SConscript', duplicate=0, \
|
||||
exports = {'platform' : platform, 'env' : env})
|
||||
|
||||
objects += SConscript('uart/omap/SConscript', duplicate=0, \
|
||||
exports = {'platform' : platform, 'env' : env})
|
||||
objects += SConscript('timer/omap/SConscript', duplicate=0, \
|
||||
exports = {'platform' : platform, 'env' : env})
|
||||
|
||||
library = env.StaticLibrary('libdev-' + variant, objects)
|
||||
@@ -1,48 +0,0 @@
|
||||
# -*- mode: python; coding: utf-8; -*-
|
||||
#
|
||||
# Codezero -- a microkernel for embedded systems.
|
||||
#
|
||||
# Copyright © 2009 B Labs Ltd
|
||||
#
|
||||
import os, sys
|
||||
|
||||
PROJRELROOT = '../..'
|
||||
|
||||
sys.path.append(PROJRELROOT)
|
||||
|
||||
from config.projpaths import *
|
||||
from config.configuration import *
|
||||
|
||||
config = configuration_retrieve()
|
||||
gcc_arch_flag = config.gcc_arch_flag
|
||||
arch = config.arch
|
||||
subarch = config.subarch
|
||||
|
||||
LIBMEM_RELDIR = 'conts/libmem'
|
||||
LIBMEM_DIR = join(PROJROOT, LIBMEM_RELDIR)
|
||||
|
||||
LIBC_RELDIR = 'conts/libc'
|
||||
LIBC_DIR = join(PROJROOT, LIBC_RELDIR)
|
||||
LIBC_INC = join(LIBC_DIR, 'include')
|
||||
|
||||
env = Environment(CC = config.toolchain_userspace + 'gcc',
|
||||
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', \
|
||||
'-nostdinc', '-Wall', '-Werror', '-march=' + gcc_arch_flag],
|
||||
LINKFLAGS = ['-nostdlib'],
|
||||
ASFLAGS = ['-D__ASSEMBLY__'],
|
||||
ENV = {'PATH' : os.environ['PATH']},
|
||||
CPPPATH = ['include', 'include/l4lib/arch', LIBC_INC, \
|
||||
join(PROJROOT,'include'), LIBMEM_DIR],
|
||||
CPPFLAGS = ' -include l4lib/macros.h ')
|
||||
|
||||
objects = env.StaticObject(Glob('src/*.c') + \
|
||||
Glob('src/lib/*.c') + \
|
||||
Glob('src/arch/' + arch + '/exregs.c') + \
|
||||
Glob('src/arch/' + arch + '/*.[cS]') + \
|
||||
Glob('src/arch/' + arch + '/' + subarch + '/*.[cS]') + \
|
||||
Glob('src/lib/cap/*.c')) + \
|
||||
Glob('src/lib/thread/*.c')
|
||||
|
||||
|
||||
library = env.StaticLibrary('l4', objects)
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2007 Bahadir Balban
|
||||
#
|
||||
|
||||
import os, glob, sys
|
||||
from os.path import join
|
||||
from string import split
|
||||
|
||||
PROJRELROOT = '../..'
|
||||
sys.path.append(PROJRELROOT)
|
||||
|
||||
from configure import *
|
||||
from config.projpaths import *
|
||||
config = configuration_retrieve()
|
||||
gcc_arch_flag = config.gcc_arch_flag
|
||||
|
||||
headers_root = join(PROJRELROOT, "include/l4")
|
||||
config_h = join(headers_root, "config.h")
|
||||
|
||||
mm = "mm"
|
||||
kmalloc = "kmalloc"
|
||||
memcache = "memcache"
|
||||
tests = "tests"
|
||||
|
||||
mm_dir = mm
|
||||
kmalloc_dir = kmalloc
|
||||
memcache_dir = memcache
|
||||
tests_dir = tests
|
||||
|
||||
LIBL4_RELDIR = 'conts/libl4'
|
||||
LIBL4_DIR = join(PROJROOT, LIBL4_RELDIR)
|
||||
LIBL4_INCLUDE = join(LIBL4_DIR, 'include')
|
||||
|
||||
# This does not work, need to check
|
||||
test_env = Environment(CC = config.toolchain_userspace + 'gcc',
|
||||
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', \
|
||||
'-nostdinc', '-Werror', '-march=' + gcc_arch_flag],
|
||||
ENV = {'PATH' : os.environ['PATH']},
|
||||
LIBS = ['mm', 'km', 'mc'],
|
||||
LIBPATH = ['#'],
|
||||
CPPPATH = ['#include', join(PROJRELROOT, "include"), "#", LIBL4_INCLUDE])
|
||||
|
||||
env = Environment(CC = config.toolchain_userspace + 'gcc',
|
||||
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', \
|
||||
'-Wall', '-Werror', '-march=' + gcc_arch_flag],
|
||||
LINKFLAGS = ['-nostdlib'],
|
||||
ASFLAGS = ['-D__ASSEMBLY__'],
|
||||
ENV = {'PATH' : os.environ['PATH']},
|
||||
LIBS = 'gcc',
|
||||
CPPPATH = ['.', join(PROJROOT, 'include'), LIBL4_INCLUDE])
|
||||
|
||||
if os.path.exists(config_h) is False:
|
||||
print "\nThis build requires a valid kernel configuration header."
|
||||
print "Please run `scons configure' in the kernel root directory."
|
||||
print "Choose the `tests' target to build memory allocator tests,"
|
||||
print "or any other target for real use.\n"
|
||||
sys.exit()
|
||||
|
||||
mm_src = glob.glob("%s/*.c" % mm_dir)
|
||||
kmalloc_src = glob.glob("%s/*.c" % kmalloc_dir)
|
||||
memcache_src = glob.glob("%s/*.c" % memcache_dir)
|
||||
tests_src = glob.glob ("%s/*.c" % tests_dir)
|
||||
|
||||
if "tests" in COMMAND_LINE_TARGETS:
|
||||
print "WARNING!!! Did you configure the kernel with test target first???"
|
||||
libmm = test_env.StaticLibrary(mm, mm_src)
|
||||
libkmalloc = test_env.StaticLibrary("km", kmalloc_src)
|
||||
libmemcache = test_env.StaticLibrary("mc", memcache_src)
|
||||
test_prog = test_env.Program("test", tests_src)
|
||||
env.Alias("tests", test_prog)
|
||||
else:
|
||||
libmm = env.StaticLibrary(mm, mm_src)
|
||||
libkmalloc = env.StaticLibrary("km", kmalloc_src)
|
||||
libmemcache = env.StaticLibrary("mc", memcache_src)
|
||||
|
||||
@@ -12,37 +12,13 @@ PROJRELROOT = '../../'
|
||||
sys.path.append(PROJRELROOT)
|
||||
sys.path.append('../../../../')
|
||||
|
||||
from config.projpaths import *
|
||||
from config.configuration import *
|
||||
from config.lib import *
|
||||
from scripts.config.projpaths import *
|
||||
from scripts.config.configuration import *
|
||||
from scripts.config.lib import *
|
||||
|
||||
config = configuration_retrieve()
|
||||
arch = config.arch
|
||||
gcc_arch_flag = config.gcc_arch_flag
|
||||
|
||||
LIBL4_RELDIR = 'conts/libl4'
|
||||
KERNEL_INCLUDE = join(PROJROOT, 'include')
|
||||
LIBL4_DIR = join(PROJROOT, LIBL4_RELDIR)
|
||||
LIBL4_INCLUDE = join(LIBL4_DIR, 'include')
|
||||
LIBL4_LIBPATH = join(BUILDDIR, LIBL4_RELDIR)
|
||||
|
||||
# Locally important paths are here
|
||||
LIBC_RELDIR = 'conts/libc'
|
||||
LIBC_DIR = join(PROJROOT, LIBC_RELDIR)
|
||||
LIBC_LIBPATH = join(BUILDDIR, LIBC_RELDIR)
|
||||
LIBC_INCLUDE = [join(LIBC_DIR, 'include'), \
|
||||
join(LIBC_DIR, 'include/arch' + '/' + arch)]
|
||||
|
||||
LIBDEV_RELDIR = 'conts/libdev'
|
||||
LIBDEV_DIR = join(PROJROOT, LIBDEV_RELDIR)
|
||||
LIBDEV_LIBPATH = join(join(BUILDDIR, LIBDEV_RELDIR), 'sys-userspace')
|
||||
LIBDEV_INCLUDE = join(LIBDEV_DIR, 'uart/include')
|
||||
|
||||
LIBMEM_RELDIR = 'conts/libmem'
|
||||
LIBMEM_DIR = join(PROJROOT, LIBMEM_RELDIR)
|
||||
LIBMEM_LIBPATH = join(BUILDDIR, LIBMEM_RELDIR)
|
||||
LIBMEM_INCLUDE = LIBMEM_DIR
|
||||
|
||||
LIBPOSIX_RELDIR = 'conts/posix/libposix'
|
||||
LIBPOSIX_DIR = join(PROJROOT, LIBPOSIX_RELDIR)
|
||||
LIBPOSIX_INCLUDE_SERVER = join(LIBPOSIX_DIR, 'include')
|
||||
@@ -50,26 +26,26 @@ LIBPOSIX_INCLUDE_USERSPACE = join(LIBPOSIX_DIR, 'include/posix')
|
||||
LIBPOSIX_LIBPATH = join(BUILDDIR, LIBPOSIX_RELDIR)
|
||||
|
||||
env = Environment(CC = config.toolchain_userspace + 'gcc',
|
||||
AR = config.toolchain_userspace + 'ar',
|
||||
RANLIB = config.toolchain_userspace + 'ranlib',
|
||||
CCFLAGS = ['-g','-nostdinc', '-nostdlib', '-ffreestanding',
|
||||
'-march=' + gcc_arch_flag, '-std=gnu99', '-Wall', '-Werror'],
|
||||
LINKFLAGS = ['-nostdlib'],
|
||||
ASFLAGS = ['-D__ASSEMBLY__'],
|
||||
PROGSUFFIX = '.elf',
|
||||
ENV = {'PATH' : os.environ['PATH']},
|
||||
LIBS = ['libl4', 'libdev-userspace', 'gcc', 'c-userspace', \
|
||||
'gcc', 'libmm', 'libmc', 'libmalloc'],
|
||||
CPPPATH = ['include', LIBDEV_INCLUDE, LIBC_INCLUDE, KERNEL_INCLUDE,
|
||||
LIBL4_INCLUDE, LIBMEM_INCLUDE, LIBPOSIX_INCLUDE_USERSPACE],
|
||||
LIBPATH = [LIBDEV_LIBPATH, LIBC_LIBPATH, LIBL4_LIBPATH,
|
||||
LIBMEM_LIBPATH, LIBPOSIX_LIBPATH],
|
||||
CPPFLAGS = '-include l4/config.h -include l4/macros.h -include l4/types.h')
|
||||
AR = config.toolchain_userspace + 'ar',
|
||||
RANLIB = config.toolchain_userspace + 'ranlib',
|
||||
CCFLAGS = ['-g','-nostdinc', '-nostdlib', '-ffreestanding', '-Wall',
|
||||
'-march=' + gcc_arch_flag, '-std=gnu99', '-Werror'],
|
||||
LINKFLAGS = ['-nostdlib'],
|
||||
ASFLAGS = ['-D__ASSEMBLY__'],
|
||||
PROGSUFFIX = '.elf',
|
||||
ENV = {'PATH' : os.environ['PATH']},
|
||||
LIBS = ['libl4', 'libdev-userspace', 'gcc', 'c-userspace', \
|
||||
'gcc', 'libmem'],
|
||||
CPPPATH = ['include', LIBDEV_INCLUDE, LIBC_INCLUDE, KERNEL_HEADERS,
|
||||
LIBL4_INCLUDE, LIBMEM_INCLUDE, LIBPOSIX_INCLUDE_USERSPACE],
|
||||
LIBPATH = [LIBDEV_USER_LIBPATH, LIBC_LIBPATH, LIBL4_LIBPATH,
|
||||
LIBMEM_LIBPATH, LIBPOSIX_LIBPATH],
|
||||
CPPFLAGS = '-include l4/config.h -include l4/macros.h -include l4/types.h')
|
||||
|
||||
contid = ARGUMENTS.get('cont', '0')
|
||||
|
||||
libposix_env = env.Clone()
|
||||
libposix_env.Replace(CPPPATH = [LIBPOSIX_INCLUDE_USERSPACE, 'include', KERNEL_INCLUDE, LIBL4_INCLUDE, LIBMEM_INCLUDE, LIBC_INCLUDE])
|
||||
libposix_env.Replace(CPPPATH = [LIBPOSIX_INCLUDE_USERSPACE, 'include', KERNEL_HEADERS, LIBL4_INCLUDE, LIBMEM_INCLUDE, LIBC_INCLUDE])
|
||||
libposix = SConscript('libposix/SConscript', \
|
||||
exports = { 'config' : config, 'env' : libposix_env, 'contid' : contid}, duplicate = 0, \
|
||||
variant_dir = join(BUILDDIR, 'conts' + '/posix' + '/libposix'))
|
||||
@@ -86,7 +62,7 @@ rootfs = SConscript('rootfs/SConscript', \
|
||||
|
||||
# No libposix reference because it conflicts with the compiler C library + the cluncky libc we have.
|
||||
test0_env = env.Clone()
|
||||
test0_env.Replace(CPPPATH = ['include', KERNEL_INCLUDE, LIBL4_INCLUDE, LIBMEM_INCLUDE, LIBC_INCLUDE, LIBPOSIX_INCLUDE_USERSPACE])
|
||||
test0_env.Replace(CPPPATH = ['include', KERNEL_HEADERS, LIBL4_INCLUDE, LIBMEM_INCLUDE, LIBC_INCLUDE, LIBPOSIX_INCLUDE_USERSPACE])
|
||||
test0 = SConscript('test0/SConscript', \
|
||||
exports = { 'config' : config, 'environment' : test0_env, 'contid' : contid, 'previmage' : rootfs }, duplicate = 0, \
|
||||
variant_dir = join(BUILDDIR, 'cont' + str(contid) + '/posix' + '/test0'))
|
||||
|
||||
@@ -19,8 +19,8 @@ PROJRELROOT = '../../../../'
|
||||
|
||||
sys.path.append(os.path.abspath(PROJRELROOT))
|
||||
|
||||
from config.projpaths import *
|
||||
from config.configuration import *
|
||||
from scripts.config.projpaths import *
|
||||
from scripts.config.configuration import *
|
||||
from tools.pyelf import elf
|
||||
|
||||
config = configuration_retrieve()
|
||||
|
||||
@@ -3,11 +3,9 @@
|
||||
#
|
||||
# Copyright (C) 2007 Bahadir Balban
|
||||
#
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
import os, sys, shutil
|
||||
from os.path import join
|
||||
from configure import *
|
||||
from scripts.config.config_invoke import *
|
||||
|
||||
config = configuration_retrieve()
|
||||
builddir = ARGUMENTS.get('builddir', 'build/conts/posix')
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user