xref: /kvm-unit-tests/lib/riscv/bitops.c (revision 48d5952451de62a4db23cf73024f702cf1a64fc3)
1*22f287f4SAndrew Jones // SPDX-License-Identifier: GPL-2.0-only
2*22f287f4SAndrew Jones /*
3*22f287f4SAndrew Jones  * Copyright (C) 2023, Ventana Micro Systems Inc., Andrew Jones <ajones@ventanamicro.com>
4*22f287f4SAndrew Jones  */
5*22f287f4SAndrew Jones #include <bitops.h>
6*22f287f4SAndrew Jones 
set_bit(int nr,volatile unsigned long * addr)7*22f287f4SAndrew Jones void set_bit(int nr, volatile unsigned long *addr)
8*22f287f4SAndrew Jones {
9*22f287f4SAndrew Jones 	volatile unsigned long *word = addr + BIT_WORD(nr);
10*22f287f4SAndrew Jones 	unsigned long mask = BIT_MASK(nr);
11*22f287f4SAndrew Jones 
12*22f287f4SAndrew Jones 	__sync_or_and_fetch(word, mask);
13*22f287f4SAndrew Jones }
14*22f287f4SAndrew Jones 
clear_bit(int nr,volatile unsigned long * addr)15*22f287f4SAndrew Jones void clear_bit(int nr, volatile unsigned long *addr)
16*22f287f4SAndrew Jones {
17*22f287f4SAndrew Jones 	volatile unsigned long *word = addr + BIT_WORD(nr);
18*22f287f4SAndrew Jones 	unsigned long mask = BIT_MASK(nr);
19*22f287f4SAndrew Jones 
20*22f287f4SAndrew Jones 	__sync_and_and_fetch(word, ~mask);
21*22f287f4SAndrew Jones }
22*22f287f4SAndrew Jones 
test_bit(int nr,const volatile unsigned long * addr)23*22f287f4SAndrew Jones int test_bit(int nr, const volatile unsigned long *addr)
24*22f287f4SAndrew Jones {
25*22f287f4SAndrew Jones 	const volatile unsigned long *word = addr + BIT_WORD(nr);
26*22f287f4SAndrew Jones 	unsigned long mask = BIT_MASK(nr);
27*22f287f4SAndrew Jones 
28*22f287f4SAndrew Jones 	return (*word & mask) != 0;
29*22f287f4SAndrew Jones }
30*22f287f4SAndrew Jones 
test_and_set_bit(int nr,volatile unsigned long * addr)31*22f287f4SAndrew Jones int test_and_set_bit(int nr, volatile unsigned long *addr)
32*22f287f4SAndrew Jones {
33*22f287f4SAndrew Jones 	volatile unsigned long *word = addr + BIT_WORD(nr);
34*22f287f4SAndrew Jones 	unsigned long mask = BIT_MASK(nr);
35*22f287f4SAndrew Jones 	unsigned long old = __sync_fetch_and_or(word, mask);
36*22f287f4SAndrew Jones 
37*22f287f4SAndrew Jones 	return (old & mask) != 0;
38*22f287f4SAndrew Jones }
39*22f287f4SAndrew Jones 
test_and_clear_bit(int nr,volatile unsigned long * addr)40*22f287f4SAndrew Jones int test_and_clear_bit(int nr, volatile unsigned long *addr)
41*22f287f4SAndrew Jones {
42*22f287f4SAndrew Jones 	volatile unsigned long *word = addr + BIT_WORD(nr);
43*22f287f4SAndrew Jones 	unsigned long mask = BIT_MASK(nr);
44*22f287f4SAndrew Jones 	unsigned long old = __sync_fetch_and_and(word, ~mask);
45*22f287f4SAndrew Jones 
46*22f287f4SAndrew Jones 	return (old & mask) != 0;
47*22f287f4SAndrew Jones }
48