1 /* 2 * QEMU PC APM controller Emulation 3 * This is split out from acpi.c 4 * 5 * Copyright (c) 2006 Fabrice Bellard 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License version 2 as published by the Free Software Foundation. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, see <http://www.gnu.org/licenses/> 18 * 19 * Contributions after 2012-01-13 are licensed under the terms of the 20 * GNU GPL, version 2 or (at your option) any later version. 21 */ 22 23 #include "qemu/osdep.h" 24 #include "hw/isa/apm.h" 25 #include "hw/pci/pci.h" 26 #include "migration/vmstate.h" 27 #include "trace.h" 28 29 30 /* fixed I/O location */ 31 #define APM_STS_IOPORT 0xb3 32 33 static void apm_ioport_writeb(void *opaque, hwaddr addr, uint64_t val, 34 unsigned size) 35 { 36 APMState *apm = opaque; 37 addr &= 1; 38 39 trace_apm_io_write(addr, val); 40 if (addr == 0) { 41 apm->apmc = val; 42 43 if (apm->callback) { 44 (apm->callback)(val, apm->arg); 45 } 46 } else { 47 apm->apms = val; 48 } 49 } 50 51 static uint64_t apm_ioport_readb(void *opaque, hwaddr addr, unsigned size) 52 { 53 APMState *apm = opaque; 54 uint32_t val; 55 56 addr &= 1; 57 if (addr == 0) { 58 val = apm->apmc; 59 } else { 60 val = apm->apms; 61 } 62 trace_apm_io_read(addr, val); 63 64 return val; 65 } 66 67 const VMStateDescription vmstate_apm = { 68 .name = "APM State", 69 .version_id = 1, 70 .minimum_version_id = 1, 71 .fields = (VMStateField[]) { 72 VMSTATE_UINT8(apmc, APMState), 73 VMSTATE_UINT8(apms, APMState), 74 VMSTATE_END_OF_LIST() 75 } 76 }; 77 78 static const MemoryRegionOps apm_ops = { 79 .read = apm_ioport_readb, 80 .write = apm_ioport_writeb, 81 .impl = { 82 .min_access_size = 1, 83 .max_access_size = 1, 84 }, 85 }; 86 87 void apm_init(PCIDevice *dev, APMState *apm, apm_ctrl_changed_t callback, 88 void *arg) 89 { 90 apm->callback = callback; 91 apm->arg = arg; 92 93 /* ioport 0xb2, 0xb3 */ 94 memory_region_init_io(&apm->io, OBJECT(dev), &apm_ops, apm, "apm-io", 2); 95 memory_region_add_subregion(pci_address_space_io(dev), APM_CNT_IOPORT, 96 &apm->io); 97 } 98