#pragma once #include struct ftl_page_group { uint8_t magic[3]; uint8_t epoch; uint32_t tail; } __attribute__((packed)); struct ftl_page_desc { char magic[4]; uint32_t va; uint32_t nused_pages; uint32_t subtrees[32]; } __attribute__((packed)); struct ftl_tlb_entry { uint32_t va, page; uint8_t flags; }; struct ftl_map { struct flash_dev *dev; struct ftl_tlb_entry outstanding; uint32_t offset; uint32_t head, tail; uint32_t root; uint32_t nused_pages; uint32_t nblocks; uint8_t log2_groups_per_block; uint8_t log2_pages_per_group; uint8_t log2_page_size; uint8_t log2_block_size; uint8_t log2_erase_size; uint8_t epoch; }; #define FTL_PRESENT BIT(7) #define FTL_NO_MAPPING BIT(6) #define FTL_AGE(x) (x & BITS(0, 3)) #define FTL_MAX_ATTEMPTS 8 int ftl_init_map(struct ftl_map *map, struct flash_dev *dev); int ftl_resume_map(struct ftl_map *map); int ftl_is_mapped(struct ftl_map *map, uint32_t va); size_t ftl_write(struct ftl_map *map, uint32_t addr, const void *data, size_t len); size_t ftl_read(struct ftl_map *map, void *data, size_t len, uint32_t va); int ftl_sync(struct ftl_map *map); int ftl_trim(struct ftl_map *map, uint32_t va); uint32_t ftl_get_size(const struct ftl_map *map); uint32_t ftl_get_capacity(const struct ftl_map *map); struct flash_dev *ftl_mount(struct flash_dev *raw_dev);