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,6 +43,8 @@ typedef struct PicState { | ||
43 | uint8_t rotate_on_auto_eoi; | 43 | uint8_t rotate_on_auto_eoi; |
44 | uint8_t special_fully_nested_mode; | 44 | uint8_t special_fully_nested_mode; |
45 | uint8_t init4; /* true if 4 byte init */ | 45 | uint8_t init4; /* true if 4 byte init */ |
46 | + uint8_t elcr; /* PIIX edge/trigger selection*/ | ||
47 | + uint8_t elcr_mask; | ||
46 | } PicState; | 48 | } PicState; |
47 | 49 | ||
48 | /* 0 is master pic, 1 is slave pic */ | 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,12 +56,24 @@ static inline void pic_set_irq1(PicState *s, int irq, int level) | ||
54 | { | 56 | { |
55 | int mask; | 57 | int mask; |
56 | mask = 1 << irq; | 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 | s->irr |= mask; | 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 | } else { | 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,7 +219,7 @@ int cpu_get_pic_interrupt(CPUState *env) | ||
205 | static void pic_ioport_write(void *opaque, uint32_t addr, uint32_t val) | 219 | static void pic_ioport_write(void *opaque, uint32_t addr, uint32_t val) |
206 | { | 220 | { |
207 | PicState *s = opaque; | 221 | PicState *s = opaque; |
208 | - int priority, cmd, irq; | 222 | + int priority, cmd, irq, tmp; |
209 | 223 | ||
210 | #ifdef DEBUG_PIC | 224 | #ifdef DEBUG_PIC |
211 | printf("pic_write: addr=0x%02x val=0x%02x\n", addr, val); | 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,7 +228,10 @@ static void pic_ioport_write(void *opaque, uint32_t addr, uint32_t val) | ||
214 | if (addr == 0) { | 228 | if (addr == 0) { |
215 | if (val & 0x10) { | 229 | if (val & 0x10) { |
216 | /* init */ | 230 | /* init */ |
231 | + tmp = s->elcr_mask; | ||
217 | memset(s, 0, sizeof(PicState)); | 232 | memset(s, 0, sizeof(PicState)); |
233 | + s->elcr_mask = tmp; | ||
234 | + | ||
218 | s->init_state = 1; | 235 | s->init_state = 1; |
219 | s->init4 = val & 1; | 236 | s->init4 = val & 1; |
220 | if (val & 0x02) | 237 | if (val & 0x02) |
@@ -356,6 +373,18 @@ uint32_t pic_intack_read(CPUState *env) | @@ -356,6 +373,18 @@ uint32_t pic_intack_read(CPUState *env) | ||
356 | return ret; | 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 | static void pic_save(QEMUFile *f, void *opaque) | 388 | static void pic_save(QEMUFile *f, void *opaque) |
360 | { | 389 | { |
361 | PicState *s = opaque; | 390 | PicState *s = opaque; |
@@ -374,6 +403,7 @@ static void pic_save(QEMUFile *f, void *opaque) | @@ -374,6 +403,7 @@ static void pic_save(QEMUFile *f, void *opaque) | ||
374 | qemu_put_8s(f, &s->rotate_on_auto_eoi); | 403 | qemu_put_8s(f, &s->rotate_on_auto_eoi); |
375 | qemu_put_8s(f, &s->special_fully_nested_mode); | 404 | qemu_put_8s(f, &s->special_fully_nested_mode); |
376 | qemu_put_8s(f, &s->init4); | 405 | qemu_put_8s(f, &s->init4); |
406 | + qemu_put_8s(f, &s->elcr); | ||
377 | } | 407 | } |
378 | 408 | ||
379 | static int pic_load(QEMUFile *f, void *opaque, int version_id) | 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,15 +427,19 @@ static int pic_load(QEMUFile *f, void *opaque, int version_id) | ||
397 | qemu_get_8s(f, &s->rotate_on_auto_eoi); | 427 | qemu_get_8s(f, &s->rotate_on_auto_eoi); |
398 | qemu_get_8s(f, &s->special_fully_nested_mode); | 428 | qemu_get_8s(f, &s->special_fully_nested_mode); |
399 | qemu_get_8s(f, &s->init4); | 429 | qemu_get_8s(f, &s->init4); |
430 | + qemu_get_8s(f, &s->elcr); | ||
400 | return 0; | 431 | return 0; |
401 | } | 432 | } |
402 | 433 | ||
403 | /* XXX: add generic master/slave system */ | 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 | register_ioport_write(io_addr, 2, 1, pic_ioport_write, s); | 437 | register_ioport_write(io_addr, 2, 1, pic_ioport_write, s); |
407 | register_ioport_read(io_addr, 2, 1, pic_ioport_read, s); | 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 | register_savevm("i8259", io_addr, 1, pic_save, pic_load, s); | 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,15 +450,18 @@ void pic_info(void) | ||
416 | 450 | ||
417 | for(i=0;i<2;i++) { | 451 | for(i=0;i<2;i++) { |
418 | s = &pics[i]; | 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 | void pic_init(void) | 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 |