VirtualBox

source: vbox/trunk/src/VBox/Devices/VirtIO/Virtio_1_0.h@ 81126

Last change on this file since 81126 was 81122, checked in by vboxsync, 5 years ago

Storage/DevVirtioSCSI.cpp: Got MSI-X support implemented and a few other small inconsequential tweaks

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.6 KB
Line 
1/* $Id: Virtio_1_0.h 81122 2019-10-07 08:54:00Z vboxsync $ */
2/** @file
3 * Virtio_1_0.h - Virtio Declarations
4 */
5
6/*
7 * Copyright (C) 2009-2019 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifndef VBOX_INCLUDED_SRC_VirtIO_Virtio_1_0_h
19#define VBOX_INCLUDED_SRC_VirtIO_Virtio_1_0_h
20#ifndef RT_WITHOUT_PRAGMA_ONCE
21# pragma once
22#endif
23
24#include <iprt/ctype.h>
25#include <iprt/sg.h>
26
27typedef void * VIRTIOHANDLE; /**< Opaque handle to the VirtIO framework */
28
29
30/**
31 * Important sizing and bounds params for this impl. of VirtIO 1.0 PCI device
32 */
33 /**
34 * TEMPORARY NOTE: Some of these values are experimental during development and will likely change.
35 */
36#define VIRTIO_MAX_QUEUE_NAME_SIZE 32 /**< Maximum length of a queue name */
37#define VIRTQ_MAX_SIZE 1024 /**< Max size (# desc elements) of a virtq */
38#define VIRTQ_MAX_CNT 24 /**< Max queues we allow guest to create */
39#define VIRTIO_NOTIFY_OFFSET_MULTIPLIER 2 /**< VirtIO Notify Cap. MMIO config param */
40#define VIRTIO_REGION_PCI_CAP 2 /**< BAR for VirtIO Cap. MMIO (impl specific) */
41#define VIRTIO_REGION_MSIX_CAP 0 /**< Bar for MSI-X handling */
42
43#define VIRTIO_HEX_DUMP(logLevel, pv, cb, base, title) \
44 do { \
45 if (LogIsItEnabled(logLevel, LOG_GROUP)) \
46 virtioHexDump((pv), (cb), (base), (title)); \
47 } while (0)
48
49
50/**
51 * The following structure holds the pre-processed context of descriptor chain pulled from a virtio queue
52 * to conduct a transaction between the client of this virtio implementation and the guest VM's virtio driver.
53 * It contains the head index of the descriptor chain, the output data from the client that has been
54 * converted to a contiguous virtual memory and a physical memory scatter-gather buffer for use by by
55 * the virtio framework to complete the transaction in the final phase of round-trip processing.
56 *
57 * The client should not modify the contents of this buffer. The primary field of interest to the
58 * client is pVirtSrc, which contains the VirtIO "OUT" (to device) buffer from the guest.
59 *
60 * Typical use is, When the client (worker thread) detects available data on the queue, it pulls the
61 * next one of these descriptor chain structs off the queue using virtioQueueGet(), processes the
62 * virtual memory buffer pVirtSrc, produces result data to pass back to the guest driver and calls
63 * virtioQueuePut() to return the result data to the client.
64 */
65typedef struct VIRTIO_DESC_CHAIN
66{
67 uint32_t uHeadIdx; /**< Head idx of associated desc chain */
68 uint32_t cbVirtSrc; /**< Size of virt source buffer */
69 void *pVirtSrc; /**< Virt mem buf holding out data from guest */
70 uint32_t cbPhysDst; /**< Total size of dst buffer */
71 PRTSGBUF pSgPhysDst; /**< Phys S/G buf to store result for guest */
72} VIRTIO_DESC_CHAIN_T, *PVIRTIO_DESC_CHAIN_T, **PPVIRTIO_DESC_CHAIN_T;
73
74/**
75 * The following structure is used to pass the PCI parameters from the consumer
76 * to this generic VirtIO framework. This framework provides the Vendor ID as Virtio.
77 */
78typedef struct VIRTIOPCIPARAMS
79{
80 uint16_t uDeviceId; /**< PCI Cfg Device ID */
81 uint16_t uClassBase; /**< PCI Cfg Base Class */
82 uint16_t uClassSub; /**< PCI Cfg Subclass */
83 uint16_t uClassProg; /**< PCI Cfg Programming Interface Class */
84 uint16_t uSubsystemId; /**< PCI Cfg Card Manufacturer Vendor ID */
85 uint16_t uSubsystemVendorId; /**< PCI Cfg Chipset Manufacturer Vendor ID */
86 uint16_t uRevisionId; /**< PCI Cfg Revision ID */
87 uint16_t uInterruptLine; /**< PCI Cfg Interrupt line */
88 uint16_t uInterruptPin; /**< PCI Cfg Interrupt pin */
89} VIRTIOPCIPARAMS, *PVIRTIOPCIPARAMS;
90
91/**
92 * Implementation-specific client callback to notify client of significant device status
93 * changes.
94 *
95 * @param hVirtio Handle to VirtIO framework
96 * @param fDriverOk True if guest driver is okay (thus queues, etc... are valid)
97 * @param pClient Pointer to opaque client data (state)
98 */
99typedef DECLCALLBACK(void) FNVIRTIOSTATUSCHANGED(VIRTIOHANDLE hVirtio, void *pClient, uint32_t fDriverOk);
100typedef FNVIRTIOSTATUSCHANGED *PFNVIRTIOSTATUSCHANGED;
101
102/**
103 * When guest-to-host queue notifications are enabled, the guest driver notifies the host
104 * that the avail queue has buffers, and this callback informs the client.
105 *
106 * @param hVirtio Handle to the VirtIO framework
107 * @param qIdx Index of the notified queue
108 * @param pClient Pointer to opaque client data (state)
109 */
110typedef DECLCALLBACK(void) FNVIRTIOQUEUENOTIFIED(VIRTIOHANDLE hVirtio, void *pClient, uint16_t qIdx);
111typedef FNVIRTIOQUEUENOTIFIED *PFNVIRTIOQUEUENOTIFIED;
112
113 /**
114 * Implementation-specific client callback to access VirtIO Device-specific capabilities
115 * (other VirtIO capabilities and features are handled in VirtIO implementation)
116 *
117 * @param pDevIns The device instance.
118 * @param offset Offset within device specific capabilities struct
119 * @param pvBuf Buffer in which to save read data
120 * @param cbWrite Number of bytes to write
121 */
122typedef DECLCALLBACK(int) FNVIRTIODEVCAPWRITE(PPDMDEVINS pDevIns, uint32_t uOffset, const void *pvBuf, uint32_t cbWrite);
123typedef FNVIRTIODEVCAPWRITE *PFNVIRTIODEVCAPWRITE;
124
125/**
126 * Implementation-specific client ballback to access VirtIO Device-specific capabilities
127 * (other VirtIO capabilities and features are handled in VirtIO implementation)
128 *
129 * @param pDevIns The device instance.
130 * @param offset Offset within device specific capabilities struct
131 * @param pvBuf Buffer in which to save read data
132 * @param cbRead Number of bytes to read
133 */
134typedef DECLCALLBACK(int) FNVIRTIODEVCAPREAD(PPDMDEVINS pDevIns, uint32_t uOffset, const void *pvBuf, uint32_t cbRead);
135typedef FNVIRTIODEVCAPREAD *PFNVIRTIODEVCAPREAD;
136
137
138/** @name VirtIO port I/O callbacks.
139 * @{ */
140typedef struct VIRTIOCALLBACKS
141{
142 DECLCALLBACKMEMBER(void, pfnVirtioStatusChanged)
143 (VIRTIOHANDLE hVirtio, void *pClient, uint32_t fDriverOk);
144 DECLCALLBACKMEMBER(void, pfnVirtioQueueNotified)
145 (VIRTIOHANDLE hVirtio, void *pClient, uint16_t qIdx);
146 DECLCALLBACKMEMBER(int, pfnVirtioDevCapRead)
147 (PPDMDEVINS pDevIns, uint32_t uOffset, const void *pvBuf, uint32_t cbRead);
148 DECLCALLBACKMEMBER(int, pfnVirtioDevCapWrite)
149 (PPDMDEVINS pDevIns, uint32_t uOffset, const void *pvBuf, uint32_t cbWrite);
150 DECLCALLBACKMEMBER(int, pfnSSMDevLiveExec)
151 (PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass);
152 DECLCALLBACKMEMBER(int, pfnSSMDevSaveExec)
153 (PPDMDEVINS pDevIns, PSSMHANDLE pSSM);
154 DECLCALLBACKMEMBER(int, pfnSSMDevLoadExec)
155 (PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass);
156 DECLCALLBACKMEMBER(int, pfnSSMDevLoadDone)
157 (PPDMDEVINS pDevIns, PSSMHANDLE pSSM);
158
159} VIRTIOCALLBACKS, *PVIRTIOCALLBACKS;
160/** @} */
161
162/** API for VirtIO client */
163
164/**
165 * Allocate client context for client to work with VirtIO-provided with queue
166 *
167 * @param hVirtio - Handle to VirtIO framework
168 * @param qIdx - Queue number
169 * @param pcszName - Name to give queue
170 *
171 * @returns status VINF_SUCCESS - Success
172 * VERR_INVALID_STATE - VirtIO not in ready state
173 * VERR_NO_MEMORY - Out of memory
174 *
175 * @returns status. If false, the call failed and the client should call virtioResetAll()
176 */
177int virtioQueueAttach(VIRTIOHANDLE hVirtio, uint16_t qIdx, const char *pcszName);
178
179/**
180 * Detaches from queue and release resources
181 *
182 * @param hVirtio - Handle for VirtIO framework
183 * @param qIdx - Queue number
184 *
185 */
186int virtioQueueDetach(VIRTIOHANDLE hVirtio, uint16_t qIdx);
187
188/**
189 * Removes descriptor chain from avail ring of indicated queue and converts the descriptor
190 * chain into its OUT (to device) and IN to guest components. Additionally it converts
191 * the OUT desc chain data to a contiguous virtual memory buffer for easy consumption
192 * by the caller. The caller must return the descriptor chain pointer via virtioQueuePut()
193 * and then call virtioQueueSync() at some point to return the data to the guest and
194 * complete the transaction.
195 *
196 * @param hVirtio - Handle for VirtIO framework
197 * @param qIdx - Queue number
198 * @param fRemove - flags whether to remove desc chain from queue (false = peek)
199 * @param ppDescChain - Address to store pointer to descriptor chain that contains the
200 * pre-processed transaction information pulled from the virtq.
201 *
202 * @returns status VINF_SUCCESS - Success
203 * VERR_INVALID_STATE - VirtIO not in ready state
204 */
205int virtioQueueGet(VIRTIOHANDLE hVirtio, uint16_t qIdx, PPVIRTIO_DESC_CHAIN_T ppDescChain, bool fRemove);
206
207
208/**
209 * Returns data to the guest to complete a transaction initiated by virtQueueGet().
210 * The caller passes in a pointer to a scatter-gather buffer of virtual memory segments
211 * and a pointer to the descriptor chain context originally derived from the pulled
212 * queue entry, and this function will write the virtual memory s/g buffer into the
213 * guest's physical memory free the descriptor chain. The caller handles the freeing
214 * (as needed) of the virtual memory buffer.
215 *
216 * NOTE: This does a write-ahead to the used ring of the guest's queue.
217 * The data written won't be seen by the guest until the next call to virtioQueueSync()
218 *
219 *
220 * @param hVirtio - Handle for VirtIO framework
221 * @param qIdx - Queue number
222 *
223 * @param pSgVirtReturn - Points toscatter-gather buffer of virtual memory segments
224 the caller is returning to the guest.
225 *
226 * @param pDescChain - This contains the context of the scatter-gather buffer
227 * originally pulled from the queue.
228 *
229 * @parame fFence - If true, put up copy fence (memory barrier) after
230 * copying to guest phys. mem.
231 *
232 * @returns VINF_SUCCESS - Success
233 * VERR_INVALID_STATE - VirtIO not in ready state
234 * VERR_NOT_AVAILABLE - Queue is empty
235 */
236
237 int virtioQueuePut(VIRTIOHANDLE hVirtio, uint16_t qIdx, PRTSGBUF pSgVirtReturn,
238 PVIRTIO_DESC_CHAIN_T pDescChain, bool fFence);
239
240
241/**
242 * Updates the indicated virtq's "used ring" descriptor index to match the
243 * current write-head index, thus exposing the data added to the used ring by all
244 * virtioQueuePut() calls since the last sync. This should be called after one or
245 * more virtQueuePut() calls to inform the guest driver there is data in the queue.
246 * Explicit notifications (e.g. interrupt or MSI-X) will be sent to the guest,
247 * depending on VirtIO features negotiated and conditions, otherwise the guest
248 * will detect the update by polling. (see VirtIO 1.0
249 * specification, Section 2.4 "Virtqueues").
250 *
251 * @param hVirtio - Handle for VirtIO framework
252 * @param qIdx - Queue number
253 *
254 * @returns VINF_SUCCESS - Success
255 * VERR_INVALID_STATE - VirtIO not in ready state
256 */
257int virtioQueueSync(VIRTIOHANDLE hVirtio, uint16_t qIdx);
258
259/**
260 * Check if the associated queue is empty
261 *
262 * @param hVirtio - Handle for VirtIO framework
263 * @param qIdx - Queue number
264 *
265 * @returns true - Queue is empty or unavailable.
266 * false - Queue is available and has entries
267 */
268bool virtioQueueIsEmpty (VIRTIOHANDLE hVirtio, uint16_t qIdx);
269
270/**
271 * Return queue enable state
272 *
273 * @param hVirtio - Handle for VirtIO framework
274 * @param qIdx - Queue number
275 * @param fEnabled - Flag indicating whether to enable queue or not
276 */
277bool virtioIsQueueEnabled(VIRTIOHANDLE hVirtio, uint16_t qIdx);
278
279/**
280 * Enable or disable queue
281 *
282 * @param hVirtio - Handle for VirtIO framework
283 * @param qIdx - Queue number
284 * @param fEnabled - Flag indicating whether to enable queue or not
285 */
286void virtioQueueEnable(VIRTIOHANDLE hVirtio, uint16_t qIdx, bool fEnabled);
287
288/**
289 * Request orderly teardown of VirtIO on host and guest
290 * @param hVirtio - Handle for VirtIO framework
291 *
292 */
293void virtioResetAll(VIRTIOHANDLE hVirtio);
294
295/**
296 * This sends notification ('kicks') guest driver to check queues for any new
297 * elements in the used queue to process. It should be called after resuming
298 * in case anything was added to the queues during suspend/quiescing and a
299 * notification was missed, to prevent the guest from stalling after suspend.
300 */
301void virtioPropagateResumeNotification(VIRTIOHANDLE hVirtio);
302
303/**
304 * Get name of queue, by qIdx, assigned at virtioQueueAttach()
305 *
306 * @param hVirtio - Handle for VirtIO framework
307 * @param qIdx - Queue number
308 *
309 * @returns Success: Returns pointer to queue name
310 * Failure: Returns "<null>" (never returns NULL pointer).
311 */
312const char *virtioQueueGetName(VIRTIOHANDLE hVirtio, uint16_t qIdx);
313
314/**
315 * Get the features VirtIO is running withnow.
316 *
317 * @returns Features the guest driver has accepted, finalizing the operational features
318 *
319 */
320uint64_t virtioGetNegotiatedFeatures(VIRTIOHANDLE hVirtio);
321
322/** CLIENT MUST CALL ON RELOCATE CALLBACK! */
323void virtioRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta);
324
325/**
326 * Constructor sets up the PCI device controller and VirtIO state
327 *
328 * @param pDevIns Device instance data
329 * @param pClientContext Opaque client context (such as state struct)
330 * @param pVirtio Device State
331 * @param pPciParams Values to populate industry standard PCI Configuration Space data structure
332 * @param pcszInstance Device instance name
333 * @param uDevSpecificFeatures VirtIO device-specific features offered by client
334 * @param devCapReadCallback Client handler to call upon guest read to device specific capabilities.
335 * @param devCapWriteCallback Client handler to call upon guest write to device specific capabilities.
336 * @param devStatusChangedCallback Client handler to call for major device status changes
337 * @param queueNotifiedCallback Client handler for guest-to-host notifications that avail queue has ring data
338 * @param ssmLiveExecCallback Client handler for SSM live exec
339 * @param ssmSaveExecCallback Client handler for SSM save exec
340 * @param ssmLoadExecCallback Client handler for SSM load exec
341 * @param ssmLoadDoneCallback Client handler for SSM load done
342 * @param cbDevSpecificCfg Size of virtio_pci_device_cap device-specific configuration struct
343 * @param pDevSpecificCfg Address of client's VirtIO dev-specific configuration struct
344 */
345int virtioConstruct(PPDMDEVINS pDevIns,
346 void *pClientContext,
347 VIRTIOHANDLE *phVirtio,
348 PVIRTIOPCIPARAMS pPciParams,
349 const char *pcszInstance,
350 uint64_t uDevSpecificFeatures,
351 PFNVIRTIODEVCAPREAD devCapReadCallback,
352 PFNVIRTIODEVCAPWRITE devCapWriteCallback,
353 PFNVIRTIOSTATUSCHANGED devStatusChangedCallback,
354 PFNVIRTIOQUEUENOTIFIED queueNotifiedCallback,
355 PFNSSMDEVLIVEEXEC ssmLiveExecCallback,
356 PFNSSMDEVSAVEEXEC ssmSaveExecCallback,
357 PFNSSMDEVLOADEXEC ssmLoadExecCallback,
358 PFNSSMDEVLOADDONE ssmLoadDoneCallback,
359 uint16_t cbDevSpecificCfg,
360 void *pDevSpecificCfg);
361
362/**
363 * Log memory-mapped I/O input or output value.
364 *
365 * This is designed to be invoked by macros that can make contextual assumptions
366 * (e.g. implicitly derive MACRO parameters from the invoking function). It is exposed
367 * for the VirtIO client doing the device-specific implementation in order to log in a
368 * similar fashion accesses to the device-specific MMIO configuration structure. Macros
369 * that leverage this function are in Virtio_1_0_impl.h and can be used as an example
370 * of how to use this effectively for the device-specific code.
371 *
372 * @param pszFunc - To avoid displaying this function's name via __FUNCTION__ or LogFunc()
373 * @param pszMember - Name of struct member
374 * @param pv - pointer to value
375 * @param cb - size of value
376 * @param uOffset - offset into member where value starts
377 * @param fWrite - True if write I/O
378 * @param fHasIndex - True if the member is indexed
379 * @param idx - The index if fHasIndex
380 */
381void virtioLogMappedIoValue(const char *pszFunc, const char *pszMember, uint32_t uMemberSize,
382 const void *pv, uint32_t cb, uint32_t uOffset,
383 int fWrite, int fHasIndex, uint32_t idx);
384/**
385 * Does a formatted hex dump using Log(()), recommend using VIRTIO_HEX_DUMP() macro to
386 * control enabling of logging efficiently.
387 *
388 * @param pv - pointer to buffer to dump contents of
389 * @param cb - count of characters to dump from buffer
390 * @param uBase - base address of per-row address prefixing of hex output
391 * @param pszTitle - Optional title. If present displays title that lists
392 * provided text with value of cb to indicate size next to it.
393 */
394void virtioHexDump(uint8_t *pv, uint32_t cb, uint32_t uBase, const char *pszTitle);
395
396#endif /* !VBOX_INCLUDED_SRC_VirtIO_Virtio_1_0_h */
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette