mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-30 10:38:55 +00:00
parent
044a109c3a
commit
a8d071b372
base-hw/src/core
@ -200,6 +200,25 @@ namespace Imx53
|
||||
if (i <= MAX_INTERRUPT_ID)
|
||||
write<Enclear::Clear_enable>(1, i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wether an interrupt is inter-processor interrupt of a processor
|
||||
*
|
||||
* \param interrupt_id kernel name of the interrupt
|
||||
* \param processor_id kernel name of the processor
|
||||
*/
|
||||
bool is_ip_interrupt(unsigned const interrupt_id,
|
||||
unsigned const processor_id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger the inter-processor interrupt of a processor
|
||||
*
|
||||
* \param processor_id kernel name of the processor
|
||||
*/
|
||||
void trigger_ip_interrupt(unsigned const processor_id) { }
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -30,14 +30,26 @@ void Kernel::Execution_context::_interrupt(unsigned const processor_id)
|
||||
{
|
||||
/* determine handling for specific interrupt */
|
||||
unsigned irq_id;
|
||||
if (pic()->take_request(irq_id))
|
||||
Pic * const ic = pic();
|
||||
if (ic->take_request(irq_id))
|
||||
{
|
||||
/* check wether the interrupt is a scheduling timeout */
|
||||
if (timer()->interrupt_id(processor_id) == irq_id)
|
||||
{
|
||||
/* handle scheduling timeout */
|
||||
/* check wether the interrupt is a processor-scheduling timeout */
|
||||
if (timer()->interrupt_id(processor_id) == irq_id) {
|
||||
|
||||
__processor->scheduler()->yield_occupation();
|
||||
timer()->clear_interrupt(processor_id);
|
||||
|
||||
/* check wether the interrupt is our inter-processor interrupt */
|
||||
} else if (ic->is_ip_interrupt(irq_id, processor_id)) {
|
||||
|
||||
/*
|
||||
* This interrupt solely denotes that another processor has
|
||||
* modified the scheduling plan of this processor and thus
|
||||
* a more prior user context than the current one might be
|
||||
* available.
|
||||
*/
|
||||
|
||||
/* after all it must be a user interrupt */
|
||||
} else {
|
||||
|
||||
/* try to inform the user interrupt-handler */
|
||||
@ -45,23 +57,32 @@ void Kernel::Execution_context::_interrupt(unsigned const processor_id)
|
||||
}
|
||||
}
|
||||
/* end interrupt request at controller */
|
||||
pic()->finish_request();
|
||||
ic->finish_request();
|
||||
}
|
||||
|
||||
|
||||
void Kernel::Execution_context::_schedule()
|
||||
{
|
||||
/* schedule thread */
|
||||
__processor->scheduler()->insert(this);
|
||||
|
||||
/* let processor of the scheduled thread notice the change immediately */
|
||||
unsigned const processor_id = __processor->id();
|
||||
if (processor_id != Processor::executing_id()) {
|
||||
pic()->trigger_ip_interrupt(processor_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Kernel::Execution_context::_unschedule()
|
||||
{
|
||||
assert(__processor->id() == Processor::executing_id());
|
||||
__processor->scheduler()->remove(this);
|
||||
}
|
||||
|
||||
|
||||
void Kernel::Execution_context::_yield()
|
||||
{
|
||||
assert(__processor->id() == Processor::executing_id());
|
||||
__processor->scheduler()->yield_occupation();
|
||||
}
|
||||
|
@ -127,6 +127,15 @@ class Arm_gic::Pic
|
||||
struct Edge_triggered : Bitfield<1, 1> { };
|
||||
};
|
||||
|
||||
/**
|
||||
* Software generated interrupt register
|
||||
*/
|
||||
struct Sgir : Register<0xf00, 32>
|
||||
{
|
||||
struct Sgi_int_id : Bitfield<0, 4> { };
|
||||
struct Cpu_target_list : Bitfield<16, 8> { };
|
||||
};
|
||||
|
||||
/**
|
||||
* Minimum supported interrupt priority
|
||||
*/
|
||||
@ -201,7 +210,6 @@ class Arm_gic::Pic
|
||||
struct Iar : Register<0x0c, 32, true>
|
||||
{
|
||||
struct Irq_id : Bitfield<0,10> { };
|
||||
struct Cpu_id : Bitfield<10,3> { };
|
||||
};
|
||||
|
||||
/**
|
||||
@ -222,6 +230,16 @@ class Arm_gic::Pic
|
||||
*/
|
||||
inline static bool _use_security_ext();
|
||||
|
||||
/**
|
||||
* Return inter-processor interrupt of a specific processor
|
||||
*
|
||||
* \param processor_id kernel name of targeted processor
|
||||
*/
|
||||
unsigned _ip_interrupt(unsigned const processor_id) const
|
||||
{
|
||||
return processor_id + 1;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
@ -337,6 +355,32 @@ class Arm_gic::Pic
|
||||
{
|
||||
_distr.write<Distr::Icenabler::Clear_enable>(1, interrupt_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wether an interrupt is inter-processor interrupt of a processor
|
||||
*
|
||||
* \param interrupt_id kernel name of the interrupt
|
||||
* \param processor_id kernel name of the processor
|
||||
*/
|
||||
bool is_ip_interrupt(unsigned const interrupt_id,
|
||||
unsigned const processor_id)
|
||||
{
|
||||
return interrupt_id == _ip_interrupt(processor_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger the inter-processor interrupt of a processor
|
||||
*
|
||||
* \param processor_id kernel name of the processor
|
||||
*/
|
||||
void trigger_ip_interrupt(unsigned const processor_id)
|
||||
{
|
||||
typedef Distr::Sgir Sgir;
|
||||
Sgir::access_t sgir = 0;
|
||||
Sgir::Sgi_int_id::set(sgir, _ip_interrupt(processor_id));
|
||||
Sgir::Cpu_target_list::set(sgir, 1 << processor_id);
|
||||
_distr.write<Sgir>(sgir);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _PIC__ARM_GIC_H_ */
|
||||
|
@ -203,6 +203,25 @@ namespace Imx31
|
||||
*/
|
||||
void mask(unsigned const i) {
|
||||
if (i <= MAX_INTERRUPT_ID) write<Intdisnum>(i); }
|
||||
|
||||
/**
|
||||
* Wether an interrupt is inter-processor interrupt of a processor
|
||||
*
|
||||
* \param interrupt_id kernel name of the interrupt
|
||||
* \param processor_id kernel name of the processor
|
||||
*/
|
||||
bool is_ip_interrupt(unsigned const interrupt_id,
|
||||
unsigned const processor_id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger the inter-processor interrupt of a processor
|
||||
*
|
||||
* \param processor_id kernel name of the processor
|
||||
*/
|
||||
void trigger_ip_interrupt(unsigned const processor_id) { }
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -117,6 +117,25 @@ namespace Kernel
|
||||
else
|
||||
write<Irq_disable_gpu_2>(1 << (i - 8 - 32));
|
||||
}
|
||||
|
||||
/**
|
||||
* Wether an interrupt is inter-processor interrupt of a processor
|
||||
*
|
||||
* \param interrupt_id kernel name of the interrupt
|
||||
* \param processor_id kernel name of the processor
|
||||
*/
|
||||
bool is_ip_interrupt(unsigned const interrupt_id,
|
||||
unsigned const processor_id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger the inter-processor interrupt of a processor
|
||||
*
|
||||
* \param processor_id kernel name of the processor
|
||||
*/
|
||||
void trigger_ip_interrupt(unsigned const processor_id) { }
|
||||
};
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user