Ovmf/Xen: port XenBusDxe to other architectures
This patch updates XenBusDxe to use the 16-bit compare and exchange function that was introduced for this purpose to the BaseSynchronizationLib. It also provides a new generic implementation of TestAndClearBit () using the same 16-bit compare and exchange, making this module fully architecture agnostic. Contributed-under: TianoCore Contribution Agreement 1.0 Reviewed-by: Anthony PERARD <anthony.perard@citrix.com> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Laszlo Ersek <lersek@redhat.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16975 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
45
OvmfPkg/XenBusDxe/TestAndClearBit.c
Normal file
45
OvmfPkg/XenBusDxe/TestAndClearBit.c
Normal file
@@ -0,0 +1,45 @@
|
||||
/** @file
|
||||
Implementation of TestAndClearBit using compare-exchange primitive
|
||||
|
||||
Copyright (C) 2015, Linaro Ltd.
|
||||
|
||||
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 <Base.h>
|
||||
#include <Library/SynchronizationLib.h>
|
||||
|
||||
INT32
|
||||
EFIAPI
|
||||
TestAndClearBit (
|
||||
IN INT32 Bit,
|
||||
IN VOID *Address
|
||||
)
|
||||
{
|
||||
UINT16 Word, Read;
|
||||
UINT16 Mask;
|
||||
|
||||
//
|
||||
// Calculate the effective address relative to 'Address' based on the
|
||||
// higher order bits of 'Bit'. Use signed shift instead of division to
|
||||
// ensure we round towards -Inf, and end up with a positive shift in
|
||||
// 'Bit', even if 'Bit' itself is negative.
|
||||
//
|
||||
Address += (Bit >> 4) * sizeof(UINT16);
|
||||
Mask = 1U << (Bit & 15);
|
||||
|
||||
for (Word = *(UINT16 *) Address; Word & Mask; Word = Read) {
|
||||
Read = InterlockedCompareExchange16 (Address, Word, Word & ~Mask);
|
||||
if (Read == Word) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user