1 /* 2 * Copyright (C) 2015-2021 Alibaba Group Holding Limited 3 */ 4 5 #ifndef __AOS_MTD_H 6 #define __AOS_MTD_H 7 8 #include <stddef.h> 9 #include <stdint.h> 10 #include <aos/kernel.h> 11 #include "device/aos_device.h" 12 13 #define MTD_TYPE_NOR 1 14 #define MTD_TYPE_NAND 2 15 16 #define MTD_DEVICE_NAME_PREFIX "mtdblock" 17 #define MTD_DEVICE_NAME_FORMAT MTD_DEVICE_NAME_PREFIX"%u" 18 #define MTD_PARTITION_NAME_MAX 16 19 #define MTD_DEVICE_NAME_MAX 16 20 21 #define IOC_MTD_BASE 'M' 22 #define IOC_MTD_GET_SIZE (IOC_MTD_BASE + 0x1) 23 #define IOC_MTD_GET_OFFSET (IOC_MTD_BASE + 0x2) 24 #define IOC_MTD_ERASE (IOC_MTD_BASE + 0x3) 25 26 /* standard partition names */ 27 #define MTD_PART_NAME_BOOTLOADER "BOOT" /*Bootloader*/ 28 #define MTD_PART_NAME_BOOTLOADER_SEC "BOOTSEC" /*Secure Boot*/ 29 #define MTD_PART_NAME_2ND_BOOTLOADER "BOOT2A" /*The 2nd bootloader*/ 30 #define MTD_PART_NAME_2ND_BOOTLOADER2 "BOOT2B" /*The 2nd bootloader backup*/ 31 #define MTD_PART_NAME_ENV "ENV" /* Eviroment, e.g. for OTA*/ 32 #define MTD_PART_NAME_ENV2 "ENV2" /* Enviroment, e.g. others.*/ 33 #define MTD_PART_NAME_DTB "DTB" 34 #define MTD_PART_NAME_KERNEL "KERNEL" 35 #define MTD_PART_NAME_KERNEL2 "KERNEL2" 36 #define MTD_PART_NAME_ROMFS "ROMFS" 37 #define MTD_PART_NAME_ROMFS2 "ROMFS2" 38 #define MTD_PART_NAME_LITTLEFS "LFS" 39 #define MTD_PART_NAME_LITTLEFS2 "LFS2" 40 #define MTD_PART_NAME_APP "APP" 41 #define MTD_PART_NAME_FACTORY "FACTORY" /* Factory data*/ 42 #define MTD_PART_NAME_FACTORY2 "FACTORY2" /* Factory data backup */ 43 #define MTD_PART_NAME_KV "KV" 44 #define MTD_PART_NAME_UNKNOWN "UNKNOWN" 45 /* subject to add more hereafter ... */ 46 47 /** 48 * MTD operation modes 49 * 50 * @MTD_OPM_PLACE_OOB: OOB data are placed at the given offset (default) 51 * @MTD_OPM_AUTO_OOB: OOB data are automatically placed at the free areas 52 * @MTD_OPM_RAW: data are transferred as-is, with no error correction; 53 */ 54 enum mtd_opm 55 { 56 MTD_OPM_PLACE_OOB = 0, 57 MTD_OPM_AUTO_OOB = 1, 58 MTD_OPM_RAW = 2, 59 }; 60 61 struct mtd_erase_info { 62 unsigned long offset; 63 unsigned long length; 64 }; 65 66 struct mtd_block_info { 67 unsigned long block_size; 68 unsigned long block_start; 69 unsigned long block_end; 70 }; 71 72 73 struct mtd_oob_region 74 { 75 uint8_t offset; 76 uint8_t length; 77 }; 78 79 typedef struct mtd_info 80 { 81 struct aos_device parent; 82 const struct mtd_ops *ops; 83 84 uint16_t oob_size; 85 uint16_t sector_size; /* Minimal writable flash unit size */ 86 uint32_t block_size:28; /* Erase size for the device */ 87 uint32_t type:4; 88 89 size_t size; /* Total size of the MTD */ 90 off_t offset; /* At which this MTD starts, from the beginning of the MEMORY */ 91 struct mtd_info *master; 92 93 void *priv; 94 } aos_mtd_t; 95 96 struct mtd_io_desc 97 { 98 uint8_t mode; /* operation mode(enum mtd_opm) */ 99 uint8_t ooblen; /* number of oob bytes to write/read */ 100 uint8_t oobretlen; /* number of oob bytes written/read */ 101 uint8_t ooboffs; /* offset in the oob area */ 102 uint8_t *oobbuf; 103 104 size_t datlen; /* number of data bytes to write/read */ 105 size_t datretlen; /* number of data bytes written/read */ 106 uint8_t *datbuf; /* if NULL only oob are read/written */ 107 }; 108 109 struct mtd_ops 110 { 111 int(*erase)(aos_mtd_t *mtd, off_t addr, size_t len); /* return 0 if success */ 112 int(*read) (aos_mtd_t *mtd, off_t from, struct mtd_io_desc *ops); /* return 0 if success */ 113 int(*write) (aos_mtd_t *mtd, off_t to, struct mtd_io_desc *ops); /* return 0 if success */ 114 int(*isbad) (aos_mtd_t *mtd, uint32_t block); /* return 1 if bad, 0 not bad */ 115 int(*markbad) (aos_mtd_t *mtd, uint32_t block); /* return 0 if success */ 116 }; 117 118 struct mtd_part 119 { 120 const char *name; /* platform specific name of the MTD partition provided, optionally to be the same as name_std */ 121 const char *name_std; /* standard name of the MTD partition define in alios */ 122 off_t offset; /* start addr of partion */ 123 size_t size; /* size of partion */ 124 }; 125 126 struct mtd_part_info 127 { 128 off_t offset; /* start addr of partion */ 129 size_t size; /* size of partion */ 130 char part_name[MTD_PARTITION_NAME_MAX]; /* original name of the MTD partition, usually provided by platform */ 131 char part_name_std[MTD_PARTITION_NAME_MAX]; /* standard name of the MTD partition, defined by alios */ 132 char dev_name[MTD_DEVICE_NAME_MAX]; /* device name of the MTD partition */ 133 }; 134 135 /** 136 * Open a mtd device 137 * 138 * @param[in] name partition name 139 * 140 * @return A mtd device handle, NULL: error 141 */ 142 aos_mtd_t* aos_mtd_open(const char *name); 143 144 /** 145 * Close a mtd device 146 * 147 * @param[in] mtd A mtd device handle 148 * 149 * @return 0:success, <0: error 150 */ 151 aos_status_t aos_mtd_close(aos_mtd_t *mtd); 152 153 /** 154 * Read data from mtd device 155 * 156 * @param[in] mtd A mtd device handle 157 * @param[in] offset The offset address of mtd device which read from 158 * @param[out] buf The buffer to store data read from mtd device 159 * @param[in] size The size of request to read 160 * 161 * @return >0:The size of data that really read; 0: end of device; <0: error 162 */ 163 ssize_t aos_mtd_read(aos_mtd_t *mtd, off_t offset, void *buf, size_t size); 164 165 /** 166 * Read out-of-band data from mtd device 167 * 168 * @param[in] mtd A mtd device handle 169 * @param[in] offset The offset address of mtd device which read from 170 * @param[in] info The description information of mtd IO 171 * 172 * @return >0:The size of out-of-band data that really read; 0: end of device; <0: error 173 */ 174 ssize_t aos_mtd_oob_read(aos_mtd_t *mtd, off_t offset, struct mtd_io_desc *info); 175 176 /** 177 * Write data to mtd device 178 * 179 * @param[in] mtd A mtd device handle 180 * @param[in] offset The offset address of mtd device which write to 181 * @param[in] buf The buffer to store data to be written 182 * @param[in] size The size of request to write 183 184 * @return >0:The size of data that really be written; <0: error 185 */ 186 ssize_t aos_mtd_write(aos_mtd_t *mtd, off_t offset, const void *buf, size_t size); 187 188 /** 189 * Write out-of-band data to mtd device 190 * 191 * @param[in] mtd A mtd device handle 192 * @param[in] offset The offset address of mtd device which write to 193 * @param[in] info The description information of mtd IO 194 * 195 * @return >0:The size of out-of-band data that really written; <0: error 196 */ 197 ssize_t aos_mtd_oob_write(aos_mtd_t *mtd, off_t offset, struct mtd_io_desc *info); 198 199 /** 200 * Erase a region of mtd device 201 * 202 * @param[in] mtd A mtd device handle 203 * @param[in] offset The offset address of mtd device to be erased 204 * @param[in] size The size of request to be erased 205 * 206 * @return 0: success, <0: error 207 */ 208 aos_status_t aos_mtd_erase(aos_mtd_t *mtd, off_t offset, size_t size); 209 210 /** 211 * Erase a block of mtd device 212 * 213 * @param[in] mtd A mtd device handle 214 * @param[in] block The block index to be erased 215 * 216 * @return 0: success, <0: error 217 */ 218 aos_status_t aos_mtd_block_erase(aos_mtd_t *mtd, uint32_t block); 219 220 /** 221 * Mark a block of mtd device as bad 222 * 223 * @param[in] mtd A mtd device handle 224 * @param[in] block The block index to be marked 225 * 226 * @return 0: success, <0: error 227 */ 228 aos_status_t aos_mtd_block_mark_bad(aos_mtd_t *mtd, uint32_t block); 229 230 /** 231 * Check if a block of mtd device is bad 232 * 233 * @param[in] mtd A mtd device handle 234 * @param[in] block The block index to be checked 235 * 236 * @return 0: success, <0: error 237 */ 238 aos_status_t aos_mtd_block_is_bad(aos_mtd_t *mtd, uint32_t block); 239 240 241 /* get mtd partition information, caller to free the info memory */ 242 int aos_mtd_part_info_get(struct mtd_part_info **info, int *cnt); 243 244 /* register mtd paritions */ 245 int aos_mtd_register(aos_mtd_t *master, const struct mtd_part *parts, int np); 246 247 #endif /*__AOS_MTD_H*/ 248