aboutsummaryrefslogtreecommitdiffstats
path: root/xen/include/asm-x86/hvm/io.h
blob: 410a5f6f84979e2e14ab1b990b18436caa98584e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
 * io.h: HVM IO support
 *
 * Copyright (c) 2004, Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place - Suite 330, Boston, MA 02111-1307 USA.
 */

#ifndef __ASM_X86_HVM_IO_H__
#define __ASM_X86_HVM_IO_H__

#include <asm/hvm/vpic.h>
#include <asm/hvm/vioapic.h>
#include <public/hvm/ioreq.h>
#include <public/event_channel.h>

#define MAX_IO_HANDLER             16

#define HVM_PORTIO                  0
#define HVM_BUFFERED_IO             2

typedef int (*hvm_mmio_read_t)(struct vcpu *v,
                               unsigned long addr,
                               unsigned long length,
                               unsigned long *val);
typedef int (*hvm_mmio_write_t)(struct vcpu *v,
                                unsigned long addr,
                                unsigned long length,
                                unsigned long val);
typedef int (*hvm_mmio_check_t)(struct vcpu *v, unsigned long addr);

typedef int (*portio_action_t)(
    int dir, uint32_t port, uint32_t bytes, uint32_t *val);
typedef int (*mmio_action_t)(ioreq_t *);
struct io_handler {
    int                 type;
    unsigned long       addr;
    unsigned long       size;
    union {
        portio_action_t portio;
        mmio_action_t   mmio;
        void           *ptr;
    } action;
};

struct hvm_io_handler {
    int     num_slot;
    struct  io_handler hdl_list[MAX_IO_HANDLER];
};

struct hvm_mmio_handler {
    hvm_mmio_check_t check_handler;
    hvm_mmio_read_t read_handler;
    hvm_mmio_write_t write_handler;
};

extern const struct hvm_mmio_handler hpet_mmio_handler;
extern const struct hvm_mmio_handler vlapic_mmio_handler;
extern const struct hvm_mmio_handler vioapic_mmio_handler;
extern const struct hvm_mmio_handler msixtbl_mmio_handler;
extern const struct hvm_mmio_handler iommu_mmio_handler;

#define HVM_MMIO_HANDLER_NR 5

int hvm_io_intercept(ioreq_t *p, int type);
void register_io_handler(
    struct domain *d, unsigned long addr, unsigned long size,
    void *action, int type);
void relocate_io_handler(
    struct domain *d, unsigned long old_addr, unsigned long new_addr,
    unsigned long size, int type);

static inline int hvm_portio_intercept(ioreq_t *p)
{
    return hvm_io_intercept(p, HVM_PORTIO);
}

static inline int hvm_buffered_io_intercept(ioreq_t *p)
{
    return hvm_io_intercept(p, HVM_BUFFERED_IO);
}

int hvm_mmio_intercept(ioreq_t *p);
int hvm_buffered_io_send(ioreq_t *p);

static inline void register_portio_handler(
    struct domain *d, unsigned long addr,
    unsigned long size, portio_action_t action)
{
    register_io_handler(d, addr, size, action, HVM_PORTIO);
}

static inline void relocate_portio_handler(
    struct domain *d, unsigned long old_addr, unsigned long new_addr,
    unsigned long size)
{
    relocate_io_handler(d, old_addr, new_addr, size, HVM_PORTIO);
}

static inline void register_buffered_io_handler(
    struct domain *d, unsigned long addr,
    unsigned long size, mmio_action_t action)
{
    register_io_handler(d, addr, size, action, HVM_BUFFERED_IO);
}

void send_timeoffset_req(unsigned long timeoff);
void send_invalidate_req(void);
int handle_mmio(void);
int handle_mmio_with_translation(unsigned long gva, unsigned long gpfn);
int handle_pio(uint16_t port, int size, int dir);
void hvm_interrupt_post(struct vcpu *v, int vector, int type);
void hvm_io_assist(void);
void hvm_dpci_eoi(struct domain *d, unsigned int guest_irq,
                  union vioapic_redir_entry *ent);

struct hvm_hw_stdvga {
    uint8_t sr_index;
    uint8_t sr[8];
    uint8_t gr_index;
    uint8_t gr[9];
    bool_t stdvga;
    bool_t cache;
    uint32_t latch;
    struct page_info *vram_page[64];  /* shadow of 0xa0000-0xaffff */
    spinlock_t lock;
};

void stdvga_init(struct domain *d);
void stdvga_deinit(struct domain *d);

extern void hvm_dpci_msi_eoi(struct domain *d, int vector);
#endif /* __ASM_X86_HVM_IO_H__ */