Commit 660de33686226402a064e3fbab9cc6dfed06b087
1 parent
69135b5c
PIIX ELCR register support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@820 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
48 additions
and
11 deletions
hw/i8259.c
| ... | ... | @@ -43,6 +43,8 @@ typedef struct PicState { |
| 43 | 43 | uint8_t rotate_on_auto_eoi; |
| 44 | 44 | uint8_t special_fully_nested_mode; |
| 45 | 45 | uint8_t init4; /* true if 4 byte init */ |
| 46 | + uint8_t elcr; /* PIIX edge/trigger selection*/ | |
| 47 | + uint8_t elcr_mask; | |
| 46 | 48 | } PicState; |
| 47 | 49 | |
| 48 | 50 | /* 0 is master pic, 1 is slave pic */ |
| ... | ... | @@ -54,12 +56,24 @@ static inline void pic_set_irq1(PicState *s, int irq, int level) |
| 54 | 56 | { |
| 55 | 57 | int mask; |
| 56 | 58 | mask = 1 << irq; |
| 57 | - if (level) { | |
| 58 | - if ((s->last_irr & mask) == 0) | |
| 59 | + if (s->elcr & mask) { | |
| 60 | + /* level triggered */ | |
| 61 | + if (level) { | |
| 59 | 62 | s->irr |= mask; |
| 60 | - s->last_irr |= mask; | |
| 63 | + s->last_irr |= mask; | |
| 64 | + } else { | |
| 65 | + s->irr &= ~mask; | |
| 66 | + s->last_irr &= ~mask; | |
| 67 | + } | |
| 61 | 68 | } else { |
| 62 | - s->last_irr &= ~mask; | |
| 69 | + /* edge triggered */ | |
| 70 | + if (level) { | |
| 71 | + if ((s->last_irr & mask) == 0) | |
| 72 | + s->irr |= mask; | |
| 73 | + s->last_irr |= mask; | |
| 74 | + } else { | |
| 75 | + s->last_irr &= ~mask; | |
| 76 | + } | |
| 63 | 77 | } |
| 64 | 78 | } |
| 65 | 79 | |
| ... | ... | @@ -205,7 +219,7 @@ int cpu_get_pic_interrupt(CPUState *env) |
| 205 | 219 | static void pic_ioport_write(void *opaque, uint32_t addr, uint32_t val) |
| 206 | 220 | { |
| 207 | 221 | PicState *s = opaque; |
| 208 | - int priority, cmd, irq; | |
| 222 | + int priority, cmd, irq, tmp; | |
| 209 | 223 | |
| 210 | 224 | #ifdef DEBUG_PIC |
| 211 | 225 | printf("pic_write: addr=0x%02x val=0x%02x\n", addr, val); |
| ... | ... | @@ -214,7 +228,10 @@ static void pic_ioport_write(void *opaque, uint32_t addr, uint32_t val) |
| 214 | 228 | if (addr == 0) { |
| 215 | 229 | if (val & 0x10) { |
| 216 | 230 | /* init */ |
| 231 | + tmp = s->elcr_mask; | |
| 217 | 232 | memset(s, 0, sizeof(PicState)); |
| 233 | + s->elcr_mask = tmp; | |
| 234 | + | |
| 218 | 235 | s->init_state = 1; |
| 219 | 236 | s->init4 = val & 1; |
| 220 | 237 | if (val & 0x02) |
| ... | ... | @@ -356,6 +373,18 @@ uint32_t pic_intack_read(CPUState *env) |
| 356 | 373 | return ret; |
| 357 | 374 | } |
| 358 | 375 | |
| 376 | +static void elcr_ioport_write(void *opaque, uint32_t addr, uint32_t val) | |
| 377 | +{ | |
| 378 | + PicState *s = opaque; | |
| 379 | + s->elcr = val & s->elcr_mask; | |
| 380 | +} | |
| 381 | + | |
| 382 | +static uint32_t elcr_ioport_read(void *opaque, uint32_t addr1) | |
| 383 | +{ | |
| 384 | + PicState *s = opaque; | |
| 385 | + return s->elcr; | |
| 386 | +} | |
| 387 | + | |
| 359 | 388 | static void pic_save(QEMUFile *f, void *opaque) |
| 360 | 389 | { |
| 361 | 390 | PicState *s = opaque; |
| ... | ... | @@ -374,6 +403,7 @@ static void pic_save(QEMUFile *f, void *opaque) |
| 374 | 403 | qemu_put_8s(f, &s->rotate_on_auto_eoi); |
| 375 | 404 | qemu_put_8s(f, &s->special_fully_nested_mode); |
| 376 | 405 | qemu_put_8s(f, &s->init4); |
| 406 | + qemu_put_8s(f, &s->elcr); | |
| 377 | 407 | } |
| 378 | 408 | |
| 379 | 409 | static int pic_load(QEMUFile *f, void *opaque, int version_id) |
| ... | ... | @@ -397,15 +427,19 @@ static int pic_load(QEMUFile *f, void *opaque, int version_id) |
| 397 | 427 | qemu_get_8s(f, &s->rotate_on_auto_eoi); |
| 398 | 428 | qemu_get_8s(f, &s->special_fully_nested_mode); |
| 399 | 429 | qemu_get_8s(f, &s->init4); |
| 430 | + qemu_get_8s(f, &s->elcr); | |
| 400 | 431 | return 0; |
| 401 | 432 | } |
| 402 | 433 | |
| 403 | 434 | /* XXX: add generic master/slave system */ |
| 404 | -static void pic_init1(int io_addr, PicState *s) | |
| 435 | +static void pic_init1(int io_addr, int elcr_addr, PicState *s) | |
| 405 | 436 | { |
| 406 | 437 | register_ioport_write(io_addr, 2, 1, pic_ioport_write, s); |
| 407 | 438 | register_ioport_read(io_addr, 2, 1, pic_ioport_read, s); |
| 408 | - | |
| 439 | + if (elcr_addr >= 0) { | |
| 440 | + register_ioport_write(elcr_addr, 1, 1, elcr_ioport_write, s); | |
| 441 | + register_ioport_read(elcr_addr, 1, 1, elcr_ioport_read, s); | |
| 442 | + } | |
| 409 | 443 | register_savevm("i8259", io_addr, 1, pic_save, pic_load, s); |
| 410 | 444 | } |
| 411 | 445 | |
| ... | ... | @@ -416,15 +450,18 @@ void pic_info(void) |
| 416 | 450 | |
| 417 | 451 | for(i=0;i<2;i++) { |
| 418 | 452 | s = &pics[i]; |
| 419 | - term_printf("pic%d: irr=%02x imr=%02x isr=%02x hprio=%d irq_base=%02x rr_sel=%d\n", | |
| 420 | - i, s->irr, s->imr, s->isr, s->priority_add, s->irq_base, s->read_reg_select); | |
| 453 | + term_printf("pic%d: irr=%02x imr=%02x isr=%02x hprio=%d irq_base=%02x rr_sel=%d elcr=%02x\n", | |
| 454 | + i, s->irr, s->imr, s->isr, s->priority_add, | |
| 455 | + s->irq_base, s->read_reg_select, s->elcr); | |
| 421 | 456 | } |
| 422 | 457 | } |
| 423 | 458 | |
| 424 | 459 | |
| 425 | 460 | void pic_init(void) |
| 426 | 461 | { |
| 427 | - pic_init1(0x20, &pics[0]); | |
| 428 | - pic_init1(0xa0, &pics[1]); | |
| 462 | + pic_init1(0x20, 0x4d0, &pics[0]); | |
| 463 | + pic_init1(0xa0, 0x4d1, &pics[1]); | |
| 464 | + pics[0].elcr_mask = 0xf8; | |
| 465 | + pics[1].elcr_mask = 0xde; | |
| 429 | 466 | } |
| 430 | 467 | ... | ... |