hw & x86: Use register framework for IRTEs

Ref #1494
This commit is contained in:
Martin Stein 2015-04-29 13:05:41 +02:00 committed by Christian Helmuth
parent 6ec39d8df5
commit c6417051ce

View File

@ -22,46 +22,41 @@
namespace Genode namespace Genode
{ {
/*
* Redirection table entry
*/
struct Irte;
/**
* IO advanced programmable interrupt controller
*/
class Ioapic;
/** /**
* Programmable interrupt controller for core * Programmable interrupt controller for core
*/ */
class Pic; class Pic;
} }
struct Genode::Irte : Register<64>
{
struct Pol : Bitfield<13, 1> { };
struct Trg : Bitfield<15, 1> { };
struct Mask : Bitfield<16, 1> { };
};
class Genode::Pic : public Mmio class Genode::Ioapic : public Mmio
{ {
private: private:
enum { REMAP_BASE = Board::VECTOR_REMAP_BASE }; enum { REMAP_BASE = Board::VECTOR_REMAP_BASE };
/* Registers */
struct EOI : Register<0x0b0, 32, true> { };
struct Svr : Register<0x0f0, 32>
{
struct APIC_enable : Bitfield<8, 1> { };
};
/*
* ISR register, see Intel SDM Vol. 3A, section 10.8.4. Each of the 8
* 32-bit ISR values is followed by 12 bytes of padding.
*/
struct Isr : Register_array<0x100, 32, 8 * 4, 32> { };
class Ioapic : public Mmio
{
private:
uint8_t _irt_count; uint8_t _irt_count;
enum { enum {
/* Number of Redirection Table entries */ /* Number of Redirection Table entries */
IRTE_COUNT = 0x17, IRTE_COUNT = 0x17,
IRTE_BIT_POL = 13,
IRTE_BIT_TRG = 15,
IRTE_BIT_MASK = 16,
/* Register selectors */ /* Register selectors */
IOAPICVER = 0x01, IOAPICVER = 0x01,
IOREDTBL = 0x10, IOREDTBL = 0x10,
@ -70,16 +65,16 @@ class Genode::Pic : public Mmio
/** /**
* Create redirection table entry for given IRQ * Create redirection table entry for given IRQ
*/ */
uint64_t _create_irt_entry(unsigned irq) Irte::access_t _create_irt_entry(unsigned const irq)
{ {
uint32_t entry = REMAP_BASE + irq; Irte::access_t irte = REMAP_BASE + irq;
/* Use level-triggered, low-active mode for non-legacy IRQs */
if (irq > Board::ISA_IRQ_END) { if (irq > Board::ISA_IRQ_END) {
/* Use level-triggered, high-active mode for non-legacy Irte::Pol::set(irte, 1);
* IRQs */ Irte::Trg::set(irte, 1);
entry |= 1 << IRTE_BIT_POL | 1 << IRTE_BIT_TRG;
} }
return entry; return irte;
} }
/** /**
@ -97,11 +92,11 @@ class Genode::Pic : public Mmio
{ {
/* Remap all supported IRQs */ /* Remap all supported IRQs */
for (unsigned i = 0; i <= IRTE_COUNT; i++) { for (unsigned i = 0; i <= IRTE_COUNT; i++) {
uint64_t val = _create_irt_entry(i); Irte::access_t irte = _create_irt_entry(i);
write<Ioregsel>(IOREDTBL + 2 * i + 1); write<Ioregsel>(IOREDTBL + 2 * i + 1);
write<Iowin>(val >> 32); write<Iowin>(irte >> Iowin::ACCESS_WIDTH);
write<Ioregsel>(IOREDTBL + 2 * i); write<Ioregsel>(IOREDTBL + 2 * i);
write<Iowin>(val & 0xffffffff); write<Iowin>(irte);
} }
}; };
@ -119,21 +114,33 @@ class Genode::Pic : public Mmio
if (_edge_triggered(vector)) { return; } if (_edge_triggered(vector)) { return; }
write<Ioregsel>(IOREDTBL + (2 * (vector - REMAP_BASE))); write<Ioregsel>(IOREDTBL + (2 * (vector - REMAP_BASE)));
Irte::access_t irte = read<Iowin>();
uint32_t val = read<Iowin>(); Irte::Mask::set(irte, set);
if (set) { write<Iowin>(irte);
val |= 1 << IRTE_BIT_MASK;
} else {
val &= ~(1 << IRTE_BIT_MASK);
}
write<Iowin>(val);
} }
/* Registers */ /* Registers */
struct Ioregsel : Register<0x00, 32> { }; struct Ioregsel : Register<0x00, 32> { };
struct Iowin : Register<0x10, 32> { }; struct Iowin : Register<0x10, 32> { };
};
class Genode::Pic : public Mmio
{
private:
/* Registers */
struct EOI : Register<0x0b0, 32, true> { };
struct Svr : Register<0x0f0, 32>
{
struct APIC_enable : Bitfield<8, 1> { };
}; };
/*
* ISR register, see Intel SDM Vol. 3A, section 10.8.4. Each of the 8
* 32-bit ISR values is followed by 12 bytes of padding.
*/
struct Isr : Register_array<0x100, 32, 8 * 4, 32> { };
Ioapic _ioapic; Ioapic _ioapic;
/** /**