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, write to the Free Software Foundation, Inc., 59 Temple |
---|
17 | * Place - Suite 330, Boston, MA 02111-1307 USA. |
---|
18 | */ |
---|
19 | |
---|
20 | #ifndef __ASM_X86_HVM_IO_H__ |
---|
21 | #define __ASM_X86_HVM_IO_H__ |
---|
22 | |
---|
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 operand_size(operand) \ |
---|
29 | ((operand >> 24) & 0xFF) |
---|
30 | |
---|
31 | #define operand_index(operand) \ |
---|
32 | ((operand >> 16) & 0xFF) |
---|
33 | |
---|
34 | /* for instruction.operand[].size */ |
---|
35 | #define BYTE 1 |
---|
36 | #define WORD 2 |
---|
37 | #define LONG 4 |
---|
38 | #define QUAD 8 |
---|
39 | #define BYTE_64 16 |
---|
40 | |
---|
41 | /* for instruction.operand[].flag */ |
---|
42 | #define REGISTER 0x1 |
---|
43 | #define MEMORY 0x2 |
---|
44 | #define IMMEDIATE 0x4 |
---|
45 | |
---|
46 | /* for instruction.flags */ |
---|
47 | #define REPZ 0x1 |
---|
48 | #define REPNZ 0x2 |
---|
49 | #define OVERLAP 0x4 |
---|
50 | |
---|
51 | /* instruction type */ |
---|
52 | #define INSTR_PIO 1 |
---|
53 | #define INSTR_OR 2 |
---|
54 | #define INSTR_AND 3 |
---|
55 | #define INSTR_XOR 4 |
---|
56 | #define INSTR_CMP 5 |
---|
57 | #define INSTR_MOV 6 |
---|
58 | #define INSTR_MOVS 7 |
---|
59 | #define INSTR_MOVZX 8 |
---|
60 | #define INSTR_MOVSX 9 |
---|
61 | #define INSTR_STOS 10 |
---|
62 | #define INSTR_LODS 11 |
---|
63 | #define INSTR_TEST 12 |
---|
64 | #define INSTR_BT 13 |
---|
65 | #define INSTR_XCHG 14 |
---|
66 | #define INSTR_SUB 15 |
---|
67 | #define INSTR_ADD 16 |
---|
68 | #define INSTR_PUSH 17 |
---|
69 | |
---|
70 | #define MAX_INST_LEN 15 /* Maximum instruction length = 15 bytes */ |
---|
71 | |
---|
72 | struct hvm_io_op { |
---|
73 | unsigned int instr; /* instruction */ |
---|
74 | unsigned int flags; |
---|
75 | unsigned long addr; /* virt addr for overlap PIO/MMIO */ |
---|
76 | struct { |
---|
77 | unsigned int operand[2]; /* operands */ |
---|
78 | unsigned long immediate; /* immediate portion */ |
---|
79 | }; |
---|
80 | struct cpu_user_regs io_context; /* current context */ |
---|
81 | }; |
---|
82 | |
---|
83 | #define MAX_IO_HANDLER 9 |
---|
84 | |
---|
85 | #define HVM_PORTIO 0 |
---|
86 | #define HVM_MMIO 1 |
---|
87 | |
---|
88 | typedef int (*intercept_action_t)(ioreq_t *); |
---|
89 | typedef unsigned long (*hvm_mmio_read_t)(struct vcpu *v, |
---|
90 | unsigned long addr, |
---|
91 | unsigned long length); |
---|
92 | |
---|
93 | typedef void (*hvm_mmio_write_t)(struct vcpu *v, |
---|
94 | unsigned long addr, |
---|
95 | unsigned long length, |
---|
96 | unsigned long val); |
---|
97 | |
---|
98 | typedef int (*hvm_mmio_check_t)(struct vcpu *v, unsigned long addr); |
---|
99 | |
---|
100 | struct io_handler { |
---|
101 | int type; |
---|
102 | unsigned long addr; |
---|
103 | unsigned long size; |
---|
104 | intercept_action_t action; |
---|
105 | }; |
---|
106 | |
---|
107 | struct hvm_io_handler { |
---|
108 | int num_slot; |
---|
109 | struct io_handler hdl_list[MAX_IO_HANDLER]; |
---|
110 | }; |
---|
111 | |
---|
112 | struct hvm_mmio_handler { |
---|
113 | hvm_mmio_check_t check_handler; |
---|
114 | hvm_mmio_read_t read_handler; |
---|
115 | hvm_mmio_write_t write_handler; |
---|
116 | }; |
---|
117 | |
---|
118 | /* global io interception point in HV */ |
---|
119 | extern int hvm_io_intercept(ioreq_t *p, int type); |
---|
120 | extern int register_io_handler( |
---|
121 | struct domain *d, unsigned long addr, unsigned long size, |
---|
122 | intercept_action_t action, int type); |
---|
123 | |
---|
124 | static inline int hvm_portio_intercept(ioreq_t *p) |
---|
125 | { |
---|
126 | return hvm_io_intercept(p, HVM_PORTIO); |
---|
127 | } |
---|
128 | |
---|
129 | extern int hvm_mmio_intercept(ioreq_t *p); |
---|
130 | extern int hvm_buffered_io_send(ioreq_t *p); |
---|
131 | extern int hvm_buffered_io_intercept(ioreq_t *p); |
---|
132 | |
---|
133 | static inline int register_portio_handler( |
---|
134 | struct domain *d, unsigned long addr, |
---|
135 | unsigned long size, intercept_action_t action) |
---|
136 | { |
---|
137 | return register_io_handler(d, addr, size, action, HVM_PORTIO); |
---|
138 | } |
---|
139 | |
---|
140 | #if defined(__i386__) || defined(__x86_64__) |
---|
141 | static inline int irq_masked(unsigned long eflags) |
---|
142 | { |
---|
143 | return ((eflags & X86_EFLAGS_IF) == 0); |
---|
144 | } |
---|
145 | #endif |
---|
146 | |
---|
147 | extern void send_pio_req(unsigned long port, unsigned long count, int size, |
---|
148 | paddr_t value, int dir, int df, int value_is_ptr); |
---|
149 | void send_timeoffset_req(unsigned long timeoff); |
---|
150 | void send_invalidate_req(void); |
---|
151 | extern void handle_mmio(unsigned long gpa); |
---|
152 | extern void hvm_interrupt_post(struct vcpu *v, int vector, int type); |
---|
153 | extern void hvm_io_assist(void); |
---|
154 | |
---|
155 | #endif /* __ASM_X86_HVM_IO_H__ */ |
---|
156 | |
---|