commit 8d13fcc01b78f024cf4904572559a7a645535898
Author: Edgar E. Iglesias <edgar.iglesias@gmail.com>
Date:   Tue May 5 12:38:39 2009 +0200

    ETRAX: Simplify the interrupt controller model.
    
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>

diff --git a/hw/etraxfs_pic.c b/hw/etraxfs_pic.c
index f32b302..9654420 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;
 }
