ahci-allwinner.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /*
  2. * QEMU Allwinner AHCI Emulation
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation; either version 2
  7. * of the License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include "qemu/osdep.h"
  18. #include "qemu/error-report.h"
  19. #include "qemu/module.h"
  20. #include "sysemu/dma.h"
  21. #include "hw/ide/internal.h"
  22. #include "migration/vmstate.h"
  23. #include "ahci_internal.h"
  24. #include "trace.h"
  25. #define ALLWINNER_AHCI(obj) \
  26. OBJECT_CHECK(AllwinnerAHCIState, (obj), TYPE_ALLWINNER_AHCI)
  27. #define ALLWINNER_AHCI_BISTAFR ((0xa0 - ALLWINNER_AHCI_MMIO_OFF) / 4)
  28. #define ALLWINNER_AHCI_BISTCR ((0xa4 - ALLWINNER_AHCI_MMIO_OFF) / 4)
  29. #define ALLWINNER_AHCI_BISTFCTR ((0xa8 - ALLWINNER_AHCI_MMIO_OFF) / 4)
  30. #define ALLWINNER_AHCI_BISTSR ((0xac - ALLWINNER_AHCI_MMIO_OFF) / 4)
  31. #define ALLWINNER_AHCI_BISTDECR ((0xb0 - ALLWINNER_AHCI_MMIO_OFF) / 4)
  32. #define ALLWINNER_AHCI_DIAGNR0 ((0xb4 - ALLWINNER_AHCI_MMIO_OFF) / 4)
  33. #define ALLWINNER_AHCI_DIAGNR1 ((0xb8 - ALLWINNER_AHCI_MMIO_OFF) / 4)
  34. #define ALLWINNER_AHCI_OOBR ((0xbc - ALLWINNER_AHCI_MMIO_OFF) / 4)
  35. #define ALLWINNER_AHCI_PHYCS0R ((0xc0 - ALLWINNER_AHCI_MMIO_OFF) / 4)
  36. #define ALLWINNER_AHCI_PHYCS1R ((0xc4 - ALLWINNER_AHCI_MMIO_OFF) / 4)
  37. #define ALLWINNER_AHCI_PHYCS2R ((0xc8 - ALLWINNER_AHCI_MMIO_OFF) / 4)
  38. #define ALLWINNER_AHCI_TIMER1MS ((0xe0 - ALLWINNER_AHCI_MMIO_OFF) / 4)
  39. #define ALLWINNER_AHCI_GPARAM1R ((0xe8 - ALLWINNER_AHCI_MMIO_OFF) / 4)
  40. #define ALLWINNER_AHCI_GPARAM2R ((0xec - ALLWINNER_AHCI_MMIO_OFF) / 4)
  41. #define ALLWINNER_AHCI_PPARAMR ((0xf0 - ALLWINNER_AHCI_MMIO_OFF) / 4)
  42. #define ALLWINNER_AHCI_TESTR ((0xf4 - ALLWINNER_AHCI_MMIO_OFF) / 4)
  43. #define ALLWINNER_AHCI_VERSIONR ((0xf8 - ALLWINNER_AHCI_MMIO_OFF) / 4)
  44. #define ALLWINNER_AHCI_IDR ((0xfc - ALLWINNER_AHCI_MMIO_OFF) / 4)
  45. #define ALLWINNER_AHCI_RWCR ((0xfc - ALLWINNER_AHCI_MMIO_OFF) / 4)
  46. static uint64_t allwinner_ahci_mem_read(void *opaque, hwaddr addr,
  47. unsigned size)
  48. {
  49. AllwinnerAHCIState *a = opaque;
  50. AHCIState *s = &(SYSBUS_AHCI(a)->ahci);
  51. uint64_t val = a->regs[addr / 4];
  52. switch (addr / 4) {
  53. case ALLWINNER_AHCI_PHYCS0R:
  54. val |= 0x2 << 28;
  55. break;
  56. case ALLWINNER_AHCI_PHYCS2R:
  57. val &= ~(0x1 << 24);
  58. break;
  59. }
  60. trace_allwinner_ahci_mem_read(s, a, addr, val, size);
  61. return val;
  62. }
  63. static void allwinner_ahci_mem_write(void *opaque, hwaddr addr,
  64. uint64_t val, unsigned size)
  65. {
  66. AllwinnerAHCIState *a = opaque;
  67. AHCIState *s = &(SYSBUS_AHCI(a)->ahci);
  68. trace_allwinner_ahci_mem_write(s, a, addr, val, size);
  69. a->regs[addr / 4] = val;
  70. }
  71. static const MemoryRegionOps allwinner_ahci_mem_ops = {
  72. .read = allwinner_ahci_mem_read,
  73. .write = allwinner_ahci_mem_write,
  74. .valid.min_access_size = 4,
  75. .valid.max_access_size = 4,
  76. .endianness = DEVICE_LITTLE_ENDIAN,
  77. };
  78. static void allwinner_ahci_init(Object *obj)
  79. {
  80. SysbusAHCIState *s = SYSBUS_AHCI(obj);
  81. AllwinnerAHCIState *a = ALLWINNER_AHCI(obj);
  82. memory_region_init_io(&a->mmio, OBJECT(obj), &allwinner_ahci_mem_ops, a,
  83. "allwinner-ahci", ALLWINNER_AHCI_MMIO_SIZE);
  84. memory_region_add_subregion(&s->ahci.mem, ALLWINNER_AHCI_MMIO_OFF,
  85. &a->mmio);
  86. }
  87. static const VMStateDescription vmstate_allwinner_ahci = {
  88. .name = "allwinner-ahci",
  89. .version_id = 1,
  90. .minimum_version_id = 1,
  91. .fields = (VMStateField[]) {
  92. VMSTATE_UINT32_ARRAY(regs, AllwinnerAHCIState,
  93. ALLWINNER_AHCI_MMIO_SIZE / 4),
  94. VMSTATE_END_OF_LIST()
  95. }
  96. };
  97. static void allwinner_ahci_class_init(ObjectClass *klass, void *data)
  98. {
  99. DeviceClass *dc = DEVICE_CLASS(klass);
  100. dc->vmsd = &vmstate_allwinner_ahci;
  101. }
  102. static const TypeInfo allwinner_ahci_info = {
  103. .name = TYPE_ALLWINNER_AHCI,
  104. .parent = TYPE_SYSBUS_AHCI,
  105. .instance_size = sizeof(AllwinnerAHCIState),
  106. .instance_init = allwinner_ahci_init,
  107. .class_init = allwinner_ahci_class_init,
  108. };
  109. static void sysbus_ahci_register_types(void)
  110. {
  111. type_register_static(&allwinner_ahci_info);
  112. }
  113. type_init(sysbus_ahci_register_types)