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 "apm.h"
  23. #include "hw.h"
  24. #include "pci/pci.h"
  25. //#define DEBUG
  26. #ifdef DEBUG
  27. # define APM_DPRINTF(format, ...) printf(format, ## __VA_ARGS__)
  28. #else
  29. # define APM_DPRINTF(format, ...) do { } while (0)
  30. #endif
  31. /* fixed I/O location */
  32. #define APM_CNT_IOPORT 0xb2
  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%x val=0x%02x\n", addr, val);
  40. if (addr == 0) {
  41. apm->apmc = val;
  42. if (apm->callback) {
  43. (apm->callback)(val, apm->arg);
  44. }
  45. } else {
  46. apm->apms = val;
  47. }
  48. }
  49. static uint64_t apm_ioport_readb(void *opaque, hwaddr addr, unsigned size)
  50. {
  51. APMState *apm = opaque;
  52. uint32_t val;
  53. addr &= 1;
  54. if (addr == 0) {
  55. val = apm->apmc;
  56. } else {
  57. val = apm->apms;
  58. }
  59. APM_DPRINTF("apm_ioport_readb addr=0x%x val=0x%02x\n", addr, val);
  60. return val;
  61. }
  62. const VMStateDescription vmstate_apm = {
  63. .name = "APM State",
  64. .version_id = 1,
  65. .minimum_version_id = 1,
  66. .minimum_version_id_old = 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, &apm_ops, apm, "apm-io", 2);
  88. memory_region_add_subregion(pci_address_space_io(dev), APM_CNT_IOPORT,
  89. &apm->io);
  90. }