acpi, acpi_piix, vt82c686: factor out PM1_CNT logic
factor out ACPI PM1_CNT logic. This will be used by ich9 acpi. Cc: Blue Swirl <blauwirbel@gmail.com> Cc: Huacai Chen <zltjiangshi@gmail.com> Cc: Aurelien Jarno <aurelien@aurel32.net> Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
		
							parent
							
								
									04dc308f68
								
							
						
					
					
						commit
						eaba51c573
					
				
							
								
								
									
										49
									
								
								hw/acpi.c
								
								
								
								
							
							
						
						
									
										49
									
								
								hw/acpi.c
								
								
								
								
							| 
						 | 
				
			
			@ -279,3 +279,52 @@ void acpi_pm_tmr_reset(ACPIPMTimer *tmr)
 | 
			
		|||
    tmr->overflow_time = 0;
 | 
			
		||||
    qemu_del_timer(tmr->timer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ACPI PM1aCNT */
 | 
			
		||||
void acpi_pm1_cnt_init(ACPIPM1CNT *pm1_cnt, qemu_irq cmos_s3)
 | 
			
		||||
{
 | 
			
		||||
    pm1_cnt->cmos_s3 = cmos_s3;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void acpi_pm1_cnt_write(ACPIPM1EVT *pm1a, ACPIPM1CNT *pm1_cnt, uint16_t val)
 | 
			
		||||
{
 | 
			
		||||
    pm1_cnt->cnt = val & ~(ACPI_BITMASK_SLEEP_ENABLE);
 | 
			
		||||
 | 
			
		||||
    if (val & ACPI_BITMASK_SLEEP_ENABLE) {
 | 
			
		||||
        /* change suspend type */
 | 
			
		||||
        uint16_t sus_typ = (val >> 10) & 7;
 | 
			
		||||
        switch(sus_typ) {
 | 
			
		||||
        case 0: /* soft power off */
 | 
			
		||||
            qemu_system_shutdown_request();
 | 
			
		||||
            break;
 | 
			
		||||
        case 1:
 | 
			
		||||
            /* ACPI_BITMASK_WAKE_STATUS should be set on resume.
 | 
			
		||||
               Pretend that resume was caused by power button */
 | 
			
		||||
            pm1a->sts |=
 | 
			
		||||
                (ACPI_BITMASK_WAKE_STATUS | ACPI_BITMASK_POWER_BUTTON_STATUS);
 | 
			
		||||
            qemu_system_reset_request();
 | 
			
		||||
            qemu_irq_raise(pm1_cnt->cmos_s3);
 | 
			
		||||
        default:
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void acpi_pm1_cnt_update(ACPIPM1CNT *pm1_cnt,
 | 
			
		||||
                         bool sci_enable, bool sci_disable)
 | 
			
		||||
{
 | 
			
		||||
    /* ACPI specs 3.0, 4.7.2.5 */
 | 
			
		||||
    if (sci_enable) {
 | 
			
		||||
        pm1_cnt->cnt |= ACPI_BITMASK_SCI_ENABLE;
 | 
			
		||||
    } else if (sci_disable) {
 | 
			
		||||
        pm1_cnt->cnt &= ~ACPI_BITMASK_SCI_ENABLE;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void acpi_pm1_cnt_reset(ACPIPM1CNT *pm1_cnt)
 | 
			
		||||
{
 | 
			
		||||
    pm1_cnt->cnt = 0;
 | 
			
		||||
    if (pm1_cnt->cmos_s3) {
 | 
			
		||||
        qemu_irq_lower(pm1_cnt->cmos_s3);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										14
									
								
								hw/acpi.h
								
								
								
								
							
							
						
						
									
										14
									
								
								hw/acpi.h
								
								
								
								
							| 
						 | 
				
			
			@ -112,4 +112,18 @@ void acpi_pm1_evt_write_sts(ACPIPM1EVT *pm1, ACPIPMTimer *tmr, uint16_t val);
 | 
			
		|||
void acpi_pm1_evt_power_down(ACPIPM1EVT *pm1, ACPIPMTimer *tmr);
 | 
			
		||||
void acpi_pm1_evt_reset(ACPIPM1EVT *pm1);
 | 
			
		||||
 | 
			
		||||
/* PM1a_CNT: piix and ich9 don't implement PM1b CNT. */
 | 
			
		||||
struct ACPIPM1CNT {
 | 
			
		||||
    uint16_t cnt;
 | 
			
		||||
 | 
			
		||||
    qemu_irq cmos_s3;
 | 
			
		||||
};
 | 
			
		||||
typedef struct ACPIPM1CNT ACPIPM1CNT;
 | 
			
		||||
 | 
			
		||||
void acpi_pm1_cnt_init(ACPIPM1CNT *pm1_cnt, qemu_irq cmos_s3);
 | 
			
		||||
void acpi_pm1_cnt_write(ACPIPM1EVT *pm1a, ACPIPM1CNT *pm1_cnt, uint16_t val);
 | 
			
		||||
void acpi_pm1_cnt_update(ACPIPM1CNT *pm1_cnt,
 | 
			
		||||
                         bool sci_enable, bool sci_disable);
 | 
			
		||||
void acpi_pm1_cnt_reset(ACPIPM1CNT *pm1_cnt);
 | 
			
		||||
 | 
			
		||||
#endif /* !QEMU_HW_ACPI_H */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -55,7 +55,7 @@ typedef struct PIIX4PMState {
 | 
			
		|||
    PCIDevice dev;
 | 
			
		||||
    IORange ioport;
 | 
			
		||||
    ACPIPM1EVT pm1a;
 | 
			
		||||
    uint16_t pmcntrl;
 | 
			
		||||
    ACPIPM1CNT pm1_cnt;
 | 
			
		||||
 | 
			
		||||
    APMState apm;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -65,7 +65,6 @@ typedef struct PIIX4PMState {
 | 
			
		|||
    uint32_t smb_io_base;
 | 
			
		||||
 | 
			
		||||
    qemu_irq irq;
 | 
			
		||||
    qemu_irq cmos_s3;
 | 
			
		||||
    qemu_irq smi_irq;
 | 
			
		||||
    int kvm_enabled;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -124,30 +123,7 @@ static void pm_ioport_write(IORange *ioport, uint64_t addr, unsigned width,
 | 
			
		|||
        pm_update_sci(s);
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x04:
 | 
			
		||||
        {
 | 
			
		||||
            int sus_typ;
 | 
			
		||||
            s->pmcntrl = val & ~(ACPI_BITMASK_SLEEP_ENABLE);
 | 
			
		||||
            if (val & ACPI_BITMASK_SLEEP_ENABLE) {
 | 
			
		||||
                /* change suspend type */
 | 
			
		||||
                sus_typ = (val >> 10) & 7;
 | 
			
		||||
                switch(sus_typ) {
 | 
			
		||||
                case 0: /* soft power off */
 | 
			
		||||
                    qemu_system_shutdown_request();
 | 
			
		||||
                    break;
 | 
			
		||||
                case 1:
 | 
			
		||||
                    /* ACPI_BITMASK_WAKE_STATUS should be set on resume.
 | 
			
		||||
                       Pretend that resume was caused by power button */
 | 
			
		||||
                    s->pm1a.sts |= (ACPI_BITMASK_WAKE_STATUS |
 | 
			
		||||
                                    ACPI_BITMASK_POWER_BUTTON_STATUS);
 | 
			
		||||
                    qemu_system_reset_request();
 | 
			
		||||
                    if (s->cmos_s3) {
 | 
			
		||||
                        qemu_irq_raise(s->cmos_s3);
 | 
			
		||||
                    }
 | 
			
		||||
                default:
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        acpi_pm1_cnt_write(&s->pm1a, &s->pm1_cnt, val);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        break;
 | 
			
		||||
| 
						 | 
				
			
			@ -170,7 +146,7 @@ static void pm_ioport_read(IORange *ioport, uint64_t addr, unsigned width,
 | 
			
		|||
        val = s->pm1a.en;
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x04:
 | 
			
		||||
        val = s->pmcntrl;
 | 
			
		||||
        val = s->pm1_cnt.cnt;
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x08:
 | 
			
		||||
        val = acpi_pm_tmr_get(&s->tmr);
 | 
			
		||||
| 
						 | 
				
			
			@ -193,11 +169,7 @@ static void apm_ctrl_changed(uint32_t val, void *arg)
 | 
			
		|||
    PIIX4PMState *s = arg;
 | 
			
		||||
 | 
			
		||||
    /* ACPI specs 3.0, 4.7.2.5 */
 | 
			
		||||
    if (val == ACPI_ENABLE) {
 | 
			
		||||
        s->pmcntrl |= ACPI_BITMASK_SCI_ENABLE;
 | 
			
		||||
    } else if (val == ACPI_DISABLE) {
 | 
			
		||||
        s->pmcntrl &= ~ACPI_BITMASK_SCI_ENABLE;
 | 
			
		||||
    }
 | 
			
		||||
    acpi_pm1_cnt_update(&s->pm1_cnt, val == ACPI_ENABLE, val == ACPI_DISABLE);
 | 
			
		||||
 | 
			
		||||
    if (s->dev.config[0x5b] & (1 << 1)) {
 | 
			
		||||
        if (s->smi_irq) {
 | 
			
		||||
| 
						 | 
				
			
			@ -276,7 +248,7 @@ static const VMStateDescription vmstate_acpi = {
 | 
			
		|||
        VMSTATE_PCI_DEVICE(dev, PIIX4PMState),
 | 
			
		||||
        VMSTATE_UINT16(pm1a.sts, PIIX4PMState),
 | 
			
		||||
        VMSTATE_UINT16(pm1a.en, PIIX4PMState),
 | 
			
		||||
        VMSTATE_UINT16(pmcntrl, PIIX4PMState),
 | 
			
		||||
        VMSTATE_UINT16(pm1_cnt.cnt, PIIX4PMState),
 | 
			
		||||
        VMSTATE_STRUCT(apm, PIIX4PMState, 0, vmstate_apm, APMState),
 | 
			
		||||
        VMSTATE_TIMER(tmr.timer, PIIX4PMState),
 | 
			
		||||
        VMSTATE_INT64(tmr.overflow_time, PIIX4PMState),
 | 
			
		||||
| 
						 | 
				
			
			@ -396,7 +368,7 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
 | 
			
		|||
 | 
			
		||||
    s = DO_UPCAST(PIIX4PMState, dev, dev);
 | 
			
		||||
    s->irq = sci_irq;
 | 
			
		||||
    s->cmos_s3 = cmos_s3;
 | 
			
		||||
    acpi_pm1_cnt_init(&s->pm1_cnt, cmos_s3);
 | 
			
		||||
    s->smi_irq = smi_irq;
 | 
			
		||||
    s->kvm_enabled = kvm_enabled;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -157,7 +157,7 @@ static void vt82c686b_write_config(PCIDevice * d, uint32_t address,
 | 
			
		|||
typedef struct VT686PMState {
 | 
			
		||||
    PCIDevice dev;
 | 
			
		||||
    ACPIPM1EVT pm1a;
 | 
			
		||||
    uint16_t pmcntrl;
 | 
			
		||||
    ACPIPM1CNT pm1_cnt;
 | 
			
		||||
    APMState apm;
 | 
			
		||||
    ACPIPMTimer tmr;
 | 
			
		||||
    PMSMBus smb;
 | 
			
		||||
| 
						 | 
				
			
			@ -209,21 +209,7 @@ static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
 | 
			
		|||
        pm_update_sci(s);
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x04:
 | 
			
		||||
        {
 | 
			
		||||
            int sus_typ;
 | 
			
		||||
            s->pmcntrl = val & ~(SUS_EN);
 | 
			
		||||
            if (val & SUS_EN) {
 | 
			
		||||
                /* change suspend type */
 | 
			
		||||
                sus_typ = (val >> 10) & 3;
 | 
			
		||||
                switch (sus_typ) {
 | 
			
		||||
                case 0: /* soft power off */
 | 
			
		||||
                    qemu_system_shutdown_request();
 | 
			
		||||
                    break;
 | 
			
		||||
                default:
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        acpi_pm1_cnt_write(&s->pm1a, &s->pm1_cnt, val);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        break;
 | 
			
		||||
| 
						 | 
				
			
			@ -245,7 +231,7 @@ static uint32_t pm_ioport_readw(void *opaque, uint32_t addr)
 | 
			
		|||
        val = s->pm1a.en;
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x04:
 | 
			
		||||
        val = s->pmcntrl;
 | 
			
		||||
        val = s->pm1_cnt.cnt;
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        val = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -322,7 +308,7 @@ static const VMStateDescription vmstate_acpi = {
 | 
			
		|||
        VMSTATE_PCI_DEVICE(dev, VT686PMState),
 | 
			
		||||
        VMSTATE_UINT16(pm1a.sts, VT686PMState),
 | 
			
		||||
        VMSTATE_UINT16(pm1a.en, VT686PMState),
 | 
			
		||||
        VMSTATE_UINT16(pmcntrl, VT686PMState),
 | 
			
		||||
        VMSTATE_UINT16(pm1_cnt.cnt, VT686PMState),
 | 
			
		||||
        VMSTATE_STRUCT(apm, VT686PMState, 0, vmstate_apm, APMState),
 | 
			
		||||
        VMSTATE_TIMER(tmr.timer, VT686PMState),
 | 
			
		||||
        VMSTATE_INT64(tmr.overflow_time, VT686PMState),
 | 
			
		||||
| 
						 | 
				
			
			@ -446,6 +432,7 @@ static int vt82c686b_pm_initfn(PCIDevice *dev)
 | 
			
		|||
    apm_init(&s->apm, NULL, s);
 | 
			
		||||
 | 
			
		||||
    acpi_pm_tmr_init(&s->tmr, pm_tmr_timer);
 | 
			
		||||
    acpi_pm1_cnt_init(&s->pm1_cnt, NULL);
 | 
			
		||||
 | 
			
		||||
    pm_smbus_init(&s->dev.qdev, &s->smb);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue