Commit 6eb011b038ccce4759312c834a3d7129f97bd3f0

Authored by aliguori
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;
... ...