kvm-guest-drivers-windows
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#endif43
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 0xFFFF49
50static u32 ReadVirtIODeviceRegister(ULONG_PTR ulRegister)51{
52if (ulRegister & ~PORT_MASK) {53return StorPortReadRegisterUlong(NULL, (PULONG)(ulRegister));54} else {55return StorPortReadPortUlong(NULL, (PULONG)(ulRegister));56}57}
58
59static void WriteVirtIODeviceRegister(ULONG_PTR ulRegister, u32 ulValue)60{
61if (ulRegister & ~PORT_MASK) {62StorPortWriteRegisterUlong(NULL, (PULONG)(ulRegister), (ULONG)(ulValue));63} else {64StorPortWritePortUlong(NULL, (PULONG)(ulRegister), (ULONG)(ulValue));65}66}
67
68static u8 ReadVirtIODeviceByte(ULONG_PTR ulRegister)69{
70if (ulRegister & ~PORT_MASK) {71return StorPortReadRegisterUchar(NULL, (PUCHAR)(ulRegister));72} else {73return StorPortReadPortUchar(NULL, (PUCHAR)(ulRegister));74}75}
76
77static void WriteVirtIODeviceByte(ULONG_PTR ulRegister, u8 bValue)78{
79if (ulRegister & ~PORT_MASK) {80StorPortWriteRegisterUchar(NULL, (PUCHAR)(ulRegister), (UCHAR)(bValue));81} else {82StorPortWritePortUchar(NULL, (PUCHAR)(ulRegister), (UCHAR)(bValue));83}84}
85
86static u16 ReadVirtIODeviceWord(ULONG_PTR ulRegister)87{
88if (ulRegister & ~PORT_MASK) {89return StorPortReadRegisterUshort(NULL, (PUSHORT)(ulRegister));90} else {91return StorPortReadPortUshort(NULL, (PUSHORT)(ulRegister));92}93}
94
95static void WriteVirtIODeviceWord(ULONG_PTR ulRegister, u16 wValue)96{
97if (ulRegister & ~PORT_MASK) {98StorPortWriteRegisterUshort(NULL, (PUSHORT)(ulRegister), (USHORT)(wValue));99} else {100StorPortWritePortUshort(NULL, (PUSHORT)(ulRegister), (USHORT)(wValue));101}102}
103
104static void *mem_alloc_contiguous_pages(void *context, size_t size)105{
106PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)context;107PVOID ptr = (PVOID)((ULONG_PTR)adaptExt->pageAllocationVa + adaptExt->pageOffset);108
109if ((adaptExt->pageOffset + size) <= adaptExt->pageAllocationSize) {110size = ROUND_TO_PAGES(size);111adaptExt->pageOffset += size;112RtlZeroMemory(ptr, size);113return ptr;114} else {115RhelDbgPrint(TRACE_LEVEL_FATAL, " Ran out of memory in (%Id)\n", size);116return NULL;117}118}
119
120static void mem_free_contiguous_pages(void *context, void *virt)121{
122UNREFERENCED_PARAMETER(context);123UNREFERENCED_PARAMETER(virt);124
125/* We allocate pages from a single uncached extension by simply moving the126* adaptExt->allocationOffset pointer forward. Nothing to do here.
127*/
128}
129
130static ULONGLONG mem_get_physical_address(void *context, void *virt)131{
132ULONG uLength;133STOR_PHYSICAL_ADDRESS pa = StorPortGetPhysicalAddress(context, NULL, virt, &uLength);134return pa.QuadPart;135}
136
137static void *mem_alloc_nonpaged_block(void *context, size_t size)138{
139return VioStorPoolAlloc(context, size);140}
141
142static void mem_free_nonpaged_block(void *context, void *addr)143{
144/* We allocate memory from a single non-paged pool allocation by simply moving145* the adaptExt->poolOffset pointer forward. Nothing to do here.
146*/
147}
148
149static int pci_read_config_byte(void *context, int where, u8 *bVal)150{
151PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)context;152*bVal = adaptExt->pci_config_buf[where];153return 0;154}
155
156static int pci_read_config_word(void *context, int where, u16 *wVal)157{
158PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)context;159*wVal = *(u16 *)&adaptExt->pci_config_buf[where];160return 0;161}
162
163static int pci_read_config_dword(void *context, int where, u32 *dwVal)164{
165PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)context;166*dwVal = *(u32 *)&adaptExt->pci_config_buf[where];167return 0;168}
169
170static size_t pci_get_resource_len(void *context, int bar)171{
172PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)context;173if (bar < PCI_TYPE0_ADDRESSES) {174return adaptExt->pci_bars[bar].uLength;175}176return 0;177}
178
179static void *pci_map_address_range(void *context, int bar, size_t offset, size_t maxlen)180{
181PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)context;182if (bar < PCI_TYPE0_ADDRESSES) {183PVIRTIO_BAR pBar = &adaptExt->pci_bars[bar];184if (pBar->pBase == NULL) {185pBar->pBase = StorPortGetDeviceBase(186adaptExt,187PCIBus,188adaptExt->system_io_bus_number,189pBar->BasePA,190pBar->uLength,191!!pBar->bPortSpace);192}193if (pBar->pBase != NULL && offset < pBar->uLength) {194return (PUCHAR)pBar->pBase + offset;195}196}197return NULL;198}
199
200static u16 vdev_get_msix_vector(void *context, int queue)201{
202PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)context;203u16 vector = VIRTIO_MSI_NO_VECTOR;204
205if (queue >= 0) {206/* queue interrupt */207if (adaptExt->msix_enabled) {208if (adaptExt->msix_one_vector) {209vector = 0;210} else {211vector = queue + 1;212}213}214} else {215/* on-device-config-change interrupt */216if (!adaptExt->msix_one_vector) {217vector = VIRTIO_BLK_MSIX_CONFIG_VECTOR;218}219}220
221return vector;222}
223
224static void vdev_sleep(void *context, unsigned int msecs)225{
226UNREFERENCED_PARAMETER(context);227
228/* We can't really sleep in a storage miniport so we just busy wait. */229StorPortStallExecution(1000 * msecs);230}
231
232VirtIOSystemOps 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