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