/src/hbfa-fl/HBFA/UefiHostFuzzTestCasePkg/TestCase/OvmfPkg/VirtioPciDeviceDxe/TestVirtioPciDevice.c
Line | Count | Source (jump to first uncovered line) |
1 | | /** @file |
2 | | |
3 | | Copyright (c) 2018, Intel Corporation. All rights reserved.<BR> |
4 | | SPDX-License-Identifier: BSD-2-Clause-Patent |
5 | | |
6 | | **/ |
7 | | |
8 | | #include <stdio.h> |
9 | | #include <stdlib.h> |
10 | | #include <string.h> |
11 | | #include <assert.h> |
12 | | |
13 | | #include <Uefi.h> |
14 | | |
15 | | #include <Library/BaseLib.h> |
16 | | #include <Library/DebugLib.h> |
17 | | #include <Library/BaseMemoryLib.h> |
18 | | #include <Library/MemoryAllocationLib.h> |
19 | | #include <Library/VirtioPciDeviceStubLib.h> |
20 | | #include <Library/PciCapPciIoLib.h> |
21 | | #include <Library/PciCapLib.h> |
22 | | |
23 | 3.23k | #define TOTAL_SIZE (512 * 1024) |
24 | | #define BLOCK_SIZE (512) |
25 | | #define IO_ALIGN (1) |
26 | | |
27 | | UINTN |
28 | | EFIAPI |
29 | | GetMaxBufferSize ( |
30 | | VOID |
31 | | ) |
32 | 3.23k | { |
33 | 3.23k | return TOTAL_SIZE; |
34 | 3.23k | } |
35 | | |
36 | | EFI_STATUS |
37 | | EFIAPI |
38 | | ParseCapabilities ( |
39 | | IN OUT VIRTIO_1_0_DEV *Device |
40 | | ) |
41 | 311 | { |
42 | 311 | EFI_STATUS Status; |
43 | 311 | PCI_CAP_DEV *PciDevice; |
44 | 311 | PCI_CAP_LIST *CapList; |
45 | 311 | UINT16 VendorInstance; |
46 | 311 | PCI_CAP *VendorCap; |
47 | | |
48 | 311 | Status = PciCapPciIoDeviceInit (Device->PciIo, &PciDevice); |
49 | 311 | if (EFI_ERROR (Status)) { |
50 | 0 | return Status; |
51 | 0 | } |
52 | | |
53 | 311 | Status = PciCapListInit (PciDevice, &CapList); |
54 | 311 | if (EFI_ERROR (Status)) { |
55 | 74 | goto UninitPciDevice; |
56 | 74 | } |
57 | | |
58 | 237 | for (VendorInstance = 0; |
59 | 771 | !EFI_ERROR (PciCapListFindCap (CapList, PciCapNormal, |
60 | 237 | EFI_PCI_CAPABILITY_ID_VENDOR, VendorInstance, |
61 | 237 | &VendorCap)); |
62 | 574 | VendorInstance++) { |
63 | 574 | UINT8 CapLen; |
64 | 574 | VIRTIO_PCI_CAP VirtIoCap; |
65 | 574 | VIRTIO_1_0_CONFIG *ParsedConfig; |
66 | | |
67 | | // |
68 | | // Big enough to accommodate a VIRTIO_PCI_CAP structure? |
69 | | // |
70 | 574 | Status = PciCapRead (PciDevice, VendorCap, |
71 | 574 | OFFSET_OF (EFI_PCI_CAPABILITY_VENDOR_HDR, Length), &CapLen, |
72 | 574 | sizeof CapLen); |
73 | 574 | if (EFI_ERROR (Status)) { |
74 | 0 | goto UninitCapList; |
75 | 0 | } |
76 | 574 | if (CapLen < sizeof VirtIoCap) { |
77 | | // |
78 | | // Too small, move to next. |
79 | | // |
80 | 401 | continue; |
81 | 401 | } |
82 | | |
83 | | // |
84 | | // Read interesting part of capability. |
85 | | // |
86 | 173 | Status = PciCapRead (PciDevice, VendorCap, 0, &VirtIoCap, sizeof VirtIoCap); |
87 | 173 | if (EFI_ERROR (Status)) { |
88 | 27 | goto UninitCapList; |
89 | 27 | } |
90 | | |
91 | 146 | switch (VirtIoCap.ConfigType) { |
92 | 34 | case VIRTIO_PCI_CAP_COMMON_CFG: |
93 | 34 | ParsedConfig = &Device->CommonConfig; |
94 | 34 | break; |
95 | 51 | case VIRTIO_PCI_CAP_NOTIFY_CFG: |
96 | 51 | ParsedConfig = &Device->NotifyConfig; |
97 | 51 | break; |
98 | 14 | case VIRTIO_PCI_CAP_DEVICE_CFG: |
99 | 14 | ParsedConfig = &Device->SpecificConfig; |
100 | 14 | break; |
101 | 47 | default: |
102 | | // |
103 | | // Capability is not interesting. |
104 | | // |
105 | 47 | continue; |
106 | 146 | } |
107 | | |
108 | | // |
109 | | // Save the location of the register block into ParsedConfig. |
110 | | // |
111 | 99 | Status = GetBarType (Device->PciIo, VirtIoCap.Bar, &ParsedConfig->BarType); |
112 | 99 | if (EFI_ERROR (Status)) { |
113 | 9 | goto UninitCapList; |
114 | 9 | } |
115 | 90 | ParsedConfig->Bar = VirtIoCap.Bar; |
116 | 90 | ParsedConfig->Offset = VirtIoCap.Offset; |
117 | 90 | ParsedConfig->Length = VirtIoCap.Length; |
118 | | |
119 | 90 | if (VirtIoCap.ConfigType == VIRTIO_PCI_CAP_NOTIFY_CFG) { |
120 | | // |
121 | | // This capability has an additional field called NotifyOffsetMultiplier; |
122 | | // parse it too. |
123 | | // |
124 | 46 | if (CapLen < sizeof VirtIoCap + sizeof Device->NotifyOffsetMultiplier) { |
125 | | // |
126 | | // Too small, move to next. |
127 | | // |
128 | 16 | continue; |
129 | 16 | } |
130 | | |
131 | 30 | Status = PciCapRead (PciDevice, VendorCap, sizeof VirtIoCap, |
132 | 30 | &Device->NotifyOffsetMultiplier, |
133 | 30 | sizeof Device->NotifyOffsetMultiplier); |
134 | 30 | if (EFI_ERROR (Status)) { |
135 | 4 | goto UninitCapList; |
136 | 4 | } |
137 | 30 | } |
138 | | |
139 | | // |
140 | | // Capability parsed successfully. |
141 | | // |
142 | 70 | ParsedConfig->Exists = TRUE; |
143 | 70 | } |
144 | | |
145 | 197 | ASSERT_EFI_ERROR (Status); |
146 | | |
147 | 237 | UninitCapList: |
148 | 237 | PciCapListUninit (CapList); |
149 | | |
150 | 311 | UninitPciDevice: |
151 | 311 | PciCapPciIoDeviceUninit (PciDevice); |
152 | | |
153 | 311 | return Status; |
154 | 237 | } |
155 | | |
156 | | VOID |
157 | | EFIAPI |
158 | | RunTestHarness( |
159 | | IN VOID *TestBuffer, |
160 | | IN UINTN TestBufferSize |
161 | | ) |
162 | 411 | { |
163 | 411 | VIRTIO_1_0_DEV *VirtioPciDevice; |
164 | 411 | EFI_STATUS Status; |
165 | 411 | EFI_PCI_IO_PROTOCOL *PciIo; |
166 | | |
167 | 411 | VirtioPciDevice = (VIRTIO_1_0_DEV *) AllocateZeroPool(sizeof (*VirtioPciDevice)); |
168 | | |
169 | 411 | PciIo = (EFI_PCI_IO_PROTOCOL *)AllocateZeroPool(sizeof (*PciIo)); |
170 | | |
171 | 411 | VirtioPciDevice->PciIo = PciIo; |
172 | | |
173 | 411 | Status = InitVirtioPciDevice (VirtioPciDevice, TestBuffer, TestBufferSize, PciIo); |
174 | | |
175 | 411 | if (!EFI_ERROR(Status)) { |
176 | 311 | ParseCapabilities (VirtioPciDevice); |
177 | 311 | } |
178 | | |
179 | 411 | FreePool (PciIo); |
180 | 411 | FreePool (VirtioPciDevice); |
181 | 411 | } |