mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-31 00:24:51 +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 */
|
||||
#include <base/printf.h>
|
||||
#include <base/log.h>
|
||||
|
||||
/* core includes */
|
||||
#include <platform.h>
|
||||
#include <irq_root.h>
|
||||
#include <irq_args.h>
|
||||
|
||||
#include <sel4/sel4.h>
|
||||
|
||||
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()
|
||||
{
|
||||
PDBG("not implemented");
|
||||
seL4_Wait(_kernel_notify_sel.value(), nullptr);
|
||||
}
|
||||
|
||||
|
||||
void Irq_object::start()
|
||||
{
|
||||
PDBG("not implemented");
|
||||
::Thread::start();
|
||||
_sync_bootup.lock();
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
:
|
||||
Thread_deprecated<4096>("irq"),
|
||||
_sync_ack(Lock::LOCKED), _sync_bootup(Lock::LOCKED),
|
||||
_irq(irq)
|
||||
_sync_bootup(Lock::LOCKED),
|
||||
_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();
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
@ -72,7 +143,7 @@ Irq_session_component::Irq_session_component(Range_allocator *irq_alloc,
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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 { }
|
||||
|
||||
|
@ -59,7 +59,19 @@ void Thread::_init_platform_thread(size_t, Type type)
|
||||
|
||||
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