interrupts.cc revision 11320
12810Srdreslin@umich.edu/*
212500Snikos.nikoleris@arm.com * Copyright (c) 2009, 2012-2013 ARM Limited
311051Sandreas.hansson@arm.com * All rights reserved.
411051Sandreas.hansson@arm.com *
511051Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall
611051Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual
711051Sandreas.hansson@arm.com * property including but not limited to intellectual property relating
811051Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software
911051Sandreas.hansson@arm.com * licensed hereunder.  You may use the software subject to the license
1011051Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated
1111051Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software,
1211051Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form.
1311051Sandreas.hansson@arm.com *
1411051Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without
1511051Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are
162810Srdreslin@umich.edu * met: redistributions of source code must retain the above copyright
172810Srdreslin@umich.edu * notice, this list of conditions and the following disclaimer;
182810Srdreslin@umich.edu * redistributions in binary form must reproduce the above copyright
192810Srdreslin@umich.edu * notice, this list of conditions and the following disclaimer in the
202810Srdreslin@umich.edu * documentation and/or other materials provided with the distribution;
212810Srdreslin@umich.edu * neither the name of the copyright holders nor the names of its
222810Srdreslin@umich.edu * contributors may be used to endorse or promote products derived from
232810Srdreslin@umich.edu * this software without specific prior written permission.
242810Srdreslin@umich.edu *
252810Srdreslin@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
262810Srdreslin@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
272810Srdreslin@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
282810Srdreslin@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
292810Srdreslin@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
302810Srdreslin@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
312810Srdreslin@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
322810Srdreslin@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
332810Srdreslin@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
342810Srdreslin@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
352810Srdreslin@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
362810Srdreslin@umich.edu *
372810Srdreslin@umich.edu * Authors: Ali Saidi
382810Srdreslin@umich.edu */
392810Srdreslin@umich.edu
402810Srdreslin@umich.edu#include "arch/arm/interrupts.hh"
412810Srdreslin@umich.edu#include "arch/arm/system.hh"
4211051Sandreas.hansson@arm.com
4311051Sandreas.hansson@arm.comArmISA::Interrupts *
442810Srdreslin@umich.eduArmInterruptsParams::create()
4511051Sandreas.hansson@arm.com{
4611051Sandreas.hansson@arm.com    return new ArmISA::Interrupts(this);
4712349Snikos.nikoleris@arm.com}
482810Srdreslin@umich.edu
492810Srdreslin@umich.edubool
502810Srdreslin@umich.eduArmISA::Interrupts::takeInt(ThreadContext *tc, InterruptTypes int_type) const
512810Srdreslin@umich.edu{
5211051Sandreas.hansson@arm.com    // Table G1-17~19 of ARM V8 ARM
532810Srdreslin@umich.edu    InterruptMask mask;
542810Srdreslin@umich.edu    bool highest_el_is_64 = ArmSystem::highestELIs64(tc);
5511051Sandreas.hansson@arm.com
562810Srdreslin@umich.edu    CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
5712724Snikos.nikoleris@arm.com    SCR scr;
5812724Snikos.nikoleris@arm.com    HCR hcr;
5912724Snikos.nikoleris@arm.com    hcr = tc->readMiscReg(MISCREG_HCR);
6012334Sgabeblack@google.com    ExceptionLevel el = (ExceptionLevel) ((uint32_t) cpsr.el);
6112724Snikos.nikoleris@arm.com    bool cpsr_mask_bit, scr_routing_bit, scr_fwaw_bit, hcr_mask_override_bit;
6211051Sandreas.hansson@arm.com
6311051Sandreas.hansson@arm.com    if (!highest_el_is_64)
6411051Sandreas.hansson@arm.com        scr = tc->readMiscReg(MISCREG_SCR);
6511288Ssteve.reinhardt@amd.com    else
6612724Snikos.nikoleris@arm.com        scr = tc->readMiscReg(MISCREG_SCR_EL3);
6713223Sodanrc@yahoo.com.br
6811051Sandreas.hansson@arm.com    bool is_secure = inSecureState(scr, cpsr);
6912724Snikos.nikoleris@arm.com
7012724Snikos.nikoleris@arm.com    switch(int_type) {
7112724Snikos.nikoleris@arm.com      case INT_FIQ:
7212724Snikos.nikoleris@arm.com        cpsr_mask_bit = cpsr.f;
7311051Sandreas.hansson@arm.com        scr_routing_bit = scr.fiq;
7411053Sandreas.hansson@arm.com        scr_fwaw_bit = scr.fw;
7511053Sandreas.hansson@arm.com        hcr_mask_override_bit = hcr.fmo;
7612724Snikos.nikoleris@arm.com        break;
7711051Sandreas.hansson@arm.com      case INT_IRQ:
7811051Sandreas.hansson@arm.com        cpsr_mask_bit = cpsr.i;
7911051Sandreas.hansson@arm.com        scr_routing_bit = scr.irq;
8011051Sandreas.hansson@arm.com        scr_fwaw_bit = 1;
8111601Sandreas.hansson@arm.com        hcr_mask_override_bit = hcr.imo;
8211601Sandreas.hansson@arm.com        break;
8311051Sandreas.hansson@arm.com      case INT_ABT:
8412724Snikos.nikoleris@arm.com        cpsr_mask_bit = cpsr.a;
8511051Sandreas.hansson@arm.com        scr_routing_bit = scr.ea;
8612724Snikos.nikoleris@arm.com        scr_fwaw_bit = scr.aw;
8711600Sandreas.hansson@arm.com        hcr_mask_override_bit = hcr.amo;
8811600Sandreas.hansson@arm.com        break;
8911051Sandreas.hansson@arm.com      default:
9011051Sandreas.hansson@arm.com        panic("Unhandled interrupt type!");
9111051Sandreas.hansson@arm.com    }
9211284Sandreas.hansson@arm.com
9311051Sandreas.hansson@arm.com    if (hcr.tge)
9411051Sandreas.hansson@arm.com        hcr_mask_override_bit = 1;
9511051Sandreas.hansson@arm.com
9611602Sandreas.hansson@arm.com    if (!highest_el_is_64) {
9711051Sandreas.hansson@arm.com        // AArch32
9811051Sandreas.hansson@arm.com        if (!scr_routing_bit) {
9911284Sandreas.hansson@arm.com            // SCR IRQ == 0
10011051Sandreas.hansson@arm.com            if (!hcr_mask_override_bit)
10111284Sandreas.hansson@arm.com                mask = INT_MASK_M;
10211602Sandreas.hansson@arm.com            else {
10311051Sandreas.hansson@arm.com                if (!is_secure && (el == EL0 || el == EL1))
10411051Sandreas.hansson@arm.com                    mask = INT_MASK_T;
10511284Sandreas.hansson@arm.com                else
10611051Sandreas.hansson@arm.com                    mask = INT_MASK_M;
10711284Sandreas.hansson@arm.com            }
10811284Sandreas.hansson@arm.com        } else {
10911284Sandreas.hansson@arm.com            // SCR IRQ == 1
11011051Sandreas.hansson@arm.com            if ((!is_secure) &&
11111051Sandreas.hansson@arm.com                (hcr_mask_override_bit ||
11211051Sandreas.hansson@arm.com                    (!scr_fwaw_bit && !hcr_mask_override_bit)))
11311284Sandreas.hansson@arm.com                mask = INT_MASK_T;
11411284Sandreas.hansson@arm.com            else
11511284Sandreas.hansson@arm.com                mask = INT_MASK_M;
11611284Sandreas.hansson@arm.com        }
11711051Sandreas.hansson@arm.com    } else {
11811051Sandreas.hansson@arm.com        // AArch64
11911051Sandreas.hansson@arm.com        if (!scr_routing_bit) {
12011284Sandreas.hansson@arm.com            // SCR IRQ == 0
12111284Sandreas.hansson@arm.com            if (!scr.rw) {
12211284Sandreas.hansson@arm.com                // SCR RW == 0
12311197Sandreas.hansson@arm.com                if (!hcr_mask_override_bit) {
12411601Sandreas.hansson@arm.com                    if (el == EL3)
12511601Sandreas.hansson@arm.com                        mask = INT_MASK_P;
12611601Sandreas.hansson@arm.com                    else
12711601Sandreas.hansson@arm.com                        mask = INT_MASK_M;
12811601Sandreas.hansson@arm.com                } else {
12911601Sandreas.hansson@arm.com                    if (el == EL3)
13011601Sandreas.hansson@arm.com                        mask = INT_MASK_T;
13111601Sandreas.hansson@arm.com                    else if (is_secure || el == EL2)
13211197Sandreas.hansson@arm.com                        mask = INT_MASK_M;
13311601Sandreas.hansson@arm.com                    else
13411601Sandreas.hansson@arm.com                        mask = INT_MASK_T;
13511601Sandreas.hansson@arm.com                }
13611601Sandreas.hansson@arm.com            } else {
13711601Sandreas.hansson@arm.com                // SCR RW == 1
13811601Sandreas.hansson@arm.com                if (!hcr_mask_override_bit) {
13911601Sandreas.hansson@arm.com                    if (el == EL3 || el == EL2)
14011051Sandreas.hansson@arm.com                        mask = INT_MASK_P;
14111051Sandreas.hansson@arm.com                    else
14211051Sandreas.hansson@arm.com                        mask = INT_MASK_M;
14311051Sandreas.hansson@arm.com                } else {
14411051Sandreas.hansson@arm.com                    if (el == EL3)
14511284Sandreas.hansson@arm.com                        mask = INT_MASK_P;
14611284Sandreas.hansson@arm.com                    else if (is_secure || el == EL2)
14711051Sandreas.hansson@arm.com                        mask = INT_MASK_M;
14811051Sandreas.hansson@arm.com                    else
14911051Sandreas.hansson@arm.com                        mask = INT_MASK_T;
15011051Sandreas.hansson@arm.com                }
15111284Sandreas.hansson@arm.com            }
15211051Sandreas.hansson@arm.com        } else {
15311051Sandreas.hansson@arm.com            // SCR IRQ == 1
15411051Sandreas.hansson@arm.com            if (el == EL3)
15511051Sandreas.hansson@arm.com                mask = INT_MASK_M;
15611051Sandreas.hansson@arm.com            else
15711051Sandreas.hansson@arm.com                mask = INT_MASK_T;
15811051Sandreas.hansson@arm.com        }
15911051Sandreas.hansson@arm.com    }
16011051Sandreas.hansson@arm.com
16111051Sandreas.hansson@arm.com    return ((mask == INT_MASK_T) ||
16211051Sandreas.hansson@arm.com            ((mask == INT_MASK_M) && !cpsr_mask_bit)) &&
16311051Sandreas.hansson@arm.com            (mask != INT_MASK_P);
16411051Sandreas.hansson@arm.com}
16511051Sandreas.hansson@arm.com
16611051Sandreas.hansson@arm.com