Commit 8d13fcc01b78f024cf4904572559a7a645535898
1 parent
7a3161ba
ETRAX: Simplify the interrupt controller model.
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
Showing
1 changed file
with
24 additions
and
57 deletions
hw/etraxfs_pic.c
| ... | ... | @@ -29,33 +29,33 @@ |
| 29 | 29 | |
| 30 | 30 | #define D(x) |
| 31 | 31 | |
| 32 | +#define R_RW_MASK 0 | |
| 33 | +#define R_R_VECT 1 | |
| 34 | +#define R_R_MASKED_VECT 2 | |
| 35 | +#define R_R_NMI 3 | |
| 36 | +#define R_R_GURU 4 | |
| 37 | +#define R_MAX 5 | |
| 38 | + | |
| 32 | 39 | struct fs_pic_state_t |
| 33 | 40 | { |
| 34 | 41 | CPUState *env; |
| 35 | - | |
| 36 | - uint32_t rw_mask; | |
| 37 | - /* Active interrupt lines. */ | |
| 38 | - uint32_t r_vect; | |
| 39 | - /* Active lines, gated through the mask. */ | |
| 40 | - uint32_t r_masked_vect; | |
| 41 | - uint32_t r_nmi; | |
| 42 | - uint32_t r_guru; | |
| 42 | + uint32_t regs[R_MAX]; | |
| 43 | 43 | }; |
| 44 | 44 | |
| 45 | 45 | static void pic_update(struct fs_pic_state_t *fs) |
| 46 | 46 | { |
| 47 | 47 | CPUState *env = fs->env; |
| 48 | - int i; | |
| 49 | 48 | uint32_t vector = 0; |
| 49 | + int i; | |
| 50 | 50 | |
| 51 | - fs->r_masked_vect = fs->r_vect & fs->rw_mask; | |
| 51 | + fs->regs[R_R_MASKED_VECT] = fs->regs[R_R_VECT] & fs->regs[R_RW_MASK]; | |
| 52 | 52 | |
| 53 | 53 | /* The ETRAX interrupt controller signals interrupts to teh core |
| 54 | 54 | through an interrupt request wire and an irq vector bus. If |
| 55 | 55 | multiple interrupts are simultaneously active it chooses vector |
| 56 | 56 | 0x30 and lets the sw choose the priorities. */ |
| 57 | - if (fs->r_masked_vect) { | |
| 58 | - uint32_t mv = fs->r_masked_vect; | |
| 57 | + if (fs->regs[R_R_MASKED_VECT]) { | |
| 58 | + uint32_t mv = fs->regs[R_R_MASKED_VECT]; | |
| 59 | 59 | for (i = 0; i < 31; i++) { |
| 60 | 60 | if (mv & 1) { |
| 61 | 61 | vector = 0x31 + i; |
| ... | ... | @@ -83,28 +83,7 @@ static uint32_t pic_readl (void *opaque, target_phys_addr_t addr) |
| 83 | 83 | struct fs_pic_state_t *fs = opaque; |
| 84 | 84 | uint32_t rval; |
| 85 | 85 | |
| 86 | - switch (addr) | |
| 87 | - { | |
| 88 | - case 0x0: | |
| 89 | - rval = fs->rw_mask; | |
| 90 | - break; | |
| 91 | - case 0x4: | |
| 92 | - rval = fs->r_vect; | |
| 93 | - break; | |
| 94 | - case 0x8: | |
| 95 | - rval = fs->r_masked_vect; | |
| 96 | - break; | |
| 97 | - case 0xc: | |
| 98 | - rval = fs->r_nmi; | |
| 99 | - break; | |
| 100 | - case 0x10: | |
| 101 | - rval = fs->r_guru; | |
| 102 | - break; | |
| 103 | - default: | |
| 104 | - cpu_abort(fs->env, "invalid PIC register.\n"); | |
| 105 | - break; | |
| 106 | - | |
| 107 | - } | |
| 86 | + rval = fs->regs[addr >> 2]; | |
| 108 | 87 | D(printf("%s %x=%x\n", __func__, addr, rval)); |
| 109 | 88 | return rval; |
| 110 | 89 | } |
| ... | ... | @@ -114,15 +93,10 @@ pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value) |
| 114 | 93 | { |
| 115 | 94 | struct fs_pic_state_t *fs = opaque; |
| 116 | 95 | D(printf("%s addr=%x val=%x\n", __func__, addr, value)); |
| 117 | - switch (addr) | |
| 118 | - { | |
| 119 | - case 0x0: | |
| 120 | - fs->rw_mask = value; | |
| 121 | - pic_update(fs); | |
| 122 | - break; | |
| 123 | - default: | |
| 124 | - cpu_abort(fs->env, "invalid PIC register.\n"); | |
| 125 | - break; | |
| 96 | + | |
| 97 | + if (addr == R_RW_MASK) { | |
| 98 | + fs->regs[R_RW_MASK] = value; | |
| 99 | + pic_update(fs); | |
| 126 | 100 | } |
| 127 | 101 | } |
| 128 | 102 | |
| ... | ... | @@ -147,14 +121,9 @@ void irq_info(Monitor *mon) |
| 147 | 121 | static void irq_handler(void *opaque, int irq, int level) |
| 148 | 122 | { |
| 149 | 123 | struct fs_pic_state_t *fs = (void *)opaque; |
| 150 | - | |
| 151 | - D(printf("%s irq=%d level=%d mask=%x v=%x mv=%x\n", | |
| 152 | - __func__, irq, level, | |
| 153 | - fs->rw_mask, fs->r_vect, fs->r_masked_vect)); | |
| 154 | - | |
| 155 | 124 | irq -= 1; |
| 156 | - fs->r_vect &= ~(1 << irq); | |
| 157 | - fs->r_vect |= (!!level << irq); | |
| 125 | + fs->regs[R_R_VECT] &= ~(1 << irq); | |
| 126 | + fs->regs[R_R_VECT] |= (!!level << irq); | |
| 158 | 127 | |
| 159 | 128 | pic_update(fs); |
| 160 | 129 | } |
| ... | ... | @@ -167,11 +136,11 @@ static void nmi_handler(void *opaque, int irq, int level) |
| 167 | 136 | |
| 168 | 137 | mask = 1 << irq; |
| 169 | 138 | if (level) |
| 170 | - fs->r_nmi |= mask; | |
| 139 | + fs->regs[R_R_NMI] |= mask; | |
| 171 | 140 | else |
| 172 | - fs->r_nmi &= ~mask; | |
| 141 | + fs->regs[R_R_NMI] &= ~mask; | |
| 173 | 142 | |
| 174 | - if (fs->r_nmi) | |
| 143 | + if (fs->regs[R_R_NMI]) | |
| 175 | 144 | cpu_interrupt(env, CPU_INTERRUPT_NMI); |
| 176 | 145 | else |
| 177 | 146 | cpu_reset_interrupt(env, CPU_INTERRUPT_NMI); |
| ... | ... | @@ -180,9 +149,7 @@ static void nmi_handler(void *opaque, int irq, int level) |
| 180 | 149 | static void guru_handler(void *opaque, int irq, int level) |
| 181 | 150 | { |
| 182 | 151 | struct fs_pic_state_t *fs = (void *)opaque; |
| 183 | - CPUState *env = fs->env; | |
| 184 | - cpu_abort(env, "%s unsupported exception\n", __func__); | |
| 185 | - | |
| 152 | + cpu_abort(fs->env, "%s unsupported exception\n", __func__); | |
| 186 | 153 | } |
| 187 | 154 | |
| 188 | 155 | 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) |
| 200 | 167 | pic->guru = qemu_allocate_irqs(guru_handler, fs, 1); |
| 201 | 168 | |
| 202 | 169 | intr_vect_regs = cpu_register_io_memory(0, pic_read, pic_write, fs); |
| 203 | - cpu_register_physical_memory(base, 0x14, intr_vect_regs); | |
| 170 | + cpu_register_physical_memory(base, R_MAX * 4, intr_vect_regs); | |
| 204 | 171 | |
| 205 | 172 | return pic; |
| 206 | 173 | } | ... | ... |