hw: use one IRQ for all cpus to send IPIs

Until now, one distinct software generated IRQ per cpu was used to
send signals between cpus. As ARM's GIC has 16 software generated
IRQs only, and they need to be partitioned between secure/non-secure
TrustZone world as well as virtual and non-virtual worlds, we should
save them.

Ref #1405
This commit is contained in:
Stefan Kalkowski 2015-02-09 14:49:20 +01:00 committed by Christian Helmuth
parent a40932a324
commit 0836726df2
4 changed files with 7 additions and 12 deletions

View File

@ -182,6 +182,7 @@ class Genode::Pic
typedef Arm_gic_cpu_interface Cpui;
typedef Arm_gic_distributor Distr;
static constexpr unsigned ipi = 1;
static constexpr unsigned min_spi = 32;
static constexpr unsigned spurious_id = 1023;
@ -190,11 +191,6 @@ class Genode::Pic
unsigned const _max_irq;
unsigned _last_request;
/**
* Return inter-processor IRQ of the CPU with kernel name 'cpu_id'
*/
unsigned _ipi(unsigned const cpu_id) const { return cpu_id + 1; }
/**
* Platform specific initialization
*/
@ -268,10 +264,9 @@ class Genode::Pic
* Return wether an IRQ is inter-processor IRQ of a CPU
*
* \param irq_id kernel name of the IRQ
* \param cpu_id kernel name of the CPU
*/
bool is_ip_interrupt(unsigned const irq_id, unsigned const cpu_id) {
return irq_id == _ipi(cpu_id); }
bool is_ip_interrupt(unsigned const irq_id) {
return irq_id == ipi; }
/**
* Raise inter-processor IRQ of the CPU with kernel name 'cpu_id'
@ -280,7 +275,7 @@ class Genode::Pic
{
typedef Distr::Sgir Sgir;
Sgir::access_t sgir = 0;
Sgir::Sgi_int_id::set(sgir, _ipi(cpu_id));
Sgir::Sgi_int_id::set(sgir, ipi);
Sgir::Cpu_target_list::set(sgir, 1 << cpu_id);
_distr.write<Sgir>(sgir);
}

View File

@ -149,7 +149,7 @@ class Genode::Pic : public Mmio
/**
* Wether an interrupt is inter-processor interrupt of a CPU
*/
bool is_ip_interrupt(unsigned, unsigned) { return false; }
bool is_ip_interrupt(unsigned) { return false; }
/*************
** Dummies **

View File

@ -239,7 +239,7 @@ class Genode::Pic : Mmio
* Dummies
*/
bool is_ip_interrupt(unsigned, unsigned) { return false; }
bool is_ip_interrupt(unsigned) { return false; }
void trigger_ip_interrupt(unsigned) { }
};

View File

@ -99,7 +99,7 @@ void Cpu_job::_interrupt(unsigned const cpu_id)
if (!_cpu->timer_irq(irq_id)) {
/* check wether the interrupt is our IPI */
if (ic->is_ip_interrupt(irq_id, cpu_id)) {
if (ic->is_ip_interrupt(irq_id)) {
cpu_domain_update_list()->do_each();
_cpu->ip_interrupt_handled();