]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/XenBusDxe/TestAndClearBit.c
OvmfPkg/AmdSevDxe: sort #includes, and entries in INF file sections
[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
AB
6\r
7 This program and the accompanying materials\r
8 are licensed and made available under the terms and conditions of the BSD License\r
9 which accompanies this distribution. The full text of the license may be found at\r
10 http://opensource.org/licenses/bsd-license.php\r
11\r
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14\r
15**/\r
16\r
17#include <Base.h>\r
18#include <Library/SynchronizationLib.h>\r
19\r
20INT32\r
21EFIAPI\r
22TestAndClearBit (\r
23 IN INT32 Bit,\r
24 IN VOID *Address\r
25 )\r
26{\r
27 UINT16 Word, Read;\r
28 UINT16 Mask;\r
29\r
30 //\r
31 // Calculate the effective address relative to 'Address' based on the\r
32 // higher order bits of 'Bit'. Use signed shift instead of division to\r
33 // ensure we round towards -Inf, and end up with a positive shift in\r
34 // 'Bit', even if 'Bit' itself is negative.\r
35 //\r
9b8e4148 36 Address = (VOID*)((UINT8*) Address + ((Bit >> 4) * sizeof(UINT16)));\r
e482753b
AB
37 Mask = 1U << (Bit & 15);\r
38\r
39 for (Word = *(UINT16 *) Address; Word & Mask; Word = Read) {\r
40 Read = InterlockedCompareExchange16 (Address, Word, Word & ~Mask);\r
41 if (Read == Word) {\r
42 return 1;\r
43 }\r
44 }\r
45 return 0;\r
46}\r