]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/XenBusDxe/TestAndClearBit.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[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
ac0a286f
MK
17 IN INT32 Bit,\r
18 IN VOID *Address\r
e482753b
AB
19 )\r
20{\r
ac0a286f
MK
21 UINT16 Word, Read;\r
22 UINT16 Mask;\r
e482753b
AB
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
ac0a286f
MK
30 Address = (VOID *)((UINT8 *)Address + ((Bit >> 4) * sizeof (UINT16)));\r
31 Mask = 1U << (Bit & 15);\r
e482753b 32\r
ac0a286f 33 for (Word = *(UINT16 *)Address; Word &Mask; Word = Read) {\r
e482753b
AB
34 Read = InterlockedCompareExchange16 (Address, Word, Word & ~Mask);\r
35 if (Read == Word) {\r
36 return 1;\r
37 }\r
38 }\r
ac0a286f 39\r
e482753b
AB
40 return 0;\r
41}\r