aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdgar E. Iglesias <edgar.iglesias@gmail.com>2009-05-05 12:38:39 +0200
committerEdgar E. Iglesias <edgar.iglesias@gmail.com>2009-05-05 12:38:39 +0200
commit8d13fcc01b78f024cf4904572559a7a645535898 (patch)
tree23984b16c4ca78262b937a72d4643ed3e6185c98
parent7a3161bafbda89f08701601a7b6d27329548ce62 (diff)
ETRAX: Simplify the interrupt controller model.
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
-rw-r--r--hw/etraxfs_pic.c81
1 files changed, 24 insertions, 57 deletions
diff --git a/hw/etraxfs_pic.c b/hw/etraxfs_pic.c
index f32b3021c4..9654420de2 100644
--- a/hw/etraxfs_pic.c
+++ b/hw/etraxfs_pic.c
@@ -29,33 +29,33 @@
#define D(x)
+#define R_RW_MASK 0
+#define R_R_VECT 1
+#define R_R_MASKED_VECT 2
+#define R_R_NMI 3
+#define R_R_GURU 4
+#define R_MAX 5
+
struct fs_pic_state_t
{
CPUState *env;
-
- uint32_t rw_mask;
- /* Active interrupt lines. */
- uint32_t r_vect;
- /* Active lines, gated through the mask. */
- uint32_t r_masked_vect;
- uint32_t r_nmi;
- uint32_t r_guru;
+ uint32_t regs[R_MAX];
};
static void pic_update(struct fs_pic_state_t *fs)
{
CPUState *env = fs->env;
- int i;
uint32_t vector = 0;
+ int i;
- fs->r_masked_vect = fs->r_vect & fs->rw_mask;
+ fs->regs[R_R_MASKED_VECT] = fs->regs[R_R_VECT] & fs->regs[R_RW_MASK];
/* The ETRAX interrupt controller signals interrupts to teh core
through an interrupt request wire and an irq vector bus. If
multiple interrupts are simultaneously active it chooses vector
0x30 and lets the sw choose the priorities. */
- if (fs->r_masked_vect) {
- uint32_t mv = fs->r_masked_vect;
+ if (fs->regs[R_R_MASKED_VECT]) {
+ uint32_t mv = fs->regs[R_R_MASKED_VECT];
for (i = 0; i < 31; i++) {
if (mv & 1) {
vector = 0x31 + i;
@@ -83,28 +83,7 @@ static uint32_t pic_readl (void *opaque, target_phys_addr_t addr)
struct fs_pic_state_t *fs = opaque;
uint32_t rval;
- switch (addr)
- {
- case 0x0:
- rval = fs->rw_mask;
- break;
- case 0x4:
- rval = fs->r_vect;
- break;
- case 0x8:
- rval = fs->r_masked_vect;
- break;
- case 0xc:
- rval = fs->r_nmi;
- break;
- case 0x10:
- rval = fs->r_guru;
- break;
- default:
- cpu_abort(fs->env, "invalid PIC register.\n");
- break;
-
- }
+ rval = fs->regs[addr >> 2];
D(printf("%s %x=%x\n", __func__, addr, rval));
return rval;
}
@@ -114,15 +93,10 @@ pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
{
struct fs_pic_state_t *fs = opaque;
D(printf("%s addr=%x val=%x\n", __func__, addr, value));
- switch (addr)
- {
- case 0x0:
- fs->rw_mask = value;
- pic_update(fs);
- break;
- default:
- cpu_abort(fs->env, "invalid PIC register.\n");
- break;
+
+ if (addr == R_RW_MASK) {
+ fs->regs[R_RW_MASK] = value;
+ pic_update(fs);
}
}
@@ -147,14 +121,9 @@ void irq_info(Monitor *mon)
static void irq_handler(void *opaque, int irq, int level)
{
struct fs_pic_state_t *fs = (void *)opaque;
-
- D(printf("%s irq=%d level=%d mask=%x v=%x mv=%x\n",
- __func__, irq, level,
- fs->rw_mask, fs->r_vect, fs->r_masked_vect));
-
irq -= 1;
- fs->r_vect &= ~(1 << irq);
- fs->r_vect |= (!!level << irq);
+ fs->regs[R_R_VECT] &= ~(1 << irq);
+ fs->regs[R_R_VECT] |= (!!level << irq);
pic_update(fs);
}
@@ -167,11 +136,11 @@ static void nmi_handler(void *opaque, int irq, int level)
mask = 1 << irq;
if (level)
- fs->r_nmi |= mask;
+ fs->regs[R_R_NMI] |= mask;
else
- fs->r_nmi &= ~mask;
+ fs->regs[R_R_NMI] &= ~mask;
- if (fs->r_nmi)
+ if (fs->regs[R_R_NMI])
cpu_interrupt(env, CPU_INTERRUPT_NMI);
else
cpu_reset_interrupt(env, CPU_INTERRUPT_NMI);
@@ -180,9 +149,7 @@ static void nmi_handler(void *opaque, int irq, int level)
static void guru_handler(void *opaque, int irq, int level)
{
struct fs_pic_state_t *fs = (void *)opaque;
- CPUState *env = fs->env;
- cpu_abort(env, "%s unsupported exception\n", __func__);
-
+ cpu_abort(fs->env, "%s unsupported exception\n", __func__);
}
struct etraxfs_pic *etraxfs_pic_init(CPUState *env, target_phys_addr_t base)
@@ -200,7 +167,7 @@ struct etraxfs_pic *etraxfs_pic_init(CPUState *env, target_phys_addr_t base)
pic->guru = qemu_allocate_irqs(guru_handler, fs, 1);
intr_vect_regs = cpu_register_io_memory(0, pic_read, pic_write, fs);
- cpu_register_physical_memory(base, 0x14, intr_vect_regs);
+ cpu_register_physical_memory(base, R_MAX * 4, intr_vect_regs);
return pic;
}