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 #define MAX_PILS 16 48 49 typedef struct SLAVIO_INTCTLState { 50 uint32_t intreg_pending[MAX_CPUS]; 51 uint32_t intregm_pending; 52 uint32_t intregm_disabled; 53 uint32_t target_cpu; 54 #ifdef DEBUG_IRQ_COUNT 55 uint64_t irq_count[32]; 56 #endif 57 qemu_irq *cpu_irqs[MAX_CPUS]; 58 const uint32_t *intbit_to_level; 59 uint32_t cputimer_bit; 60 uint32_t pil_out[MAX_CPUS]; 61 } SLAVIO_INTCTLState; 62 63 #define INTCTL_MAXADDR 0xf 64 #define INTCTL_SIZE (INTCTL_MAXADDR + 1) 65 #define INTCTLM_MAXADDR 0x13 66 #define INTCTLM_SIZE (INTCTLM_MAXADDR + 1) 67 #define INTCTLM_MASK 0x1f 68 static void slavio_check_interrupts(void *opaque); 69 70 // per-cpu interrupt controller 71 static uint32_t slavio_intctl_mem_readl(void *opaque, target_phys_addr_t addr) 72 { 73 SLAVIO_INTCTLState *s = opaque; 74 uint32_t saddr, ret; 75 int cpu; 76 77 cpu = (addr & (MAX_CPUS - 1) * TARGET_PAGE_SIZE) >> 12; 78 saddr = (addr & INTCTL_MAXADDR) >> 2; 79 switch (saddr) { 80 case 0: 81 ret = s->intreg_pending[cpu]; 82 break; 83 default: 84 ret = 0; 85 break; 86 } 87 DPRINTF("read cpu %d reg 0x" TARGET_FMT_plx " = %x\n", cpu, addr, ret); 88 89 return ret; 90 } 91 92 static void slavio_intctl_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) 93 { 94 SLAVIO_INTCTLState *s = opaque; 95 uint32_t saddr; 96 int cpu; 97 98 cpu = (addr & (MAX_CPUS - 1) * TARGET_PAGE_SIZE) >> 12; 99 saddr = (addr & INTCTL_MAXADDR) >> 2; 100 DPRINTF("write cpu %d reg 0x" TARGET_FMT_plx " = %x\n", cpu, addr, val); 101 switch (saddr) { 102 case 1: // clear pending softints 103 if (val & 0x4000) 104 val |= 80000000; 105 val &= 0xfffe0000; 106 s->intreg_pending[cpu] &= ~val; 107 slavio_check_interrupts(s); 108 DPRINTF("Cleared cpu %d irq mask %x, curmask %x\n", cpu, val, s->intreg_pending[cpu]); 109 break; 110 case 2: // set softint 111 val &= 0xfffe0000; 112 s->intreg_pending[cpu] |= val; 113 slavio_check_interrupts(s); 114 DPRINTF("Set cpu %d irq mask %x, curmask %x\n", cpu, val, s->intreg_pending[cpu]); 115 break; 116 default: 117 break; 118 } 119 } 120 121 static CPUReadMemoryFunc *slavio_intctl_mem_read[3] = { 122 slavio_intctl_mem_readl, 123 slavio_intctl_mem_readl, 124 slavio_intctl_mem_readl, 125 }; 126 127 static CPUWriteMemoryFunc *slavio_intctl_mem_write[3] = { 128 slavio_intctl_mem_writel, 129 slavio_intctl_mem_writel, 130 slavio_intctl_mem_writel, 131 }; 132 133 // master system interrupt controller 134 static uint32_t slavio_intctlm_mem_readl(void *opaque, target_phys_addr_t addr) 135 { 136 SLAVIO_INTCTLState *s = opaque; 137 uint32_t saddr, ret; 138 139 saddr = (addr & INTCTLM_MAXADDR) >> 2; 140 switch (saddr) { 141 case 0: 142 ret = s->intregm_pending & 0x7fffffff; 143 break; 144 case 1: 145 ret = s->intregm_disabled; 146 break; 147 case 4: 148 ret = s->target_cpu; 149 break; 150 default: 151 ret = 0; 152 break; 153 } 154 DPRINTF("read system reg 0x" TARGET_FMT_plx " = %x\n", addr, ret); 155 156 return ret; 157 } 158 159 static void slavio_intctlm_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) 160 { 161 SLAVIO_INTCTLState *s = opaque; 162 uint32_t saddr; 163 164 saddr = (addr & INTCTLM_MASK) >> 2; 165 DPRINTF("write system reg 0x" TARGET_FMT_plx " = %x\n", addr, val); 166 switch (saddr) { 167 case 2: // clear (enable) 168 // Force clear unused bits 169 val &= ~0x4fb2007f; 170 s->intregm_disabled &= ~val; 171 DPRINTF("Enabled master irq mask %x, curmask %x\n", val, s->intregm_disabled); 172 slavio_check_interrupts(s); 173 break; 174 case 3: // set (disable, clear pending) 175 // Force clear unused bits 176 val &= ~0x4fb2007f; 177 s->intregm_disabled |= val; 178 s->intregm_pending &= ~val; 179 slavio_check_interrupts(s); 180 DPRINTF("Disabled master irq mask %x, curmask %x\n", val, s->intregm_disabled); 181 break; 182 case 4: 183 s->target_cpu = val & (MAX_CPUS - 1); 184 slavio_check_interrupts(s); 185 DPRINTF("Set master irq cpu %d\n", s->target_cpu); 186 break; 187 default: 188 break; 189 } 190 } 191 192 static CPUReadMemoryFunc *slavio_intctlm_mem_read[3] = { 193 slavio_intctlm_mem_readl, 194 slavio_intctlm_mem_readl, 195 slavio_intctlm_mem_readl, 196 }; 197 198 static CPUWriteMemoryFunc *slavio_intctlm_mem_write[3] = { 199 slavio_intctlm_mem_writel, 200 slavio_intctlm_mem_writel, 201 slavio_intctlm_mem_writel, 202 }; 203 204 void slavio_pic_info(void *opaque) 205 { 206 SLAVIO_INTCTLState *s = opaque; 207 int i; 208 209 for (i = 0; i < MAX_CPUS; i++) { 210 term_printf("per-cpu %d: pending 0x%08x\n", i, s->intreg_pending[i]); 211 } 212 term_printf("master: pending 0x%08x, disabled 0x%08x\n", s->intregm_pending, s->intregm_disabled); 213 } 214 215 void slavio_irq_info(void *opaque) 216 { 217 #ifndef DEBUG_IRQ_COUNT 218 term_printf("irq statistic code not compiled.\n"); 219 #else 220 SLAVIO_INTCTLState *s = opaque; 221 int i; 222 int64_t count; 223 224 term_printf("IRQ statistics:\n"); 225 for (i = 0; i < 32; i++) { 226 count = s->irq_count[i]; 227 if (count > 0) 228 term_printf("%2d: %" PRId64 "\n", i, count); 229 } 230 #endif 231 } 232 233 static void slavio_check_interrupts(void *opaque) 234 { 235 SLAVIO_INTCTLState *s = opaque; 236 uint32_t pending = s->intregm_pending, pil_pending; 237 unsigned int i, j; 238 239 pending &= ~s->intregm_disabled; 240 241 DPRINTF("pending %x disabled %x\n", pending, s->intregm_disabled); 242 for (i = 0; i < MAX_CPUS; i++) { 243 pil_pending = 0; 244 if (pending && !(s->intregm_disabled & 0x80000000) && 245 (i == s->target_cpu)) { 246 for (j = 0; j < 32; j++) { 247 if (pending & (1 << j)) 248 pil_pending |= 1 << s->intbit_to_level[j]; 249 } 250 } 251 pil_pending |= (s->intreg_pending[i] >> 16) & 0xfffe; 252 253 for (j = 0; j < MAX_PILS; j++) { 254 if (pil_pending & (1 << j)) { 255 if (!(s->pil_out[i] & (1 << j))) 256 qemu_irq_raise(s->cpu_irqs[i][j]); 257 } else { 258 if (s->pil_out[i] & (1 << j)) 259 qemu_irq_lower(s->cpu_irqs[i][j]); 260 } 261 } 262 s->pil_out[i] = pil_pending; 263 } 264 } 265 266 /* 267 * "irq" here is the bit number in the system interrupt register to 268 * separate serial and keyboard interrupts sharing a level. 269 */ 270 static void slavio_set_irq(void *opaque, int irq, int level) 271 { 272 SLAVIO_INTCTLState *s = opaque; 273 uint32_t mask = 1 << irq; 274 uint32_t pil = s->intbit_to_level[irq]; 275 276 DPRINTF("Set cpu %d irq %d -> pil %d level %d\n", s->target_cpu, irq, pil, 277 level); 278 if (pil > 0) { 279 if (level) { 280 #ifdef DEBUG_IRQ_COUNT 281 s->irq_count[pil]++; 282 #endif 283 s->intregm_pending |= mask; 284 s->intreg_pending[s->target_cpu] |= 1 << pil; 285 } else { 286 s->intregm_pending &= ~mask; 287 s->intreg_pending[s->target_cpu] &= ~(1 << pil); 288 } 289 slavio_check_interrupts(s); 290 } 291 } 292 293 static void slavio_set_timer_irq_cpu(void *opaque, int cpu, int level) 294 { 295 SLAVIO_INTCTLState *s = opaque; 296 297 DPRINTF("Set cpu %d local timer level %d\n", cpu, level); 298 299 if (level) 300 s->intreg_pending[cpu] |= s->cputimer_bit; 301 else 302 s->intreg_pending[cpu] &= ~s->cputimer_bit; 303 304 slavio_check_interrupts(s); 305 } 306 307 static void slavio_intctl_save(QEMUFile *f, void *opaque) 308 { 309 SLAVIO_INTCTLState *s = opaque; 310 int i; 311 312 for (i = 0; i < MAX_CPUS; i++) { 313 qemu_put_be32s(f, &s->intreg_pending[i]); 314 } 315 qemu_put_be32s(f, &s->intregm_pending); 316 qemu_put_be32s(f, &s->intregm_disabled); 317 qemu_put_be32s(f, &s->target_cpu); 318 } 319 320 static int slavio_intctl_load(QEMUFile *f, void *opaque, int version_id) 321 { 322 SLAVIO_INTCTLState *s = opaque; 323 int i; 324 325 if (version_id != 1) 326 return -EINVAL; 327 328 for (i = 0; i < MAX_CPUS; i++) { 329 qemu_get_be32s(f, &s->intreg_pending[i]); 330 } 331 qemu_get_be32s(f, &s->intregm_pending); 332 qemu_get_be32s(f, &s->intregm_disabled); 333 qemu_get_be32s(f, &s->target_cpu); 334 slavio_check_interrupts(s); 335 return 0; 336 } 337 338 static void slavio_intctl_reset(void *opaque) 339 { 340 SLAVIO_INTCTLState *s = opaque; 341 int i; 342 343 for (i = 0; i < MAX_CPUS; i++) { 344 s->intreg_pending[i] = 0; 345 } 346 s->intregm_disabled = ~0xffb2007f; 347 s->intregm_pending = 0; 348 s->target_cpu = 0; 349 slavio_check_interrupts(s); 350 } 351 352 void *slavio_intctl_init(target_phys_addr_t addr, target_phys_addr_t addrg, 353 const uint32_t *intbit_to_level, 354 qemu_irq **irq, qemu_irq **cpu_irq, 355 qemu_irq **parent_irq, unsigned int cputimer) 356 { 357 int slavio_intctl_io_memory, slavio_intctlm_io_memory, i; 358 SLAVIO_INTCTLState *s; 359 360 s = qemu_mallocz(sizeof(SLAVIO_INTCTLState)); 361 if (!s) 362 return NULL; 363 364 s->intbit_to_level = intbit_to_level; 365 for (i = 0; i < MAX_CPUS; i++) { 366 slavio_intctl_io_memory = cpu_register_io_memory(0, slavio_intctl_mem_read, slavio_intctl_mem_write, s); 367 cpu_register_physical_memory(addr + i * TARGET_PAGE_SIZE, INTCTL_SIZE, 368 slavio_intctl_io_memory); 369 s->cpu_irqs[i] = parent_irq[i]; 370 } 371 372 slavio_intctlm_io_memory = cpu_register_io_memory(0, slavio_intctlm_mem_read, slavio_intctlm_mem_write, s); 373 cpu_register_physical_memory(addrg, INTCTLM_SIZE, slavio_intctlm_io_memory); 374 375 register_savevm("slavio_intctl", addr, 1, slavio_intctl_save, slavio_intctl_load, s); 376 qemu_register_reset(slavio_intctl_reset, s); 377 *irq = qemu_allocate_irqs(slavio_set_irq, s, 32); 378 379 *cpu_irq = qemu_allocate_irqs(slavio_set_timer_irq_cpu, s, MAX_CPUS); 380 s->cputimer_bit = 1 << s->intbit_to_level[cputimer]; 381 slavio_intctl_reset(s); 382 return s; 383 } 384 385