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/mm.h>
23 #include <asm/hvm/vpic.h>
24 #include <asm/hvm/vioapic.h>
25 #include <public/hvm/ioreq.h>
26 #include <public/event_channel.h>
27 
28 #define NR_IO_HANDLERS 32
29 
30 typedef int (*hvm_mmio_read_t)(struct vcpu *v,
31                                unsigned long addr,
32                                unsigned int length,
33                                unsigned long *val);
34 typedef int (*hvm_mmio_write_t)(struct vcpu *v,
35                                 unsigned long addr,
36                                 unsigned int length,
37                                 unsigned long val);
38 typedef int (*hvm_mmio_check_t)(struct vcpu *v, unsigned long addr);
39 
40 struct hvm_mmio_ops {
41     hvm_mmio_check_t check;
42     hvm_mmio_read_t  read;
43     hvm_mmio_write_t write;
44 };
45 
hvm_mmio_first_byte(const ioreq_t * p)46 static inline paddr_t hvm_mmio_first_byte(const ioreq_t *p)
47 {
48     return unlikely(p->df) ?
49            p->addr - (p->count - 1ul) * p->size :
50            p->addr;
51 }
52 
hvm_mmio_last_byte(const ioreq_t * p)53 static inline paddr_t hvm_mmio_last_byte(const ioreq_t *p)
54 {
55     unsigned long size = p->size;
56 
57     return unlikely(p->df) ?
58            p->addr + size - 1:
59            p->addr + (p->count * size) - 1;
60 }
61 
62 typedef int (*portio_action_t)(
63     int dir, unsigned int port, unsigned int bytes, uint32_t *val);
64 
65 struct hvm_io_handler {
66     union {
67         struct {
68             const struct hvm_mmio_ops *ops;
69         } mmio;
70         struct {
71             unsigned int port, size;
72             portio_action_t action;
73         } portio;
74     };
75     const struct hvm_io_ops *ops;
76     uint8_t type;
77 };
78 
79 typedef int (*hvm_io_read_t)(const struct hvm_io_handler *,
80                              uint64_t addr,
81                              uint32_t size,
82                              uint64_t *data);
83 typedef int (*hvm_io_write_t)(const struct hvm_io_handler *,
84                               uint64_t addr,
85                               uint32_t size,
86                               uint64_t data);
87 typedef bool_t (*hvm_io_accept_t)(const struct hvm_io_handler *,
88                                   const ioreq_t *p);
89 typedef void (*hvm_io_complete_t)(const struct hvm_io_handler *);
90 
91 struct hvm_io_ops {
92     hvm_io_accept_t   accept;
93     hvm_io_read_t     read;
94     hvm_io_write_t    write;
95     hvm_io_complete_t complete;
96 };
97 
98 int hvm_process_io_intercept(const struct hvm_io_handler *handler,
99                              ioreq_t *p);
100 
101 int hvm_io_intercept(ioreq_t *p);
102 
103 struct hvm_io_handler *hvm_next_io_handler(struct domain *d);
104 
105 bool_t hvm_mmio_internal(paddr_t gpa);
106 
107 void register_mmio_handler(struct domain *d,
108                            const struct hvm_mmio_ops *ops);
109 
110 void register_portio_handler(
111     struct domain *d, unsigned int port, unsigned int size,
112     portio_action_t action);
113 
114 void relocate_portio_handler(
115     struct domain *d, unsigned int old_port, unsigned int new_port,
116     unsigned int size);
117 
118 void send_timeoffset_req(unsigned long timeoff);
119 void send_invalidate_req(void);
120 bool handle_mmio_with_translation(unsigned long gla, unsigned long gpfn,
121                                   struct npfec);
122 bool handle_pio(uint16_t port, unsigned int size, int dir);
123 void hvm_interrupt_post(struct vcpu *v, int vector, int type);
124 void hvm_dpci_eoi(struct domain *d, unsigned int guest_irq,
125                   const union vioapic_redir_entry *ent);
126 void msix_write_completion(struct vcpu *);
127 void msixtbl_init(struct domain *d);
128 
129 enum stdvga_cache_state {
130     STDVGA_CACHE_UNINITIALIZED,
131     STDVGA_CACHE_ENABLED,
132     STDVGA_CACHE_DISABLED
133 };
134 
135 struct hvm_hw_stdvga {
136     uint8_t sr_index;
137     uint8_t sr[8];
138     uint8_t gr_index;
139     uint8_t gr[9];
140     bool_t stdvga;
141     enum stdvga_cache_state cache;
142     uint32_t latch;
143     struct page_info *vram_page[64];  /* shadow of 0xa0000-0xaffff */
144     spinlock_t lock;
145 };
146 
147 void stdvga_init(struct domain *d);
148 void stdvga_deinit(struct domain *d);
149 
150 extern void hvm_dpci_msi_eoi(struct domain *d, int vector);
151 
152 /* Decode a PCI port IO access into a bus/slot/func/reg. */
153 unsigned int hvm_pci_decode_addr(unsigned int cf8, unsigned int addr,
154                                  unsigned int *bus, unsigned int *slot,
155                                  unsigned int *func);
156 
157 /*
158  * HVM port IO handler that performs forwarding of guest IO ports into machine
159  * IO ports.
160  */
161 void register_g2m_portio_handler(struct domain *d);
162 
163 #endif /* __ASM_X86_HVM_IO_H__ */
164 
165 
166 /*
167  * Local variables:
168  * mode: C
169  * c-file-style: "BSD"
170  * c-basic-offset: 4
171  * tab-width: 4
172  * indent-tabs-mode: nil
173  * End:
174  */
175