Skip to content
This repository has been archived by the owner on Nov 5, 2019. It is now read-only.

Commit

Permalink
consider BASEPRI for disabling interrupts
Browse files Browse the repository at this point in the history
  • Loading branch information
ilg-ul committed Jul 25, 2016
1 parent 9dfbfd0 commit 3cb3c6c
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 0 deletions.
3 changes: 3 additions & 0 deletions hw/cortexm/cortexm-mcu.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,9 @@ static void cortexm_mcu_realize_callback(DeviceState *dev, Error **errp)
sysbus_connect_irq(SYS_BUS_DEVICE(cm_state->nvic), 0,
qdev_get_gpio_in(DEVICE(cm_state->cpu), ARM_CPU_IRQ));

GICState *gs = ARM_GIC_COMMON(nvic);
gs->basepri_ptr = &env->v7m.basepri;

/*
* Create the CPU exception handler interrupts. Peripherals
* will connect to them and set interrupts to be delivered to
Expand Down
20 changes: 20 additions & 0 deletions hw/intc/arm_gic.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,13 @@
//#define DEBUG_GIC

#ifdef DEBUG_GIC
#if defined(CONFIG_GNU_ARM_ECLIPSE)
#define DPRINTF(fmt, ...) \
do { fprintf(stdout, "arm_gic: " fmt , ## __VA_ARGS__); } while (0)
#else
#define DPRINTF(fmt, ...) \
do { fprintf(stderr, "arm_gic: " fmt , ## __VA_ARGS__); } while (0)
#endif
#else
#define DPRINTF(fmt, ...) do {} while(0)
#endif
Expand Down Expand Up @@ -76,10 +81,21 @@ void gic_update(GICState *s)
for (irq = 0; irq < s->num_irq; irq++) {
if (GIC_TEST_ENABLED(irq, cm) && gic_test_pending(s, irq, cm) &&
(irq < GIC_INTERNAL || GIC_TARGET(irq) & cm)) {
#if defined(CONFIG_GNU_ARM_ECLIPSE)
int prio = GIC_GET_PRIORITY(irq, cpu);
uint32_t basepri = *(s->basepri_ptr);
if ((basepri == 0) || (prio <= basepri)) {
if (prio < best_prio) {
best_prio = prio;
best_irq = irq;
}
}
#else
if (GIC_GET_PRIORITY(irq, cpu) < best_prio) {
best_prio = GIC_GET_PRIORITY(irq, cpu);
best_irq = irq;
}
#endif
}
}

Expand Down Expand Up @@ -829,6 +845,10 @@ static void gic_dist_writeb(void *opaque, hwaddr offset,
for (i = 0; i < 8; i++) {
if (value & (1 << i)) {
GIC_SET_PENDING(irq + i, GIC_TARGET(irq + i));
#if defined(CONFIG_GNU_ARM_ECLIPSE)
DPRINTF("GIC_SET_PENDING s->irq_state[%d].pending is %d\n",
irq + i, s->irq_state[irq + i].pending);
#endif
}
}
} else if (offset < 0x300) {
Expand Down
4 changes: 4 additions & 0 deletions include/hw/intc/arm_gic_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ typedef struct GICState {
uint16_t running_priority[GIC_NCPU];
uint16_t current_pending[GIC_NCPU];

#if defined(CONFIG_GNU_ARM_ECLIPSE)
uint32_t* basepri_ptr;
#endif

/* If we present the GICv2 without security extensions to a guest,
* the guest can configure the GICC_CTLR to configure group 1 binary point
* in the abpr.
Expand Down
31 changes: 31 additions & 0 deletions target-arm/helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
#include <zlib.h> /* For crc32 */
#include "exec/semihost.h"

#if defined(CONFIG_GNU_ARM_ECLIPSE)
#include "hw/intc/gic_internal.h"
#endif

#define ARM_CPU_FREQ 1000000000 /* FIXME: 1 GHz, should be configurable */

#ifndef CONFIG_USER_ONLY
Expand Down Expand Up @@ -7580,6 +7584,30 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t reg, uint32_t val)
env->daif &= ~PSTATE_I;
}
break;

#if defined(CONFIG_GNU_ARM_ECLIPSE)

case 17: /* BASEPRI */
env->v7m.basepri = val & 0xff;

void* nvic = env->nvic;
GICState* gic = ARM_GIC_COMMON(nvic);
gic_update(gic);
break;

case 18: /* BASEPRI_MAX */
val &= 0xff;
if (val != 0 && (val < env->v7m.basepri || env->v7m.basepri == 0)) {
env->v7m.basepri = val;

void* nvic = env->nvic;
GICState* gic = ARM_GIC_COMMON(nvic);
gic_update(gic);
}
break;

#else

case 17: /* BASEPRI */
env->v7m.basepri = val & 0xff;
break;
Expand All @@ -7588,6 +7616,9 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t reg, uint32_t val)
if (val != 0 && (val < env->v7m.basepri || env->v7m.basepri == 0))
env->v7m.basepri = val;
break;

#endif

case 19: /* FAULTMASK */
if (val & 1) {
env->daif |= PSTATE_F;
Expand Down

0 comments on commit 3cb3c6c

Please sign in to comment.