Revision 098d314a
b/hw/i8259.c | ||
---|---|---|
59 | 59 |
uint8_t elcr; /* PIIX edge/trigger selection*/ |
60 | 60 |
uint8_t elcr_mask; |
61 | 61 |
PicState2 *pics_state; |
62 |
MemoryRegion base_io; |
|
63 |
MemoryRegion elcr_io; |
|
62 | 64 |
} PicState; |
63 | 65 |
|
64 | 66 |
struct PicState2 { |
... | ... | |
284 | 286 |
/* Note: ELCR is not reset */ |
285 | 287 |
} |
286 | 288 |
|
287 |
static void pic_ioport_write(void *opaque, uint32_t addr, uint32_t val) |
|
289 |
static void pic_ioport_write(void *opaque, target_phys_addr_t addr64, |
|
290 |
uint64_t val64, unsigned size) |
|
288 | 291 |
{ |
289 | 292 |
PicState *s = opaque; |
293 |
uint32_t addr = addr64; |
|
294 |
uint32_t val = val64; |
|
290 | 295 |
int priority, cmd, irq; |
291 | 296 |
|
292 | 297 |
DPRINTF("write: addr=0x%02x val=0x%02x\n", addr, val); |
293 |
addr &= 1; |
|
294 | 298 |
if (addr == 0) { |
295 | 299 |
if (val & 0x10) { |
296 | 300 |
/* init */ |
... | ... | |
374 | 378 |
} |
375 | 379 |
} |
376 | 380 |
|
377 |
static uint32_t pic_poll_read (PicState *s, uint32_t addr1)
|
|
381 |
static uint32_t pic_poll_read(PicState *s)
|
|
378 | 382 |
{ |
379 | 383 |
int ret; |
380 | 384 |
|
381 | 385 |
ret = pic_get_irq(s); |
382 | 386 |
if (ret >= 0) { |
383 |
if (addr1 >> 7) { |
|
387 |
bool slave = (s == &isa_pic->pics[1]); |
|
388 |
|
|
389 |
if (slave) { |
|
384 | 390 |
s->pics_state->pics[0].isr &= ~(1 << 2); |
385 | 391 |
s->pics_state->pics[0].irr &= ~(1 << 2); |
386 | 392 |
} |
387 | 393 |
s->irr &= ~(1 << ret); |
388 | 394 |
s->isr &= ~(1 << ret); |
389 |
if (addr1 >> 7 || ret != 2)
|
|
395 |
if (slave || ret != 2)
|
|
390 | 396 |
pic_update_irq(s->pics_state); |
391 | 397 |
} else { |
392 | 398 |
ret = 0x07; |
... | ... | |
396 | 402 |
return ret; |
397 | 403 |
} |
398 | 404 |
|
399 |
static uint32_t pic_ioport_read(void *opaque, uint32_t addr1) |
|
405 |
static uint64_t pic_ioport_read(void *opaque, target_phys_addr_t addr1, |
|
406 |
unsigned size) |
|
400 | 407 |
{ |
401 | 408 |
PicState *s = opaque; |
402 |
unsigned int addr; |
|
409 |
unsigned int addr = addr1;
|
|
403 | 410 |
int ret; |
404 | 411 |
|
405 |
addr = addr1; |
|
406 |
addr &= 1; |
|
407 | 412 |
if (s->poll) { |
408 |
ret = pic_poll_read(s, addr1);
|
|
413 |
ret = pic_poll_read(s); |
|
409 | 414 |
s->poll = 0; |
410 | 415 |
} else { |
411 | 416 |
if (addr == 0) { |
... | ... | |
417 | 422 |
ret = s->imr; |
418 | 423 |
} |
419 | 424 |
} |
420 |
DPRINTF("read: addr=0x%02x val=0x%02x\n", addr1, ret);
|
|
425 |
DPRINTF("read: addr=0x%02x val=0x%02x\n", addr, ret); |
|
421 | 426 |
return ret; |
422 | 427 |
} |
423 | 428 |
|
... | ... | |
427 | 432 |
{ |
428 | 433 |
int ret; |
429 | 434 |
|
430 |
ret = pic_poll_read(&s->pics[0], 0x00);
|
|
435 |
ret = pic_poll_read(&s->pics[0]); |
|
431 | 436 |
if (ret == 2) |
432 |
ret = pic_poll_read(&s->pics[1], 0x80) + 8;
|
|
437 |
ret = pic_poll_read(&s->pics[1]) + 8; |
|
433 | 438 |
/* Prepare for ISR read */ |
434 | 439 |
s->pics[0].read_reg_select = 1; |
435 | 440 |
|
436 | 441 |
return ret; |
437 | 442 |
} |
438 | 443 |
|
439 |
static void elcr_ioport_write(void *opaque, uint32_t addr, uint32_t val) |
|
444 |
static void elcr_ioport_write(void *opaque, target_phys_addr_t addr, |
|
445 |
uint64_t val, unsigned size) |
|
440 | 446 |
{ |
441 | 447 |
PicState *s = opaque; |
442 | 448 |
s->elcr = val & s->elcr_mask; |
443 | 449 |
} |
444 | 450 |
|
445 |
static uint32_t elcr_ioport_read(void *opaque, uint32_t addr1) |
|
451 |
static uint64_t elcr_ioport_read(void *opaque, target_phys_addr_t addr, |
|
452 |
unsigned size) |
|
446 | 453 |
{ |
447 | 454 |
PicState *s = opaque; |
448 | 455 |
return s->elcr; |
... | ... | |
474 | 481 |
} |
475 | 482 |
}; |
476 | 483 |
|
484 |
static const MemoryRegionOps pic_base_ioport_ops = { |
|
485 |
.read = pic_ioport_read, |
|
486 |
.write = pic_ioport_write, |
|
487 |
.impl = { |
|
488 |
.min_access_size = 1, |
|
489 |
.max_access_size = 1, |
|
490 |
}, |
|
491 |
}; |
|
492 |
|
|
493 |
static const MemoryRegionOps pic_elcr_ioport_ops = { |
|
494 |
.read = elcr_ioport_read, |
|
495 |
.write = elcr_ioport_write, |
|
496 |
.impl = { |
|
497 |
.min_access_size = 1, |
|
498 |
.max_access_size = 1, |
|
499 |
}, |
|
500 |
}; |
|
501 |
|
|
477 | 502 |
/* XXX: add generic master/slave system */ |
478 | 503 |
static void pic_init1(int io_addr, int elcr_addr, PicState *s) |
479 | 504 |
{ |
480 |
register_ioport_write(io_addr, 2, 1, pic_ioport_write, s); |
|
481 |
register_ioport_read(io_addr, 2, 1, pic_ioport_read, s); |
|
505 |
memory_region_init_io(&s->base_io, &pic_base_ioport_ops, s, "pic", 2); |
|
506 |
memory_region_init_io(&s->elcr_io, &pic_elcr_ioport_ops, s, "elcr", 1); |
|
507 |
|
|
508 |
isa_register_ioport(NULL, &s->base_io, io_addr); |
|
482 | 509 |
if (elcr_addr >= 0) { |
483 |
register_ioport_write(elcr_addr, 1, 1, elcr_ioport_write, s); |
|
484 |
register_ioport_read(elcr_addr, 1, 1, elcr_ioport_read, s); |
|
510 |
isa_register_ioport(NULL, &s->elcr_io, elcr_addr); |
|
485 | 511 |
} |
512 |
|
|
486 | 513 |
vmstate_register(NULL, io_addr, &vmstate_pic, s); |
487 | 514 |
qemu_register_reset(pic_reset, s); |
488 | 515 |
} |
Also available in: Unified diff