/* * \brief Freescale's TrustZone aware interrupt controller * \author Stefan Kalkowski * \date 2012-10-24 */ /* * Copyright (C) 2012-2017 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU Affero General Public License version 3. */ #ifndef _SRC__LIB__HW__SPEC__ARM__IMX_TZIC_H_ #define _SRC__LIB__HW__SPEC__ARM__IMX_TZIC_H_ #include namespace Hw { class Pic; } class Hw::Pic : public Genode::Mmio { public: enum { NR_OF_IRQ = 109, }; protected: /** * Software Interrupt Trigger Register */ struct Swint : Register<0xf00, 32> { struct Intid : Bitfield<0,10> { }; }; /** * Interrupt control register */ struct Intctrl : Register<0, 32> { struct Enable : Bitfield<0,1> { }; struct Nsen : Bitfield<16,1> { }; struct Nsen_mask : Bitfield<31,1> { }; }; /** * Priority mask register */ struct Priomask : Register<0xc, 32> { struct Mask : Bitfield<0,8> { }; }; /** * Interrupt security registers */ struct Intsec : Register_array<0x80, 32, NR_OF_IRQ, 1> { struct Nonsecure : Bitfield<0, 1> { }; }; /** * Interrupt set enable registers */ struct Enset : Register_array<0x100, 32, NR_OF_IRQ, 1, true> { struct Set_enable : Bitfield<0, 1> { }; }; /** * Interrupt clear enable registers */ struct Enclear : Register_array<0x180, 32, NR_OF_IRQ, 1, true> { struct Clear_enable : Bitfield<0, 1> { }; }; /** * Interrupt priority level registers */ struct Priority : Register_array<0x400, 32, NR_OF_IRQ, 8> { }; /** * Highest interrupt pending registers */ struct Hipndr : Register_array<0xd80, 32, NR_OF_IRQ, 1, true> { struct Pending : Bitfield<0, 1> { }; }; /** * Validate request number 'i' */ bool _valid(unsigned const i) const { return i < NR_OF_IRQ; } public: enum { IPI = 0xffff }; Pic(); /** * Receive a pending request number 'i' */ bool take_request(unsigned & i) { for (unsigned j = 0; j < NR_OF_IRQ; j++) { if (!read(j)) { continue; } i = j; return true; } return false; } void finish_request() { } /** * Unmask interrupt 'i' */ void unmask(unsigned const i, unsigned) { if (_valid(i)) { write(1, i); } } /** * Mask interrupt 'i' */ void mask(unsigned const i) { if (_valid(i)) { write(1, i); } } /* * Trigger interrupt 'i' from software if possible */ void trigger(unsigned const i) { write(Swint::Intid::bits(i)); } bool secure(unsigned i) { return !read(i); } static constexpr bool fast_interrupts() { return true; } }; #endif /* _SRC__LIB__HW__SPEC__ARM__IMX_TZIC_H_ */