* Copyright (c) 2025 HiSilicon Technologies Co., Ltd. All rights reserved.
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*/
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include "ummu_log.h"
#include "ummu_common.h"
#define UMMU_URANDOM_DEV "/dev/urandom"
int ummu_gen_random(uint32_t *value)
{
uint32_t random_val = 0;
int fd, ret;
fd = open(UMMU_URANDOM_DEV, O_RDONLY);
if (fd < 0) {
UMMU_MAPT_ERROR_LOG("Open random fd failed, errno = %d.\n", errno);
return -errno;
}
ret = read(fd, &random_val, sizeof(uint32_t));
if (ret != sizeof(uint32_t)) {
UMMU_MAPT_ERROR_LOG("Get random value failed, ret = %d, errno = %d.\n", ret, errno);
close(fd);
return -errno;
}
close(fd);
*value = random_val;
return 0;
}
unsigned long find_first_zero_bit(const unsigned long *array, unsigned long size)
{
unsigned long i;
unsigned long ret = 0;
unsigned long array_size;
if (UNLIKELY(size == 0)) {
return size;
}
array_size = BITS_TO_LONGS(size);
for (i = 0; i < array_size; i++) {
if (~array[i]) {
return (ret + ffz(array[i]));
} else {
ret += BITS_PER_LONG;
}
}
return size;
}
unsigned long find_first_bit(const unsigned long *array, unsigned long size)
{
unsigned long i;
unsigned long ret = 0;
unsigned long array_size;
if (UNLIKELY(size == 0)) {
return size;
}
array_size = BITS_TO_LONGS(size);
for (i = 0; i < array_size; i++) {
if (array[i] != 0) {
return (ret + ffz(~array[i]));
} else {
ret += BITS_PER_LONG;
}
}
return size;
}
unsigned long find_next_bit(const unsigned long *array, unsigned long size, unsigned long offset)
{
unsigned long i;
unsigned long ret;
unsigned long long_offset;
unsigned long tmp;
unsigned long array_size;
if (UNLIKELY(offset >= size || size == 0)) {
return size;
}
i = offset >> BITS_PER_LONG_SHIFT;
ret = i * BITS_PER_LONG;
long_offset = offset % BITS_PER_LONG;
tmp = array[i] & (~0UL << long_offset);
if (tmp != 0) {
return (ret + ffz(~tmp));
} else {
ret += BITS_PER_LONG;
i++;
}
array_size = BITS_TO_LONGS(size);
for (; i < array_size; i++) {
tmp = array[i];
if (tmp != 0) {
return (ret + ffz(~tmp));
} else {
ret += BITS_PER_LONG;
}
}
return size;
}