Commit 240f0bab authored by Philippe Gerum's avatar Philippe Gerum
Browse files

evenless: nothing more


Signed-off-by: Philippe Gerum's avatarPhilippe Gerum <rpm@xenomai.org>
parents
lib/git-stamp.h
include/uapi
include scripts/config.mk
GOALS := all clean clobber mrproper install
TARGETS := include lib tests utils commands
$(GOALS):
@for target in $(TARGETS); do \
$(MAKE) -C $$target O=$(O_DIR)/$$target V=$(V) $@; \
done
$(TARGETS):
$(Q)$(MAKE) -C $@ O=$(O_DIR)/$@ V=$(V)
lib: include
tests utils: lib
.PHONY: $(GOALS) $(TARGETS)
Evenless (EVL) core library and utilities
=========================================
What's that?
------------
Building
--------
Prerequisites:
- a GCC toolchain with working thread-local storage support (TLS).
- the UAPI headers from the target kernel fit with the EVL core. We
need access to the contents of include/uapi/asm/ and
include/uapi/evenless/ from the source Linux tree.
Command:
$ make [-C $SRCDIR] [ARCH=$cpu_arch] [CROSS_COMPILE=$toolchain] UAPI=$uapi_dir [OTHER_BUILD_VARS] [goal...]
Make goals
~~~~~~~~~~
all generate binaries
clean remove build files
install copy generated binaries to $DESTDIR
Main build variables
~~~~~~~~~~~~~~~~~~~~
$SRCDIR Path to this source tree
$cpu_arch CPU architecture you build for
(e.g. 'arm', 'arm64')
$toolchain Optional fixed part of the binutils filename
(e.g. 'aarch64-linux-gnu-', 'arm-linux-gnueabihf-')
Other build variables
~~~~~~~~~~~~~~~~~~~~~
D={0|1} Disable|enable debug build, i.e. -g -O0 vs -O2 [0]
O=$output_dir Generate binary output files into $output_dir [.]
V={0|1} Set build verbosity level, 0 is terse [0]
DESTDIR=$install_dir Install library and binaries into $install_dir [/usr/evenless]
Build command examples
~~~~~~~~~~~~~~~~~~~~~~
Say the library source code is located at ~/git/evenless, and the
kernel sources featuring the EVL core is located at
~/git/linux-evenless. You could build+install the EVL library and
utilities directly to a staging directory at
/nfsroot/<machine>/usr/evenless as follows:
$ mkdir /tmp/build-hikey && cd /tmp/build-hikey
$ make -C ~/git/evenless O=$PWD ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- UAPI=~/git/linux-evenless DESTDIR=/nfsroot/imx6q/usr/evenless install
or,
$ mkdir /tmp/build-hikey
$ cd ~/git/evenless
$ make O=/tmp/build-hikey ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- UAPI=~/git/linux-evenless DESTDIR=/nfsroot/hikey/usr/evenless install
include ../scripts/config.mk
CMDFILES := $(wildcard *.c)
BINARIES = $(CMDFILES:%.c=%)
TARGETS = $(CMDFILES:%.c=$(O_DIR)/%)
DEPFILES = $(CMDFILES:%.c=$(O_DIR)/%.d)
CMD_CPPFLAGS := $(BASE_CPPFLAGS) -I.
CMD_CFLAGS := $(CMD_CPPFLAGS) $(BASE_CFLAGS)
override CFLAGS := $(CMD_CFLAGS) $(CFLAGS)
all: $(TARGETS)
install: all
$(Q)for bin in $(BINARIES); do \
$(INSTALL) -D $(O_DIR)/$$bin $(DESTDIR)/$(bindir)/$$bin; \
done
clean clobber mrproper:
$(Q)$(RM) -f $(TARGETS) $(DEPFILES)
$(O_DIR)/%: %.c
$(call ccld-cmd,$@,$(Q)$(CC) -o $(@) $< $(CFLAGS) $(LDFLAGS))
.PHONY: all install clean clobber mrproper
-include $(DEPFILES)
#! /bin/sh
# SPDX-License-Identifier: MIT
set -- $(getopt -n $(basename $0) el "$@")
if [ $? -ne 0 ]; then
echo >&2 "usage: $0 [-el]"
exit 1
fi
all=false
long=false
for opt
do
case "$opt" in
-e) all=true
shift;;
-l) long=true
shift;;
--) shift; break;;
esac
done
# TBD
exit 0
#! /bin/sh
# SPDX-License-Identifier: MIT
if test \! -d $EVL_TRACEDIR; then
echo >&2 "no kernel support for tracing"
exit 2
fi
usage() {
echo >&2 "usage: $1 [-e [-s <buffer_size>]] [-d] [-p] [-f] [-?] [-c <cpu>]"
}
set -- $(getopt -n $(basename $0) 'es:dc:pf?' "$@")
if [ $? -ne 0 ]; then
usage $0
exit 1
fi
enable=false
disable=false
print=true
full=false
bufsz=64
pcpu=
help=false
for opt
do
case "$opt" in
-e) enable=true
disable=false
shift;;
-s) bufsz=$(eval echo $2)
shift;;
-d) enable=false
disable=true
shift;;
-p) print=true
shift;;
-f) full=true
shift;;
-c) pcpu=per_cpu/cpu$(eval echo $2)/
shift;;
-?) help=true
shift;;
--) shift; break;;
esac
done
if test x$help = xtrue; then
usage $0
exit 0
fi
cd $EVL_TRACEDIR
if test x$enable = xtrue; then
echo nop > current_tracer
echo 0 > snapshot
echo $bufsz > ${pcpu}buffer_size_kb
if test x$full = xfalse; then
echo 1 > events/irq/enable
echo 1 > events/power/cpu_idle/enable
echo 1 > events/evenless/enable
else
echo function > current_tracer
fi
echo 1 > ${pcpu}snapshot
echo 1 > events/evenless/evl_timer_shot/enable
echo \!snapshot > events/evenless/evl_trigger/trigger
echo snapshot > events/evenless/evl_trigger/trigger
echo 1 > events/evenless/evl_trigger/enable
echo 1 > events/evenless/evl_latspot/enable
echo "tracing enabled"
print=false
elif test x$disable = xtrue; then
echo nop > current_tracer
echo 0 > snapshot
echo "tracing disabled"
print=false
fi
if test x$print = xtrue; then
cat ${pcpu}snapshot
fi
exit 0
/*
* SPDX-License-Identifier: MIT
*
* Copyright (C) 2019 Philippe Gerum <rpm@xenomai.org>
*/
#include <errno.h>
#include <error.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include <ctype.h>
#include <libgen.h>
#include <getopt.h>
static char *find_command_dir(const char *arg0)
{
char *cmddir;
int ret;
cmddir = malloc(PATH_MAX);
if (cmddir == NULL)
error(1, ENOMEM, "malloc");
ret = readlink("/proc/self/exe", cmddir, PATH_MAX);
if (ret < 0)
error(1, errno, "readlink");
return dirname(cmddir);
}
static void usage(void)
{
fprintf(stderr, "usage: evl [options] <command> [<args>]\n");
fprintf(stderr, "-P --prefix=<path> set command path prefix\n");
}
#define short_optlist "P:"
static const struct option options[] = {
{
.name = "prefix",
.has_arg = required_argument,
.val = 'P'
},
{ /* Sentinel */ }
};
static int is_word(const char *s)
{
while (*s && isalpha(*s))
s++;
return *s == '\0';
}
int main(int argc, char *const argv[])
{
char *cmddir = NULL, *cmdpath, **cmdargv, *cmd;
int ret, c, n, wcount, wpos = -1, cmdargc;
const char *arg0 = argv[0];
if (argc < 2) {
wpos = 0;
cmd = strdup("help");
goto run;
}
for (n = 1, wcount = 0; n < argc; n++) {
if (is_word(argv[n])) {
wpos = n;
if (++wcount > 1)
break;
} else
wcount = 0;
}
if (wpos < 0) {
fprintf(stderr, "evl: no command word\n");
usage();
return 2;
}
cmd = strdup(argv[wpos]);
*argv[wpos] = '\0';
opterr = 0;
for (;;) {
c = getopt_long(wpos, argv, short_optlist, options, NULL);
if (c == EOF)
break;
switch (c) {
case 0:
break;
case 'P':
cmddir = optarg;
break;
case '?':
default:
usage();
return 2;
}
}
run:
if (cmddir == NULL)
cmddir = find_command_dir(arg0);
ret = asprintf(&cmdpath, "%s/evl-%s", cmddir, cmd);
if (ret < 0)
error(1, ENOMEM, arg0);
setenv("EVL_CMDDIR", cmddir, 1);
setenv("EVL_SYSDIR", "/sys/devices/virtual", 1);
setenv("EVL_TRACEDIR", "/sys/kernel/debug/tracing", 1);
cmdargv = malloc(sizeof(char *) * (argc - wpos + 1));
if (cmdargv == NULL)
error(1, ENOMEM, "malloc");
cmdargv[0] = basename(cmdpath);
for (cmdargc = 1, n = wpos + 1; n < argc; n++)
cmdargv[cmdargc++] = argv[n];
cmdargv[cmdargc] = NULL;
execv(cmdpath, cmdargv);
fprintf(stderr, "evl: undefined command '%s'\n", cmd);
return 1;
}
# SPDX-License-Identifier: MIT
include ../scripts/config.mk
O_UAPI = $(O_DIR)/uapi
TARGETS := uapi
uapi: $(O_DIR)/.uapi_stamp $(O_DIR)/uapi
$(O_DIR)/.uapi_stamp $(O_DIR)/uapi:
$(Q)$(MKDIR_P) $(O_UAPI)
$(Q)$(RM) -f $(O_UAPI)/asm $(O_UAPI)/evenless
$(Q)if test -r $(UAPI)/Makefile; then \
$(LN_S) $(UAPI)/arch/$(ARCH)/include/uapi/asm $(O_UAPI)/asm; \
$(LN_S) $(UAPI)/include/uapi/evenless $(O_UAPI)/evenless; \
else \
$(LN_S) $(UAPI)/asm $(O_UAPI)/asm; \
$(LN_S) $(UAPI)/evenless $(O_UAPI)/evenless; \
fi; \
touch $@
all: uapi
clean clobber mrproper:
$(Q)$(RM) -f $(O_DIR)/.uapi_stamp $(O_UAPI)/asm $(O_UAPI)/evenless
install: all
$(Q)$(MKDIR_P) $(DESTDIR)/$(includedir)/uapi
$(Q)(cd $(O_UAPI) && find -L evenless \! \( -name '*~' \) -type f | $(CPIO) -Lpdum $(DESTDIR)/$(includedir)/uapi)
$(Q)(find evenless \! \( -name '*~' \) -type f | $(CPIO) -Lpdum $(DESTDIR)/$(includedir))
.PHONY: clean clobber mrproper install
/*
* SPDX-License-Identifier: MIT
*
* Copyright (C) 2018 Philippe Gerum <rpm@xenomai.org>
*/
#ifndef _EVENLESS_ATOMIC_H
#define _EVENLESS_ATOMIC_H
#include <linux/types.h>
typedef struct { __u32 val; } atomic_t;
#define ATOMIC_INIT(__val) { (__val) }
static inline int atomic_read(const atomic_t *ptr)
{
return ptr->val;
}
static inline void atomic_set(atomic_t *ptr, long val)
{
ptr->val = val;
}
#ifndef atomic_cmpxchg
#define atomic_cmpxchg(__ptr, __old, __new) \
__sync_val_compare_and_swap(&(__ptr)->val, __old, __new)
#endif
#ifndef smp_mb
#define smp_mb() __sync_synchronize()
#endif
#define compiler_barrier() __asm__ __volatile__("": : :"memory")
#endif /* _EVENLESS_ATOMIC_H */
/*
* SPDX-License-Identifier: MIT
*
* Copyright (C) 2018 Philippe Gerum <rpm@xenomai.org>
*/
#ifndef _EVENLESS_CLOCK_H
#define _EVENLESS_CLOCK_H
#include <time.h>
#include <errno.h>
#include <sys/timex.h>
#include <sys/ioctl.h>
#include <evenless/syscall.h>
#include <uapi/evenless/clock.h>
#ifdef __cplusplus
extern "C" {
#endif
static inline
int evl_read_clock(int efd, struct timespec *tp)
{
extern int (*arch_clock_gettime)(clockid_t clk_id,
struct timespec *tp);
switch (efd) {
case -CLOCK_MONOTONIC:
case -CLOCK_REALTIME:
return arch_clock_gettime(-efd, tp) ? -errno : 0;
default:
return oob_ioctl(efd, EVL_CLKIOC_GET_TIME, tp) ? -errno : 0;
}
}
int evl_set_clock(int efd, const struct timespec *tp);
int evl_get_clock_resolution(int efd, struct timespec *tp);
int evl_adjust_clock(int efd, struct timex *tx);
int evl_delay(int efd, const struct timespec *timeout,
struct timespec *remain);
#ifdef __cplusplus
}
#endif
#endif /* _EVENLESS_CLOCK_H */
/*
* SPDX-License-Identifier: MIT
*
* Copyright (C) 2018 Philippe Gerum <rpm@xenomai.org>
*/
#ifndef _EVENLESS_INIT_H
#define _EVENLESS_INIT_H
#include <signal.h>
#define __EVL__ 0 /* API revision */
#ifdef __cplusplus
extern "C" {
#endif
int evl_init(void);
int evl_sigshadow_handler(int sig, siginfo_t *si, void *ctxt);
void evl_sigdebug_handler(int sig, siginfo_t *si, void *ctxt);
unsigned int evl_detect_fpu(void);
#ifdef __cplusplus
}
#endif
#endif /* _EVENLESS_INIT_H */
/*
* SPDX-License-Identifier: MIT
*
* Copyright (C) 2018 Philippe Gerum <rpm@xenomai.org>
*/
#ifndef _EVENLESS_LOGGER_H
#define _EVENLESS_LOGGER_H
#include <sys/types.h>
#include <linux/types.h>
#include <uapi/evenless/logger.h>
#ifdef __cplusplus
extern "C" {
#endif
int evl_new_logger(int dstfd, size_t logsz,
const char *fmt, ...);
ssize_t evl_write_logger(int efd,
const void *buf, size_t len);
int evl_printf_logger(int efd,
const char *fmt, ...);
#ifdef __cplusplus
}
#endif
#endif /* _EVENLESS_LOGGER_H */
/*
* SPDX-License-Identifier: MIT
*
* Copyright (C) 2018 Philippe Gerum <rpm@xenomai.org>
*/
#ifndef _EVENLESS_MAPPER_H
#define _EVENLESS_MAPPER_H
#include <sys/types.h>
#include <linux/types.h>
#include <uapi/evenless/mapper.h>
#ifdef __cplusplus
extern "C" {
#endif
int evl_new_mapper(int mapfd, const char *fmt, ...);
#ifdef __cplusplus
}
#endif
#endif /* _EVENLESS_MAPPER_H */
/*
* SPDX-License-Identifier: MIT
*
* Copyright (C) 2018 Philippe Gerum <rpm@xenomai.org>
*/
#ifndef _EVENLESS_MONITOR_H
#define _EVENLESS_MONITOR_H
#include <stdbool.h>
#include <time.h>
#include <evenless/atomic.h>
#include <linux/types.h>
#include <uapi/evenless/types.h>
#include <uapi/evenless/monitor.h>
struct evl_thread;
struct evl_monitor {
unsigned int magic;
union {
struct {
fundle_t fundle;
struct evl_monitor_state *state;
int efd;
int type;
} active;
struct {
const char *name;
int clockfd;
unsigned int ceiling;
int type;
} uninit;
};
};
#define __MONITOR_ACTIVE_MAGIC 0xab12ab12
#define __MONITOR_UNINIT_MAGIC 0xfe11fe11
#define __MONITOR_DEAD_MAGIC 0
#define EVL_GATE_INITIALIZER(__name, __clock, __ceiling) { \
.magic = __MONITOR_UNINIT_MAGIC, \
.uninit = { \
.type = (__ceiling) ? EVL_MONITOR_PP : EVL_MONITOR_PI, \
.name = (__name), \
.clockfd = (__clockfd), \
.ceiling = (__ceiling), \
} \
}
#define EVL_EVENT_INITIALIZER(__name, __clockfd) { \
.magic = __MONITOR_UNINIT_MAGIC, \
.uninit = { \
.type = EVL_MONITOR_EV, \
.name = (__name), \
.clockfd = (__clockfd), \
} \
}
#ifdef __cplusplus
extern "C" {
#endif