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,33 +29,33 @@ | ||
| 29 | 29 | ||
| 30 | #define D(x) | 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 | struct fs_pic_state_t | 39 | struct fs_pic_state_t |
| 33 | { | 40 | { |
| 34 | CPUState *env; | 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 | static void pic_update(struct fs_pic_state_t *fs) | 45 | static void pic_update(struct fs_pic_state_t *fs) |
| 46 | { | 46 | { |
| 47 | CPUState *env = fs->env; | 47 | CPUState *env = fs->env; |
| 48 | - int i; | ||
| 49 | uint32_t vector = 0; | 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 | /* The ETRAX interrupt controller signals interrupts to teh core | 53 | /* The ETRAX interrupt controller signals interrupts to teh core |
| 54 | through an interrupt request wire and an irq vector bus. If | 54 | through an interrupt request wire and an irq vector bus. If |
| 55 | multiple interrupts are simultaneously active it chooses vector | 55 | multiple interrupts are simultaneously active it chooses vector |
| 56 | 0x30 and lets the sw choose the priorities. */ | 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 | for (i = 0; i < 31; i++) { | 59 | for (i = 0; i < 31; i++) { |
| 60 | if (mv & 1) { | 60 | if (mv & 1) { |
| 61 | vector = 0x31 + i; | 61 | vector = 0x31 + i; |
| @@ -83,28 +83,7 @@ static uint32_t pic_readl (void *opaque, target_phys_addr_t addr) | @@ -83,28 +83,7 @@ static uint32_t pic_readl (void *opaque, target_phys_addr_t addr) | ||
| 83 | struct fs_pic_state_t *fs = opaque; | 83 | struct fs_pic_state_t *fs = opaque; |
| 84 | uint32_t rval; | 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 | D(printf("%s %x=%x\n", __func__, addr, rval)); | 87 | D(printf("%s %x=%x\n", __func__, addr, rval)); |
| 109 | return rval; | 88 | return rval; |
| 110 | } | 89 | } |
| @@ -114,15 +93,10 @@ pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value) | @@ -114,15 +93,10 @@ pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value) | ||
| 114 | { | 93 | { |
| 115 | struct fs_pic_state_t *fs = opaque; | 94 | struct fs_pic_state_t *fs = opaque; |
| 116 | D(printf("%s addr=%x val=%x\n", __func__, addr, value)); | 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,14 +121,9 @@ void irq_info(Monitor *mon) | ||
| 147 | static void irq_handler(void *opaque, int irq, int level) | 121 | static void irq_handler(void *opaque, int irq, int level) |
| 148 | { | 122 | { |
| 149 | struct fs_pic_state_t *fs = (void *)opaque; | 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 | irq -= 1; | 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 | pic_update(fs); | 128 | pic_update(fs); |
| 160 | } | 129 | } |
| @@ -167,11 +136,11 @@ static void nmi_handler(void *opaque, int irq, int level) | @@ -167,11 +136,11 @@ static void nmi_handler(void *opaque, int irq, int level) | ||
| 167 | 136 | ||
| 168 | mask = 1 << irq; | 137 | mask = 1 << irq; |
| 169 | if (level) | 138 | if (level) |
| 170 | - fs->r_nmi |= mask; | 139 | + fs->regs[R_R_NMI] |= mask; |
| 171 | else | 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 | cpu_interrupt(env, CPU_INTERRUPT_NMI); | 144 | cpu_interrupt(env, CPU_INTERRUPT_NMI); |
| 176 | else | 145 | else |
| 177 | cpu_reset_interrupt(env, CPU_INTERRUPT_NMI); | 146 | cpu_reset_interrupt(env, CPU_INTERRUPT_NMI); |
| @@ -180,9 +149,7 @@ static void nmi_handler(void *opaque, int irq, int level) | @@ -180,9 +149,7 @@ static void nmi_handler(void *opaque, int irq, int level) | ||
| 180 | static void guru_handler(void *opaque, int irq, int level) | 149 | static void guru_handler(void *opaque, int irq, int level) |
| 181 | { | 150 | { |
| 182 | struct fs_pic_state_t *fs = (void *)opaque; | 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 | struct etraxfs_pic *etraxfs_pic_init(CPUState *env, target_phys_addr_t base) | 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,7 +167,7 @@ struct etraxfs_pic *etraxfs_pic_init(CPUState *env, target_phys_addr_t base) | ||
| 200 | pic->guru = qemu_allocate_irqs(guru_handler, fs, 1); | 167 | pic->guru = qemu_allocate_irqs(guru_handler, fs, 1); |
| 201 | 168 | ||
| 202 | intr_vect_regs = cpu_register_io_memory(0, pic_read, pic_write, fs); | 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 | return pic; | 172 | return pic; |
| 206 | } | 173 | } |