]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/XenBusDxe/TestAndClearBit.c
IntelFsp2Pkg/SplitFspBin.py: Support rebasing 1.x binary.
[mirror_edk2.git] / OvmfPkg / XenBusDxe / TestAndClearBit.c
CommitLineData
e482753b
AB
1/** @file\r
2 Implementation of TestAndClearBit using compare-exchange primitive\r
3\r
4 Copyright (C) 2015, Linaro Ltd.\r
9b8e4148 5 Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
e482753b 6\r
b26f0cf9 7 SPDX-License-Identifier: BSD-2-Clause-Patent\r
e482753b
AB
8\r
9**/\r
10\r
11#include <Base.h>\r
12#include <Library/SynchronizationLib.h>\r
13\r
14INT32\r
15EFIAPI\r
16TestAndClearBit (\r
17 IN INT32 Bit,\r
18 IN VOID *Address\r
19 )\r
20{\r
21 UINT16 Word, Read;\r
22 UINT16 Mask;\r
23\r
24 //\r
25 // Calculate the effective address relative to 'Address' based on the\r
26 // higher order bits of 'Bit'. Use signed shift instead of division to\r
27 // ensure we round towards -Inf, and end up with a positive shift in\r
28 // 'Bit', even if 'Bit' itself is negative.\r
29 //\r
9b8e4148 30 Address = (VOID*)((UINT8*) Address + ((Bit >> 4) * sizeof(UINT16)));\r
e482753b
AB
31 Mask = 1U << (Bit & 15);\r
32\r
33 for (Word = *(UINT16 *) Address; Word & Mask; Word = Read) {\r
34 Read = InterlockedCompareExchange16 (Address, Word, Word & ~Mask);\r
35 if (Read == Word) {\r
36 return 1;\r
37 }\r
38 }\r
39 return 0;\r
40}\r