kvm-guest-drivers-windows

Форк
0
251 строка · 8.3 Кб
1
/*
2
 * Virtio PCI driver
3
 *
4
 * Copyright IBM Corp. 2007
5
 *
6
 * Authors:
7
 *  Anthony Liguori  <aliguori@us.ibm.com>
8
 *  Windows porting - Yan Vugenfirer <yvugenfi@redhat.com>
9
 *  StorPort/ScsiPort code adjustment Vadim Rozenfeld <vrozenfe@redhat.com>
10
 *
11
 * Redistribution and use in source and binary forms, with or without
12
 * modification, are permitted provided that the following conditions
13
 * are met :
14
 * 1. Redistributions of source code must retain the above copyright
15
 *    notice, this list of conditions and the following disclaimer.
16
 * 2. Redistributions in binary form must reproduce the above copyright
17
 *    notice, this list of conditions and the following disclaimer in the
18
 *    documentation and / or other materials provided with the distribution.
19
 * 3. Neither the names of the copyright holders nor the names of their contributors
20
 *    may be used to endorse or promote products derived from this software
21
 *    without specific prior written permission.
22
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
23
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
 * ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
26
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32
 * SUCH DAMAGE.
33
 */
34
#include "osdep.h"
35
#include "virtio_pci.h"
36
#include "virtio_stor_utils.h"
37
#include "virtio_stor_hw_helper.h"
38
#include "virtio_stor.h"
39

40
#if defined(EVENT_TRACING)
41
#include "virtio_pci.tmh"
42
#endif
43

44
/* The lower 64k of memory is never mapped so we can use the same routines
45
 * for both port I/O and memory access and use the address alone to decide
46
 * which space to use.
47
 */
48
#define PORT_MASK 0xFFFF
49

50
static u32 ReadVirtIODeviceRegister(ULONG_PTR ulRegister)
51
{
52
    if (ulRegister & ~PORT_MASK) {
53
        return StorPortReadRegisterUlong(NULL, (PULONG)(ulRegister));
54
    } else {
55
        return StorPortReadPortUlong(NULL, (PULONG)(ulRegister));
56
    }
57
}
58

59
static void WriteVirtIODeviceRegister(ULONG_PTR ulRegister, u32 ulValue)
60
{
61
    if (ulRegister & ~PORT_MASK) {
62
        StorPortWriteRegisterUlong(NULL, (PULONG)(ulRegister), (ULONG)(ulValue));
63
    } else {
64
        StorPortWritePortUlong(NULL, (PULONG)(ulRegister), (ULONG)(ulValue));
65
    }
66
}
67

68
static u8 ReadVirtIODeviceByte(ULONG_PTR ulRegister)
69
{
70
    if (ulRegister & ~PORT_MASK) {
71
        return StorPortReadRegisterUchar(NULL, (PUCHAR)(ulRegister));
72
    } else {
73
        return StorPortReadPortUchar(NULL, (PUCHAR)(ulRegister));
74
    }
75
}
76

77
static void WriteVirtIODeviceByte(ULONG_PTR ulRegister, u8 bValue)
78
{
79
    if (ulRegister & ~PORT_MASK) {
80
        StorPortWriteRegisterUchar(NULL, (PUCHAR)(ulRegister), (UCHAR)(bValue));
81
    } else {
82
        StorPortWritePortUchar(NULL, (PUCHAR)(ulRegister), (UCHAR)(bValue));
83
    }
84
}
85

86
static u16 ReadVirtIODeviceWord(ULONG_PTR ulRegister)
87
{
88
    if (ulRegister & ~PORT_MASK) {
89
        return StorPortReadRegisterUshort(NULL, (PUSHORT)(ulRegister));
90
    } else {
91
        return StorPortReadPortUshort(NULL, (PUSHORT)(ulRegister));
92
    }
93
}
94

95
static void WriteVirtIODeviceWord(ULONG_PTR ulRegister, u16 wValue)
96
{
97
    if (ulRegister & ~PORT_MASK) {
98
        StorPortWriteRegisterUshort(NULL, (PUSHORT)(ulRegister), (USHORT)(wValue));
99
    } else {
100
        StorPortWritePortUshort(NULL, (PUSHORT)(ulRegister), (USHORT)(wValue));
101
    }
102
}
103

104
static void *mem_alloc_contiguous_pages(void *context, size_t size)
105
{
106
    PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)context;
107
    PVOID ptr = (PVOID)((ULONG_PTR)adaptExt->pageAllocationVa + adaptExt->pageOffset);
108

109
    if ((adaptExt->pageOffset + size) <= adaptExt->pageAllocationSize) {
110
        size = ROUND_TO_PAGES(size);
111
        adaptExt->pageOffset += size;
112
        RtlZeroMemory(ptr, size);
113
        return ptr;
114
    } else {
115
        RhelDbgPrint(TRACE_LEVEL_FATAL, " Ran out of memory in (%Id)\n", size);
116
        return NULL;
117
    }
118
}
119

120
static void mem_free_contiguous_pages(void *context, void *virt)
121
{
122
    UNREFERENCED_PARAMETER(context);
123
    UNREFERENCED_PARAMETER(virt);
124

125
    /* We allocate pages from a single uncached extension by simply moving the
126
     * adaptExt->allocationOffset pointer forward. Nothing to do here.
127
     */
128
}
129

130
static ULONGLONG mem_get_physical_address(void *context, void *virt)
131
{
132
    ULONG uLength;
133
    STOR_PHYSICAL_ADDRESS pa = StorPortGetPhysicalAddress(context, NULL, virt, &uLength);
134
    return pa.QuadPart;
135
}
136

137
static void *mem_alloc_nonpaged_block(void *context, size_t size)
138
{
139
    return VioStorPoolAlloc(context, size);
140
}
141

142
static void mem_free_nonpaged_block(void *context, void *addr)
143
{
144
    /* We allocate memory from a single non-paged pool allocation by simply moving
145
     * the adaptExt->poolOffset pointer forward. Nothing to do here.
146
     */
147
}
148

149
static int pci_read_config_byte(void *context, int where, u8 *bVal)
150
{
151
    PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)context;
152
    *bVal = adaptExt->pci_config_buf[where];
153
    return 0;
154
}
155

156
static int pci_read_config_word(void *context, int where, u16 *wVal)
157
{
158
    PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)context;
159
    *wVal = *(u16 *)&adaptExt->pci_config_buf[where];
160
    return 0;
161
}
162

163
static int pci_read_config_dword(void *context, int where, u32 *dwVal)
164
{
165
    PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)context;
166
    *dwVal = *(u32 *)&adaptExt->pci_config_buf[where];
167
    return 0;
168
}
169

170
static size_t pci_get_resource_len(void *context, int bar)
171
{
172
    PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)context;
173
    if (bar < PCI_TYPE0_ADDRESSES) {
174
        return adaptExt->pci_bars[bar].uLength;
175
    }
176
    return 0;
177
}
178

179
static void *pci_map_address_range(void *context, int bar, size_t offset, size_t maxlen)
180
{
181
    PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)context;
182
    if (bar < PCI_TYPE0_ADDRESSES) {
183
        PVIRTIO_BAR pBar = &adaptExt->pci_bars[bar];
184
        if (pBar->pBase == NULL) {
185
            pBar->pBase = StorPortGetDeviceBase(
186
                adaptExt,
187
                PCIBus,
188
                adaptExt->system_io_bus_number,
189
                pBar->BasePA,
190
                pBar->uLength,
191
                !!pBar->bPortSpace);
192
        }
193
        if (pBar->pBase != NULL && offset < pBar->uLength) {
194
            return (PUCHAR)pBar->pBase + offset;
195
        }
196
    }
197
    return NULL;
198
}
199

200
static u16 vdev_get_msix_vector(void *context, int queue)
201
{
202
    PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)context;
203
    u16 vector = VIRTIO_MSI_NO_VECTOR;
204

205
    if (queue >= 0) {
206
        /* queue interrupt */
207
        if (adaptExt->msix_enabled) {
208
            if (adaptExt->msix_one_vector) {
209
                vector = 0;
210
            } else {
211
                vector = queue + 1;
212
            }
213
        }
214
    } else {
215
        /* on-device-config-change interrupt */
216
        if (!adaptExt->msix_one_vector) {
217
            vector = VIRTIO_BLK_MSIX_CONFIG_VECTOR;
218
        }
219
    }
220

221
    return vector;
222
}
223

224
static void vdev_sleep(void *context, unsigned int msecs)
225
{
226
    UNREFERENCED_PARAMETER(context);
227

228
    /* We can't really sleep in a storage miniport so we just busy wait. */
229
    StorPortStallExecution(1000 * msecs);
230
}
231

232
VirtIOSystemOps VioStorSystemOps = {
233
    .vdev_read_byte = ReadVirtIODeviceByte,
234
    .vdev_read_word = ReadVirtIODeviceWord,
235
    .vdev_read_dword = ReadVirtIODeviceRegister,
236
    .vdev_write_byte = WriteVirtIODeviceByte,
237
    .vdev_write_word = WriteVirtIODeviceWord,
238
    .vdev_write_dword = WriteVirtIODeviceRegister,
239
    .mem_alloc_contiguous_pages = mem_alloc_contiguous_pages,
240
    .mem_free_contiguous_pages = mem_free_contiguous_pages,
241
    .mem_get_physical_address = mem_get_physical_address,
242
    .mem_alloc_nonpaged_block = mem_alloc_nonpaged_block,
243
    .mem_free_nonpaged_block = mem_free_nonpaged_block,
244
    .pci_read_config_byte = pci_read_config_byte,
245
    .pci_read_config_word = pci_read_config_word,
246
    .pci_read_config_dword = pci_read_config_dword,
247
    .pci_get_resource_len = pci_get_resource_len,
248
    .pci_map_address_range = pci_map_address_range,
249
    .vdev_get_msix_vector = vdev_get_msix_vector,
250
    .vdev_sleep = vdev_sleep,
251
};
252

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.