Commit d7edfd27021b36c5ca065293e13639e139ddd5da
1 parent
70c0de96
Use qemu_irq between interrupt controller and timers
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2874 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
39 additions
and
41 deletions
hw/slavio_intctl.c
| @@ -55,6 +55,7 @@ typedef struct SLAVIO_INTCTLState { | @@ -55,6 +55,7 @@ typedef struct SLAVIO_INTCTLState { | ||
| 55 | #endif | 55 | #endif |
| 56 | CPUState *cpu_envs[MAX_CPUS]; | 56 | CPUState *cpu_envs[MAX_CPUS]; |
| 57 | const uint32_t *intbit_to_level; | 57 | const uint32_t *intbit_to_level; |
| 58 | + uint32_t cputimer_bit; | ||
| 58 | } SLAVIO_INTCTLState; | 59 | } SLAVIO_INTCTLState; |
| 59 | 60 | ||
| 60 | #define INTCTL_MAXADDR 0xf | 61 | #define INTCTL_MAXADDR 0xf |
| @@ -280,7 +281,7 @@ static void slavio_check_interrupts(void *opaque) | @@ -280,7 +281,7 @@ static void slavio_check_interrupts(void *opaque) | ||
| 280 | * "irq" here is the bit number in the system interrupt register to | 281 | * "irq" here is the bit number in the system interrupt register to |
| 281 | * separate serial and keyboard interrupts sharing a level. | 282 | * separate serial and keyboard interrupts sharing a level. |
| 282 | */ | 283 | */ |
| 283 | -void slavio_set_irq(void *opaque, int irq, int level) | 284 | +static void slavio_set_irq(void *opaque, int irq, int level) |
| 284 | { | 285 | { |
| 285 | SLAVIO_INTCTLState *s = opaque; | 286 | SLAVIO_INTCTLState *s = opaque; |
| 286 | 287 | ||
| @@ -302,26 +303,20 @@ void slavio_set_irq(void *opaque, int irq, int level) | @@ -302,26 +303,20 @@ void slavio_set_irq(void *opaque, int irq, int level) | ||
| 302 | } | 303 | } |
| 303 | } | 304 | } |
| 304 | 305 | ||
| 305 | -void pic_set_irq_cpu(void *opaque, int irq, int level, unsigned int cpu) | 306 | +static void slavio_set_timer_irq_cpu(void *opaque, int cpu, int level) |
| 306 | { | 307 | { |
| 307 | SLAVIO_INTCTLState *s = opaque; | 308 | SLAVIO_INTCTLState *s = opaque; |
| 308 | 309 | ||
| 309 | - DPRINTF("Set cpu %d local irq %d level %d\n", cpu, irq, level); | ||
| 310 | - if (cpu == (unsigned int)-1) { | ||
| 311 | - slavio_set_irq(opaque, irq, level); | 310 | + DPRINTF("Set cpu %d local level %d\n", cpu, level); |
| 311 | + if (!s->cpu_envs[cpu]) | ||
| 312 | return; | 312 | return; |
| 313 | + | ||
| 314 | + if (level) { | ||
| 315 | + s->intreg_pending[cpu] |= s->cputimer_bit; | ||
| 316 | + } else { | ||
| 317 | + s->intreg_pending[cpu] &= ~s->cputimer_bit; | ||
| 313 | } | 318 | } |
| 314 | - if (irq < 32) { | ||
| 315 | - uint32_t pil = s->intbit_to_level[irq]; | ||
| 316 | - if (pil > 0) { | ||
| 317 | - if (level) { | ||
| 318 | - s->intreg_pending[cpu] |= 1 << pil; | ||
| 319 | - } | ||
| 320 | - else { | ||
| 321 | - s->intreg_pending[cpu] &= ~(1 << pil); | ||
| 322 | - } | ||
| 323 | - } | ||
| 324 | - } | 319 | + |
| 325 | slavio_check_interrupts(s); | 320 | slavio_check_interrupts(s); |
| 326 | } | 321 | } |
| 327 | 322 | ||
| @@ -371,12 +366,15 @@ static void slavio_intctl_reset(void *opaque) | @@ -371,12 +366,15 @@ static void slavio_intctl_reset(void *opaque) | ||
| 371 | void slavio_intctl_set_cpu(void *opaque, unsigned int cpu, CPUState *env) | 366 | void slavio_intctl_set_cpu(void *opaque, unsigned int cpu, CPUState *env) |
| 372 | { | 367 | { |
| 373 | SLAVIO_INTCTLState *s = opaque; | 368 | SLAVIO_INTCTLState *s = opaque; |
| 369 | + | ||
| 374 | s->cpu_envs[cpu] = env; | 370 | s->cpu_envs[cpu] = env; |
| 375 | } | 371 | } |
| 376 | 372 | ||
| 377 | void *slavio_intctl_init(target_phys_addr_t addr, target_phys_addr_t addrg, | 373 | void *slavio_intctl_init(target_phys_addr_t addr, target_phys_addr_t addrg, |
| 378 | const uint32_t *intbit_to_level, | 374 | const uint32_t *intbit_to_level, |
| 379 | - qemu_irq **irq) | 375 | + qemu_irq **irq, qemu_irq **cpu_irq, |
| 376 | + unsigned int cputimer) | ||
| 377 | + | ||
| 380 | { | 378 | { |
| 381 | int slavio_intctl_io_memory, slavio_intctlm_io_memory, i; | 379 | int slavio_intctl_io_memory, slavio_intctlm_io_memory, i; |
| 382 | SLAVIO_INTCTLState *s; | 380 | SLAVIO_INTCTLState *s; |
| @@ -398,6 +396,9 @@ void *slavio_intctl_init(target_phys_addr_t addr, target_phys_addr_t addrg, | @@ -398,6 +396,9 @@ void *slavio_intctl_init(target_phys_addr_t addr, target_phys_addr_t addrg, | ||
| 398 | register_savevm("slavio_intctl", addr, 1, slavio_intctl_save, slavio_intctl_load, s); | 396 | register_savevm("slavio_intctl", addr, 1, slavio_intctl_save, slavio_intctl_load, s); |
| 399 | qemu_register_reset(slavio_intctl_reset, s); | 397 | qemu_register_reset(slavio_intctl_reset, s); |
| 400 | *irq = qemu_allocate_irqs(slavio_set_irq, s, 32); | 398 | *irq = qemu_allocate_irqs(slavio_set_irq, s, 32); |
| 399 | + | ||
| 400 | + *cpu_irq = qemu_allocate_irqs(slavio_set_timer_irq_cpu, s, MAX_CPUS); | ||
| 401 | + s->cputimer_bit = 1 << s->intbit_to_level[cputimer]; | ||
| 401 | slavio_intctl_reset(s); | 402 | slavio_intctl_reset(s); |
| 402 | return s; | 403 | return s; |
| 403 | } | 404 | } |
hw/slavio_timer.c
| @@ -48,14 +48,12 @@ do { printf("TIMER: " fmt , ##args); } while (0) | @@ -48,14 +48,12 @@ do { printf("TIMER: " fmt , ##args); } while (0) | ||
| 48 | */ | 48 | */ |
| 49 | 49 | ||
| 50 | typedef struct SLAVIO_TIMERState { | 50 | typedef struct SLAVIO_TIMERState { |
| 51 | + qemu_irq irq; | ||
| 51 | ptimer_state *timer; | 52 | ptimer_state *timer; |
| 52 | uint32_t count, counthigh, reached; | 53 | uint32_t count, counthigh, reached; |
| 53 | uint64_t limit; | 54 | uint64_t limit; |
| 54 | - int irq; | ||
| 55 | int stopped; | 55 | int stopped; |
| 56 | int mode; // 0 = processor, 1 = user, 2 = system | 56 | int mode; // 0 = processor, 1 = user, 2 = system |
| 57 | - unsigned int cpu; | ||
| 58 | - void *intctl; | ||
| 59 | } SLAVIO_TIMERState; | 57 | } SLAVIO_TIMERState; |
| 60 | 58 | ||
| 61 | #define TIMER_MAXADDR 0x1f | 59 | #define TIMER_MAXADDR 0x1f |
| @@ -83,7 +81,7 @@ static void slavio_timer_irq(void *opaque) | @@ -83,7 +81,7 @@ static void slavio_timer_irq(void *opaque) | ||
| 83 | DPRINTF("callback: count %x%08x\n", s->counthigh, s->count); | 81 | DPRINTF("callback: count %x%08x\n", s->counthigh, s->count); |
| 84 | s->reached = 0x80000000; | 82 | s->reached = 0x80000000; |
| 85 | if (s->mode != 1) | 83 | if (s->mode != 1) |
| 86 | - pic_set_irq_cpu(s->intctl, s->irq, 1, s->cpu); | 84 | + qemu_irq_raise(s->irq); |
| 87 | } | 85 | } |
| 88 | 86 | ||
| 89 | static uint32_t slavio_timer_mem_readl(void *opaque, target_phys_addr_t addr) | 87 | static uint32_t slavio_timer_mem_readl(void *opaque, target_phys_addr_t addr) |
| @@ -98,7 +96,7 @@ static uint32_t slavio_timer_mem_readl(void *opaque, target_phys_addr_t addr) | @@ -98,7 +96,7 @@ static uint32_t slavio_timer_mem_readl(void *opaque, target_phys_addr_t addr) | ||
| 98 | // part of counter (user mode) | 96 | // part of counter (user mode) |
| 99 | if (s->mode != 1) { | 97 | if (s->mode != 1) { |
| 100 | // clear irq | 98 | // clear irq |
| 101 | - pic_set_irq_cpu(s->intctl, s->irq, 0, s->cpu); | 99 | + qemu_irq_lower(s->irq); |
| 102 | s->reached = 0; | 100 | s->reached = 0; |
| 103 | ret = s->limit & 0x7fffffff; | 101 | ret = s->limit & 0x7fffffff; |
| 104 | } | 102 | } |
| @@ -145,7 +143,7 @@ static void slavio_timer_mem_writel(void *opaque, target_phys_addr_t addr, uint3 | @@ -145,7 +143,7 @@ static void slavio_timer_mem_writel(void *opaque, target_phys_addr_t addr, uint3 | ||
| 145 | case 0: | 143 | case 0: |
| 146 | // set limit, reset counter | 144 | // set limit, reset counter |
| 147 | reload = 1; | 145 | reload = 1; |
| 148 | - pic_set_irq_cpu(s->intctl, s->irq, 0, s->cpu); | 146 | + qemu_irq_lower(s->irq); |
| 149 | // fall through | 147 | // fall through |
| 150 | case 2: | 148 | case 2: |
| 151 | // set limit without resetting counter | 149 | // set limit without resetting counter |
| @@ -172,7 +170,7 @@ static void slavio_timer_mem_writel(void *opaque, target_phys_addr_t addr, uint3 | @@ -172,7 +170,7 @@ static void slavio_timer_mem_writel(void *opaque, target_phys_addr_t addr, uint3 | ||
| 172 | if (s->mode == 0 || s->mode == 1) | 170 | if (s->mode == 0 || s->mode == 1) |
| 173 | s->mode = val & 1; | 171 | s->mode = val & 1; |
| 174 | if (s->mode == 1) { | 172 | if (s->mode == 1) { |
| 175 | - pic_set_irq_cpu(s->intctl, s->irq, 0, s->cpu); | 173 | + qemu_irq_lower(s->irq); |
| 176 | s->limit = -1ULL; | 174 | s->limit = -1ULL; |
| 177 | } | 175 | } |
| 178 | ptimer_set_limit(s->timer, s->limit >> 9, 1); | 176 | ptimer_set_limit(s->timer, s->limit >> 9, 1); |
| @@ -201,7 +199,7 @@ static void slavio_timer_save(QEMUFile *f, void *opaque) | @@ -201,7 +199,7 @@ static void slavio_timer_save(QEMUFile *f, void *opaque) | ||
| 201 | qemu_put_be64s(f, &s->limit); | 199 | qemu_put_be64s(f, &s->limit); |
| 202 | qemu_put_be32s(f, &s->count); | 200 | qemu_put_be32s(f, &s->count); |
| 203 | qemu_put_be32s(f, &s->counthigh); | 201 | qemu_put_be32s(f, &s->counthigh); |
| 204 | - qemu_put_be32s(f, &s->irq); | 202 | + qemu_put_be32(f, 0); // Was irq |
| 205 | qemu_put_be32s(f, &s->reached); | 203 | qemu_put_be32s(f, &s->reached); |
| 206 | qemu_put_be32s(f, &s->stopped); | 204 | qemu_put_be32s(f, &s->stopped); |
| 207 | qemu_put_be32s(f, &s->mode); | 205 | qemu_put_be32s(f, &s->mode); |
| @@ -211,6 +209,7 @@ static void slavio_timer_save(QEMUFile *f, void *opaque) | @@ -211,6 +209,7 @@ static void slavio_timer_save(QEMUFile *f, void *opaque) | ||
| 211 | static int slavio_timer_load(QEMUFile *f, void *opaque, int version_id) | 209 | static int slavio_timer_load(QEMUFile *f, void *opaque, int version_id) |
| 212 | { | 210 | { |
| 213 | SLAVIO_TIMERState *s = opaque; | 211 | SLAVIO_TIMERState *s = opaque; |
| 212 | + uint32_t tmp; | ||
| 214 | 213 | ||
| 215 | if (version_id != 2) | 214 | if (version_id != 2) |
| 216 | return -EINVAL; | 215 | return -EINVAL; |
| @@ -218,7 +217,7 @@ static int slavio_timer_load(QEMUFile *f, void *opaque, int version_id) | @@ -218,7 +217,7 @@ static int slavio_timer_load(QEMUFile *f, void *opaque, int version_id) | ||
| 218 | qemu_get_be64s(f, &s->limit); | 217 | qemu_get_be64s(f, &s->limit); |
| 219 | qemu_get_be32s(f, &s->count); | 218 | qemu_get_be32s(f, &s->count); |
| 220 | qemu_get_be32s(f, &s->counthigh); | 219 | qemu_get_be32s(f, &s->counthigh); |
| 221 | - qemu_get_be32s(f, &s->irq); | 220 | + qemu_get_be32s(f, &tmp); // Was irq |
| 222 | qemu_get_be32s(f, &s->reached); | 221 | qemu_get_be32s(f, &s->reached); |
| 223 | qemu_get_be32s(f, &s->stopped); | 222 | qemu_get_be32s(f, &s->stopped); |
| 224 | qemu_get_be32s(f, &s->mode); | 223 | qemu_get_be32s(f, &s->mode); |
| @@ -238,11 +237,10 @@ static void slavio_timer_reset(void *opaque) | @@ -238,11 +237,10 @@ static void slavio_timer_reset(void *opaque) | ||
| 238 | ptimer_set_limit(s->timer, s->limit >> 9, 1); | 237 | ptimer_set_limit(s->timer, s->limit >> 9, 1); |
| 239 | ptimer_run(s->timer, 0); | 238 | ptimer_run(s->timer, 0); |
| 240 | s->stopped = 1; | 239 | s->stopped = 1; |
| 241 | - slavio_timer_irq(s); | 240 | + qemu_irq_lower(s->irq); |
| 242 | } | 241 | } |
| 243 | 242 | ||
| 244 | -void slavio_timer_init(target_phys_addr_t addr, int irq, int mode, | ||
| 245 | - unsigned int cpu, void *intctl) | 243 | +void slavio_timer_init(target_phys_addr_t addr, qemu_irq irq, int mode) |
| 246 | { | 244 | { |
| 247 | int slavio_timer_io_memory; | 245 | int slavio_timer_io_memory; |
| 248 | SLAVIO_TIMERState *s; | 246 | SLAVIO_TIMERState *s; |
| @@ -253,11 +251,9 @@ void slavio_timer_init(target_phys_addr_t addr, int irq, int mode, | @@ -253,11 +251,9 @@ void slavio_timer_init(target_phys_addr_t addr, int irq, int mode, | ||
| 253 | return; | 251 | return; |
| 254 | s->irq = irq; | 252 | s->irq = irq; |
| 255 | s->mode = mode; | 253 | s->mode = mode; |
| 256 | - s->cpu = cpu; | ||
| 257 | bh = qemu_bh_new(slavio_timer_irq, s); | 254 | bh = qemu_bh_new(slavio_timer_irq, s); |
| 258 | s->timer = ptimer_init(bh); | 255 | s->timer = ptimer_init(bh); |
| 259 | ptimer_set_period(s->timer, 500ULL); | 256 | ptimer_set_period(s->timer, 500ULL); |
| 260 | - s->intctl = intctl; | ||
| 261 | 257 | ||
| 262 | slavio_timer_io_memory = cpu_register_io_memory(0, slavio_timer_mem_read, | 258 | slavio_timer_io_memory = cpu_register_io_memory(0, slavio_timer_mem_read, |
| 263 | slavio_timer_mem_write, s); | 259 | slavio_timer_mem_write, s); |
hw/sun4m.c
| @@ -56,7 +56,7 @@ struct hwdef { | @@ -56,7 +56,7 @@ struct hwdef { | ||
| 56 | long vram_size, nvram_size; | 56 | long vram_size, nvram_size; |
| 57 | // IRQ numbers are not PIL ones, but master interrupt controller register | 57 | // IRQ numbers are not PIL ones, but master interrupt controller register |
| 58 | // bit numbers | 58 | // bit numbers |
| 59 | - int intctl_g_intr, esp_irq, le_irq, cpu_irq, clock_irq, clock1_irq; | 59 | + int intctl_g_intr, esp_irq, le_irq, clock_irq, clock1_irq; |
| 60 | int ser_irq, ms_kb_irq, fd_irq, me_irq, cs_irq; | 60 | int ser_irq, ms_kb_irq, fd_irq, me_irq, cs_irq; |
| 61 | int machine_id; // For NVRAM | 61 | int machine_id; // For NVRAM |
| 62 | uint32_t intbit_to_level[32]; | 62 | uint32_t intbit_to_level[32]; |
| @@ -264,7 +264,8 @@ static void sun4m_hw_init(const struct hwdef *hwdef, int ram_size, | @@ -264,7 +264,8 @@ static void sun4m_hw_init(const struct hwdef *hwdef, int ram_size, | ||
| 264 | unsigned int i; | 264 | unsigned int i; |
| 265 | void *iommu, *espdma, *ledma, *main_esp; | 265 | void *iommu, *espdma, *ledma, *main_esp; |
| 266 | const sparc_def_t *def; | 266 | const sparc_def_t *def; |
| 267 | - qemu_irq *slavio_irq, *espdma_irq, *ledma_irq; | 267 | + qemu_irq *slavio_irq, *slavio_cpu_irq, |
| 268 | + *espdma_irq, *ledma_irq; | ||
| 268 | 269 | ||
| 269 | /* init CPUs */ | 270 | /* init CPUs */ |
| 270 | sparc_find_by_name(cpu_model, &def); | 271 | sparc_find_by_name(cpu_model, &def); |
| @@ -291,7 +292,8 @@ static void sun4m_hw_init(const struct hwdef *hwdef, int ram_size, | @@ -291,7 +292,8 @@ static void sun4m_hw_init(const struct hwdef *hwdef, int ram_size, | ||
| 291 | slavio_intctl = slavio_intctl_init(hwdef->intctl_base, | 292 | slavio_intctl = slavio_intctl_init(hwdef->intctl_base, |
| 292 | hwdef->intctl_base + 0x10000ULL, | 293 | hwdef->intctl_base + 0x10000ULL, |
| 293 | &hwdef->intbit_to_level[0], | 294 | &hwdef->intbit_to_level[0], |
| 294 | - &slavio_irq); | 295 | + &slavio_irq, &slavio_cpu_irq, |
| 296 | + hwdef->clock_irq); | ||
| 295 | for(i = 0; i < smp_cpus; i++) { | 297 | for(i = 0; i < smp_cpus; i++) { |
| 296 | slavio_intctl_set_cpu(slavio_intctl, i, envs[i]); | 298 | slavio_intctl_set_cpu(slavio_intctl, i, envs[i]); |
| 297 | } | 299 | } |
| @@ -320,10 +322,10 @@ static void sun4m_hw_init(const struct hwdef *hwdef, int ram_size, | @@ -320,10 +322,10 @@ static void sun4m_hw_init(const struct hwdef *hwdef, int ram_size, | ||
| 320 | for (i = 0; i < MAX_CPUS; i++) { | 322 | for (i = 0; i < MAX_CPUS; i++) { |
| 321 | slavio_timer_init(hwdef->counter_base + | 323 | slavio_timer_init(hwdef->counter_base + |
| 322 | (target_phys_addr_t)(i * TARGET_PAGE_SIZE), | 324 | (target_phys_addr_t)(i * TARGET_PAGE_SIZE), |
| 323 | - hwdef->clock_irq, 0, i, slavio_intctl); | 325 | + slavio_cpu_irq[i], 0); |
| 324 | } | 326 | } |
| 325 | - slavio_timer_init(hwdef->counter_base + 0x10000ULL, hwdef->clock1_irq, 2, | ||
| 326 | - (unsigned int)-1, slavio_intctl); | 327 | + slavio_timer_init(hwdef->counter_base + 0x10000ULL, |
| 328 | + slavio_irq[hwdef->clock1_irq], 2); | ||
| 327 | slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[hwdef->ms_kb_irq]); | 329 | slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[hwdef->ms_kb_irq]); |
| 328 | // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device | 330 | // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device |
| 329 | // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device | 331 | // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device |
vl.h
| @@ -1230,10 +1230,10 @@ void tcx_init(DisplayState *ds, target_phys_addr_t addr, uint8_t *vram_base, | @@ -1230,10 +1230,10 @@ void tcx_init(DisplayState *ds, target_phys_addr_t addr, uint8_t *vram_base, | ||
| 1230 | int depth); | 1230 | int depth); |
| 1231 | 1231 | ||
| 1232 | /* slavio_intctl.c */ | 1232 | /* slavio_intctl.c */ |
| 1233 | -void pic_set_irq_cpu(void *opaque, int irq, int level, unsigned int cpu); | ||
| 1234 | void *slavio_intctl_init(target_phys_addr_t addr, target_phys_addr_t addrg, | 1233 | void *slavio_intctl_init(target_phys_addr_t addr, target_phys_addr_t addrg, |
| 1235 | const uint32_t *intbit_to_level, | 1234 | const uint32_t *intbit_to_level, |
| 1236 | - qemu_irq **irq); | 1235 | + qemu_irq **irq, qemu_irq **cpu_irq, |
| 1236 | + unsigned int cputimer); | ||
| 1237 | void slavio_intctl_set_cpu(void *opaque, unsigned int cpu, CPUState *env); | 1237 | void slavio_intctl_set_cpu(void *opaque, unsigned int cpu, CPUState *env); |
| 1238 | void slavio_pic_info(void *opaque); | 1238 | void slavio_pic_info(void *opaque); |
| 1239 | void slavio_irq_info(void *opaque); | 1239 | void slavio_irq_info(void *opaque); |
| @@ -1247,8 +1247,7 @@ int load_aout(const char *filename, uint8_t *addr); | @@ -1247,8 +1247,7 @@ int load_aout(const char *filename, uint8_t *addr); | ||
| 1247 | int load_uboot(const char *filename, target_ulong *ep, int *is_linux); | 1247 | int load_uboot(const char *filename, target_ulong *ep, int *is_linux); |
| 1248 | 1248 | ||
| 1249 | /* slavio_timer.c */ | 1249 | /* slavio_timer.c */ |
| 1250 | -void slavio_timer_init(target_phys_addr_t addr, int irq, int mode, | ||
| 1251 | - unsigned int cpu, void *intctl); | 1250 | +void slavio_timer_init(target_phys_addr_t addr, qemu_irq irq, int mode); |
| 1252 | 1251 | ||
| 1253 | /* slavio_serial.c */ | 1252 | /* slavio_serial.c */ |
| 1254 | SerialState *slavio_serial_init(target_phys_addr_t base, qemu_irq irq, | 1253 | SerialState *slavio_serial_init(target_phys_addr_t base, qemu_irq irq, |