vgic-mmio.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /*
  2. * Copyright (C) 2015, 2016 ARM Ltd.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 as
  6. * published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #ifndef __KVM_ARM_VGIC_MMIO_H__
  17. #define __KVM_ARM_VGIC_MMIO_H__
  18. struct vgic_register_region {
  19. unsigned int reg_offset;
  20. unsigned int len;
  21. unsigned int bits_per_irq;
  22. unsigned int access_flags;
  23. union {
  24. unsigned long (*read)(struct kvm_vcpu *vcpu, gpa_t addr,
  25. unsigned int len);
  26. unsigned long (*its_read)(struct kvm *kvm, struct vgic_its *its,
  27. gpa_t addr, unsigned int len);
  28. };
  29. union {
  30. void (*write)(struct kvm_vcpu *vcpu, gpa_t addr,
  31. unsigned int len, unsigned long val);
  32. void (*its_write)(struct kvm *kvm, struct vgic_its *its,
  33. gpa_t addr, unsigned int len,
  34. unsigned long val);
  35. };
  36. unsigned long (*uaccess_read)(struct kvm_vcpu *vcpu, gpa_t addr,
  37. unsigned int len);
  38. union {
  39. int (*uaccess_write)(struct kvm_vcpu *vcpu, gpa_t addr,
  40. unsigned int len, unsigned long val);
  41. int (*uaccess_its_write)(struct kvm *kvm, struct vgic_its *its,
  42. gpa_t addr, unsigned int len,
  43. unsigned long val);
  44. };
  45. };
  46. extern struct kvm_io_device_ops kvm_io_gic_ops;
  47. #define VGIC_ACCESS_8bit 1
  48. #define VGIC_ACCESS_32bit 2
  49. #define VGIC_ACCESS_64bit 4
  50. /*
  51. * Generate a mask that covers the number of bytes required to address
  52. * up to 1024 interrupts, each represented by <bits> bits. This assumes
  53. * that <bits> is a power of two.
  54. */
  55. #define VGIC_ADDR_IRQ_MASK(bits) (((bits) * 1024 / 8) - 1)
  56. /*
  57. * (addr & mask) gives us the _byte_ offset for the INT ID.
  58. * We multiply this by 8 the get the _bit_ offset, then divide this by
  59. * the number of bits to learn the actual INT ID.
  60. * But instead of a division (which requires a "long long div" implementation),
  61. * we shift by the binary logarithm of <bits>.
  62. * This assumes that <bits> is a power of two.
  63. */
  64. #define VGIC_ADDR_TO_INTID(addr, bits) (((addr) & VGIC_ADDR_IRQ_MASK(bits)) * \
  65. 8 >> ilog2(bits))
  66. /*
  67. * Some VGIC registers store per-IRQ information, with a different number
  68. * of bits per IRQ. For those registers this macro is used.
  69. * The _WITH_LENGTH version instantiates registers with a fixed length
  70. * and is mutually exclusive with the _PER_IRQ version.
  71. */
  72. #define REGISTER_DESC_WITH_BITS_PER_IRQ(off, rd, wr, ur, uw, bpi, acc) \
  73. { \
  74. .reg_offset = off, \
  75. .bits_per_irq = bpi, \
  76. .len = bpi * 1024 / 8, \
  77. .access_flags = acc, \
  78. .read = rd, \
  79. .write = wr, \
  80. .uaccess_read = ur, \
  81. .uaccess_write = uw, \
  82. }
  83. #define REGISTER_DESC_WITH_LENGTH(off, rd, wr, length, acc) \
  84. { \
  85. .reg_offset = off, \
  86. .bits_per_irq = 0, \
  87. .len = length, \
  88. .access_flags = acc, \
  89. .read = rd, \
  90. .write = wr, \
  91. }
  92. #define REGISTER_DESC_WITH_LENGTH_UACCESS(off, rd, wr, urd, uwr, length, acc) \
  93. { \
  94. .reg_offset = off, \
  95. .bits_per_irq = 0, \
  96. .len = length, \
  97. .access_flags = acc, \
  98. .read = rd, \
  99. .write = wr, \
  100. .uaccess_read = urd, \
  101. .uaccess_write = uwr, \
  102. }
  103. int kvm_vgic_register_mmio_region(struct kvm *kvm, struct kvm_vcpu *vcpu,
  104. struct vgic_register_region *reg_desc,
  105. struct vgic_io_device *region,
  106. int nr_irqs, bool offset_private);
  107. unsigned long vgic_data_mmio_bus_to_host(const void *val, unsigned int len);
  108. void vgic_data_host_to_mmio_bus(void *buf, unsigned int len,
  109. unsigned long data);
  110. unsigned long extract_bytes(u64 data, unsigned int offset,
  111. unsigned int num);
  112. u64 update_64bit_reg(u64 reg, unsigned int offset, unsigned int len,
  113. unsigned long val);
  114. unsigned long vgic_mmio_read_raz(struct kvm_vcpu *vcpu,
  115. gpa_t addr, unsigned int len);
  116. unsigned long vgic_mmio_read_rao(struct kvm_vcpu *vcpu,
  117. gpa_t addr, unsigned int len);
  118. void vgic_mmio_write_wi(struct kvm_vcpu *vcpu, gpa_t addr,
  119. unsigned int len, unsigned long val);
  120. int vgic_mmio_uaccess_write_wi(struct kvm_vcpu *vcpu, gpa_t addr,
  121. unsigned int len, unsigned long val);
  122. unsigned long vgic_mmio_read_group(struct kvm_vcpu *vcpu, gpa_t addr,
  123. unsigned int len);
  124. void vgic_mmio_write_group(struct kvm_vcpu *vcpu, gpa_t addr,
  125. unsigned int len, unsigned long val);
  126. unsigned long vgic_mmio_read_enable(struct kvm_vcpu *vcpu,
  127. gpa_t addr, unsigned int len);
  128. void vgic_mmio_write_senable(struct kvm_vcpu *vcpu,
  129. gpa_t addr, unsigned int len,
  130. unsigned long val);
  131. void vgic_mmio_write_cenable(struct kvm_vcpu *vcpu,
  132. gpa_t addr, unsigned int len,
  133. unsigned long val);
  134. unsigned long vgic_mmio_read_pending(struct kvm_vcpu *vcpu,
  135. gpa_t addr, unsigned int len);
  136. void vgic_mmio_write_spending(struct kvm_vcpu *vcpu,
  137. gpa_t addr, unsigned int len,
  138. unsigned long val);
  139. void vgic_mmio_write_cpending(struct kvm_vcpu *vcpu,
  140. gpa_t addr, unsigned int len,
  141. unsigned long val);
  142. unsigned long vgic_mmio_read_active(struct kvm_vcpu *vcpu,
  143. gpa_t addr, unsigned int len);
  144. void vgic_mmio_write_cactive(struct kvm_vcpu *vcpu,
  145. gpa_t addr, unsigned int len,
  146. unsigned long val);
  147. void vgic_mmio_write_sactive(struct kvm_vcpu *vcpu,
  148. gpa_t addr, unsigned int len,
  149. unsigned long val);
  150. int vgic_mmio_uaccess_write_cactive(struct kvm_vcpu *vcpu,
  151. gpa_t addr, unsigned int len,
  152. unsigned long val);
  153. int vgic_mmio_uaccess_write_sactive(struct kvm_vcpu *vcpu,
  154. gpa_t addr, unsigned int len,
  155. unsigned long val);
  156. unsigned long vgic_mmio_read_priority(struct kvm_vcpu *vcpu,
  157. gpa_t addr, unsigned int len);
  158. void vgic_mmio_write_priority(struct kvm_vcpu *vcpu,
  159. gpa_t addr, unsigned int len,
  160. unsigned long val);
  161. unsigned long vgic_mmio_read_config(struct kvm_vcpu *vcpu,
  162. gpa_t addr, unsigned int len);
  163. void vgic_mmio_write_config(struct kvm_vcpu *vcpu,
  164. gpa_t addr, unsigned int len,
  165. unsigned long val);
  166. int vgic_uaccess(struct kvm_vcpu *vcpu, struct vgic_io_device *dev,
  167. bool is_write, int offset, u32 *val);
  168. u64 vgic_read_irq_line_level_info(struct kvm_vcpu *vcpu, u32 intid);
  169. void vgic_write_irq_line_level_info(struct kvm_vcpu *vcpu, u32 intid,
  170. const u64 val);
  171. unsigned int vgic_v2_init_dist_iodev(struct vgic_io_device *dev);
  172. unsigned int vgic_v3_init_dist_iodev(struct vgic_io_device *dev);
  173. u64 vgic_sanitise_outer_cacheability(u64 reg);
  174. u64 vgic_sanitise_inner_cacheability(u64 reg);
  175. u64 vgic_sanitise_shareability(u64 reg);
  176. u64 vgic_sanitise_field(u64 reg, u64 field_mask, int field_shift,
  177. u64 (*sanitise_fn)(u64));
  178. /* Find the proper register handler entry given a certain address offset */
  179. const struct vgic_register_region *
  180. vgic_find_mmio_region(const struct vgic_register_region *regions,
  181. int nr_regions, unsigned int offset);
  182. #endif