/* * \brief Programmable interrupt controller for core * \author Stefan Kalkowski * \date 2012-10-24 */ /* * Copyright (C) 2012-2019 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. */ #include Hw::Gicv2::Gicv2() : _distr(Board::Cpu_mmio::IRQ_CONTROLLER_DISTR_BASE), _cpui (Board::Cpu_mmio::IRQ_CONTROLLER_CPU_BASE), _last_iar(Cpu_interface::Iar::Irq_id::bits(spurious_id)), _max_irq(_distr.max_irq()) { static bool distributor_initialized = false; if (!distributor_initialized) { distributor_initialized = true; /* disable device */ _distr.write(0); /* configure every shared peripheral interrupt */ for (unsigned i = min_spi; i <= _max_irq; i++) { if (Board::NON_SECURE) { _distr.write(1, i); } _distr.write(0, i); _distr.write(0, i); _distr.write(1, i); } /* enable device */ Distributor::Ctlr::access_t v = 0; if (Board::NON_SECURE) { Distributor::Ctlr::Enable_grp0::set(v, 1); Distributor::Ctlr::Enable_grp1::set(v, 1); } else { Distributor::Ctlr::Enable::set(v, 1); } _distr.write(v); } if (Board::NON_SECURE) { _cpui.write(0); /* mark software-generated IRQs as being non-secure */ for (unsigned i = 0; i < min_spi; i++) _distr.write(1, i); } /* disable the priority filter */ _cpui.write(_distr.min_priority()); /* disable preemption of IRQ handling by other IRQs */ _cpui.write(~0); /* enable device */ Cpu_interface::Ctlr::access_t v = 0; if (Board::NON_SECURE) { Cpu_interface::Ctlr::Enable_grp0::set(v, 1); Cpu_interface::Ctlr::Enable_grp1::set(v, 1); Cpu_interface::Ctlr::Fiq_en::set(v, 1); } else { Cpu_interface::Ctlr::Enable::set(v, 1); } _cpui.write(v); }