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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Isaku Yamahata
						Isaku Yamahata