1 /*
2 * io.h: HVM IO support
3 *
4 * Copyright (c) 2004, Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program; If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #ifndef __ASM_X86_HVM_IO_H__
20 #define __ASM_X86_HVM_IO_H__
21
22 #include <xen/pci.h>
23 #include <public/hvm/ioreq.h>
24
25 #define NR_IO_HANDLERS 32
26
27 typedef int (*hvm_mmio_read_t)(struct vcpu *v,
28 unsigned long addr,
29 unsigned int length,
30 unsigned long *val);
31 typedef int (*hvm_mmio_write_t)(struct vcpu *v,
32 unsigned long addr,
33 unsigned int length,
34 unsigned long val);
35 typedef int (*hvm_mmio_check_t)(struct vcpu *v, unsigned long addr);
36
37 struct hvm_mmio_ops {
38 hvm_mmio_check_t check;
39 hvm_mmio_read_t read;
40 hvm_mmio_write_t write;
41 };
42
hvm_mmio_first_byte(const ioreq_t * p)43 static inline paddr_t hvm_mmio_first_byte(const ioreq_t *p)
44 {
45 return unlikely(p->df) ?
46 p->addr - (p->count - 1ul) * p->size :
47 p->addr;
48 }
49
hvm_mmio_last_byte(const ioreq_t * p)50 static inline paddr_t hvm_mmio_last_byte(const ioreq_t *p)
51 {
52 unsigned long size = p->size;
53
54 return unlikely(p->df) ?
55 p->addr + size - 1:
56 p->addr + (p->count * size) - 1;
57 }
58
59 typedef int (*portio_action_t)(
60 int dir, unsigned int port, unsigned int bytes, uint32_t *val);
61
62 struct hvm_io_handler {
63 union {
64 struct {
65 const struct hvm_mmio_ops *ops;
66 } mmio;
67 struct {
68 unsigned int port, size;
69 portio_action_t action;
70 } portio;
71 };
72 const struct hvm_io_ops *ops;
73 uint8_t type;
74 };
75
76 typedef int (*hvm_io_read_t)(const struct hvm_io_handler *,
77 uint64_t addr,
78 uint32_t size,
79 uint64_t *data);
80 typedef int (*hvm_io_write_t)(const struct hvm_io_handler *,
81 uint64_t addr,
82 uint32_t size,
83 uint64_t data);
84 typedef bool_t (*hvm_io_accept_t)(const struct hvm_io_handler *,
85 const ioreq_t *p);
86 typedef void (*hvm_io_complete_t)(const struct hvm_io_handler *);
87
88 struct hvm_io_ops {
89 hvm_io_accept_t accept;
90 hvm_io_read_t read;
91 hvm_io_write_t write;
92 hvm_io_complete_t complete;
93 };
94
95 int hvm_process_io_intercept(const struct hvm_io_handler *handler,
96 ioreq_t *p);
97
98 int hvm_io_intercept(ioreq_t *p);
99
100 struct hvm_io_handler *hvm_next_io_handler(struct domain *d);
101
102 bool_t hvm_mmio_internal(paddr_t gpa);
103
104 void register_mmio_handler(struct domain *d,
105 const struct hvm_mmio_ops *ops);
106
107 void register_portio_handler(
108 struct domain *d, unsigned int port, unsigned int size,
109 portio_action_t action);
110
111 bool relocate_portio_handler(
112 struct domain *d, unsigned int old_port, unsigned int new_port,
113 unsigned int size);
114
115 void send_timeoffset_req(unsigned long timeoff);
116 void send_invalidate_req(void);
117 bool handle_mmio_with_translation(unsigned long gla, unsigned long gpfn,
118 struct npfec);
119 bool handle_pio(uint16_t port, unsigned int size, int dir);
120 void hvm_interrupt_post(struct vcpu *v, int vector, int type);
121 void hvm_dpci_eoi(struct domain *d, unsigned int guest_irq,
122 const union vioapic_redir_entry *ent);
123 void msix_write_completion(struct vcpu *);
124
125 #ifdef CONFIG_HVM
126 void msixtbl_init(struct domain *d);
127 #else
msixtbl_init(struct domain * d)128 static inline void msixtbl_init(struct domain *d) {}
129 #endif
130
131 /* Arch-specific MSI data for vPCI. */
132 struct vpci_arch_msi {
133 int pirq;
134 };
135
136 /* Arch-specific MSI-X entry data for vPCI. */
137 struct vpci_arch_msix_entry {
138 int pirq;
139 };
140
141 enum stdvga_cache_state {
142 STDVGA_CACHE_UNINITIALIZED,
143 STDVGA_CACHE_ENABLED,
144 STDVGA_CACHE_DISABLED
145 };
146
147 struct hvm_hw_stdvga {
148 uint8_t sr_index;
149 uint8_t sr[8];
150 uint8_t gr_index;
151 uint8_t gr[9];
152 bool_t stdvga;
153 enum stdvga_cache_state cache;
154 uint32_t latch;
155 struct page_info *vram_page[64]; /* shadow of 0xa0000-0xaffff */
156 spinlock_t lock;
157 };
158
159 void stdvga_init(struct domain *d);
160 void stdvga_deinit(struct domain *d);
161
162 extern void hvm_dpci_msi_eoi(struct domain *d, int vector);
163
164 /* Decode a PCI port IO access into a bus/slot/func/reg. */
165 unsigned int hvm_pci_decode_addr(unsigned int cf8, unsigned int addr,
166 pci_sbdf_t *sbdf);
167
168 /*
169 * HVM port IO handler that performs forwarding of guest IO ports into machine
170 * IO ports.
171 */
172 void register_g2m_portio_handler(struct domain *d);
173
174 /* HVM port IO handler for vPCI accesses. */
175 void register_vpci_portio_handler(struct domain *d);
176
177 /* HVM MMIO handler for PCI MMCFG accesses. */
178 int register_vpci_mmcfg_handler(struct domain *d, paddr_t addr,
179 unsigned int start_bus, unsigned int end_bus,
180 unsigned int seg);
181 /* Destroy tracked MMCFG areas. */
182 void destroy_vpci_mmcfg(struct domain *d);
183
184 /* Check if an address is between a MMCFG region for a domain. */
185 bool vpci_is_mmcfg_address(const struct domain *d, paddr_t addr);
186
187 #endif /* __ASM_X86_HVM_IO_H__ */
188
189
190 /*
191 * Local variables:
192 * mode: C
193 * c-file-style: "BSD"
194 * c-basic-offset: 4
195 * tab-width: 4
196 * indent-tabs-mode: nil
197 * End:
198 */
199