genode/repos/base-hw/src/include/hw/spec/arm/imx_tzic.h

119 lines
2.4 KiB
C++

/*
* \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 <util/mmio.h>
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:
Pic();
/**
* Receive a pending request number 'i'
*/
bool take_request(unsigned & i)
{
for (unsigned j = 0; j < NR_OF_IRQ; j++) {
if (!read<Hipndr::Pending>(j)) { continue; }
i = j;
return true;
}
return false;
}
void finish_request() { }
/**
* Unmask interrupt 'i'
*/
void unmask(unsigned const i, unsigned) {
if (_valid(i)) { write<Enset::Set_enable>(1, i); } }
/**
* Mask interrupt 'i'
*/
void mask(unsigned const i) {
if (_valid(i)) { write<Enclear::Clear_enable>(1, i); } }
};
#endif /* _SRC__LIB__HW__SPEC__ARM__IMX_TZIC_H_ */