interrupts.cc revision 14171
12810SN/A/*
22810SN/A * Copyright (c) 2009, 2012-2013, 2016, 2019 ARM Limited
32810SN/A * All rights reserved.
42810SN/A *
52810SN/A * The license below extends only to copyright in the software and shall
62810SN/A * not be construed as granting a license to any other intellectual
72810SN/A * property including but not limited to intellectual property relating
82810SN/A * to a hardware implementation of the functionality of the software
92810SN/A * licensed hereunder.  You may use the software subject to the license
102810SN/A * terms below provided that you ensure that this notice is replicated
112810SN/A * unmodified and in its entirety in all distributions of the software,
122810SN/A * modified or unmodified, in source code or in binary form.
132810SN/A *
142810SN/A * Redistribution and use in source and binary forms, with or without
152810SN/A * modification, are permitted provided that the following conditions are
162810SN/A * met: redistributions of source code must retain the above copyright
172810SN/A * notice, this list of conditions and the following disclaimer;
182810SN/A * redistributions in binary form must reproduce the above copyright
192810SN/A * notice, this list of conditions and the following disclaimer in the
202810SN/A * documentation and/or other materials provided with the distribution;
212810SN/A * neither the name of the copyright holders nor the names of its
222810SN/A * contributors may be used to endorse or promote products derived from
232810SN/A * this software without specific prior written permission.
242810SN/A *
252810SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
262810SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
272810SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
282810SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
292810SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
302810SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
312810SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
322810SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
332810SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
342810SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
354626SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
364626SN/A *
372810SN/A * Authors: Ali Saidi
382810SN/A */
394626SN/A
408229Snate@binkert.org#include "arch/arm/interrupts.hh"
414626SN/A
422810SN/A#include "arch/arm/system.hh"
432810SN/A
443374SN/AArmISA::Interrupts *
452810SN/AArmInterruptsParams::create()
464626SN/A{
474626SN/A    return new ArmISA::Interrupts(this);
482810SN/A}
495314SN/A
505314SN/Abool
515314SN/AArmISA::Interrupts::takeInt(ThreadContext *tc, InterruptTypes int_type) const
522810SN/A{
534626SN/A    // Table G1-17~19 of ARM V8 ARM
544626SN/A    InterruptMask mask;
552810SN/A    bool highest_el_is_64 = ArmSystem::highestELIs64(tc);
564626SN/A
574666SN/A    CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
584626SN/A    SCR scr;
592810SN/A    HCR hcr;
602810SN/A    hcr = tc->readMiscReg(MISCREG_HCR);
612810SN/A    ExceptionLevel el = currEL(tc);
622810SN/A    bool cpsr_mask_bit, scr_routing_bit, scr_fwaw_bit, hcr_mask_override_bit;
634626SN/A
644626SN/A    if (!highest_el_is_64)
654626SN/A        scr = tc->readMiscReg(MISCREG_SCR);
662810SN/A    else
674626SN/A        scr = tc->readMiscReg(MISCREG_SCR_EL3);
682810SN/A
692810SN/A    bool is_secure = inSecureState(tc);
704626SN/A
714626SN/A    switch(int_type) {
722810SN/A      case INT_FIQ:
732810SN/A        cpsr_mask_bit = cpsr.f;
742810SN/A        scr_routing_bit = scr.fiq;
754666SN/A        scr_fwaw_bit = scr.fw;
764666SN/A        hcr_mask_override_bit = hcr.fmo;
774666SN/A        break;
782810SN/A      case INT_IRQ:
794626SN/A        cpsr_mask_bit = cpsr.i;
802810SN/A        scr_routing_bit = scr.irq;
814626SN/A        scr_fwaw_bit = 1;
824626SN/A        hcr_mask_override_bit = hcr.imo;
834628SN/A        break;
844628SN/A      case INT_ABT:
854628SN/A        cpsr_mask_bit = cpsr.a;
862810SN/A        scr_routing_bit = scr.ea;
872810SN/A        scr_fwaw_bit = scr.aw;
884626SN/A        hcr_mask_override_bit = hcr.amo;
894626SN/A        break;
904626SN/A      default:
914626SN/A        panic("Unhandled interrupt type!");
922810SN/A    }
935314SN/A
945314SN/A    if (hcr.tge)
952810SN/A        hcr_mask_override_bit = 1;
962810SN/A
972810SN/A    if (!highest_el_is_64) {
982810SN/A        // AArch32
992810SN/A        if (!scr_routing_bit) {
1004626SN/A            // SCR IRQ == 0
1012810SN/A            if (!hcr_mask_override_bit)
1022810SN/A                mask = INT_MASK_M;
1032810SN/A            else {
1044626SN/A                if (!is_secure && (el == EL0 || el == EL1))
1052810SN/A                    mask = INT_MASK_T;
1062810SN/A                else
1074626SN/A                    mask = INT_MASK_M;
1082810SN/A            }
1094626SN/A        } else {
1102810SN/A            // SCR IRQ == 1
1112810SN/A            if ((!is_secure) &&
1122810SN/A                (hcr_mask_override_bit ||
1132991SN/A                    (!scr_fwaw_bit && !hcr_mask_override_bit)))
1142810SN/A                mask = INT_MASK_T;
1152810SN/A            else
1163374SN/A                mask = INT_MASK_M;
1172982SN/A        }
1182810SN/A    } else {
1192810SN/A        // AArch64
1204626SN/A        if (!scr_routing_bit) {
1212810SN/A            // SCR IRQ == 0
1224920SN/A            if (!scr.rw) {
1234920SN/A                // SCR RW == 0
1242810SN/A                if (!hcr_mask_override_bit) {
1253374SN/A                    if (el == EL3)
1262810SN/A                        mask = INT_MASK_P;
1272982SN/A                    else
1282810SN/A                        mask = INT_MASK_M;
1292810SN/A                } else {
1302810SN/A                    if (el == EL3)
1314626SN/A                        mask = INT_MASK_T;
1322810SN/A                    else if (is_secure || el == EL2)
1334666SN/A                        mask = INT_MASK_M;
1344666SN/A                    else
1352810SN/A                        mask = INT_MASK_T;
1362810SN/A                }
1372810SN/A            } else {
1382810SN/A                // SCR RW == 1
1392810SN/A                if (!hcr_mask_override_bit) {
1402810SN/A                    if (el == EL3 || el == EL2)
1414626SN/A                        mask = INT_MASK_P;
1422810SN/A                    else
1432810SN/A                        mask = INT_MASK_M;
1444626SN/A                } else {
1454626SN/A                    if (el == EL3)
1462810SN/A                        mask = INT_MASK_P;
1472810SN/A                    else if (is_secure || el == EL2)
1482810SN/A                        mask = INT_MASK_M;
1494626SN/A                    else
1502810SN/A                        mask = INT_MASK_T;
1512810SN/A                }
1524626SN/A            }
1534626SN/A        } else {
1544626SN/A            // SCR IRQ == 1
1552810SN/A            if (el == EL3)
1562810SN/A                mask = INT_MASK_M;
1572810SN/A            else
1582810SN/A                mask = INT_MASK_T;
1592810SN/A        }
1604666SN/A    }
1612810SN/A
1622810SN/A    return ((mask == INT_MASK_T) ||
1637667Ssteve.reinhardt@amd.com            ((mask == INT_MASK_M) && !cpsr_mask_bit)) &&
1642810SN/A            (mask != INT_MASK_P);
1652810SN/A}
1664626SN/A
1672810SN/A