/* * \brief Interrupt controller for kernel * \author Norman Feske * \date 2013-04-05 */ /* * Copyright (C) 2013 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. */ #ifndef _RPI__PIC_H_ #define _RPI__PIC_H_ /* Genode includes */ #include #include /* core includes */ #include namespace Kernel { class Pic : Genode::Mmio { struct Irq_pending_basic : Register<0x0, 32> { struct Timer : Bitfield<0, 1> { }; struct Gpu : Bitfield<8, 2> { }; }; struct Irq_pending_gpu_1 : Register<0x04, 32> { }; struct Irq_pending_gpu_2 : Register<0x08, 32> { }; struct Irq_enable_gpu_1 : Register<0x10, 32> { }; struct Irq_enable_gpu_2 : Register<0x14, 32> { }; struct Irq_enable_basic : Register<0x18, 32> { }; struct Irq_disable_gpu_1 : Register<0x1c, 32> { }; struct Irq_disable_gpu_2 : Register<0x20, 32> { }; struct Irq_disable_basic : Register<0x24, 32> { }; private: typedef Genode::uint32_t uint32_t; /** * Return true if specified interrupt is pending */ static bool _is_pending(unsigned i, uint32_t p1, uint32_t p2) { return i < 32 ? (p1 & (1 << i)) : (p2 & (1 << (i - 32))); } public: Pic() : Genode::Mmio(Genode::Board::IRQ_CONTROLLER_BASE) { } bool take_request(unsigned &irq) { /* read basic IRQ status mask */ uint32_t const p = read(); /* read GPU IRQ status mask */ uint32_t const p1 = read(), p2 = read(); if (Irq_pending_basic::Timer::get(p)) { irq = 0; return true; } /* search for lowest set bit in pending masks */ for (unsigned i = 0; i < 64; i++) { if (!_is_pending(i, p1, p2)) continue; irq = Genode::Board_base::GPU_IRQ_BASE + i; return true; } return false; } void finish_request() { } void unmask() { PDBG("not implemented"); } void mask() { PDBG("not implemented"); } void unmask(unsigned const i) { if (i < 8) write(1 << i); else if (i < 32 + 8) { write(1 << (i - 8)); write(1 << 8); } else { write(1 << (i - 8 - 32)); write(1 << 9); } } void mask(unsigned const i) { if (i < 8) write(1 << i); else if (i < 32 + 8) write(1 << (i - 8)); else write(1 << (i - 8 - 32)); } }; } #endif /* _RPI__PIC_H_ */