2011-12-22 16:19:25 +01:00
|
|
|
/*
|
|
|
|
* \brief Core-specific instance of the CPU session/thread interfaces
|
|
|
|
* \author Christian Helmuth
|
|
|
|
* \date 2006-07-17
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2017-01-04 11:38:39 +01:00
|
|
|
* Copyright (C) 2006-2017 Genode Labs GmbH
|
2011-12-22 16:19:25 +01:00
|
|
|
*
|
|
|
|
* This file is part of the Genode OS framework, which is distributed
|
2017-02-20 13:23:52 +01:00
|
|
|
* under the terms of the GNU Affero General Public License version 3.
|
2011-12-22 16:19:25 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _CPU_SESSION_COMPONENT_H_
|
|
|
|
#define _CPU_SESSION_COMPONENT_H_
|
|
|
|
|
|
|
|
/* Genode includes */
|
2016-05-17 16:13:23 +02:00
|
|
|
#include <base/allocator.h>
|
2016-11-23 17:07:49 +01:00
|
|
|
#include <base/env.h>
|
2011-12-22 16:19:25 +01:00
|
|
|
#include <base/rpc_server.h>
|
2016-11-23 17:07:49 +01:00
|
|
|
#include <base/service.h>
|
2016-05-17 16:13:23 +02:00
|
|
|
#include <base/thread.h>
|
2020-05-15 15:13:19 +02:00
|
|
|
#include <util/retry.h>
|
2011-12-22 16:19:25 +01:00
|
|
|
#include <cpu_session/client.h>
|
2016-11-23 17:07:49 +01:00
|
|
|
#include <parent/parent.h>
|
2016-05-17 16:13:23 +02:00
|
|
|
#include <pd_session/capability.h>
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
/* GDB monitor includes */
|
2016-05-17 16:13:23 +02:00
|
|
|
#include "append_list.h"
|
2016-11-23 17:07:49 +01:00
|
|
|
#include "genode_child_resources.h"
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2016-05-17 16:13:23 +02:00
|
|
|
namespace Gdb_monitor
|
|
|
|
{
|
2017-01-04 11:38:39 +01:00
|
|
|
using namespace Genode;
|
|
|
|
|
2016-05-17 16:13:23 +02:00
|
|
|
class Cpu_session_component;
|
|
|
|
class Cpu_thread_component;
|
2016-11-23 17:07:49 +01:00
|
|
|
class Local_cpu_factory;
|
|
|
|
|
2017-01-04 11:38:39 +01:00
|
|
|
typedef Local_service<Cpu_session_component> Cpu_service;
|
2016-05-17 16:13:23 +02:00
|
|
|
}
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2016-11-23 17:07:49 +01:00
|
|
|
|
2016-05-17 16:13:23 +02:00
|
|
|
class Gdb_monitor::Cpu_session_component : public Rpc_object<Cpu_session>
|
2011-12-22 16:19:25 +01:00
|
|
|
{
|
2016-05-17 16:13:23 +02:00
|
|
|
|
2011-12-22 16:19:25 +01:00
|
|
|
private:
|
|
|
|
|
2017-01-04 11:38:39 +01:00
|
|
|
Env &_env;
|
2016-11-23 17:07:49 +01:00
|
|
|
|
2017-01-04 11:38:39 +01:00
|
|
|
Parent::Client _parent_client;
|
2016-11-23 17:07:49 +01:00
|
|
|
|
2017-01-04 11:38:39 +01:00
|
|
|
Id_space<Parent::Client>::Element const _id_space_element
|
2016-11-23 17:07:49 +01:00
|
|
|
{ _parent_client, _env.id_space() };
|
2016-05-17 16:13:23 +02:00
|
|
|
|
2017-01-04 11:38:39 +01:00
|
|
|
Rpc_entrypoint &_ep;
|
|
|
|
Allocator &_md_alloc;
|
2016-05-17 16:13:23 +02:00
|
|
|
|
2017-01-04 11:38:39 +01:00
|
|
|
Pd_session_capability _core_pd;
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2020-05-15 15:13:19 +02:00
|
|
|
struct Expanding_parent_cpu_session : Cpu_session_client
|
|
|
|
{
|
|
|
|
Cpu_session_component &_component;
|
|
|
|
|
|
|
|
Expanding_parent_cpu_session(Cpu_session_capability cap,
|
|
|
|
Cpu_session_component &component)
|
|
|
|
:
|
|
|
|
Cpu_session_client(cap), _component(component) { }
|
|
|
|
|
|
|
|
Thread_capability create_thread(Capability<Pd_session> pd,
|
|
|
|
Cpu_session::Name const &name,
|
|
|
|
Affinity::Location affinity,
|
|
|
|
Weight weight,
|
|
|
|
addr_t utcb) override
|
|
|
|
{
|
|
|
|
enum { UPGRADE_ATTEMPTS = ~0U };
|
|
|
|
return Genode::retry<Out_of_ram>(
|
|
|
|
[&] () {
|
|
|
|
return Genode::retry<Out_of_caps>(
|
|
|
|
[&] () { return Cpu_session_client::create_thread(pd, name, affinity, weight, utcb); },
|
|
|
|
[&] () { _component._env.upgrade(_component._id_space_element.id(), "cap_quota=3"); },
|
|
|
|
UPGRADE_ATTEMPTS);
|
|
|
|
},
|
|
|
|
[&] () { _component._env.upgrade(_component._id_space_element.id(), "ram_quota=8K"); },
|
|
|
|
UPGRADE_ATTEMPTS);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
Expanding_parent_cpu_session _parent_cpu_session;
|
2019-01-21 10:34:56 +01:00
|
|
|
Entrypoint &_signal_ep;
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2019-04-29 16:53:44 +02:00
|
|
|
int const _new_thread_pipe_write_end;
|
|
|
|
int const _breakpoint_len;
|
|
|
|
unsigned char const *_breakpoint_data;
|
|
|
|
|
2017-01-04 11:38:39 +01:00
|
|
|
Append_list<Cpu_thread_component> _thread_list;
|
2016-05-17 16:13:23 +02:00
|
|
|
|
2017-01-04 11:38:39 +01:00
|
|
|
bool _stop_new_threads = true;
|
|
|
|
Lock _stop_new_threads_lock;
|
2016-05-17 16:13:23 +02:00
|
|
|
|
2017-01-04 11:38:39 +01:00
|
|
|
Capability<Cpu_session::Native_cpu> _native_cpu_cap;
|
2016-11-23 17:07:49 +01:00
|
|
|
|
2017-01-04 11:38:39 +01:00
|
|
|
Capability<Cpu_session::Native_cpu> _setup_native_cpu();
|
2016-05-17 16:13:23 +02:00
|
|
|
void _cleanup_native_cpu();
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor
|
|
|
|
*/
|
2017-01-04 11:38:39 +01:00
|
|
|
Cpu_session_component(Env &env,
|
2016-11-23 17:07:49 +01:00
|
|
|
Rpc_entrypoint &ep,
|
2017-01-04 11:38:39 +01:00
|
|
|
Allocator &md_alloc,
|
2016-11-23 17:07:49 +01:00
|
|
|
Pd_session_capability core_pd,
|
2019-01-21 10:34:56 +01:00
|
|
|
Entrypoint &signal_ep,
|
2016-11-23 17:07:49 +01:00
|
|
|
const char *args,
|
2019-04-29 16:53:44 +02:00
|
|
|
Affinity const &affinity,
|
|
|
|
int const new_thread_pipe_write_end,
|
|
|
|
int const breakpoint_len,
|
|
|
|
unsigned char const *breakpoint_data);
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Destructor
|
|
|
|
*/
|
|
|
|
~Cpu_session_component();
|
|
|
|
|
2016-05-17 16:13:23 +02:00
|
|
|
Cpu_session &parent_cpu_session();
|
|
|
|
Rpc_entrypoint &thread_ep();
|
2019-01-21 10:34:56 +01:00
|
|
|
Entrypoint &signal_ep();
|
2011-12-22 16:19:25 +01:00
|
|
|
Thread_capability thread_cap(unsigned long lwpid);
|
2016-05-17 16:13:23 +02:00
|
|
|
unsigned long lwpid(Thread_capability thread_cap);
|
|
|
|
Cpu_thread_component *lookup_cpu_thread(unsigned long lwpid);
|
|
|
|
Cpu_thread_component *lookup_cpu_thread(Thread_capability thread_cap);
|
|
|
|
int signal_pipe_read_fd(Thread_capability thread_cap);
|
|
|
|
int send_signal(Thread_capability thread_cap, int signo);
|
|
|
|
void handle_unresolved_page_fault();
|
|
|
|
void stop_new_threads(bool stop);
|
|
|
|
bool stop_new_threads();
|
|
|
|
Lock &stop_new_threads_lock();
|
|
|
|
int handle_initial_breakpoint(unsigned long lwpid);
|
|
|
|
void pause_all_threads();
|
|
|
|
void resume_all_threads();
|
2012-10-19 16:00:22 +02:00
|
|
|
Thread_capability first();
|
|
|
|
Thread_capability next(Thread_capability);
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
/***************************
|
|
|
|
** CPU session interface **
|
|
|
|
***************************/
|
|
|
|
|
2016-05-17 16:13:23 +02:00
|
|
|
Thread_capability create_thread(Capability<Pd_session>,
|
|
|
|
Name const &,
|
|
|
|
Affinity::Location,
|
|
|
|
Weight,
|
|
|
|
addr_t) override;
|
2016-04-20 21:12:57 +02:00
|
|
|
void kill_thread(Thread_capability) override;
|
2016-05-10 18:05:38 +02:00
|
|
|
void exception_sigh(Signal_context_capability handler) override;
|
2016-04-20 21:12:57 +02:00
|
|
|
Affinity::Space affinity_space() const override;
|
|
|
|
Dataspace_capability trace_control() override;
|
|
|
|
int ref_account(Cpu_session_capability c) override;
|
2017-01-04 11:38:39 +01:00
|
|
|
int transfer_quota(Cpu_session_capability c, size_t q) override;
|
2015-03-27 14:05:55 +01:00
|
|
|
Quota quota() override;
|
2016-03-30 15:34:37 +02:00
|
|
|
Capability<Native_cpu> native_cpu() override;
|
2011-12-22 16:19:25 +01:00
|
|
|
};
|
|
|
|
|
2016-11-23 17:07:49 +01:00
|
|
|
|
|
|
|
class Gdb_monitor::Local_cpu_factory : public Cpu_service::Factory
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
|
2017-01-04 11:38:39 +01:00
|
|
|
Env &_env;
|
|
|
|
Rpc_entrypoint &_ep;
|
2016-11-23 17:07:49 +01:00
|
|
|
|
2017-01-04 11:38:39 +01:00
|
|
|
Allocator &_md_alloc;
|
2016-11-23 17:07:49 +01:00
|
|
|
Pd_session_capability _core_pd;
|
2019-01-21 10:34:56 +01:00
|
|
|
Entrypoint &_signal_ep;
|
2019-04-29 16:53:44 +02:00
|
|
|
int const _new_thread_pipe_write_end;
|
|
|
|
int const _breakpoint_len;
|
|
|
|
unsigned char const *_breakpoint_data;
|
2016-11-23 17:07:49 +01:00
|
|
|
Genode_child_resources *_genode_child_resources;
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
2017-01-04 11:38:39 +01:00
|
|
|
Local_cpu_factory(Env &env,
|
|
|
|
Rpc_entrypoint &ep,
|
|
|
|
Allocator &md_alloc,
|
|
|
|
Pd_session_capability core_pd,
|
2019-01-21 10:34:56 +01:00
|
|
|
Entrypoint &signal_ep,
|
2019-04-29 16:53:44 +02:00
|
|
|
int new_thread_pipe_write_end,
|
|
|
|
int const breakpoint_len,
|
|
|
|
unsigned char const *breakpoint_data,
|
2016-11-23 17:07:49 +01:00
|
|
|
Genode_child_resources *genode_child_resources)
|
|
|
|
: _env(env), _ep(ep),
|
|
|
|
_md_alloc(md_alloc),
|
|
|
|
_core_pd(core_pd),
|
2019-01-21 10:34:56 +01:00
|
|
|
_signal_ep(signal_ep),
|
2019-04-29 16:53:44 +02:00
|
|
|
_new_thread_pipe_write_end(new_thread_pipe_write_end),
|
|
|
|
_breakpoint_len(breakpoint_len),
|
|
|
|
_breakpoint_data(breakpoint_data),
|
2016-11-23 17:07:49 +01:00
|
|
|
_genode_child_resources(genode_child_resources)
|
|
|
|
{ }
|
|
|
|
|
|
|
|
/***********************
|
|
|
|
** Factory interface **
|
|
|
|
***********************/
|
|
|
|
|
|
|
|
Cpu_session_component &create(Args const &args, Affinity affinity) override
|
|
|
|
{
|
|
|
|
Cpu_session_component *cpu_session_component =
|
|
|
|
new (_md_alloc)
|
|
|
|
Cpu_session_component(_env,
|
|
|
|
_ep,
|
|
|
|
_md_alloc,
|
|
|
|
_core_pd,
|
2019-01-21 10:34:56 +01:00
|
|
|
_signal_ep,
|
2016-11-23 17:07:49 +01:00
|
|
|
args.string(),
|
2019-04-29 16:53:44 +02:00
|
|
|
affinity,
|
|
|
|
_new_thread_pipe_write_end,
|
|
|
|
_breakpoint_len,
|
|
|
|
_breakpoint_data);
|
2016-11-23 17:07:49 +01:00
|
|
|
_genode_child_resources->cpu_session_component(cpu_session_component);
|
|
|
|
return *cpu_session_component;
|
|
|
|
}
|
|
|
|
|
|
|
|
void upgrade(Cpu_session_component &, Args const &) override { }
|
|
|
|
|
|
|
|
void destroy(Cpu_session_component &session) override
|
|
|
|
{
|
2017-01-04 11:38:39 +01:00
|
|
|
Genode::destroy(_md_alloc, &session);
|
2016-11-23 17:07:49 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2011-12-22 16:19:25 +01:00
|
|
|
#endif /* _CPU_SESSION_COMPONENT_H_ */
|