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:
parent
f3a7d3750f
commit
e855638266
|
@ -92,5 +92,5 @@ Irq_session_component::Irq_session_component(Range_allocator &irq_alloc,
|
||||||
|
|
||||||
Irq_args const irq_args(args);
|
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());
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,7 @@ namespace Kernel
|
||||||
constexpr Call_arg call_id_delete_obj() { return 122; }
|
constexpr Call_arg call_id_delete_obj() { return 122; }
|
||||||
constexpr Call_arg call_id_cancel_thread_blocking() { return 123; }
|
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_new_core_thread() { return 124; }
|
||||||
|
constexpr Call_arg call_id_irq_mode() { return 125; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invalidate TLB entries for the `pd` in region `addr`, `sz`
|
* 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);
|
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
|
* Acknowledge interrupt
|
||||||
*
|
*
|
||||||
|
|
|
@ -577,6 +577,12 @@ void Thread::_call_new_irq()
|
||||||
user_arg_0(0);
|
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() {
|
void Thread::_call_ack_irq() {
|
||||||
reinterpret_cast<User_irq*>(user_arg_1())->enable(); }
|
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_vm(): _call_pause_vm(); return;
|
||||||
case call_id_pause_thread(): _call_pause_thread(); return;
|
case call_id_pause_thread(): _call_pause_thread(); return;
|
||||||
case call_id_new_irq(): _call_new_irq(); 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_delete_irq(): _call_delete<Irq>(); return;
|
||||||
case call_id_ack_irq(): _call_ack_irq(); return;
|
case call_id_ack_irq(): _call_ack_irq(); return;
|
||||||
case call_id_new_obj(): _call_new_obj(); return;
|
case call_id_new_obj(): _call_new_obj(); return;
|
||||||
|
|
|
@ -228,6 +228,7 @@ class Kernel::Thread
|
||||||
void _call_pause_vm();
|
void _call_pause_vm();
|
||||||
void _call_pager();
|
void _call_pager();
|
||||||
void _call_new_irq();
|
void _call_new_irq();
|
||||||
|
void _call_irq_mode();
|
||||||
void _call_ack_irq();
|
void _call_ack_irq();
|
||||||
void _call_new_obj();
|
void _call_new_obj();
|
||||||
void _call_delete_obj();
|
void _call_delete_obj();
|
||||||
|
|
|
@ -94,16 +94,6 @@ class Genode::Platform : public Genode::Platform_generic
|
||||||
*/
|
*/
|
||||||
static long irq(long const user_irq);
|
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
|
* Get MSI-related parameters from device PCI config space
|
||||||
*
|
*
|
||||||
|
|
|
@ -136,3 +136,6 @@ void Board::Pic::mask(unsigned const i)
|
||||||
else
|
else
|
||||||
write<Irq_disable_gpu_2>(1 << (i - 8 - 32));
|
write<Irq_disable_gpu_2>(1 << (i - 8 - 32));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Board::Pic::irq_mode(unsigned, unsigned, unsigned) { }
|
||||||
|
|
|
@ -115,6 +115,7 @@ class Board::Pic : Genode::Mmio
|
||||||
void mask();
|
void mask();
|
||||||
void unmask(unsigned const i, unsigned);
|
void unmask(unsigned const i, unsigned);
|
||||||
void mask(unsigned const i);
|
void mask(unsigned const i);
|
||||||
|
void irq_mode(unsigned, unsigned, unsigned);
|
||||||
|
|
||||||
static constexpr bool fast_interrupts() { return false; }
|
static constexpr bool fast_interrupts() { return false; }
|
||||||
};
|
};
|
||||||
|
|
|
@ -56,3 +56,6 @@ void Board::Pic::mask(unsigned const i)
|
||||||
|
|
||||||
Genode::raw("irq of peripherals != timer not implemented yet!");
|
Genode::raw("irq of peripherals != timer not implemented yet!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Board::Pic::irq_mode(unsigned, unsigned, unsigned) { }
|
||||||
|
|
|
@ -59,6 +59,7 @@ class Board::Pic : Genode::Mmio
|
||||||
void mask();
|
void mask();
|
||||||
void unmask(unsigned const i, unsigned);
|
void unmask(unsigned const i, unsigned);
|
||||||
void mask(unsigned const i);
|
void mask(unsigned const i);
|
||||||
|
void irq_mode(unsigned, unsigned, unsigned);
|
||||||
|
|
||||||
static constexpr bool fast_interrupts() { return false; }
|
static constexpr bool fast_interrupts() { return false; }
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,8 +20,6 @@ void Platform::_init_io_port_alloc() { };
|
||||||
|
|
||||||
void Platform::_init_additional_platform_info(Genode::Xml_generator&) { }
|
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; }
|
long Platform::irq(long const user_irq) { return user_irq; }
|
||||||
|
|
||||||
bool Platform::get_msi_params(const addr_t /* mmconf */, addr_t & /* address */,
|
bool Platform::get_msi_params(const addr_t /* mmconf */, addr_t & /* address */,
|
||||||
|
|
|
@ -39,6 +39,7 @@ class Board::Pic
|
||||||
void unmask(unsigned, unsigned) { }
|
void unmask(unsigned, unsigned) { }
|
||||||
void mask(unsigned) { }
|
void mask(unsigned) { }
|
||||||
void finish_request() { }
|
void finish_request() { }
|
||||||
|
void irq_mode(unsigned, unsigned, unsigned) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _CORE__SPEC__RISCV__PIC_H_ */
|
#endif /* _CORE__SPEC__RISCV__PIC_H_ */
|
||||||
|
|
|
@ -25,8 +25,6 @@ void Platform::_init_io_port_alloc() { }
|
||||||
|
|
||||||
void Platform::_init_additional_platform_info(Genode::Xml_generator&) { }
|
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; }
|
long Platform::irq(long const /* user_irq */) { return 0; }
|
||||||
|
|
||||||
bool Platform::get_msi_params(addr_t /* mmconf */, addr_t & /* address */,
|
bool Platform::get_msi_params(addr_t /* mmconf */, addr_t & /* address */,
|
||||||
|
|
|
@ -62,6 +62,7 @@ class Board::Pic
|
||||||
void mask(unsigned const) { }
|
void mask(unsigned const) { }
|
||||||
bool is_ip_interrupt(unsigned, unsigned) { return false; }
|
bool is_ip_interrupt(unsigned, unsigned) { return false; }
|
||||||
void store_apic_id(unsigned const) { }
|
void store_apic_id(unsigned const) { }
|
||||||
|
void irq_mode(unsigned, unsigned, unsigned) { }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -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,
|
bool Platform::get_msi_params(const addr_t mmconf, addr_t &address,
|
||||||
addr_t &data, unsigned &irq_number)
|
addr_t &data, unsigned &irq_number)
|
||||||
{
|
{
|
||||||
|
|
|
@ -88,6 +88,12 @@ void Pic::mask(unsigned const i)
|
||||||
ioapic.toggle_mask(i, true);
|
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)
|
inline unsigned Pic::get_lowest_bit(void)
|
||||||
{
|
{
|
||||||
unsigned bit, vec_base = 0;
|
unsigned bit, vec_base = 0;
|
||||||
|
@ -125,8 +131,8 @@ Ioapic::Irq_mode Ioapic::_irq_mode[IRQ_COUNT];
|
||||||
|
|
||||||
enum { REMAP_BASE = Board::VECTOR_REMAP_BASE };
|
enum { REMAP_BASE = Board::VECTOR_REMAP_BASE };
|
||||||
|
|
||||||
void Ioapic::setup_irq_mode(unsigned irq_number, unsigned trigger,
|
void Ioapic::irq_mode(unsigned irq_number, unsigned trigger,
|
||||||
unsigned polarity)
|
unsigned polarity)
|
||||||
{
|
{
|
||||||
const unsigned irq_nr = irq_number - REMAP_BASE;
|
const unsigned irq_nr = irq_number - REMAP_BASE;
|
||||||
bool needs_sync = false;
|
bool needs_sync = false;
|
||||||
|
|
|
@ -119,8 +119,8 @@ class Board::Ioapic : public Genode::Mmio
|
||||||
* \param trigger new interrupt trigger mode
|
* \param trigger new interrupt trigger mode
|
||||||
* \param polarity new interrupt polarity setting
|
* \param polarity new interrupt polarity setting
|
||||||
*/
|
*/
|
||||||
void setup_irq_mode(unsigned irq_number, unsigned trigger,
|
void irq_mode(unsigned irq_number, unsigned trigger,
|
||||||
unsigned polarity);
|
unsigned polarity);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Registers
|
* Registers
|
||||||
|
@ -207,6 +207,8 @@ class Board::Pic : public Genode::Mmio
|
||||||
|
|
||||||
void mask(unsigned const i);
|
void mask(unsigned const i);
|
||||||
|
|
||||||
|
void irq_mode(unsigned irq, unsigned trigger, unsigned polarity);
|
||||||
|
|
||||||
void store_apic_id(unsigned const cpu_id) {
|
void store_apic_id(unsigned const cpu_id) {
|
||||||
Id::access_t const lapic_id = read<Id>();
|
Id::access_t const lapic_id = read<Id>();
|
||||||
lapic_ids[cpu_id] = (lapic_id >> 24) & 0xff;
|
lapic_ids[cpu_id] = (lapic_id >> 24) & 0xff;
|
||||||
|
|
|
@ -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 &) {
|
bool Platform::get_msi_params(addr_t, addr_t &, addr_t &, unsigned &) {
|
||||||
return false; }
|
return false; }
|
||||||
|
|
||||||
|
|
|
@ -220,6 +220,11 @@ class Hw::Gicv2
|
||||||
void mask(unsigned const irq_id) {
|
void mask(unsigned const irq_id) {
|
||||||
_distr.write<Distributor::Icenabler::Clear_enable>(1, 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'
|
* Raise inter-processor IRQ of the CPU with kernel name 'cpu_id'
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -255,6 +255,8 @@ class Hw::Pic
|
||||||
_distr.write<Distributor::Icenabler::Clear_enable>(1, irq_id);
|
_distr.write<Distributor::Icenabler::Clear_enable>(1, irq_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void irq_mode(unsigned, unsigned, unsigned) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
#undef SYSTEM_REGISTER
|
#undef SYSTEM_REGISTER
|
||||||
|
|
|
@ -104,6 +104,8 @@ class Hw::Pic : public Genode::Mmio
|
||||||
|
|
||||||
void finish_request() { }
|
void finish_request() { }
|
||||||
|
|
||||||
|
void irq_mode(unsigned, unsigned, unsigned) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unmask interrupt 'i'
|
* Unmask interrupt 'i'
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue
Block a user