2c2
< * Copyright (c) 2009 ARM Limited
---
> * Copyright (c) 2009, 2012-2013 ARM Limited
40a41
> #include "arch/arm/system.hh"
46a48,165
>
> bool
> ArmISA::Interrupts::takeInt(ThreadContext *tc, InterruptTypes int_type) const
> {
> // Table G1-17~19 of ARM V8 ARM
> InterruptMask mask;
> bool highest_el_is_64 = ArmSystem::highestELIs64(tc);
>
> CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
> SCR scr;
> HCR hcr;
> hcr = tc->readMiscReg(MISCREG_HCR);
> ExceptionLevel el = (ExceptionLevel) ((uint32_t) cpsr.el);
> bool cpsr_mask_bit, scr_routing_bit, scr_fwaw_bit, hcr_mask_override_bit;
>
> if (!highest_el_is_64)
> scr = tc->readMiscReg(MISCREG_SCR);
> else
> scr = tc->readMiscReg(MISCREG_SCR_EL3);
>
> bool is_secure = inSecureState(scr, cpsr);
>
> switch(int_type) {
> case INT_FIQ:
> cpsr_mask_bit = cpsr.f;
> scr_routing_bit = scr.fiq;
> scr_fwaw_bit = scr.fw;
> hcr_mask_override_bit = hcr.fmo;
> break;
> case INT_IRQ:
> cpsr_mask_bit = cpsr.i;
> scr_routing_bit = scr.irq;
> scr_fwaw_bit = 1;
> hcr_mask_override_bit = hcr.imo;
> break;
> case INT_ABT:
> cpsr_mask_bit = cpsr.a;
> scr_routing_bit = scr.ea;
> scr_fwaw_bit = scr.aw;
> hcr_mask_override_bit = hcr.amo;
> break;
> default:
> panic("Unhandled interrupt type!");
> }
>
> if (hcr.tge)
> hcr_mask_override_bit = 1;
>
> if (!highest_el_is_64) {
> // AArch32
> if (!scr_routing_bit) {
> // SCR IRQ == 0
> if (!hcr_mask_override_bit)
> mask = INT_MASK_M;
> else {
> if (!is_secure && (el == EL0 || el == EL1))
> mask = INT_MASK_T;
> else
> mask = INT_MASK_M;
> }
> } else {
> // SCR IRQ == 1
> if ((!is_secure) &&
> (hcr_mask_override_bit ||
> (!scr_fwaw_bit && !hcr_mask_override_bit)))
> mask = INT_MASK_T;
> else
> mask = INT_MASK_M;
> }
> } else {
> // AArch64
> if (!scr_routing_bit) {
> // SCR IRQ == 0
> if (!scr.rw) {
> // SCR RW == 0
> if (!hcr_mask_override_bit) {
> if (el == EL3)
> mask = INT_MASK_P;
> else
> mask = INT_MASK_M;
> } else {
> if (el == EL3)
> mask = INT_MASK_T;
> else if (is_secure || el == EL2)
> mask = INT_MASK_M;
> else
> mask = INT_MASK_T;
> }
> } else {
> // SCR RW == 1
> if (!hcr_mask_override_bit) {
> if (el == EL3 || el == EL2)
> mask = INT_MASK_P;
> else
> mask = INT_MASK_M;
> } else {
> if (el == EL3)
> mask = INT_MASK_P;
> else if (is_secure || el == EL2)
> mask = INT_MASK_M;
> else
> mask = INT_MASK_T;
> }
> }
> } else {
> // SCR IRQ == 1
> if (el == EL3)
> mask = INT_MASK_M;
> else
> mask = INT_MASK_T;
> }
> }
>
> return ((mask == INT_MASK_T) ||
> ((mask == INT_MASK_M) && !cpsr_mask_bit)) &&
> (mask != INT_MASK_P);
> }
>