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 | } | ... | ... |