1 /*
2  * Copyright (c) 2023 Antmicro <www.antmicro.com>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stdint.h>
8 #include <stdbool.h>
9 #include <zephyr/kernel.h>
10 #include <zephyr/logging/log.h>
11 
12 #include "ext2_bitmap.h"
13 
14 LOG_MODULE_DECLARE(ext2);
15 
16 /* NOTICE: Offsets in bitmap start with 0 */
17 
ext2_bitmap_set(uint8_t * bm,uint32_t index,uint32_t size)18 int ext2_bitmap_set(uint8_t *bm, uint32_t index, uint32_t size)
19 {
20 	LOG_DBG("Setting %d bit in bitmap", index);
21 
22 	uint32_t idx = index / 8;
23 	uint32_t off = index % 8;
24 
25 	if (idx >= size) {
26 		LOG_ERR("Tried to set value outside of bitmap (%d)", index);
27 		return -EINVAL;
28 	}
29 
30 	__ASSERT((bm[idx] & BIT(off)) == 0, "Bit %d set in bitmap", index);
31 
32 	LOG_DBG("Bitmap %d: %x", idx, bm[idx]);
33 	bm[idx] |= BIT(off);
34 	LOG_DBG("Bitmap %d: %x", idx, bm[idx]);
35 
36 	return 0;
37 }
38 
ext2_bitmap_unset(uint8_t * bm,uint32_t index,uint32_t size)39 int ext2_bitmap_unset(uint8_t *bm, uint32_t index, uint32_t size)
40 {
41 	LOG_DBG("Unsetting %d bit in bitmap", index);
42 
43 	uint32_t idx = index / 8;
44 	uint32_t off = index % 8;
45 
46 	if (idx >= size) {
47 		LOG_ERR("Tried to unset value outside of bitmap (%d)", index);
48 		return -EINVAL;
49 	}
50 
51 	__ASSERT(bm[idx] & BIT(off), "Bit %d not set in bitmap", index);
52 
53 	LOG_DBG("Bitmap %d: %x", idx, bm[idx]);
54 	bm[idx] &= ~BIT(off);
55 	LOG_DBG("Bitmap %d: %x", idx, bm[idx]);
56 
57 	return 0;
58 }
59 
ext2_bitmap_find_free(uint8_t * bm,uint32_t size)60 int32_t ext2_bitmap_find_free(uint8_t *bm, uint32_t size)
61 {
62 	for (int i = 0; i < size; ++i) {
63 		LOG_DBG("Bitmap %d: %x (%x)", i, bm[i], ~bm[i]);
64 		if (bm[i] < UINT8_MAX) {
65 			/* not all bits are set here */
66 			int off = find_lsb_set(~bm[i]) - 1;
67 
68 			LOG_DBG("off: %d", off);
69 			return off + i * 8;
70 		}
71 	}
72 	return -ENOSPC;
73 }
74 
ext2_bitmap_count_set(uint8_t * bm,uint32_t size)75 uint32_t ext2_bitmap_count_set(uint8_t *bm, uint32_t size)
76 {
77 	int32_t count = 0;
78 
79 	for (uint32_t i = 0; i < size; i += 8) {
80 		uint8_t val = bm[i / 8];
81 
82 		for (int b = 0; b < 8 && i + b < size; ++b) {
83 			count += (val >> b) & BIT(0);
84 		}
85 
86 	}
87 	return count;
88 }
89