hw: add system call for irq mode setting

Core is not allowd to access the kernel's Pic implementation directly.

fixes #3474
This commit is contained in:
Sebastian Sumpf 2019-08-15 14:41:09 +02:00 committed by Christian Helmuth
parent f3a7d3750f
commit e855638266
20 changed files with 52 additions and 31 deletions

View File

@ -92,5 +92,5 @@ Irq_session_component::Irq_session_component(Range_allocator &irq_alloc,
Irq_args const irq_args(args);
Platform::setup_irq_mode(_irq_number, irq_args.trigger(), irq_args.polarity());
Kernel::irq_mode(_irq_number, irq_args.trigger(), irq_args.polarity());
}

View File

@ -60,6 +60,7 @@ namespace Kernel
constexpr Call_arg call_id_delete_obj() { return 122; }
constexpr Call_arg call_id_cancel_thread_blocking() { return 123; }
constexpr Call_arg call_id_new_core_thread() { return 124; }
constexpr Call_arg call_id_irq_mode() { return 125; }
/**
* Invalidate TLB entries for the `pd` in region `addr`, `sz`
@ -207,6 +208,17 @@ namespace Kernel
return call(call_id_new_irq(), (Call_arg) p, irq_nr, signal_context_id);
}
/**
* Set trigger/polaruty of IRQ
* \param irq_nr interrupt number
* \param trigger low or edge
* \param polarity low or high
*/
inline void irq_mode(unsigned irq_nr, unsigned trigger, unsigned polarity)
{
call(call_id_irq_mode(), irq_nr, trigger, polarity);
}
/**
* Acknowledge interrupt
*

View File

@ -577,6 +577,12 @@ void Thread::_call_new_irq()
user_arg_0(0);
}
void Thread::_call_irq_mode()
{
cpu_pool().executing_cpu().pic().irq_mode(user_arg_1(), user_arg_2(),
user_arg_3());
}
void Thread::_call_ack_irq() {
reinterpret_cast<User_irq*>(user_arg_1())->enable(); }
@ -706,6 +712,7 @@ void Thread::_call()
case call_id_pause_vm(): _call_pause_vm(); return;
case call_id_pause_thread(): _call_pause_thread(); return;
case call_id_new_irq(): _call_new_irq(); return;
case call_id_irq_mode(): _call_irq_mode(); return;
case call_id_delete_irq(): _call_delete<Irq>(); return;
case call_id_ack_irq(): _call_ack_irq(); return;
case call_id_new_obj(): _call_new_obj(); return;

View File

@ -228,6 +228,7 @@ class Kernel::Thread
void _call_pause_vm();
void _call_pager();
void _call_new_irq();
void _call_irq_mode();
void _call_ack_irq();
void _call_new_obj();
void _call_delete_obj();

View File

@ -94,16 +94,6 @@ class Genode::Platform : public Genode::Platform_generic
*/
static long irq(long const user_irq);
/**
* Setup mode of an IRQ to specified trigger mode and polarity
*
* \param irq_number ID of targeted interrupt
* \param trigger new interrupt trigger mode
* \param polarity new interrupt polarity setting
*/
static void setup_irq_mode(unsigned irq_number, unsigned trigger,
unsigned polarity);
/**
* Get MSI-related parameters from device PCI config space
*

View File

@ -136,3 +136,6 @@ void Board::Pic::mask(unsigned const i)
else
write<Irq_disable_gpu_2>(1 << (i - 8 - 32));
}
void Board::Pic::irq_mode(unsigned, unsigned, unsigned) { }

View File

@ -115,6 +115,7 @@ class Board::Pic : Genode::Mmio
void mask();
void unmask(unsigned const i, unsigned);
void mask(unsigned const i);
void irq_mode(unsigned, unsigned, unsigned);
static constexpr bool fast_interrupts() { return false; }
};

View File

@ -56,3 +56,6 @@ void Board::Pic::mask(unsigned const i)
Genode::raw("irq of peripherals != timer not implemented yet!");
}
void Board::Pic::irq_mode(unsigned, unsigned, unsigned) { }

View File

@ -59,6 +59,7 @@ class Board::Pic : Genode::Mmio
void mask();
void unmask(unsigned const i, unsigned);
void mask(unsigned const i);
void irq_mode(unsigned, unsigned, unsigned);
static constexpr bool fast_interrupts() { return false; }
};

View File

@ -20,8 +20,6 @@ void Platform::_init_io_port_alloc() { };
void Platform::_init_additional_platform_info(Genode::Xml_generator&) { }
void Platform::setup_irq_mode(unsigned, unsigned, unsigned) { }
long Platform::irq(long const user_irq) { return user_irq; }
bool Platform::get_msi_params(const addr_t /* mmconf */, addr_t & /* address */,

View File

@ -39,6 +39,7 @@ class Board::Pic
void unmask(unsigned, unsigned) { }
void mask(unsigned) { }
void finish_request() { }
void irq_mode(unsigned, unsigned, unsigned) { }
};
#endif /* _CORE__SPEC__RISCV__PIC_H_ */

View File

@ -25,8 +25,6 @@ void Platform::_init_io_port_alloc() { }
void Platform::_init_additional_platform_info(Genode::Xml_generator&) { }
void Platform::setup_irq_mode(unsigned, unsigned, unsigned) { }
long Platform::irq(long const /* user_irq */) { return 0; }
bool Platform::get_msi_params(addr_t /* mmconf */, addr_t & /* address */,

View File

@ -62,6 +62,7 @@ class Board::Pic
void mask(unsigned const) { }
bool is_ip_interrupt(unsigned, unsigned) { return false; }
void store_apic_id(unsigned const) { }
void irq_mode(unsigned, unsigned, unsigned) { }
private:

View File

@ -59,9 +59,6 @@ struct Msi_address : Register<32>
};
void Platform::setup_irq_mode(unsigned, unsigned, unsigned) { }
bool Platform::get_msi_params(const addr_t mmconf, addr_t &address,
addr_t &data, unsigned &irq_number)
{

View File

@ -88,6 +88,12 @@ void Pic::mask(unsigned const i)
ioapic.toggle_mask(i, true);
}
void Pic::irq_mode(unsigned irq_number, unsigned trigger,
unsigned polarity)
{
ioapic.irq_mode(irq_number, trigger, polarity);
}
inline unsigned Pic::get_lowest_bit(void)
{
unsigned bit, vec_base = 0;
@ -125,8 +131,8 @@ Ioapic::Irq_mode Ioapic::_irq_mode[IRQ_COUNT];
enum { REMAP_BASE = Board::VECTOR_REMAP_BASE };
void Ioapic::setup_irq_mode(unsigned irq_number, unsigned trigger,
unsigned polarity)
void Ioapic::irq_mode(unsigned irq_number, unsigned trigger,
unsigned polarity)
{
const unsigned irq_nr = irq_number - REMAP_BASE;
bool needs_sync = false;

View File

@ -119,8 +119,8 @@ class Board::Ioapic : public Genode::Mmio
* \param trigger new interrupt trigger mode
* \param polarity new interrupt polarity setting
*/
void setup_irq_mode(unsigned irq_number, unsigned trigger,
unsigned polarity);
void irq_mode(unsigned irq_number, unsigned trigger,
unsigned polarity);
/*
* Registers
@ -207,6 +207,8 @@ class Board::Pic : public Genode::Mmio
void mask(unsigned const i);
void irq_mode(unsigned irq, unsigned trigger, unsigned polarity);
void store_apic_id(unsigned const cpu_id) {
Id::access_t const lapic_id = read<Id>();
lapic_ids[cpu_id] = (lapic_id >> 24) & 0xff;

View File

@ -59,15 +59,6 @@ void Platform::_init_additional_platform_info(Xml_generator &xml)
}
void Platform::setup_irq_mode(unsigned irq_number, unsigned trigger,
unsigned polarity)
{
Kernel::cpu_pool().executing_cpu().pic().ioapic.setup_irq_mode(irq_number,
trigger,
polarity);
}
bool Platform::get_msi_params(addr_t, addr_t &, addr_t &, unsigned &) {
return false; }

View File

@ -220,6 +220,11 @@ class Hw::Gicv2
void mask(unsigned const irq_id) {
_distr.write<Distributor::Icenabler::Clear_enable>(1, irq_id); }
/**
* Set trigger and polarity
*/
void irq_mode(unsigned, unsigned, unsigned) { }
/**
* Raise inter-processor IRQ of the CPU with kernel name 'cpu_id'
*/

View File

@ -255,6 +255,8 @@ class Hw::Pic
_distr.write<Distributor::Icenabler::Clear_enable>(1, irq_id);
}
}
void irq_mode(unsigned, unsigned, unsigned) { }
};
#undef SYSTEM_REGISTER

View File

@ -104,6 +104,8 @@ class Hw::Pic : public Genode::Mmio
void finish_request() { }
void irq_mode(unsigned, unsigned, unsigned) { }
/**
* Unmask interrupt 'i'
*/