Browse Source

Merge pull request #305 from achingupta/ag/tf-issues#306

Ag/tf issues#306
pull/311/head
Achin Gupta 10 years ago
parent
commit
de975e85ff
  1. 49
      bl31/aarch64/runtime_exceptions.S
  2. 6
      drivers/arm/gic/arm_gic.c
  3. 3
      include/drivers/arm/gic_v2.h

49
bl31/aarch64/runtime_exceptions.S

@ -79,6 +79,14 @@
str x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
bl save_gp_registers
/*
* Save the EL3 system registers needed to return from
* this exception.
*/
mrs x0, spsr_el3
mrs x1, elr_el3
stp x0, x1, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
/* Switch to the runtime stack i.e. SP_EL0 */
ldr x2, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]
mov x20, sp
@ -96,13 +104,29 @@
/*
* Get the registered handler for this interrupt type. A
* NULL return value implies that an interrupt was generated
* for which there is no handler registered or the interrupt
* was routed incorrectly. This is a problem of the framework
* so report it as an error.
* NULL return value could be 'cause of the following
* conditions:
*
* a. An interrupt of a type was routed correctly but a
* handler for its type was not registered.
*
* b. An interrupt of a type was not routed correctly so
* a handler for its type was not registered.
*
* c. An interrupt of a type was routed correctly to EL3,
* but was deasserted before its pending state could
* be read. Another interrupt of a different type pended
* at the same time and its type was reported as pending
* instead. However, a handler for this type was not
* registered.
*
* a. and b. can only happen due to a programming error.
* The occurrence of c. could be beyond the control of
* Trusted Firmware. It makes sense to return from this
* exception instead of reporting an error.
*/
bl get_interrupt_type_handler
cbz x0, interrupt_error_\label
cbz x0, interrupt_exit_\label
mov x21, x0
mov x0, #INTR_ID_UNAVAILABLE
@ -117,14 +141,6 @@
b.eq interrupt_exit_\label
#endif
/*
* Save the EL3 system registers needed to return from
* this exception.
*/
mrs x3, spsr_el3
mrs x4, elr_el3
stp x3, x4, [x20, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
/* Set the current security state in the 'flags' parameter */
mrs x2, scr_el3
ubfx x1, x2, #0, #1
@ -142,13 +158,6 @@ interrupt_exit_\label:
/* Return from exception, possibly in a different security state */
b el3_exit
/*
* This label signifies a problem with the interrupt management
* framework where it is not safe to go back to the instruction
* where the interrupt was generated.
*/
interrupt_error_\label:
bl report_unhandled_interrupt
.endm

6
drivers/arm/gic/arm_gic.c

@ -401,7 +401,7 @@ uint32_t arm_gic_get_pending_interrupt_type(void)
uint32_t id;
assert(g_gicc_base);
id = gicc_read_hppir(g_gicc_base);
id = gicc_read_hppir(g_gicc_base) & INT_ID_MASK;
/* Assume that all secure interrupts are S-EL1 interrupts */
if (id < 1022)
@ -423,7 +423,7 @@ uint32_t arm_gic_get_pending_interrupt_id(void)
uint32_t id;
assert(g_gicc_base);
id = gicc_read_hppir(g_gicc_base);
id = gicc_read_hppir(g_gicc_base) & INT_ID_MASK;
if (id < 1022)
return id;
@ -435,7 +435,7 @@ uint32_t arm_gic_get_pending_interrupt_id(void)
* Find out which non-secure interrupt it is under the assumption that
* the GICC_CTLR.AckCtl bit is 0.
*/
return gicc_read_ahppir(g_gicc_base);
return gicc_read_ahppir(g_gicc_base) & INT_ID_MASK;
}
/*******************************************************************************

3
include/drivers/arm/gic_v2.h

@ -99,6 +99,9 @@
#define GICC_DIR 0x1000
#define GICC_PRIODROP GICC_EOIR
/* Common CPU Interface definitions */
#define INT_ID_MASK 0x3ff
/* GICC_CTLR bit definitions */
#define EOI_MODE_NS (1 << 10)
#define EOI_MODE_S (1 << 9)

Loading…
Cancel
Save