19ed24f4bSMarc Zyngier /* SPDX-License-Identifier: GPL-2.0-only */ 29ed24f4bSMarc Zyngier /* 39ed24f4bSMarc Zyngier * Copyright (C) 2015, 2016 ARM Ltd. 49ed24f4bSMarc Zyngier */ 59ed24f4bSMarc Zyngier #ifndef __KVM_ARM_VGIC_MMIO_H__ 69ed24f4bSMarc Zyngier #define __KVM_ARM_VGIC_MMIO_H__ 79ed24f4bSMarc Zyngier 89ed24f4bSMarc Zyngier struct vgic_register_region { 99ed24f4bSMarc Zyngier unsigned int reg_offset; 109ed24f4bSMarc Zyngier unsigned int len; 119ed24f4bSMarc Zyngier unsigned int bits_per_irq; 129ed24f4bSMarc Zyngier unsigned int access_flags; 139ed24f4bSMarc Zyngier union { 149ed24f4bSMarc Zyngier unsigned long (*read)(struct kvm_vcpu *vcpu, gpa_t addr, 159ed24f4bSMarc Zyngier unsigned int len); 169ed24f4bSMarc Zyngier unsigned long (*its_read)(struct kvm *kvm, struct vgic_its *its, 179ed24f4bSMarc Zyngier gpa_t addr, unsigned int len); 189ed24f4bSMarc Zyngier }; 199ed24f4bSMarc Zyngier union { 209ed24f4bSMarc Zyngier void (*write)(struct kvm_vcpu *vcpu, gpa_t addr, 219ed24f4bSMarc Zyngier unsigned int len, unsigned long val); 229ed24f4bSMarc Zyngier void (*its_write)(struct kvm *kvm, struct vgic_its *its, 239ed24f4bSMarc Zyngier gpa_t addr, unsigned int len, 249ed24f4bSMarc Zyngier unsigned long val); 259ed24f4bSMarc Zyngier }; 269ed24f4bSMarc Zyngier unsigned long (*uaccess_read)(struct kvm_vcpu *vcpu, gpa_t addr, 279ed24f4bSMarc Zyngier unsigned int len); 289ed24f4bSMarc Zyngier union { 299ed24f4bSMarc Zyngier int (*uaccess_write)(struct kvm_vcpu *vcpu, gpa_t addr, 309ed24f4bSMarc Zyngier unsigned int len, unsigned long val); 319ed24f4bSMarc Zyngier int (*uaccess_its_write)(struct kvm *kvm, struct vgic_its *its, 329ed24f4bSMarc Zyngier gpa_t addr, unsigned int len, 339ed24f4bSMarc Zyngier unsigned long val); 349ed24f4bSMarc Zyngier }; 359ed24f4bSMarc Zyngier }; 369ed24f4bSMarc Zyngier 37636dcd02SRikard Falkeborn extern const struct kvm_io_device_ops kvm_io_gic_ops; 389ed24f4bSMarc Zyngier 399ed24f4bSMarc Zyngier #define VGIC_ACCESS_8bit 1 409ed24f4bSMarc Zyngier #define VGIC_ACCESS_32bit 2 419ed24f4bSMarc Zyngier #define VGIC_ACCESS_64bit 4 429ed24f4bSMarc Zyngier 439ed24f4bSMarc Zyngier /* 449ed24f4bSMarc Zyngier * Generate a mask that covers the number of bytes required to address 459ed24f4bSMarc Zyngier * up to 1024 interrupts, each represented by <bits> bits. This assumes 469ed24f4bSMarc Zyngier * that <bits> is a power of two. 479ed24f4bSMarc Zyngier */ 489ed24f4bSMarc Zyngier #define VGIC_ADDR_IRQ_MASK(bits) (((bits) * 1024 / 8) - 1) 499ed24f4bSMarc Zyngier 509ed24f4bSMarc Zyngier /* 519ed24f4bSMarc Zyngier * (addr & mask) gives us the _byte_ offset for the INT ID. 529ed24f4bSMarc Zyngier * We multiply this by 8 the get the _bit_ offset, then divide this by 539ed24f4bSMarc Zyngier * the number of bits to learn the actual INT ID. 549ed24f4bSMarc Zyngier * But instead of a division (which requires a "long long div" implementation), 559ed24f4bSMarc Zyngier * we shift by the binary logarithm of <bits>. 569ed24f4bSMarc Zyngier * This assumes that <bits> is a power of two. 579ed24f4bSMarc Zyngier */ 589ed24f4bSMarc Zyngier #define VGIC_ADDR_TO_INTID(addr, bits) (((addr) & VGIC_ADDR_IRQ_MASK(bits)) * \ 599ed24f4bSMarc Zyngier 8 >> ilog2(bits)) 609ed24f4bSMarc Zyngier 619ed24f4bSMarc Zyngier /* 629ed24f4bSMarc Zyngier * Some VGIC registers store per-IRQ information, with a different number 639ed24f4bSMarc Zyngier * of bits per IRQ. For those registers this macro is used. 649ed24f4bSMarc Zyngier * The _WITH_LENGTH version instantiates registers with a fixed length 659ed24f4bSMarc Zyngier * and is mutually exclusive with the _PER_IRQ version. 669ed24f4bSMarc Zyngier */ 679ed24f4bSMarc Zyngier #define REGISTER_DESC_WITH_BITS_PER_IRQ(off, rd, wr, ur, uw, bpi, acc) \ 689ed24f4bSMarc Zyngier { \ 699ed24f4bSMarc Zyngier .reg_offset = off, \ 709ed24f4bSMarc Zyngier .bits_per_irq = bpi, \ 719ed24f4bSMarc Zyngier .len = bpi * 1024 / 8, \ 729ed24f4bSMarc Zyngier .access_flags = acc, \ 739ed24f4bSMarc Zyngier .read = rd, \ 749ed24f4bSMarc Zyngier .write = wr, \ 759ed24f4bSMarc Zyngier .uaccess_read = ur, \ 769ed24f4bSMarc Zyngier .uaccess_write = uw, \ 779ed24f4bSMarc Zyngier } 789ed24f4bSMarc Zyngier 799ed24f4bSMarc Zyngier #define REGISTER_DESC_WITH_LENGTH(off, rd, wr, length, acc) \ 809ed24f4bSMarc Zyngier { \ 819ed24f4bSMarc Zyngier .reg_offset = off, \ 829ed24f4bSMarc Zyngier .bits_per_irq = 0, \ 839ed24f4bSMarc Zyngier .len = length, \ 849ed24f4bSMarc Zyngier .access_flags = acc, \ 859ed24f4bSMarc Zyngier .read = rd, \ 869ed24f4bSMarc Zyngier .write = wr, \ 879ed24f4bSMarc Zyngier } 889ed24f4bSMarc Zyngier 899ed24f4bSMarc Zyngier #define REGISTER_DESC_WITH_LENGTH_UACCESS(off, rd, wr, urd, uwr, length, acc) \ 909ed24f4bSMarc Zyngier { \ 919ed24f4bSMarc Zyngier .reg_offset = off, \ 929ed24f4bSMarc Zyngier .bits_per_irq = 0, \ 939ed24f4bSMarc Zyngier .len = length, \ 949ed24f4bSMarc Zyngier .access_flags = acc, \ 959ed24f4bSMarc Zyngier .read = rd, \ 969ed24f4bSMarc Zyngier .write = wr, \ 979ed24f4bSMarc Zyngier .uaccess_read = urd, \ 989ed24f4bSMarc Zyngier .uaccess_write = uwr, \ 999ed24f4bSMarc Zyngier } 1009ed24f4bSMarc Zyngier 1019ed24f4bSMarc Zyngier unsigned long vgic_data_mmio_bus_to_host(const void *val, unsigned int len); 1029ed24f4bSMarc Zyngier 1039ed24f4bSMarc Zyngier void vgic_data_host_to_mmio_bus(void *buf, unsigned int len, 1049ed24f4bSMarc Zyngier unsigned long data); 1059ed24f4bSMarc Zyngier 1069ed24f4bSMarc Zyngier unsigned long extract_bytes(u64 data, unsigned int offset, 1079ed24f4bSMarc Zyngier unsigned int num); 1089ed24f4bSMarc Zyngier 1099ed24f4bSMarc Zyngier u64 update_64bit_reg(u64 reg, unsigned int offset, unsigned int len, 1109ed24f4bSMarc Zyngier unsigned long val); 1119ed24f4bSMarc Zyngier 1129ed24f4bSMarc Zyngier unsigned long vgic_mmio_read_raz(struct kvm_vcpu *vcpu, 1139ed24f4bSMarc Zyngier gpa_t addr, unsigned int len); 1149ed24f4bSMarc Zyngier 1159ed24f4bSMarc Zyngier unsigned long vgic_mmio_read_rao(struct kvm_vcpu *vcpu, 1169ed24f4bSMarc Zyngier gpa_t addr, unsigned int len); 1179ed24f4bSMarc Zyngier 1189ed24f4bSMarc Zyngier void vgic_mmio_write_wi(struct kvm_vcpu *vcpu, gpa_t addr, 1199ed24f4bSMarc Zyngier unsigned int len, unsigned long val); 1209ed24f4bSMarc Zyngier 1219ed24f4bSMarc Zyngier int vgic_mmio_uaccess_write_wi(struct kvm_vcpu *vcpu, gpa_t addr, 1229ed24f4bSMarc Zyngier unsigned int len, unsigned long val); 1239ed24f4bSMarc Zyngier 1249ed24f4bSMarc Zyngier unsigned long vgic_mmio_read_group(struct kvm_vcpu *vcpu, gpa_t addr, 1259ed24f4bSMarc Zyngier unsigned int len); 1269ed24f4bSMarc Zyngier 1279ed24f4bSMarc Zyngier void vgic_mmio_write_group(struct kvm_vcpu *vcpu, gpa_t addr, 1289ed24f4bSMarc Zyngier unsigned int len, unsigned long val); 1299ed24f4bSMarc Zyngier 1309ed24f4bSMarc Zyngier unsigned long vgic_mmio_read_enable(struct kvm_vcpu *vcpu, 1319ed24f4bSMarc Zyngier gpa_t addr, unsigned int len); 1329ed24f4bSMarc Zyngier 1339ed24f4bSMarc Zyngier void vgic_mmio_write_senable(struct kvm_vcpu *vcpu, 1349ed24f4bSMarc Zyngier gpa_t addr, unsigned int len, 1359ed24f4bSMarc Zyngier unsigned long val); 1369ed24f4bSMarc Zyngier 1379ed24f4bSMarc Zyngier void vgic_mmio_write_cenable(struct kvm_vcpu *vcpu, 1389ed24f4bSMarc Zyngier gpa_t addr, unsigned int len, 1399ed24f4bSMarc Zyngier unsigned long val); 1409ed24f4bSMarc Zyngier 1419ed24f4bSMarc Zyngier int vgic_uaccess_write_senable(struct kvm_vcpu *vcpu, 1429ed24f4bSMarc Zyngier gpa_t addr, unsigned int len, 1439ed24f4bSMarc Zyngier unsigned long val); 1449ed24f4bSMarc Zyngier 1459ed24f4bSMarc Zyngier int vgic_uaccess_write_cenable(struct kvm_vcpu *vcpu, 1469ed24f4bSMarc Zyngier gpa_t addr, unsigned int len, 1479ed24f4bSMarc Zyngier unsigned long val); 1489ed24f4bSMarc Zyngier 1499ed24f4bSMarc Zyngier unsigned long vgic_mmio_read_pending(struct kvm_vcpu *vcpu, 1509ed24f4bSMarc Zyngier gpa_t addr, unsigned int len); 1519ed24f4bSMarc Zyngier 1522cdea19aSMarc Zyngier unsigned long vgic_uaccess_read_pending(struct kvm_vcpu *vcpu, 1532cdea19aSMarc Zyngier gpa_t addr, unsigned int len); 1542cdea19aSMarc Zyngier 1559ed24f4bSMarc Zyngier void vgic_mmio_write_spending(struct kvm_vcpu *vcpu, 1569ed24f4bSMarc Zyngier gpa_t addr, unsigned int len, 1579ed24f4bSMarc Zyngier unsigned long val); 1589ed24f4bSMarc Zyngier 1599ed24f4bSMarc Zyngier void vgic_mmio_write_cpending(struct kvm_vcpu *vcpu, 1609ed24f4bSMarc Zyngier gpa_t addr, unsigned int len, 1619ed24f4bSMarc Zyngier unsigned long val); 1629ed24f4bSMarc Zyngier 1639ed24f4bSMarc Zyngier int vgic_uaccess_write_spending(struct kvm_vcpu *vcpu, 1649ed24f4bSMarc Zyngier gpa_t addr, unsigned int len, 1659ed24f4bSMarc Zyngier unsigned long val); 1669ed24f4bSMarc Zyngier 1679ed24f4bSMarc Zyngier int vgic_uaccess_write_cpending(struct kvm_vcpu *vcpu, 1689ed24f4bSMarc Zyngier gpa_t addr, unsigned int len, 1699ed24f4bSMarc Zyngier unsigned long val); 1709ed24f4bSMarc Zyngier 1719ed24f4bSMarc Zyngier unsigned long vgic_mmio_read_active(struct kvm_vcpu *vcpu, 1729ed24f4bSMarc Zyngier gpa_t addr, unsigned int len); 1739ed24f4bSMarc Zyngier 1749ed24f4bSMarc Zyngier unsigned long vgic_uaccess_read_active(struct kvm_vcpu *vcpu, 1759ed24f4bSMarc Zyngier gpa_t addr, unsigned int len); 1769ed24f4bSMarc Zyngier 1779ed24f4bSMarc Zyngier void vgic_mmio_write_cactive(struct kvm_vcpu *vcpu, 1789ed24f4bSMarc Zyngier gpa_t addr, unsigned int len, 1799ed24f4bSMarc Zyngier unsigned long val); 1809ed24f4bSMarc Zyngier 1819ed24f4bSMarc Zyngier void vgic_mmio_write_sactive(struct kvm_vcpu *vcpu, 1829ed24f4bSMarc Zyngier gpa_t addr, unsigned int len, 1839ed24f4bSMarc Zyngier unsigned long val); 1849ed24f4bSMarc Zyngier 1859ed24f4bSMarc Zyngier int vgic_mmio_uaccess_write_cactive(struct kvm_vcpu *vcpu, 1869ed24f4bSMarc Zyngier gpa_t addr, unsigned int len, 1879ed24f4bSMarc Zyngier unsigned long val); 1889ed24f4bSMarc Zyngier 1899ed24f4bSMarc Zyngier int vgic_mmio_uaccess_write_sactive(struct kvm_vcpu *vcpu, 1909ed24f4bSMarc Zyngier gpa_t addr, unsigned int len, 1919ed24f4bSMarc Zyngier unsigned long val); 1929ed24f4bSMarc Zyngier 1939ed24f4bSMarc Zyngier unsigned long vgic_mmio_read_priority(struct kvm_vcpu *vcpu, 1949ed24f4bSMarc Zyngier gpa_t addr, unsigned int len); 1959ed24f4bSMarc Zyngier 1969ed24f4bSMarc Zyngier void vgic_mmio_write_priority(struct kvm_vcpu *vcpu, 1979ed24f4bSMarc Zyngier gpa_t addr, unsigned int len, 1989ed24f4bSMarc Zyngier unsigned long val); 1999ed24f4bSMarc Zyngier 2009ed24f4bSMarc Zyngier unsigned long vgic_mmio_read_config(struct kvm_vcpu *vcpu, 2019ed24f4bSMarc Zyngier gpa_t addr, unsigned int len); 2029ed24f4bSMarc Zyngier 2039ed24f4bSMarc Zyngier void vgic_mmio_write_config(struct kvm_vcpu *vcpu, 2049ed24f4bSMarc Zyngier gpa_t addr, unsigned int len, 2059ed24f4bSMarc Zyngier unsigned long val); 2069ed24f4bSMarc Zyngier 2079ed24f4bSMarc Zyngier int vgic_uaccess(struct kvm_vcpu *vcpu, struct vgic_io_device *dev, 2089ed24f4bSMarc Zyngier bool is_write, int offset, u32 *val); 2099ed24f4bSMarc Zyngier 210*38cf0bb7SMarc Zyngier u32 vgic_read_irq_line_level_info(struct kvm_vcpu *vcpu, u32 intid); 2119ed24f4bSMarc Zyngier 2129ed24f4bSMarc Zyngier void vgic_write_irq_line_level_info(struct kvm_vcpu *vcpu, u32 intid, 213*38cf0bb7SMarc Zyngier const u32 val); 2149ed24f4bSMarc Zyngier 2159ed24f4bSMarc Zyngier unsigned int vgic_v2_init_dist_iodev(struct vgic_io_device *dev); 2169ed24f4bSMarc Zyngier 2179ed24f4bSMarc Zyngier unsigned int vgic_v3_init_dist_iodev(struct vgic_io_device *dev); 2189ed24f4bSMarc Zyngier 2199ed24f4bSMarc Zyngier u64 vgic_sanitise_outer_cacheability(u64 reg); 2209ed24f4bSMarc Zyngier u64 vgic_sanitise_inner_cacheability(u64 reg); 2219ed24f4bSMarc Zyngier u64 vgic_sanitise_shareability(u64 reg); 2229ed24f4bSMarc Zyngier u64 vgic_sanitise_field(u64 reg, u64 field_mask, int field_shift, 2239ed24f4bSMarc Zyngier u64 (*sanitise_fn)(u64)); 2249ed24f4bSMarc Zyngier 2259ed24f4bSMarc Zyngier /* Find the proper register handler entry given a certain address offset */ 2269ed24f4bSMarc Zyngier const struct vgic_register_region * 2279ed24f4bSMarc Zyngier vgic_find_mmio_region(const struct vgic_register_region *regions, 2289ed24f4bSMarc Zyngier int nr_regions, unsigned int offset); 2299ed24f4bSMarc Zyngier 2309ed24f4bSMarc Zyngier #endif 231