• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2 
3   Declarations of utility functions used by virtio device drivers.
4 
5   Copyright (C) 2012, Red Hat, Inc.
6 
7   This program and the accompanying materials are licensed and made available
8   under the terms and conditions of the BSD License which accompanies this
9   distribution. The full text of the license may be found at
10   http://opensource.org/licenses/bsd-license.php
11 
12   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
13   WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 
15 **/
16 
17 #ifndef _VIRTIO_LIB_H_
18 #define _VIRTIO_LIB_H_
19 
20 #include <Protocol/VirtioDevice.h>
21 
22 #include <IndustryStandard/Virtio.h>
23 
24 
25 /**
26 
27   Configure a virtio ring.
28 
29   This function sets up internal storage (the guest-host communication area)
30   and lays out several "navigation" (ie. no-ownership) pointers to parts of
31   that storage.
32 
33   Relevant sections from the virtio-0.9.5 spec:
34   - 1.1 Virtqueues,
35   - 2.3 Virtqueue Configuration.
36 
37   @param[in]                    The number of descriptors to allocate for the
38                                 virtio ring, as requested by the host.
39 
40   @param[out] Ring              The virtio ring to set up.
41 
42   @retval EFI_OUT_OF_RESOURCES  AllocatePages() failed to allocate contiguous
43                                 pages for the requested QueueSize. Fields of
44                                 Ring have indeterminate value.
45 
46   @retval EFI_SUCCESS           Allocation and setup successful. Ring->Base
47                                 (and nothing else) is responsible for
48                                 deallocation.
49 
50 **/
51 EFI_STATUS
52 EFIAPI
53 VirtioRingInit (
54   IN  UINT16 QueueSize,
55   OUT VRING  *Ring
56   );
57 
58 
59 /**
60 
61   Tear down the internal resources of a configured virtio ring.
62 
63   The caller is responsible to stop the host from using this ring before
64   invoking this function: the VSTAT_DRIVER_OK bit must be clear in
65   VhdrDeviceStatus.
66 
67   @param[out] Ring  The virtio ring to clean up.
68 
69 **/
70 VOID
71 EFIAPI
72 VirtioRingUninit (
73   IN OUT VRING *Ring
74   );
75 
76 
77 //
78 // Internal use structure for tracking the submission of a multi-descriptor
79 // request.
80 //
81 typedef struct {
82   UINT16 HeadDescIdx;
83   UINT16 NextDescIdx;
84 } DESC_INDICES;
85 
86 
87 /**
88 
89   Turn off interrupt notifications from the host, and prepare for appending
90   multiple descriptors to the virtio ring.
91 
92   The calling driver must be in VSTAT_DRIVER_OK state.
93 
94   @param[in,out] Ring  The virtio ring we intend to append descriptors to.
95 
96   @param[out] Indices  The DESC_INDICES structure to initialize.
97 
98 **/
99 VOID
100 EFIAPI
101 VirtioPrepare (
102   IN OUT VRING        *Ring,
103   OUT    DESC_INDICES *Indices
104   );
105 
106 
107 /**
108 
109   Append a contiguous buffer for transmission / reception via the virtio ring.
110 
111   This function implements the following section from virtio-0.9.5:
112   - 2.4.1.1 Placing Buffers into the Descriptor Table
113 
114   Free space is taken as granted, since the individual drivers support only
115   synchronous requests and host side status is processed in lock-step with
116   request submission. It is the calling driver's responsibility to verify the
117   ring size in advance.
118 
119   The caller is responsible for initializing *Indices with VirtioPrepare()
120   first.
121 
122   @param[in,out] Ring        The virtio ring to append the buffer to, as a
123                              descriptor.
124 
125   @param[in] BufferPhysAddr  (Guest pseudo-physical) start address of the
126                              transmit / receive buffer.
127 
128   @param[in] BufferSize      Number of bytes to transmit or receive.
129 
130   @param[in] Flags           A bitmask of VRING_DESC_F_* flags. The caller
131                              computes this mask dependent on further buffers to
132                              append and transfer direction.
133                              VRING_DESC_F_INDIRECT is unsupported. The
134                              VRING_DESC.Next field is always set, but the host
135                              only interprets it dependent on VRING_DESC_F_NEXT.
136 
137   @param[in,out] Indices     Indices->HeadDescIdx is not accessed.
138                              On input, Indices->NextDescIdx identifies the next
139                              descriptor to carry the buffer. On output,
140                              Indices->NextDescIdx is incremented by one, modulo
141                              2^16.
142 
143 **/
144 VOID
145 EFIAPI
146 VirtioAppendDesc (
147   IN OUT VRING        *Ring,
148   IN     UINTN        BufferPhysAddr,
149   IN     UINT32       BufferSize,
150   IN     UINT16       Flags,
151   IN OUT DESC_INDICES *Indices
152   );
153 
154 
155 /**
156 
157   Notify the host about the descriptor chain just built, and wait until the
158   host processes it.
159 
160   @param[in] VirtIo       The target virtio device to notify.
161 
162   @param[in] VirtQueueId  Identifies the queue for the target device.
163 
164   @param[in,out] Ring     The virtio ring with descriptors to submit.
165 
166   @param[in] Indices      Indices->NextDescIdx is not accessed.
167                           Indices->HeadDescIdx identifies the head descriptor
168                           of the descriptor chain.
169 
170 
171   @return              Error code from VirtIo->SetQueueNotify() if it fails.
172 
173   @retval EFI_SUCCESS  Otherwise, the host processed all descriptors.
174 
175 **/
176 EFI_STATUS
177 EFIAPI
178 VirtioFlush (
179   IN     VIRTIO_DEVICE_PROTOCOL *VirtIo,
180   IN     UINT16                 VirtQueueId,
181   IN OUT VRING                  *Ring,
182   IN     DESC_INDICES           *Indices
183   );
184 
185 #endif // _VIRTIO_LIB_H_
186