113 lines
2.3 KiB
C++
113 lines
2.3 KiB
C++
/*
|
|
* \brief Genode C API terminal functions of the L4Linux support library
|
|
* \author Stefan Kalkowski
|
|
* \date 2011-09-16
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2011-2013 Genode Labs GmbH
|
|
*
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
* under the terms of the GNU General Public License version 2.
|
|
*/
|
|
|
|
/* Genode includes */
|
|
#include <base/env.h>
|
|
#include <base/thread.h>
|
|
#include <terminal_session/connection.h>
|
|
|
|
#include <linux.h>
|
|
#include <vcpu.h>
|
|
|
|
namespace Fiasco {
|
|
#include <genode/net.h>
|
|
#include <l4/sys/irq.h>
|
|
#include <l4/sys/kdebug.h>
|
|
}
|
|
|
|
static Terminal::Connection *terminal() {
|
|
static bool initialized = false;
|
|
static Terminal::Connection *t = 0;
|
|
|
|
if (!initialized) {
|
|
try {
|
|
static Terminal::Connection terminal;
|
|
t = &terminal;
|
|
} catch(...) { }
|
|
initialized = true;
|
|
}
|
|
return t;
|
|
}
|
|
|
|
|
|
namespace {
|
|
class Signal_thread : public Genode::Thread<8192>
|
|
{
|
|
private:
|
|
|
|
Fiasco::l4_cap_idx_t _cap;
|
|
|
|
protected:
|
|
|
|
void entry()
|
|
{
|
|
using namespace Fiasco;
|
|
using namespace Genode;
|
|
|
|
Signal_receiver receiver;
|
|
Signal_context rx;
|
|
Signal_context_capability cap(receiver.manage(&rx));
|
|
terminal()->connected_sigh(cap);
|
|
terminal()->read_avail_sigh(cap);
|
|
|
|
while (true) {
|
|
receiver.wait_for_signal();
|
|
if (l4_error(l4_irq_trigger(_cap)) != -1)
|
|
PWRN("IRQ terminal trigger failed\n");
|
|
}
|
|
}
|
|
|
|
public:
|
|
|
|
Signal_thread(Fiasco::l4_cap_idx_t cap)
|
|
: Genode::Thread<8192>("terminal-signal-thread"), _cap(cap) { start(); }
|
|
};
|
|
}
|
|
|
|
|
|
static Signal_thread *signal_thread = 0;
|
|
|
|
|
|
using namespace Fiasco;
|
|
|
|
extern "C" {
|
|
|
|
unsigned genode_terminal_readchar(unsigned idx, char *buf, unsigned long sz) {
|
|
if (!terminal()->avail())
|
|
return 0;
|
|
return terminal()->read(buf, sz);
|
|
}
|
|
|
|
|
|
void genode_terminal_writechar(unsigned idx, const char *buf, unsigned long sz) {
|
|
terminal()->write(buf, sz);
|
|
}
|
|
|
|
|
|
l4_cap_idx_t genode_terminal_irq(unsigned idx) {
|
|
static Genode::Native_capability cap = L4lx::vcpu_connection()->alloc_irq();
|
|
if (!signal_thread)
|
|
signal_thread = new (Genode::env()->heap()) Signal_thread(cap.dst());
|
|
return cap.dst();
|
|
}
|
|
|
|
|
|
unsigned genode_terminal_count(void) {
|
|
return terminal() ? 1 : 0; }
|
|
|
|
|
|
void genode_terminal_stop(unsigned idx) {
|
|
destroy(Genode::env()->heap(), signal_thread);
|
|
}
|
|
}
|