/* * Copyright (c) 2023 Antmicro * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include #include #include "ext2_bitmap.h" LOG_MODULE_DECLARE(ext2); /* NOTICE: Offsets in bitmap start with 0 */ int ext2_bitmap_set(uint8_t *bm, uint32_t index, uint32_t size) { LOG_DBG("Setting %d bit in bitmap", index); uint32_t idx = index / 8; uint32_t off = index % 8; if (idx >= size) { LOG_ERR("Tried to set value outside of bitmap (%d)", index); return -EINVAL; } __ASSERT((bm[idx] & BIT(off)) == 0, "Bit %d set in bitmap", index); LOG_DBG("Bitmap %d: %x", idx, bm[idx]); bm[idx] |= BIT(off); LOG_DBG("Bitmap %d: %x", idx, bm[idx]); return 0; } int ext2_bitmap_unset(uint8_t *bm, uint32_t index, uint32_t size) { LOG_DBG("Unsetting %d bit in bitmap", index); uint32_t idx = index / 8; uint32_t off = index % 8; if (idx >= size) { LOG_ERR("Tried to unset value outside of bitmap (%d)", index); return -EINVAL; } __ASSERT(bm[idx] & BIT(off), "Bit %d not set in bitmap", index); LOG_DBG("Bitmap %d: %x", idx, bm[idx]); bm[idx] &= ~BIT(off); LOG_DBG("Bitmap %d: %x", idx, bm[idx]); return 0; } int32_t ext2_bitmap_find_free(uint8_t *bm, uint32_t size) { for (int i = 0; i < size; ++i) { LOG_DBG("Bitmap %d: %x (%x)", i, bm[i], ~bm[i]); if (bm[i] < UINT8_MAX) { /* not all bits are set here */ int off = find_lsb_set(~bm[i]) - 1; LOG_DBG("off: %d", off); return off + i * 8; } } return -ENOSPC; } uint32_t ext2_bitmap_count_set(uint8_t *bm, uint32_t size) { int32_t count = 0; for (uint32_t i = 0; i < size; i += 8) { uint8_t val = bm[i / 8]; for (int b = 0; b < 8 && i + b < size; ++b) { count += (val >> b) & BIT(0); } } return count; }