TianoCore EDK2 master
Loading...
Searching...
No Matches
XenBusDxe.c
Go to the documentation of this file.
1
20#include <Library/DebugLib.h>
22
23#include "XenBusDxe.h"
24
25#include "GrantTable.h"
26#include "XenStore.h"
27#include "XenBus.h"
28
29#include <IndustryStandard/Xen/hvm/params.h>
30#include <IndustryStandard/Xen/memory.h>
31
39 XENBUS_DXE_VERSION,
40 NULL,
41 NULL
42};
43
44STATIC EFI_LOCK mMyDeviceLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_CALLBACK);
45STATIC XENBUS_DEVICE *mMyDevice = NULL;
46
61 )
62{
63 xen_add_to_physmap_t Parameter;
64
65 ASSERT (Dev->SharedInfo == NULL);
66
67 Parameter.domid = DOMID_SELF;
68 Parameter.space = XENMAPSPACE_shared_info;
69 Parameter.idx = 0;
70
71 //
72 // using reserved page because the page is not released when Linux is
73 // starting because of the add_to_physmap. QEMU might try to access the
74 // page, and fail because it have no right to do so (segv).
75 //
76 Dev->SharedInfo = AllocateReservedPages (1);
77 Parameter.gpfn = (UINTN)Dev->SharedInfo >> EFI_PAGE_SHIFT;
78 if (XenHypercallMemoryOp (XENMEM_add_to_physmap, &Parameter) != 0) {
79 FreePages (Dev->SharedInfo, 1);
80 Dev->SharedInfo = NULL;
81 return EFI_LOAD_ERROR;
82 }
83
84 return EFI_SUCCESS;
85}
86
97EFIAPI
99 IN EFI_HANDLE ImageHandle
100 )
101{
102 EFI_STATUS Status;
103
104 EFI_HANDLE *HandleBuffer;
105 UINTN HandleCount;
106 UINTN Index;
107
108 //
109 // Retrieve array of all handles in the handle database
110 //
111 Status = gBS->LocateHandleBuffer (
113 NULL,
114 NULL,
115 &HandleCount,
116 &HandleBuffer
117 );
118 if (EFI_ERROR (Status)) {
119 return Status;
120 }
121
122 //
123 // Disconnect the current driver from handles in the handle database
124 //
125 for (Index = 0; Index < HandleCount; Index++) {
126 gBS->DisconnectController (HandleBuffer[Index], gImageHandle, NULL);
127 }
128
129 //
130 // Free the array of handles
131 //
132 FreePool (HandleBuffer);
133
134 //
135 // Uninstall protocols installed in the driver entry point
136 //
137 Status = gBS->UninstallMultipleProtocolInterfaces (
138 ImageHandle,
139 &gEfiDriverBindingProtocolGuid,
141 &gEfiComponentNameProtocolGuid,
143 &gEfiComponentName2ProtocolGuid,
145 NULL
146 );
147 if (EFI_ERROR (Status)) {
148 return Status;
149 }
150
151 return EFI_SUCCESS;
152}
153
167EFIAPI
169 IN EFI_HANDLE ImageHandle,
170 IN EFI_SYSTEM_TABLE *SystemTable
171 )
172{
173 EFI_STATUS Status;
174
175 if (!XenHypercallIsAvailable ()) {
176 return EFI_ABORTED;
177 }
178
179 //
180 // Install UEFI Driver Model protocol(s).
181 //
183 ImageHandle,
184 SystemTable,
186 ImageHandle,
189 );
190 ASSERT_EFI_ERROR (Status);
191
192 return Status;
193}
194
224EFIAPI
227 IN EFI_HANDLE ControllerHandle,
228 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
229 )
230{
231 EFI_STATUS Status;
232 XENIO_PROTOCOL *XenIo;
233
234 Status = gBS->OpenProtocol (
235 ControllerHandle,
236 &gXenIoProtocolGuid,
237 (VOID **)&XenIo,
238 This->DriverBindingHandle,
239 ControllerHandle,
240 EFI_OPEN_PROTOCOL_BY_DRIVER
241 );
242
243 if (EFI_ERROR (Status)) {
244 return Status;
245 }
246
247 gBS->CloseProtocol (
248 ControllerHandle,
249 &gXenIoProtocolGuid,
250 This->DriverBindingHandle,
251 ControllerHandle
252 );
253
254 return Status;
255}
256
257VOID
258EFIAPI
259NotifyExitBoot (
260 IN EFI_EVENT Event,
261 IN VOID *Context
262 )
263{
264 XENBUS_DEVICE *Dev = Context;
265
266 gBS->DisconnectController (
267 Dev->ControllerHandle,
268 Dev->This->DriverBindingHandle,
269 NULL
270 );
271}
272
311EFIAPI
314 IN EFI_HANDLE ControllerHandle,
315 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
316 )
317{
318 EFI_STATUS Status;
319 XENBUS_DEVICE *Dev;
320 XENIO_PROTOCOL *XenIo;
321 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
322
323 Status = gBS->OpenProtocol (
324 ControllerHandle,
325 &gXenIoProtocolGuid,
326 (VOID **)&XenIo,
327 This->DriverBindingHandle,
328 ControllerHandle,
329 EFI_OPEN_PROTOCOL_BY_DRIVER
330 );
331
332 if (EFI_ERROR (Status)) {
333 return Status;
334 }
335
336 Status = gBS->OpenProtocol (
337 ControllerHandle,
338 &gEfiDevicePathProtocolGuid,
339 (VOID **)&DevicePath,
340 This->DriverBindingHandle,
341 ControllerHandle,
342 EFI_OPEN_PROTOCOL_BY_DRIVER
343 );
344
345 if (EFI_ERROR (Status)) {
346 goto ErrorOpenningProtocol;
347 }
348
349 Dev = AllocateZeroPool (sizeof (*Dev));
350 Dev->Signature = XENBUS_DEVICE_SIGNATURE;
351 Dev->This = This;
352 Dev->ControllerHandle = ControllerHandle;
353 Dev->XenIo = XenIo;
354 Dev->DevicePath = DevicePath;
355 InitializeListHead (&Dev->ChildList);
356
357 EfiAcquireLock (&mMyDeviceLock);
358 if (mMyDevice != NULL) {
359 EfiReleaseLock (&mMyDeviceLock);
360 //
361 // There is already a XenBus running, only one can be used at a time.
362 //
363 Status = EFI_ALREADY_STARTED;
364 goto ErrorAllocated;
365 }
366
367 mMyDevice = Dev;
368 EfiReleaseLock (&mMyDeviceLock);
369
370 Status = XenGetSharedInfoPage (Dev);
371 if (EFI_ERROR (Status)) {
372 DEBUG ((DEBUG_ERROR, "XenBus: Unable to get the shared info page.\n"));
373 Status = EFI_UNSUPPORTED;
374 goto ErrorAllocated;
375 }
376
377 XenGrantTableInit (Dev);
378
379 Status = XenStoreInit (Dev);
380 ASSERT_EFI_ERROR (Status);
381
382 XenBusEnumerateBus (Dev);
383
384 Status = gBS->CreateEvent (
385 EVT_SIGNAL_EXIT_BOOT_SERVICES,
386 TPL_CALLBACK,
387 NotifyExitBoot,
388 (VOID *)Dev,
389 &Dev->ExitBootEvent
390 );
391 ASSERT_EFI_ERROR (Status);
392
393 return EFI_SUCCESS;
394
395ErrorAllocated:
396 FreePool (Dev);
397 gBS->CloseProtocol (
398 ControllerHandle,
399 &gEfiDevicePathProtocolGuid,
400 This->DriverBindingHandle,
401 ControllerHandle
402 );
403ErrorOpenningProtocol:
404 gBS->CloseProtocol (
405 ControllerHandle,
406 &gXenIoProtocolGuid,
407 This->DriverBindingHandle,
408 ControllerHandle
409 );
410 return Status;
411}
412
440EFIAPI
443 IN EFI_HANDLE ControllerHandle,
444 IN UINTN NumberOfChildren,
445 IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
446 )
447{
448 UINTN Index;
449 XENBUS_PROTOCOL *XenBusIo;
450 XENBUS_PRIVATE_DATA *ChildData;
451 EFI_STATUS Status;
452 XENBUS_DEVICE *Dev = mMyDevice;
453
454 for (Index = 0; Index < NumberOfChildren; Index++) {
455 Status = gBS->OpenProtocol (
456 ChildHandleBuffer[Index],
457 &gXenBusProtocolGuid,
458 (VOID **)&XenBusIo,
459 This->DriverBindingHandle,
460 ControllerHandle,
461 EFI_OPEN_PROTOCOL_GET_PROTOCOL
462 );
463 if (EFI_ERROR (Status)) {
464 DEBUG ((DEBUG_ERROR, "XenBusDxe: get children protocol failed: %r\n", Status));
465 continue;
466 }
467
468 ChildData = XENBUS_PRIVATE_DATA_FROM_THIS (XenBusIo);
469
470 Status = gBS->CloseProtocol (
471 Dev->ControllerHandle,
472 &gXenIoProtocolGuid,
473 Dev->This->DriverBindingHandle,
474 ChildData->Handle
475 );
476 ASSERT_EFI_ERROR (Status);
477
478 Status = gBS->UninstallMultipleProtocolInterfaces (
479 ChildData->Handle,
480 &gEfiDevicePathProtocolGuid,
481 ChildData->DevicePath,
482 &gXenBusProtocolGuid,
483 &ChildData->XenBusIo,
484 NULL
485 );
486 ASSERT_EFI_ERROR (Status);
487
488 FreePool ((VOID *)ChildData->XenBusIo.Type);
489 FreePool ((VOID *)ChildData->XenBusIo.Node);
490 FreePool ((VOID *)ChildData->XenBusIo.Backend);
491 FreePool (ChildData->DevicePath);
492 RemoveEntryList (&ChildData->Link);
493 FreePool (ChildData);
494 }
495
496 if (NumberOfChildren > 0) {
497 return EFI_SUCCESS;
498 }
499
500 gBS->CloseEvent (Dev->ExitBootEvent);
501 XenStoreDeinit (Dev);
502 XenGrantTableDeinit (Dev);
503
504 gBS->CloseProtocol (
505 ControllerHandle,
506 &gEfiDevicePathProtocolGuid,
507 This->DriverBindingHandle,
508 ControllerHandle
509 );
510 gBS->CloseProtocol (
511 ControllerHandle,
512 &gXenIoProtocolGuid,
513 This->DriverBindingHandle,
514 ControllerHandle
515 );
516
517 mMyDevice = NULL;
518 FreePool (Dev);
519 return EFI_SUCCESS;
520}
UINT64 UINTN
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
Definition: LinkedList.c:182
VOID EFIAPI FreePages(IN VOID *Buffer, IN UINTN Pages)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateReservedPages(IN UINTN Pages)
VOID XenGrantTableInit(IN XENBUS_DEVICE *Dev)
Definition: GrantTable.c:123
#define NULL
Definition: Base.h:319
#define STATIC
Definition: Base.h:264
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gXenBusDxeComponentName2
Definition: ComponentName.c:26
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gXenBusDxeComponentName
Definition: ComponentName.c:16
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_HANDLE gImageHandle
EFI_BOOT_SERVICES * gBS
#define EFI_INITIALIZE_LOCK_VARIABLE(Priority)
Definition: UefiLib.h:313
VOID EFIAPI EfiReleaseLock(IN EFI_LOCK *Lock)
Definition: UefiLib.c:499
VOID EFIAPI EfiAcquireLock(IN EFI_LOCK *Lock)
Definition: UefiLib.c:434
EFI_STATUS EFIAPI EfiLibInstallDriverBindingComponentName2(IN CONST EFI_HANDLE ImageHandle, IN CONST EFI_SYSTEM_TABLE *SystemTable, IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, IN EFI_HANDLE DriverBindingHandle, IN CONST EFI_COMPONENT_NAME_PROTOCOL *ComponentName OPTIONAL, IN CONST EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2 OPTIONAL)
@ AllHandles
Definition: UefiSpec.h:1509
XENSTORE_STATUS XenBusEnumerateBus(XENBUS_DEVICE *Dev)
Definition: XenBus.c:313
EFI_STATUS EFIAPI XenBusDxeUnload(IN EFI_HANDLE ImageHandle)
Definition: XenBusDxe.c:98
EFI_STATUS EFIAPI XenBusDxeDriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer OPTIONAL)
Definition: XenBusDxe.c:441
EFI_STATUS EFIAPI XenBusDxeDriverEntryPoint(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: XenBusDxe.c:168
EFI_DRIVER_BINDING_PROTOCOL gXenBusDxeDriverBinding
Definition: XenBusDxe.c:35
EFI_STATUS EFIAPI XenBusDxeDriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL)
Definition: XenBusDxe.c:225
EFI_STATUS EFIAPI XenBusDxeDriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL)
Definition: XenBusDxe.c:312
STATIC EFI_STATUS XenGetSharedInfoPage(IN OUT XENBUS_DEVICE *Dev)
Definition: XenBusDxe.c:59
INTN EFIAPI XenHypercallMemoryOp(IN UINTN Operation, IN OUT VOID *Arguments)
Definition: XenHypercall.c:65
BOOLEAN EFIAPI XenHypercallIsAvailable(VOID)
EFI_STATUS XenStoreInit(XENBUS_DEVICE *Dev)
Definition: XenStore.c:1085
VOID XenStoreDeinit(IN XENBUS_DEVICE *Dev)
Definition: XenStore.c:1124