Enforce in-order execution of these steps even on not sequentially consistent architectures, as discussed in [1]. These changes should be unnecessary on x86 (the only architecture OVMF currently supports), but they align the OVMF virtio code with the virtio specification and could be necessary for future OVMF ports. [1] http://lists.linuxfoundation.org/pipermail/virtualization/2013-June/024547.html Suggested-by: Stefan Hajnoczi <stefanha@redhat.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Reviewed-by: Jordan Justen <jordan.l.justen@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14601 6f19259b-4bc3-4df7-8a09-765794883524
92 lines
2.4 KiB
C
92 lines
2.4 KiB
C
/** @file
|
|
|
|
Implements
|
|
- the SNM.WaitForPacket EVT_NOTIFY_WAIT event,
|
|
- the EVT_SIGNAL_EXIT_BOOT_SERVICES event
|
|
for the virtio-net driver.
|
|
|
|
Copyright (C) 2013, Red Hat, Inc.
|
|
Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
|
|
|
|
This program and the accompanying materials are licensed and made available
|
|
under the terms and conditions of the BSD License which accompanies this
|
|
distribution. The full text of the license may be found at
|
|
http://opensource.org/licenses/bsd-license.php
|
|
|
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
|
|
WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
|
|
**/
|
|
|
|
#include <Library/BaseLib.h>
|
|
#include <Library/UefiBootServicesTableLib.h>
|
|
|
|
#include "VirtioNet.h"
|
|
|
|
/**
|
|
Invoke a notification event
|
|
|
|
@param Event Event whose notification function is being
|
|
invoked.
|
|
@param Context The pointer to the notification function's
|
|
context, which is implementation-dependent.
|
|
|
|
**/
|
|
|
|
VOID
|
|
EFIAPI
|
|
VirtioNetIsPacketAvailable (
|
|
IN EFI_EVENT Event,
|
|
IN VOID *Context
|
|
)
|
|
{
|
|
//
|
|
// This callback has been enqueued by an external application and is
|
|
// running at TPL_CALLBACK already.
|
|
//
|
|
// The WaitForPacket logic is similar to that of WaitForKey. The former has
|
|
// almost no documentation in either the UEFI-2.3.1+errC spec or the
|
|
// DWG-2.3.1, but WaitForKey does have some.
|
|
//
|
|
VNET_DEV *Dev;
|
|
UINT16 RxCurUsed;
|
|
|
|
Dev = Context;
|
|
if (Dev->Snm.State != EfiSimpleNetworkInitialized) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// virtio-0.9.5, 2.4.2 Receiving Used Buffers From the Device
|
|
//
|
|
MemoryFence ();
|
|
RxCurUsed = *Dev->RxRing.Used.Idx;
|
|
MemoryFence ();
|
|
|
|
if (Dev->RxLastUsed != RxCurUsed) {
|
|
gBS->SignalEvent (&Dev->Snp.WaitForPacket);
|
|
}
|
|
}
|
|
|
|
VOID
|
|
EFIAPI
|
|
VirtioNetExitBoot (
|
|
IN EFI_EVENT Event,
|
|
IN VOID *Context
|
|
)
|
|
{
|
|
//
|
|
// This callback has been enqueued by ExitBootServices() and is running at
|
|
// TPL_CALLBACK already.
|
|
//
|
|
// Shut down pending transfers according to DWG-2.3.1, "25.5.1 Exit Boot
|
|
// Services Event".
|
|
//
|
|
VNET_DEV *Dev;
|
|
|
|
Dev = Context;
|
|
if (Dev->Snm.State == EfiSimpleNetworkInitialized) {
|
|
VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, 0);
|
|
}
|
|
}
|