1 /* 2 * QEMU Sparc SLAVIO interrupt controller emulation 3 * 4 * Copyright (c) 2003-2005 Fabrice Bellard 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 * THE SOFTWARE. 23 */ 24 #include "vl.h" 25 //#define DEBUG_IRQ_COUNT 26 //#define DEBUG_IRQ 27 28 #ifdef DEBUG_IRQ 29 #define DPRINTF(fmt, args...) \ 30 do { printf("IRQ: " fmt , ##args); } while (0) 31 #else 32 #define DPRINTF(fmt, args...) 33 #endif 34 35 /* 36 * Registers of interrupt controller in sun4m. 37 * 38 * This is the interrupt controller part of chip STP2001 (Slave I/O), also 39 * produced as NCR89C105. See 40 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt 41 * 42 * There is a system master controller and one for each cpu. 43 * 44 */ 45 46 #define MAX_CPUS 16 47 48 typedef struct SLAVIO_INTCTLState { 49 uint32_t intreg_pending[MAX_CPUS]; 50 uint32_t intregm_pending; 51 uint32_t intregm_disabled; 52 uint32_t target_cpu; 53 #ifdef DEBUG_IRQ_COUNT 54 uint64_t irq_count[32]; 55 #endif 56 CPUState *cpu_envs[MAX_CPUS]; 57 const uint32_t *intbit_to_level; 58 } SLAVIO_INTCTLState; 59 60 #define INTCTL_MAXADDR 0xf 61 #define INTCTLM_MAXADDR 0xf 62 static void slavio_check_interrupts(void *opaque); 63 64 // per-cpu interrupt controller 65 static uint32_t slavio_intctl_mem_readl(void *opaque, target_phys_addr_t addr) 66 { 67 SLAVIO_INTCTLState *s = opaque; 68 uint32_t saddr; 69 int cpu; 70 71 cpu = (addr & (MAX_CPUS - 1) * TARGET_PAGE_SIZE) >> 12; 72 saddr = (addr & INTCTL_MAXADDR) >> 2; 73 switch (saddr) { 74 case 0: 75 return s->intreg_pending[cpu]; 76 default: 77 break; 78 } 79 return 0; 80 } 81 82 static void slavio_intctl_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) 83 { 84 SLAVIO_INTCTLState *s = opaque; 85 uint32_t saddr; 86 int cpu; 87 88 cpu = (addr & (MAX_CPUS - 1) * TARGET_PAGE_SIZE) >> 12; 89 saddr = (addr & INTCTL_MAXADDR) >> 2; 90 switch (saddr) { 91 case 1: // clear pending softints 92 if (val & 0x4000) 93 val |= 80000000; 94 val &= 0xfffe0000; 95 s->intreg_pending[cpu] &= ~val; 96 DPRINTF("Cleared cpu %d irq mask %x, curmask %x\n", cpu, val, s->intreg_pending[cpu]); 97 break; 98 case 2: // set softint 99 val &= 0xfffe0000; 100 s->intreg_pending[cpu] |= val; 101 slavio_check_interrupts(s); 102 DPRINTF("Set cpu %d irq mask %x, curmask %x\n", cpu, val, s->intreg_pending[cpu]); 103 break; 104 default: 105 break; 106 } 107 } 108 109 static CPUReadMemoryFunc *slavio_intctl_mem_read[3] = { 110 slavio_intctl_mem_readl, 111 slavio_intctl_mem_readl, 112 slavio_intctl_mem_readl, 113 }; 114 115 static CPUWriteMemoryFunc *slavio_intctl_mem_write[3] = { 116 slavio_intctl_mem_writel, 117 slavio_intctl_mem_writel, 118 slavio_intctl_mem_writel, 119 }; 120 121 // master system interrupt controller 122 static uint32_t slavio_intctlm_mem_readl(void *opaque, target_phys_addr_t addr) 123 { 124 SLAVIO_INTCTLState *s = opaque; 125 uint32_t saddr; 126 127 saddr = (addr & INTCTLM_MAXADDR) >> 2; 128 switch (saddr) { 129 case 0: 130 return s->intregm_pending & 0x7fffffff; 131 case 1: 132 return s->intregm_disabled; 133 case 4: 134 return s->target_cpu; 135 default: 136 break; 137 } 138 return 0; 139 } 140 141 static void slavio_intctlm_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) 142 { 143 SLAVIO_INTCTLState *s = opaque; 144 uint32_t saddr; 145 146 saddr = (addr & INTCTLM_MAXADDR) >> 2; 147 switch (saddr) { 148 case 2: // clear (enable) 149 // Force clear unused bits 150 val &= ~0x4fb2007f; 151 s->intregm_disabled &= ~val; 152 DPRINTF("Enabled master irq mask %x, curmask %x\n", val, s->intregm_disabled); 153 slavio_check_interrupts(s); 154 break; 155 case 3: // set (disable, clear pending) 156 // Force clear unused bits 157 val &= ~0x4fb2007f; 158 s->intregm_disabled |= val; 159 s->intregm_pending &= ~val; 160 DPRINTF("Disabled master irq mask %x, curmask %x\n", val, s->intregm_disabled); 161 break; 162 case 4: 163 s->target_cpu = val & (MAX_CPUS - 1); 164 DPRINTF("Set master irq cpu %d\n", s->target_cpu); 165 break; 166 default: 167 break; 168 } 169 } 170 171 static CPUReadMemoryFunc *slavio_intctlm_mem_read[3] = { 172 slavio_intctlm_mem_readl, 173 slavio_intctlm_mem_readl, 174 slavio_intctlm_mem_readl, 175 }; 176 177 static CPUWriteMemoryFunc *slavio_intctlm_mem_write[3] = { 178 slavio_intctlm_mem_writel, 179 slavio_intctlm_mem_writel, 180 slavio_intctlm_mem_writel, 181 }; 182 183 void slavio_pic_info(void *opaque) 184 { 185 SLAVIO_INTCTLState *s = opaque; 186 int i; 187 188 for (i = 0; i < MAX_CPUS; i++) { 189 term_printf("per-cpu %d: pending 0x%08x\n", i, s->intreg_pending[i]); 190 } 191 term_printf("master: pending 0x%08x, disabled 0x%08x\n", s->intregm_pending, s->intregm_disabled); 192 } 193 194 void slavio_irq_info(void *opaque) 195 { 196 #ifndef DEBUG_IRQ_COUNT 197 term_printf("irq statistic code not compiled.\n"); 198 #else 199 SLAVIO_INTCTLState *s = opaque; 200 int i; 201 int64_t count; 202 203 term_printf("IRQ statistics:\n"); 204 for (i = 0; i < 32; i++) { 205 count = s->irq_count[i]; 206 if (count > 0) 207 term_printf("%2d: %" PRId64 "\n", i, count); 208 } 209 #endif 210 } 211 212 static void slavio_check_interrupts(void *opaque) 213 { 214 CPUState *env; 215 SLAVIO_INTCTLState *s = opaque; 216 uint32_t pending = s->intregm_pending; 217 unsigned int i, j, max = 0; 218 219 pending &= ~s->intregm_disabled; 220 221 if (pending && !(s->intregm_disabled & 0x80000000)) { 222 for (i = 0; i < 32; i++) { 223 if (pending & (1 << i)) { 224 if (max < s->intbit_to_level[i]) 225 max = s->intbit_to_level[i]; 226 } 227 } 228 env = s->cpu_envs[s->target_cpu]; 229 if (!env) { 230 DPRINTF("No CPU %d, not triggered (pending %x)\n", s->target_cpu, pending); 231 } 232 else { 233 if (env->halted) 234 env->halted = 0; 235 if (env->interrupt_index == 0) { 236 DPRINTF("Triggered CPU %d pil %d\n", s->target_cpu, max); 237 #ifdef DEBUG_IRQ_COUNT 238 s->irq_count[max]++; 239 #endif 240 env->interrupt_index = TT_EXTINT | max; 241 cpu_interrupt(env, CPU_INTERRUPT_HARD); 242 } 243 else 244 DPRINTF("Not triggered (pending %x), pending exception %x\n", pending, env->interrupt_index); 245 } 246 } 247 else 248 DPRINTF("Not triggered (pending %x), disabled %x\n", pending, s->intregm_disabled); 249 250 for (i = 0; i < MAX_CPUS; i++) { 251 max = 0; 252 env = s->cpu_envs[i]; 253 if (!env) 254 continue; 255 for (j = 17; j < 32; j++) { 256 if (s->intreg_pending[i] & (1 << j)) { 257 if (max < j - 16) 258 max = j - 16; 259 } 260 } 261 if (max > 0) { 262 if (env->halted) 263 env->halted = 0; 264 if (env->interrupt_index == 0) { 265 DPRINTF("Triggered softint %d for cpu %d (pending %x)\n", max, i, pending); 266 #ifdef DEBUG_IRQ_COUNT 267 s->irq_count[max]++; 268 #endif 269 env->interrupt_index = TT_EXTINT | max; 270 cpu_interrupt(env, CPU_INTERRUPT_HARD); 271 } 272 } 273 } 274 } 275 276 /* 277 * "irq" here is the bit number in the system interrupt register to 278 * separate serial and keyboard interrupts sharing a level. 279 */ 280 void pic_set_irq_new(void *opaque, int irq, int level) 281 { 282 SLAVIO_INTCTLState *s = opaque; 283 284 DPRINTF("Set cpu %d irq %d level %d\n", s->target_cpu, irq, level); 285 if (irq < 32) { 286 uint32_t mask = 1 << irq; 287 uint32_t pil = s->intbit_to_level[irq]; 288 if (pil > 0) { 289 if (level) { 290 s->intregm_pending |= mask; 291 s->intreg_pending[s->target_cpu] |= 1 << pil; 292 slavio_check_interrupts(s); 293 } 294 else { 295 s->intregm_pending &= ~mask; 296 s->intreg_pending[s->target_cpu] &= ~(1 << pil); 297 } 298 } 299 } 300 } 301 302 void pic_set_irq_cpu(void *opaque, int irq, int level, unsigned int cpu) 303 { 304 SLAVIO_INTCTLState *s = opaque; 305 306 DPRINTF("Set cpu %d local irq %d level %d\n", cpu, irq, level); 307 if (cpu == (unsigned int)-1) { 308 pic_set_irq_new(opaque, irq, level); 309 return; 310 } 311 if (irq < 32) { 312 uint32_t pil = s->intbit_to_level[irq]; 313 if (pil > 0) { 314 if (level) { 315 s->intreg_pending[cpu] |= 1 << pil; 316 } 317 else { 318 s->intreg_pending[cpu] &= ~(1 << pil); 319 } 320 } 321 } 322 slavio_check_interrupts(s); 323 } 324 325 static void slavio_intctl_save(QEMUFile *f, void *opaque) 326 { 327 SLAVIO_INTCTLState *s = opaque; 328 int i; 329 330 for (i = 0; i < MAX_CPUS; i++) { 331 qemu_put_be32s(f, &s->intreg_pending[i]); 332 } 333 qemu_put_be32s(f, &s->intregm_pending); 334 qemu_put_be32s(f, &s->intregm_disabled); 335 qemu_put_be32s(f, &s->target_cpu); 336 } 337 338 static int slavio_intctl_load(QEMUFile *f, void *opaque, int version_id) 339 { 340 SLAVIO_INTCTLState *s = opaque; 341 int i; 342 343 if (version_id != 1) 344 return -EINVAL; 345 346 for (i = 0; i < MAX_CPUS; i++) { 347 qemu_get_be32s(f, &s->intreg_pending[i]); 348 } 349 qemu_get_be32s(f, &s->intregm_pending); 350 qemu_get_be32s(f, &s->intregm_disabled); 351 qemu_get_be32s(f, &s->target_cpu); 352 return 0; 353 } 354 355 static void slavio_intctl_reset(void *opaque) 356 { 357 SLAVIO_INTCTLState *s = opaque; 358 int i; 359 360 for (i = 0; i < MAX_CPUS; i++) { 361 s->intreg_pending[i] = 0; 362 } 363 s->intregm_disabled = ~0xffb2007f; 364 s->intregm_pending = 0; 365 s->target_cpu = 0; 366 } 367 368 void slavio_intctl_set_cpu(void *opaque, unsigned int cpu, CPUState *env) 369 { 370 SLAVIO_INTCTLState *s = opaque; 371 s->cpu_envs[cpu] = env; 372 } 373 374 void *slavio_intctl_init(uint32_t addr, uint32_t addrg, 375 const uint32_t *intbit_to_level) 376 { 377 int slavio_intctl_io_memory, slavio_intctlm_io_memory, i; 378 SLAVIO_INTCTLState *s; 379 380 s = qemu_mallocz(sizeof(SLAVIO_INTCTLState)); 381 if (!s) 382 return NULL; 383 384 s->intbit_to_level = intbit_to_level; 385 for (i = 0; i < MAX_CPUS; i++) { 386 slavio_intctl_io_memory = cpu_register_io_memory(0, slavio_intctl_mem_read, slavio_intctl_mem_write, s); 387 cpu_register_physical_memory(addr + i * TARGET_PAGE_SIZE, INTCTL_MAXADDR, slavio_intctl_io_memory); 388 } 389 390 slavio_intctlm_io_memory = cpu_register_io_memory(0, slavio_intctlm_mem_read, slavio_intctlm_mem_write, s); 391 cpu_register_physical_memory(addrg, INTCTLM_MAXADDR, slavio_intctlm_io_memory); 392 393 register_savevm("slavio_intctl", addr, 1, slavio_intctl_save, slavio_intctl_load, s); 394 qemu_register_reset(slavio_intctl_reset, s); 395 slavio_intctl_reset(s); 396 return s; 397 } 398 399