apm.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  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. #include "qemu/osdep.h"
  23. #include "hw/isa/apm.h"
  24. #include "hw/pci/pci.h"
  25. #include "migration/vmstate.h"
  26. //#define DEBUG
  27. #ifdef DEBUG
  28. # define APM_DPRINTF(format, ...) printf(format, ## __VA_ARGS__)
  29. #else
  30. # define APM_DPRINTF(format, ...) do { } while (0)
  31. #endif
  32. /* fixed I/O location */
  33. #define APM_STS_IOPORT 0xb3
  34. static void apm_ioport_writeb(void *opaque, hwaddr addr, uint64_t val,
  35. unsigned size)
  36. {
  37. APMState *apm = opaque;
  38. addr &= 1;
  39. APM_DPRINTF("apm_ioport_writeb addr=0x%" HWADDR_PRIx
  40. " val=0x%02" PRIx64 "\n", addr, val);
  41. if (addr == 0) {
  42. apm->apmc = val;
  43. if (apm->callback) {
  44. (apm->callback)(val, apm->arg);
  45. }
  46. } else {
  47. apm->apms = val;
  48. }
  49. }
  50. static uint64_t apm_ioport_readb(void *opaque, hwaddr addr, unsigned size)
  51. {
  52. APMState *apm = opaque;
  53. uint32_t val;
  54. addr &= 1;
  55. if (addr == 0) {
  56. val = apm->apmc;
  57. } else {
  58. val = apm->apms;
  59. }
  60. APM_DPRINTF("apm_ioport_readb addr=0x%" HWADDR_PRIx " val=0x%02x\n", addr, val);
  61. return val;
  62. }
  63. const VMStateDescription vmstate_apm = {
  64. .name = "APM State",
  65. .version_id = 1,
  66. .minimum_version_id = 1,
  67. .fields = (VMStateField[]) {
  68. VMSTATE_UINT8(apmc, APMState),
  69. VMSTATE_UINT8(apms, APMState),
  70. VMSTATE_END_OF_LIST()
  71. }
  72. };
  73. static const MemoryRegionOps apm_ops = {
  74. .read = apm_ioport_readb,
  75. .write = apm_ioport_writeb,
  76. .impl = {
  77. .min_access_size = 1,
  78. .max_access_size = 1,
  79. },
  80. };
  81. void apm_init(PCIDevice *dev, APMState *apm, apm_ctrl_changed_t callback,
  82. void *arg)
  83. {
  84. apm->callback = callback;
  85. apm->arg = arg;
  86. /* ioport 0xb2, 0xb3 */
  87. memory_region_init_io(&apm->io, OBJECT(dev), &apm_ops, apm, "apm-io", 2);
  88. memory_region_add_subregion(pci_address_space_io(dev), APM_CNT_IOPORT,
  89. &apm->io);
  90. }