l4re-base-25.08.0

This commit is contained in:
2025-09-12 15:55:45 +02:00
commit d959eaab98
37938 changed files with 9382688 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
provides: cxx_thread
requires: l4sys l4re
maintainer: warg@os.inf.tu-dresden.de

View File

@@ -0,0 +1,7 @@
PKGDIR = .
L4DIR ?= $(PKGDIR)/../..
TARGET := include src
include $(L4DIR)/mk/subdir.mk
src: include

View File

@@ -0,0 +1,7 @@
PKGDIR = ..
L4DIR ?= $(PKGDIR)/../..
EXTRA_TARGET := thread main_thread
PKGNAME := cxx
include $(L4DIR)/mk/include.mk

View File

@@ -0,0 +1,38 @@
/**
* \file
* \brief Main thread
*/
/*
* (c) 2004-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
* Alexander Warg <warg@os.inf.tu-dresden.de>
* economic rights: Technische Universität Dresden (Germany)
*
* This file is part of TUD:OS and distributed under the terms of the
* GNU General Public License 2.
* Please see the COPYING-GPL-2 file for details.
*
* As a special exception, you may use this file as part of a free software
* library without restriction. Specifically, if other files instantiate
* templates or use macros or inline functions from this file, or you compile
* this file and link it with other files to produce an executable, this
* file does not by itself cause the resulting executable to be covered by
* the GNU General Public License. This exception does not however
* invalidate any other reasons why the executable file might be covered by
* the GNU General Public License.
*/
#ifndef L4_CXX_MAIN_THREAD_H__
#define L4_CXX_MAIN_THREAD_H__
#include <l4/cxx/thread>
namespace cxx {
class MainThread : public Thread
{
public:
MainThread() : Thread(true)
{}
};
};
#endif /* L4_CXX_MAIN_THREAD_H__ */

View File

@@ -0,0 +1,75 @@
// vim:set ft=cpp: -*- Mode: C++ -*-
/**
* \file
* \brief Thread implementation
*/
/*
* (c) 2004-2009 Alexander Warg <warg@os.inf.tu-dresden.de>
* economic rights: Technische Universität Dresden (Germany)
* This file is part of TUD:OS and distributed under the terms of the
* GNU Lesser General Public License 2.1.
* Please see the COPYING-LGPL-2.1 file for details.
*/
#ifndef CXX_THREAD_H__
#define CXX_THREAD_H__
#include <l4/sys/capability>
#include <l4/sys/types.h>
namespace cxx {
class Thread
{
public:
enum State
{
Dead = 0,
Running = 1,
Stopped = 2,
};
Thread(bool initiate);
Thread(void *stack);
Thread(void *stack, L4::Cap<L4::Thread> const &cap);
virtual ~Thread();
void execute() asm ("L4_Thread_execute");
virtual void run() = 0;
virtual void shutdown() asm ("L4_Thread_shutdown");
void start();
void stop();
L4::Cap<L4::Thread> self() const throw()
{ return _cap; }
State state() const
{ return _state; }
static void start_cxx_thread(Thread *_this)
asm ("L4_Thread_start_cxx_thread");
static void kill_cxx_thread(Thread *_this)
asm ("L4_Thread_kill_cxx_thread");
static void set_pager(L4::Cap<void>const &p) throw()
{ _pager = p; }
private:
int create();
L4::Cap<L4::Thread> _cap;
State _state;
protected:
void *_stack;
private:
static L4::Cap<void> _pager;
static L4::Cap<void> _master;
};
};
#endif /* CXX_THREAD_H__ */

View File

@@ -0,0 +1,27 @@
/*
* (c) 2004-2009 Alexander Warg <warg@os.inf.tu-dresden.de>
* economic rights: Technische Universität Dresden (Germany)
* This file is part of TUD:OS and distributed under the terms of the
* GNU Lesser General Public License 2.1.
* Please see the COPYING-LGPL-2.1 file for details.
*/
#include <l4/cxx/thread>
namespace cxx {
void L4_cxx_start(void);
void L4_cxx_start(void)
{
asm volatile (".global L4_Thread_start_cxx_thread \n"
"L4_Thread_start_cxx_thread: \n"
"mov 8(%rsp), %rdi \n"
"call L4_Thread_execute \n");
}
void Thread::kill_cxx_thread(Thread *_this)
{ _this->shutdown(); }
};

View File

@@ -0,0 +1,34 @@
/*
* (c) 2004-2009 Alexander Warg <warg@os.inf.tu-dresden.de>
* economic rights: Technische Universität Dresden (Germany)
* This file is part of TUD:OS and distributed under the terms of the
* GNU Lesser General Public License 2.1.
* Please see the COPYING-LGPL-2.1 file for details.
*/
#include <l4/cxx/thread>
void L4_cxx_start(void);
void L4_cxx_start(void)
{
asm volatile (".global L4_Thread_start_cxx_thread \n"
".type L4_Thread_start_cxx_thread, #function\n"
"L4_Thread_start_cxx_thread: \n"
"ldr r0, [sp, #4] \n"
"ldr pc,1f \n"
"1: .word L4_Thread_execute \n");
}
void L4_cxx_kill(void);
void L4_cxx_kill(void)
{
asm volatile (".global L4_Thread_kill_cxx_thread \n"
".type L4_Thread_kill_cxx_thread, #function \n"
"L4_Thread_kill_cxx_thread: \n"
"ldr r0, [sp, #4] \n"
"ldr pc,1f \n"
"1: .word L4_Thread_shutdown \n");
}

View File

@@ -0,0 +1,34 @@
/*
* (c) 2004-2009 Alexander Warg <warg@os.inf.tu-dresden.de>
* economic rights: Technische Universität Dresden (Germany)
* This file is part of TUD:OS and distributed under the terms of the
* GNU Lesser General Public License 2.1.
* Please see the COPYING-LGPL-2.1 file for details.
*/
#include <l4/cxx/thread>
void L4_cxx_start(void);
void L4_cxx_start(void)
{
asm volatile (".global L4_Thread_start_cxx_thread \n"
"L4_Thread_start_cxx_thread: \n"
"ldr x0, [sp, #8]! \n"
"ldr x9, 1f \n"
"br x9 \n"
"1: .quad L4_Thread_execute \n");
}
void L4_cxx_kill(void);
void L4_cxx_kill(void)
{
asm volatile (".global L4_Thread_kill_cxx_thread \n"
"L4_Thread_kill_cxx_thread: \n"
"ldr x0, [sp, #8]! \n"
"ldr x9, 1f \n"
"br x9 \n"
"1: .quad L4_Thread_shutdown \n");
}

View File

@@ -0,0 +1,67 @@
/*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License 2.1. See the file "COPYING-LGPL-2.1" in the main directory of
* this archive for more details.
*
* Copyright (C) 2013 Imagination Technologies Ltd.
* Author: Yann Le Du <ledu@kymasys.com>
*/
#include <l4/cxx/thread>
void L4_cxx_start(void);
void L4_cxx_start(void)
{
/*
* get _this pointer from the stack and call _this->execute()
*
* void Thread::start_cxx_thread(Thread *_this)
* { _this->execute(); }
*
*/
asm volatile (".global L4_Thread_start_cxx_thread \n"
"L4_Thread_start_cxx_thread: \n"
".set push \n"
".set noreorder \n"
#if (_MIPS_SZLONG == 64)
"bal 1f \n"
"ld $a0, 8($sp) \n"
"1: \n"
".cpsetup $ra, $t9, 1b \n"
#else
".cprestore 16 \n"
"lw $a0, 4($sp) \n"
#endif
".set pop \n"
"jal L4_Thread_execute \n");
}
void L4_cxx_kill(void);
void L4_cxx_kill(void)
{
/*
* get _this pointer from the stack and call _this->shutdown()
*
* void Thread::kill_cxx_thread(Thread *_this)
* { _this->shutdown(); }
*
*/
asm volatile (".global L4_Thread_kill_cxx_thread \n"
"L4_Thread_kill_cxx_thread: \n"
".set push \n"
".set noreorder \n"
#if (_MIPS_SZLONG == 64)
"bal 1f \n"
"ld $a0, 8($sp) \n"
"1: \n"
".cpsetup $ra, $t9, 1b \n"
#else
".cprestore 16 \n"
"lw $a0, 4($sp) \n"
#endif
".set pop \n"
"jal L4_Thread_shutdown \n");
}

View File

@@ -0,0 +1,30 @@
/*
* (c) 2004-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>
* economic rights: Technische Universität Dresden (Germany)
* This file is part of TUD:OS and distributed under the terms of the
* GNU Lesser General Public License 2.1.
* Please see the COPYING-LGPL-2.1 file for details.
*/
#include <l4/cxx/thread>
void L4_cxx_start(void);
void L4_cxx_start(void)
{
asm volatile (".align 4 \n"
".global L4_Thread_start_cxx_thread \n"
"L4_Thread_start_cxx_thread: \n"
"trap \n");
}
void L4_cxx_kill(void);
void L4_cxx_kill(void)
{
asm volatile (".align 4 \n"
".global L4_Thread_kill_cxx_thread \n"
"L4_Thread_kill_cxx_thread: \n"
"trap \n");
}

View File

@@ -0,0 +1,35 @@
/* SPDX-License-Identifier: GPL-2.0-only or License-Ref-kk-custom */
/*
* Copyright (C) 2021 Kernkonzept GmbH.
* Author(s): Georg Kotheimer <georg.kotheimer@kernkonzept.com>
*/
#include <l4/cxx/thread>
void L4_cxx_start(void);
void L4_cxx_start(void)
{
asm volatile (".global L4_Thread_start_cxx_thread \n"
"L4_Thread_start_cxx_thread: \n"
#if __riscv_xlen == 32
"lw a0, 4(sp) \n"
#else
"ld a0, 8(sp) \n"
#endif
"j L4_Thread_execute \n");
}
void L4_cxx_kill(void);
void L4_cxx_kill(void)
{
asm volatile (".global L4_Thread_kill_cxx_thread \n"
"L4_Thread_kill_cxx_thread: \n"
#if __riscv_xlen == 32
"lw a0, 4(sp) \n"
#else
"ld a0, 8(sp) \n"
#endif
"j L4_Thread_shutdown \n");
}

View File

@@ -0,0 +1,28 @@
/*
* (c) 2004-2009 Alexander Warg <warg@os.inf.tu-dresden.de>
* economic rights: Technische Universität Dresden (Germany)
* This file is part of TUD:OS and distributed under the terms of the
* GNU Lesser General Public License 2.1.
* Please see the COPYING-LGPL-2.1 file for details.
*/
#include <l4/cxx/thread>
void L4_cxx_start(void);
void L4_cxx_start(void)
{
asm volatile (".global L4_Thread_start_cxx_thread \n"
"L4_Thread_start_cxx_thread: \n"
"ta 6 \n");
}
void L4_cxx_kill(void);
void L4_cxx_kill(void)
{
asm volatile (".global L4_Thread_kill_cxx_thread \n"
"L4_Thread_kill_cxx_thread: \n"
"ta 6 \n");
}

View File

@@ -0,0 +1,21 @@
/*
* (c) 2004-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
* Alexander Warg <warg@os.inf.tu-dresden.de>
* economic rights: Technische Universität Dresden (Germany)
* This file is part of TUD:OS and distributed under the terms of the
* GNU Lesser General Public License 2.1.
* Please see the COPYING-LGPL-2.1 file for details.
*/
#include <l4/cxx/thread>
namespace cxx {
void Thread::start_cxx_thread(Thread *_this)
{ _this->execute(); }
void Thread::kill_cxx_thread(Thread *_this)
{ _this->shutdown(); }
};

View File

@@ -0,0 +1,14 @@
PKGDIR ?= ..
L4DIR ?= $(PKGDIR)/../..
vpath %.cc $(PKGDIR)/src/ARCH-$(ARCH)
TARGET = libcxx_thread
SRC_CC = thread.cc thread-arch.cc
PC_FILENAME = cxx_thread
CXX_PKG_DIR=$(L4DIR)/pkg/l4re-core/cxx
include $(CXX_PKG_DIR)/lib/Makefile.inc
include $(L4DIR)/mk/lib.mk
$(GENERAL_D_LOC): $(CXX_PKG_DIR)/lib/Makefile.inc

View File

@@ -0,0 +1,133 @@
/*
* (c) 2004-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
* Alexander Warg <warg@os.inf.tu-dresden.de>
* economic rights: Technische Universität Dresden (Germany)
* This file is part of TUD:OS and distributed under the terms of the
* GNU Lesser General Public License 2.1.
* Please see the COPYING-LGPL-2.1 file for details.
*/
#include <l4/cxx/thread>
#include <l4/cxx/iostream>
#include <l4/cxx/l4iostream>
#include <l4/sys/thread>
#include <l4/sys/factory>
#include <l4/sys/scheduler>
#include <l4/sys/ipc.h>
#include <l4/util/util.h>
#include <l4/re/env>
namespace cxx {
namespace {
l4_cap_idx_t _next_cap = 20 << L4_CAP_SHIFT;
static inline l4_cap_idx_t alloc_next_cap()
{ l4_cap_idx_t r = _next_cap; _next_cap += (1UL << L4_CAP_SHIFT); return r; }
l4_addr_t _next_free_utcb;
l4_addr_t _utcb_base;
};
L4::Cap<void> Thread::_pager;
L4::Cap<void> Thread::_master;
Thread::Thread( bool /*initiate*/ )
: _cap(L4Re::Env::env()->main_thread()), _state(Running)
{
_next_free_utcb = L4Re::Env::env()->first_free_utcb();
_master = _cap;
L4::Thread::Attr attr;
_cap->control(attr);
_pager = attr.pager();
_utcb_base = l4_addr_t(l4_utcb());
}
int
Thread::create()
{
l4_msgtag_t err = L4Re::Env::env()->factory()->create(_cap);
if (l4_msgtag_has_error(err) || l4_msgtag_label(err) < 0)
return l4_msgtag_label(err);
L4::Thread::Attr attr(l4_utcb());
attr.pager(_pager);
attr.bind((l4_utcb_t*)_next_free_utcb, L4Re::This_task);
_next_free_utcb += L4_UTCB_OFFSET;
return _cap->control(attr).label();
}
Thread::Thread( void *stack )
: _cap(alloc_next_cap()), _state(Dead), _stack(stack)
{
create();
}
Thread::Thread( void *stack, L4::Cap<L4::Thread> const &cap )
: _cap(cap), _state(Dead), _stack(stack)
{
create();
}
void Thread::start()
{
if(_cap == _master) {
_state = Running;
run();
} else {
L4Re::Env::env()->scheduler()->
run_thread(_cap, l4_sched_param(0xff, 0));
*(--((l4_umword_t*&)_stack)) = (l4_umword_t)this;
*(--((l4_umword_t*&)_stack)) = 0;
_cap->ex_regs((l4_umword_t)start_cxx_thread,
(l4_umword_t)_stack, 0);
if (l4_msgtag_has_error(l4_ipc_send(_cap.cap(), l4_utcb(),
l4_msgtag(0,0,0,0),
L4_IPC_NEVER)))
L4::cerr << "ERROR: (master) error while thread handshake: "
<< _master << "->" << self() << "\n";
}
}
void Thread::execute()
{
l4_umword_t src;
l4_msgtag_t tag = l4_ipc_wait(l4_utcb(), &src, L4_IPC_NEVER);
if (l4_msgtag_has_error(tag))
L4::cerr << "ERROR: (slave) error while thread handshake: "
<< self() << "\n";
_state = Running;
run();
shutdown();
};
void Thread::shutdown()
{
_state = Stopped;
for (;;)
l4_ipc_sleep(L4_IPC_NEVER);
}
void Thread::stop()
{
#if 0
L4::cerr << "~Thread[" << self() << "]() called from "
<< l4_myself() << " @" << L4::hex
<< __builtin_return_address(0) << "\n";
#endif
if(_cap != _master)
{
*(((l4_umword_t*&)_stack)--) = (l4_umword_t)this;
_cap->ex_regs((l4_umword_t)kill_cxx_thread,
(l4_umword_t)_stack, 0);
}
}
Thread::~Thread()
{ stop(); }
};