ahci-allwinner.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  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 "system/dma.h"
  21. #include "migration/vmstate.h"
  22. #include "hw/ide/ahci-sysbus.h"
  23. #include "trace.h"
  24. #define ALLWINNER_AHCI_BISTAFR ((0xa0 - ALLWINNER_AHCI_MMIO_OFF) / 4)
  25. #define ALLWINNER_AHCI_BISTCR ((0xa4 - ALLWINNER_AHCI_MMIO_OFF) / 4)
  26. #define ALLWINNER_AHCI_BISTFCTR ((0xa8 - ALLWINNER_AHCI_MMIO_OFF) / 4)
  27. #define ALLWINNER_AHCI_BISTSR ((0xac - ALLWINNER_AHCI_MMIO_OFF) / 4)
  28. #define ALLWINNER_AHCI_BISTDECR ((0xb0 - ALLWINNER_AHCI_MMIO_OFF) / 4)
  29. #define ALLWINNER_AHCI_DIAGNR0 ((0xb4 - ALLWINNER_AHCI_MMIO_OFF) / 4)
  30. #define ALLWINNER_AHCI_DIAGNR1 ((0xb8 - ALLWINNER_AHCI_MMIO_OFF) / 4)
  31. #define ALLWINNER_AHCI_OOBR ((0xbc - ALLWINNER_AHCI_MMIO_OFF) / 4)
  32. #define ALLWINNER_AHCI_PHYCS0R ((0xc0 - ALLWINNER_AHCI_MMIO_OFF) / 4)
  33. #define ALLWINNER_AHCI_PHYCS1R ((0xc4 - ALLWINNER_AHCI_MMIO_OFF) / 4)
  34. #define ALLWINNER_AHCI_PHYCS2R ((0xc8 - ALLWINNER_AHCI_MMIO_OFF) / 4)
  35. #define ALLWINNER_AHCI_TIMER1MS ((0xe0 - ALLWINNER_AHCI_MMIO_OFF) / 4)
  36. #define ALLWINNER_AHCI_GPARAM1R ((0xe8 - ALLWINNER_AHCI_MMIO_OFF) / 4)
  37. #define ALLWINNER_AHCI_GPARAM2R ((0xec - ALLWINNER_AHCI_MMIO_OFF) / 4)
  38. #define ALLWINNER_AHCI_PPARAMR ((0xf0 - ALLWINNER_AHCI_MMIO_OFF) / 4)
  39. #define ALLWINNER_AHCI_TESTR ((0xf4 - ALLWINNER_AHCI_MMIO_OFF) / 4)
  40. #define ALLWINNER_AHCI_VERSIONR ((0xf8 - ALLWINNER_AHCI_MMIO_OFF) / 4)
  41. #define ALLWINNER_AHCI_IDR ((0xfc - ALLWINNER_AHCI_MMIO_OFF) / 4)
  42. #define ALLWINNER_AHCI_RWCR ((0xfc - ALLWINNER_AHCI_MMIO_OFF) / 4)
  43. static uint64_t allwinner_ahci_mem_read(void *opaque, hwaddr addr,
  44. unsigned size)
  45. {
  46. AllwinnerAHCIState *a = opaque;
  47. AHCIState *s = &(SYSBUS_AHCI(a)->ahci);
  48. uint64_t val = a->regs[addr / 4];
  49. switch (addr / 4) {
  50. case ALLWINNER_AHCI_PHYCS0R:
  51. val |= 0x2 << 28;
  52. break;
  53. case ALLWINNER_AHCI_PHYCS2R:
  54. val &= ~(0x1 << 24);
  55. break;
  56. }
  57. trace_allwinner_ahci_mem_read(s, a, addr, val, size);
  58. return val;
  59. }
  60. static void allwinner_ahci_mem_write(void *opaque, hwaddr addr,
  61. uint64_t val, unsigned size)
  62. {
  63. AllwinnerAHCIState *a = opaque;
  64. AHCIState *s = &(SYSBUS_AHCI(a)->ahci);
  65. trace_allwinner_ahci_mem_write(s, a, addr, val, size);
  66. a->regs[addr / 4] = val;
  67. }
  68. static const MemoryRegionOps allwinner_ahci_mem_ops = {
  69. .read = allwinner_ahci_mem_read,
  70. .write = allwinner_ahci_mem_write,
  71. .valid.min_access_size = 4,
  72. .valid.max_access_size = 4,
  73. .endianness = DEVICE_LITTLE_ENDIAN,
  74. };
  75. static void allwinner_ahci_init(Object *obj)
  76. {
  77. SysbusAHCIState *s = SYSBUS_AHCI(obj);
  78. AllwinnerAHCIState *a = ALLWINNER_AHCI(obj);
  79. memory_region_init_io(&a->mmio, obj, &allwinner_ahci_mem_ops, a,
  80. "allwinner-ahci", ALLWINNER_AHCI_MMIO_SIZE);
  81. memory_region_add_subregion(&s->ahci.mem, ALLWINNER_AHCI_MMIO_OFF,
  82. &a->mmio);
  83. }
  84. static const VMStateDescription vmstate_allwinner_ahci = {
  85. .name = "allwinner-ahci",
  86. .version_id = 1,
  87. .minimum_version_id = 1,
  88. .fields = (const VMStateField[]) {
  89. VMSTATE_UINT32_ARRAY(regs, AllwinnerAHCIState,
  90. ALLWINNER_AHCI_MMIO_SIZE / 4),
  91. VMSTATE_END_OF_LIST()
  92. }
  93. };
  94. static void allwinner_ahci_class_init(ObjectClass *klass, void *data)
  95. {
  96. DeviceClass *dc = DEVICE_CLASS(klass);
  97. dc->vmsd = &vmstate_allwinner_ahci;
  98. }
  99. static const TypeInfo allwinner_ahci_info = {
  100. .name = TYPE_ALLWINNER_AHCI,
  101. .parent = TYPE_SYSBUS_AHCI,
  102. .instance_size = sizeof(AllwinnerAHCIState),
  103. .instance_init = allwinner_ahci_init,
  104. .class_init = allwinner_ahci_class_init,
  105. };
  106. static void sysbus_ahci_register_types(void)
  107. {
  108. type_register_static(&allwinner_ahci_info);
  109. }
  110. type_init(sysbus_ahci_register_types)