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 __XEN_ARM_VGIC_VGIC_MMIO_H__
17 #define __XEN_ARM_VGIC_VGIC_MMIO_H__
18 
19 struct vgic_register_region {
20     unsigned int reg_offset;
21     unsigned int len;
22     unsigned int bits_per_irq;
23     unsigned int access_flags;
24     unsigned long (*read)(struct vcpu *vcpu, paddr_t addr,
25                           unsigned int len);
26     void (*write)(struct vcpu *vcpu, paddr_t addr,
27                   unsigned int len, unsigned long val);
28 };
29 
30 extern struct mmio_handler_ops vgic_io_ops;
31 
32 #define VGIC_ACCESS_8bit    1
33 #define VGIC_ACCESS_32bit   2
34 #define VGIC_ACCESS_64bit   4
35 
36 /*
37  * Generate a mask that covers the number of bytes required to address
38  * up to 1024 interrupts, each represented by <bits> bits. This assumes
39  * that <bits> is a power of two.
40  */
41 #define VGIC_ADDR_IRQ_MASK(bits) (((bits) * 1024 / 8) - 1)
42 
43 /*
44  * (addr & mask) gives us the _byte_ offset for the INT ID.
45  * We multiply this by 8 the get the _bit_ offset, then divide this by
46  * the number of bits to learn the actual INT ID.
47  * But instead of a division (which requires a "long long div" implementation),
48  * we shift by the binary logarithm of <bits>.
49  * This assumes that <bits> is a power of two.
50  */
51 #define VGIC_ADDR_TO_INTID(addr, bits)  (((addr) & VGIC_ADDR_IRQ_MASK(bits)) * \
52                                          8 >> ilog2(bits))
53 
54 /*
55  * Some VGIC registers store per-IRQ information, with a different number
56  * of bits per IRQ. For those registers this macro is used.
57  * The _WITH_LENGTH version instantiates registers with a fixed length
58  * and is mutually exclusive with the _PER_IRQ version.
59  */
60 #define REGISTER_DESC_WITH_BITS_PER_IRQ(off, rd, wr, bpi, acc)  \
61     {                                                           \
62         .reg_offset = off,                                      \
63         .bits_per_irq = bpi,                                    \
64         .len = bpi * 1024 / 8,                                  \
65         .access_flags = acc,                                    \
66         .read = rd,                                             \
67         .write = wr,                                            \
68     }
69 
70 #define REGISTER_DESC_WITH_LENGTH(off, rd, wr, length, acc)     \
71     {                                                           \
72         .reg_offset = off,                                      \
73         .bits_per_irq = 0,                                      \
74         .len = length,                                          \
75         .access_flags = acc,                                    \
76         .read = rd,                                             \
77         .write = wr,                                            \
78     }
79 
80 unsigned long vgic_mmio_read_raz(struct vcpu *vcpu,
81                                  paddr_t addr, unsigned int len);
82 
83 unsigned long vgic_mmio_read_rao(struct vcpu *vcpu,
84                                  paddr_t addr, unsigned int len);
85 
86 void vgic_mmio_write_wi(struct vcpu *vcpu, paddr_t addr,
87                         unsigned int len, unsigned long val);
88 
89 unsigned long vgic_mmio_read_enable(struct vcpu *vcpu,
90                                     paddr_t addr, unsigned int len);
91 
92 void vgic_mmio_write_senable(struct vcpu *vcpu,
93                              paddr_t addr, unsigned int len,
94                              unsigned long val);
95 
96 void vgic_mmio_write_cenable(struct vcpu *vcpu,
97                              paddr_t addr, unsigned int len,
98                              unsigned long val);
99 
100 unsigned long vgic_mmio_read_pending(struct vcpu *vcpu,
101                                      paddr_t addr, unsigned int len);
102 
103 void vgic_mmio_write_spending(struct vcpu *vcpu,
104                               paddr_t addr, unsigned int len,
105                               unsigned long val);
106 
107 void vgic_mmio_write_cpending(struct vcpu *vcpu,
108                               paddr_t addr, unsigned int len,
109                               unsigned long val);
110 
111 unsigned long vgic_mmio_read_active(struct vcpu *vcpu,
112                                     paddr_t addr, unsigned int len);
113 
114 void vgic_mmio_write_cactive(struct vcpu *vcpu,
115                              paddr_t addr, unsigned int len,
116                              unsigned long val);
117 
118 void vgic_mmio_write_sactive(struct vcpu *vcpu,
119                              paddr_t addr, unsigned int len,
120                              unsigned long val);
121 
122 unsigned long vgic_mmio_read_priority(struct vcpu *vcpu,
123                       paddr_t addr, unsigned int len);
124 
125 void vgic_mmio_write_priority(struct vcpu *vcpu,
126                   paddr_t addr, unsigned int len,
127                   unsigned long val);
128 
129 unsigned long vgic_mmio_read_config(struct vcpu *vcpu,
130                     paddr_t addr, unsigned int len);
131 
132 void vgic_mmio_write_config(struct vcpu *vcpu,
133                 paddr_t addr, unsigned int len,
134                 unsigned long val);
135 
136 unsigned int vgic_v2_init_dist_iodev(struct vgic_io_device *dev);
137 
138 #endif
139