Commit 6eb011b038ccce4759312c834a3d7129f97bd3f0
1 parent
8ca9217d
Fix GPE registers read/write handling. (Gleb Natapov)
For STS register bit are cleared by writing 1 into it. Signed-off-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6624 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
31 additions
and
12 deletions
hw/acpi.c
... | ... | @@ -579,22 +579,25 @@ struct pci_status { |
579 | 579 | static struct gpe_regs gpe; |
580 | 580 | static struct pci_status pci0_status; |
581 | 581 | |
582 | +static uint32_t gpe_read_val(uint16_t val, uint32_t addr) | |
583 | +{ | |
584 | + if (addr & 1) | |
585 | + return (val >> 8) & 0xff; | |
586 | + return val & 0xff; | |
587 | +} | |
588 | + | |
582 | 589 | static uint32_t gpe_readb(void *opaque, uint32_t addr) |
583 | 590 | { |
584 | 591 | uint32_t val = 0; |
585 | 592 | struct gpe_regs *g = opaque; |
586 | 593 | switch (addr) { |
587 | 594 | case GPE_BASE: |
588 | - val = g->sts & 0xFF; | |
589 | - break; | |
590 | 595 | case GPE_BASE + 1: |
591 | - val = (g->sts >> 8) & 0xFF; | |
596 | + val = gpe_read_val(g->sts, addr); | |
592 | 597 | break; |
593 | 598 | case GPE_BASE + 2: |
594 | - val = g->en & 0xFF; | |
595 | - break; | |
596 | 599 | case GPE_BASE + 3: |
597 | - val = (g->en >> 8) & 0xFF; | |
600 | + val = gpe_read_val(g->en, addr); | |
598 | 601 | break; |
599 | 602 | default: |
600 | 603 | break; |
... | ... | @@ -606,21 +609,37 @@ static uint32_t gpe_readb(void *opaque, uint32_t addr) |
606 | 609 | return val; |
607 | 610 | } |
608 | 611 | |
612 | +static void gpe_write_val(uint16_t *cur, int addr, uint32_t val) | |
613 | +{ | |
614 | + if (addr & 1) | |
615 | + *cur = (*cur & 0xff) | (val << 8); | |
616 | + else | |
617 | + *cur = (*cur & 0xff00) | (val & 0xff); | |
618 | +} | |
619 | + | |
620 | +static void gpe_reset_val(uint16_t *cur, int addr, uint32_t val) | |
621 | +{ | |
622 | + uint16_t x1, x0 = val & 0xff; | |
623 | + int shift = (addr & 1) ? 8 : 0; | |
624 | + | |
625 | + x1 = (*cur >> shift) & 0xff; | |
626 | + | |
627 | + x1 = x1 & ~x0; | |
628 | + | |
629 | + *cur = (*cur & (0xff << (8 - shift))) | (x1 << shift); | |
630 | +} | |
631 | + | |
609 | 632 | static void gpe_writeb(void *opaque, uint32_t addr, uint32_t val) |
610 | 633 | { |
611 | 634 | struct gpe_regs *g = opaque; |
612 | 635 | switch (addr) { |
613 | 636 | case GPE_BASE: |
614 | - g->sts = (g->sts & ~0xFFFF) | (val & 0xFFFF); | |
615 | - break; | |
616 | 637 | case GPE_BASE + 1: |
617 | - g->sts = (g->sts & 0xFFFF) | (val << 8); | |
638 | + gpe_reset_val(&g->sts, addr, val); | |
618 | 639 | break; |
619 | 640 | case GPE_BASE + 2: |
620 | - g->en = (g->en & ~0xFFFF) | (val & 0xFFFF); | |
621 | - break; | |
622 | 641 | case GPE_BASE + 3: |
623 | - g->en = (g->en & 0xFFFF) | (val << 8); | |
642 | + gpe_write_val(&g->en, addr, val); | |
624 | 643 | break; |
625 | 644 | default: |
626 | 645 | break; | ... | ... |