mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-07 11:50:24 +00:00
parent
46cb20e2c0
commit
93e2eecc52
48
repos/base-sel4/src/core/include/irq_object.h
Normal file
48
repos/base-sel4/src/core/include/irq_object.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* \brief Core-specific instance of the IRQ session interface
|
||||||
|
* \author Christian Helmuth
|
||||||
|
* \date 2007-09-13
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2007-2015 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _CORE__INCLUDE__IRQ_OBJECT_H_
|
||||||
|
#define _CORE__INCLUDE__IRQ_OBJECT_H_
|
||||||
|
|
||||||
|
#include <base/thread.h>
|
||||||
|
#include <irq_session/irq_session.h>
|
||||||
|
|
||||||
|
namespace Genode { class Irq_object; }
|
||||||
|
|
||||||
|
class Genode::Irq_object : public Thread_deprecated<4096> {
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Signal_context_capability _sig_cap;
|
||||||
|
Lock _sync_bootup;
|
||||||
|
unsigned _irq;
|
||||||
|
Cap_sel _kernel_irq_sel;
|
||||||
|
Cap_sel _kernel_notify_sel;
|
||||||
|
|
||||||
|
void _wait_for_irq();
|
||||||
|
|
||||||
|
void entry() override;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Irq_object(unsigned irq);
|
||||||
|
|
||||||
|
void sigh(Signal_context_capability cap) { _sig_cap = cap; }
|
||||||
|
void notify() { Genode::Signal_transmitter(_sig_cap).submit(1); }
|
||||||
|
void ack_irq();
|
||||||
|
|
||||||
|
void start() override;
|
||||||
|
bool associate(Irq_session::Trigger const, Irq_session::Polarity const);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _CORE__INCLUDE__IRQ_OBJECT_H_ */
|
@ -12,41 +12,104 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <base/printf.h>
|
#include <base/log.h>
|
||||||
|
|
||||||
/* core includes */
|
/* core includes */
|
||||||
|
#include <platform.h>
|
||||||
#include <irq_root.h>
|
#include <irq_root.h>
|
||||||
|
#include <irq_args.h>
|
||||||
|
|
||||||
|
#include <sel4/sel4.h>
|
||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
|
|
||||||
bool Irq_object::_associate() { return true; }
|
bool Irq_object::associate(Irq_session::Trigger const irq_trigger,
|
||||||
|
Irq_session::Polarity const irq_polarity)
|
||||||
|
{
|
||||||
|
/* allocate notification object within core's CNode */
|
||||||
|
Platform &platform = *platform_specific();
|
||||||
|
Range_allocator &phys_alloc = *platform.ram_alloc();
|
||||||
|
|
||||||
|
create<Notification_kobj>(phys_alloc, platform.core_cnode().sel(),
|
||||||
|
_kernel_notify_sel);
|
||||||
|
|
||||||
|
enum { IRQ_EDGE = 0, IRQ_LEVEL = 1 };
|
||||||
|
enum { IRQ_HIGH = 0, IRQ_LOW = 1 };
|
||||||
|
|
||||||
|
seL4_Word level = (_irq < 16) ? IRQ_EDGE : IRQ_LEVEL;
|
||||||
|
seL4_Word polarity = (_irq < 16) ? IRQ_HIGH : IRQ_LOW;
|
||||||
|
|
||||||
|
if (irq_trigger != Irq_session::TRIGGER_UNCHANGED)
|
||||||
|
level = (irq_trigger == Irq_session::TRIGGER_LEVEL) ? IRQ_LEVEL : IRQ_EDGE;
|
||||||
|
|
||||||
|
if (irq_polarity != Irq_session::POLARITY_UNCHANGED)
|
||||||
|
polarity = (irq_polarity == Irq_session::POLARITY_HIGH) ? IRQ_HIGH : IRQ_LOW;
|
||||||
|
|
||||||
|
/* setup irq */
|
||||||
|
seL4_CNode root = seL4_CapInitThreadCNode;
|
||||||
|
seL4_Word index = _kernel_irq_sel.value();
|
||||||
|
seL4_Uint8 depth = 32;
|
||||||
|
seL4_Word ioapic = 0;
|
||||||
|
seL4_Word pin = _irq ? _irq : 2;
|
||||||
|
seL4_Word vector = _irq;
|
||||||
|
int res = seL4_IRQControl_GetIOAPIC(seL4_CapIRQControl, root, index, depth,
|
||||||
|
ioapic, pin, level, polarity, vector);
|
||||||
|
if (res != seL4_NoError)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
seL4_CPtr irq_handler = _kernel_irq_sel.value();
|
||||||
|
seL4_CPtr notification = _kernel_notify_sel.value();
|
||||||
|
|
||||||
|
res = seL4_IRQHandler_SetNotification(irq_handler, notification);
|
||||||
|
|
||||||
|
return (res == seL4_NoError);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Irq_object::_wait_for_irq()
|
void Irq_object::_wait_for_irq()
|
||||||
{
|
{
|
||||||
PDBG("not implemented");
|
seL4_Wait(_kernel_notify_sel.value(), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Irq_object::start()
|
void Irq_object::start()
|
||||||
{
|
{
|
||||||
PDBG("not implemented");
|
::Thread::start();
|
||||||
|
_sync_bootup.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Irq_object::entry()
|
void Irq_object::entry()
|
||||||
{
|
{
|
||||||
PDBG("not implemented");
|
/* thread is up and ready */
|
||||||
|
_sync_bootup.unlock();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
|
||||||
|
_wait_for_irq();
|
||||||
|
|
||||||
|
if (!_sig_cap.valid())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
notify();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Genode::Irq_object::ack_irq()
|
||||||
|
{
|
||||||
|
int res = seL4_IRQHandler_Ack(_kernel_irq_sel.value());
|
||||||
|
if (res != seL4_NoError)
|
||||||
|
Genode::error("ack_irq failed - ", res);
|
||||||
|
}
|
||||||
|
|
||||||
Irq_object::Irq_object(unsigned irq)
|
Irq_object::Irq_object(unsigned irq)
|
||||||
:
|
:
|
||||||
Thread_deprecated<4096>("irq"),
|
Thread_deprecated<4096>("irq"),
|
||||||
_sync_ack(Lock::LOCKED), _sync_bootup(Lock::LOCKED),
|
_sync_bootup(Lock::LOCKED),
|
||||||
_irq(irq)
|
_irq(irq),
|
||||||
|
_kernel_irq_sel(platform_specific()->core_sel_alloc().alloc()),
|
||||||
|
_kernel_notify_sel(platform_specific()->core_sel_alloc().alloc())
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
||||||
@ -62,7 +125,15 @@ Irq_session_component::Irq_session_component(Range_allocator *irq_alloc,
|
|||||||
throw Root::Unavailable();
|
throw Root::Unavailable();
|
||||||
|
|
||||||
if (!irq_alloc || irq_alloc->alloc_addr(1, _irq_number).error()) {
|
if (!irq_alloc || irq_alloc->alloc_addr(1, _irq_number).error()) {
|
||||||
PERR("Unavailable IRQ 0x%x requested", _irq_number);
|
Genode::error("Unavailable IRQ ", _irq_number, " requested");
|
||||||
|
throw Root::Unavailable();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Irq_args const irq_args(args);
|
||||||
|
|
||||||
|
if (!_irq_object.associate(irq_args.trigger(), irq_args.polarity())) {
|
||||||
|
Genode::error("Could not associate with IRQ ", irq_args.irq_number());
|
||||||
throw Root::Unavailable();
|
throw Root::Unavailable();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +143,7 @@ Irq_session_component::Irq_session_component(Range_allocator *irq_alloc,
|
|||||||
|
|
||||||
Irq_session_component::~Irq_session_component()
|
Irq_session_component::~Irq_session_component()
|
||||||
{
|
{
|
||||||
PERR("Not yet implemented.");
|
Genode::error(__PRETTY_FUNCTION__, "- not yet implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -98,7 +98,25 @@ class Stack_area_region_map : public Region_map
|
|||||||
return local_addr;
|
return local_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void detach(Local_addr) override { PWRN("Not implemented!"); }
|
void detach(Local_addr local_addr) override
|
||||||
|
{
|
||||||
|
using Genode::addr_t;
|
||||||
|
|
||||||
|
if ((addr_t)local_addr >= stack_area_virtual_size())
|
||||||
|
return;
|
||||||
|
|
||||||
|
addr_t const detach = stack_area_virtual_base() + (addr_t)local_addr;
|
||||||
|
addr_t const stack = stack_virtual_size();
|
||||||
|
addr_t const pages = ((detach & ~(stack - 1)) + stack - detach)
|
||||||
|
>> get_page_size_log2();
|
||||||
|
|
||||||
|
unmap_local(detach, pages);
|
||||||
|
|
||||||
|
/* XXX missing XXX */
|
||||||
|
warning(__PRETTY_FUNCTION__, ": not implemented");
|
||||||
|
// Untyped_memory::convert_to_untyped_frames(phys_addr, phys_size)
|
||||||
|
// Untyped_memory::free_pages(phys_alloc, num_pages);
|
||||||
|
}
|
||||||
|
|
||||||
void fault_handler(Signal_context_capability) override { }
|
void fault_handler(Signal_context_capability) override { }
|
||||||
|
|
||||||
|
@ -59,7 +59,19 @@ void Thread::_init_platform_thread(size_t, Type type)
|
|||||||
|
|
||||||
void Thread::_deinit_platform_thread()
|
void Thread::_deinit_platform_thread()
|
||||||
{
|
{
|
||||||
PDBG("not implemented");
|
addr_t const utcb_virt_addr = (addr_t)&_stack->utcb();
|
||||||
|
|
||||||
|
bool ret = unmap_local(utcb_virt_addr, 1);
|
||||||
|
ASSERT(ret);
|
||||||
|
|
||||||
|
int res = seL4_CNode_Delete(seL4_CapInitThreadCNode,
|
||||||
|
native_thread().lock_sel, 32);
|
||||||
|
if (res)
|
||||||
|
error(__PRETTY_FUNCTION__, ": seL4_CNode_Delete (",
|
||||||
|
Hex(native_thread().lock_sel), ") returned ", res);
|
||||||
|
|
||||||
|
Platform &platform = *platform_specific();
|
||||||
|
platform.core_sel_alloc().free(Cap_sel(native_thread().lock_sel));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user