-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
xieyangrun
committed
Jan 14, 2021
1 parent
a9f54f8
commit 44701d3
Showing
7 changed files
with
625 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
from building import * | ||
import rtconfig | ||
|
||
cwd = GetCurrentDir() | ||
src = Glob('*.c') | ||
CPPPATH = [cwd] | ||
LOCAL_CCFLAGS = '' | ||
|
||
src += Glob('port/of_mtd_rtt.c') | ||
if GetDepend(['OF_USING_SFUD_PORT']): | ||
src += Glob('port/of_flash_sfud_port.c') | ||
|
||
group = DefineGroup('OF-mtd', src, depend = [''], CPPPATH = CPPPATH, LOCAL_CCFLAGS = LOCAL_CCFLAGS) | ||
|
||
Return('group') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
/* | ||
* Copyright (c) 2021-2031, OF(OpenFree) Development Team | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* Change Logs: | ||
* Date Author Notes | ||
* 2021-01-14 geniusgogo first version | ||
* | ||
*/ | ||
|
||
#include <of_mtd.h> | ||
|
||
int of_mtd_block_erase(of_mtd_t mtd, uint32_t block) | ||
{ | ||
uint32_t total_blks; | ||
loff_t addr; | ||
|
||
total_blks = mtd->size / mtd->block_size; | ||
if (block >= total_blks) | ||
return -1; | ||
addr = mtd->offset + mtd->block_size * block; | ||
|
||
return mtd->ops->erase(mtd->master, addr, mtd->block_size); | ||
} | ||
|
||
int of_mtd_block_isbad(of_mtd_t mtd, uint32_t block) | ||
{ | ||
uint32_t total_blks, offset_blk; | ||
|
||
if (!mtd->ops->isbad) | ||
return 0; | ||
|
||
total_blks = mtd->size / mtd->block_size; | ||
if (block >= total_blks) | ||
return -1; | ||
offset_blk = mtd->offset / mtd->block_size; | ||
|
||
return mtd->ops->isbad(mtd->master, block + offset_blk); | ||
} | ||
|
||
int of_mtd_block_markbad(of_mtd_t mtd, uint32_t block) | ||
{ | ||
uint32_t total_blks, offset_blk; | ||
|
||
if (!mtd->ops->markbad) | ||
return -1; | ||
|
||
total_blks = mtd->size / mtd->block_size; | ||
if (block >= total_blks) | ||
return -1; | ||
offset_blk = mtd->offset / mtd->block_size; | ||
|
||
return mtd->ops->markbad(mtd->master, block + offset_blk); | ||
} | ||
|
||
int of_mtd_erase(of_mtd_t mtd, loff_t addr, size_t size) | ||
{ | ||
if (addr > mtd->size || (addr + size) > mtd->size) | ||
return -1; | ||
addr += mtd->offset; | ||
|
||
return mtd->ops->erase(mtd->master, addr, size); | ||
} | ||
|
||
/* | ||
* Read data only | ||
* | ||
* @from offset to read from | ||
* @return success size or error code | ||
*/ | ||
int of_mtd_read(of_mtd_t mtd, loff_t from, uint8_t *buf, size_t len) | ||
{ | ||
int ret; | ||
struct of_mtd_io_desc desc = {0}; | ||
|
||
if (from < 0 || from >= (loff_t)mtd->size || len > mtd->size - from) | ||
return -1; | ||
if (!len) | ||
return 0; | ||
|
||
desc.datbuf = buf; | ||
desc.datlen = len; | ||
ret = mtd->ops->read(mtd->master, from + mtd->offset, &desc); | ||
if (ret) | ||
return ret; | ||
|
||
return desc.datretlen; | ||
} | ||
|
||
/** | ||
* Write data only | ||
* | ||
* @to offset to write from | ||
* @return success size or error code | ||
*/ | ||
int of_mtd_write(of_mtd_t mtd, loff_t to, const uint8_t *buf, size_t len) | ||
{ | ||
int ret; | ||
struct of_mtd_io_desc desc = {0}; | ||
|
||
if (to < 0 || to >= (loff_t)mtd->size || len > mtd->size - to) | ||
return -1; | ||
if (!mtd->ops->write) | ||
return -1; | ||
if (!len) | ||
return 0; | ||
|
||
desc.datbuf = (uint8_t*)buf; | ||
desc.datlen = len; | ||
ret = mtd->ops->write(mtd->master, to + mtd->offset, &desc); | ||
if (ret) | ||
return ret; | ||
|
||
return desc.datretlen; | ||
} | ||
|
||
/** | ||
* Read data and/or out-of-band | ||
* | ||
* @from offset to read from | ||
* @desc sector operation description structure | ||
* @return error code, 0 success | ||
*/ | ||
int of_mtd_read_oob(of_mtd_t mtd, loff_t from, struct of_mtd_io_desc *desc) | ||
{ | ||
desc->datretlen = 0; | ||
desc->oobretlen = 0; | ||
|
||
if (from < 0 || from >= (loff_t)mtd->size) | ||
return -1; | ||
|
||
if (desc->datbuf && (desc->datlen > (mtd->size - from))) | ||
return -1; | ||
|
||
return mtd->ops->read(mtd->master, from + mtd->offset, desc); | ||
} | ||
|
||
/** | ||
* Write data and/or out-of-band | ||
* | ||
* @to offset to read from | ||
* @desc sector operation description structure | ||
* @return error code, 0 success | ||
*/ | ||
int of_mtd_write_oob(of_mtd_t mtd, loff_t to, struct of_mtd_io_desc *desc) | ||
{ | ||
desc->datretlen = 0; | ||
desc->oobretlen = 0; | ||
|
||
if (to < 0 || to >= (loff_t)mtd->size) | ||
return -1; | ||
|
||
if (desc->datbuf && (desc->datlen >(mtd->size - to))) | ||
return -1; | ||
|
||
return mtd->ops->write(mtd->master, to + mtd->offset, desc); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
/* | ||
* Copyright (c) 2021-2031, OF(OpenFree) Development Team | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* Change Logs: | ||
* Date Author Notes | ||
* 2021-01-14 geniusgogo first version | ||
* | ||
*/ | ||
|
||
#ifndef _OF_MTD_H_ | ||
#define _OF_MTD_H_ | ||
|
||
#include <stddef.h> | ||
#include <stdint.h> | ||
|
||
#define OF_MTD_TYPE_NOR 1 | ||
#define OF_MTD_TYPE_NAND 2 | ||
|
||
/** | ||
* MTD operation modes | ||
* | ||
* @MTD_OPM_PLACE_OOB: OOB data are placed at the given offset (default) | ||
* @MTD_OPM_AUTO_OOB: OOB data are automatically placed at the free areas | ||
* @MTD_OPM_RAW: data are transferred as-is, with no error correction; | ||
*/ | ||
enum of_mtd_opm | ||
{ | ||
MTD_OPM_PLACE_OOB = 0, | ||
MTD_OPM_AUTO_OOB = 1, | ||
MTD_OPM_RAW = 2, | ||
}; | ||
|
||
#ifndef loff_t | ||
typedef long loff_t; | ||
#endif | ||
|
||
struct of_mtd_oob_region | ||
{ | ||
uint8_t offset; | ||
uint8_t length; | ||
}; | ||
|
||
struct of_mtd_info | ||
{ | ||
const struct of_mtd_ops *ops; | ||
struct of_mtd_info *master; | ||
|
||
uint16_t oob_size; | ||
uint16_t sector_size; /* Minimal writable flash unit size */ | ||
uint32_t block_size:28; /* Erase size for the device */ | ||
uint32_t type:4; | ||
|
||
size_t size; /* Total size of the MTD */ | ||
loff_t offset; /* At which this MTD starts, from the beginning of the MEMORY */ | ||
}; | ||
typedef struct of_mtd_info* of_mtd_t; | ||
|
||
struct of_mtd_io_desc | ||
{ | ||
uint8_t mode; /* operation mode(enum mtd_opm) */ | ||
uint8_t ooblen; /* number of oob bytes to write/read */ | ||
uint8_t oobretlen; /* number of oob bytes written/read */ | ||
uint8_t ooboffs; /* offset in the oob area */ | ||
uint8_t *oobbuf; | ||
|
||
size_t datlen; /* number of data bytes to write/read */ | ||
size_t datretlen; /* number of data bytes written/read */ | ||
uint8_t *datbuf; /* if NULL only oob are read/written */ | ||
}; | ||
|
||
struct of_mtd_ops | ||
{ | ||
int(*erase)(of_mtd_t mtd, loff_t addr, size_t len); /* return 0 if success */ | ||
int(*read) (of_mtd_t mtd, loff_t from, struct of_mtd_io_desc *ops); /* return 0 if success */ | ||
int(*write) (of_mtd_t mtd, loff_t to, struct of_mtd_io_desc *ops); /* return 0 if success */ | ||
int(*isbad) (of_mtd_t mtd, uint32_t block); /* return 1 if bad, 0 not bad */ | ||
int(*markbad) (of_mtd_t mtd, uint32_t block); /* return 0 if success */ | ||
}; | ||
|
||
struct of_mtd_part_info | ||
{ | ||
const char *name; /* name of the MTD partion */ | ||
loff_t offset; /* start addr of partion */ | ||
size_t size; /* size of partion */ | ||
}; | ||
|
||
// user api | ||
int of_mtd_erase(of_mtd_t mtd, loff_t addr, size_t size); | ||
int of_mtd_read(of_mtd_t mtd, loff_t from, uint8_t *buf, size_t len); | ||
int of_mtd_write(of_mtd_t mtd, loff_t to, const uint8_t *buf, size_t len); | ||
int of_mtd_block_erase(of_mtd_t mtd, uint32_t block); | ||
int of_mtd_read_oob(of_mtd_t mtd, loff_t from, struct of_mtd_io_desc *desc); | ||
int of_mtd_write_oob(of_mtd_t mtd, loff_t to, struct of_mtd_io_desc *desc); | ||
int of_mtd_block_markbad(of_mtd_t mtd, uint32_t block); | ||
int of_mtd_block_isbad(of_mtd_t mtd, uint32_t block); | ||
|
||
// porting interface | ||
of_mtd_t of_mtd_get(const char *name); | ||
int of_mtd_register(const char *name, of_mtd_t mtd); | ||
int of_mtd_parts_add(of_mtd_t mtd, const struct of_mtd_part_info *parts, int np); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
/* | ||
* Copyright (c) 2021-2031, OF(OpenFree) Development Team | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* Change Logs: | ||
* Date Author Notes | ||
* 2021-01-14 geniusgogo first version | ||
* | ||
*/ | ||
|
||
#include <of_nor.h> | ||
|
||
static int _nor_erase(of_mtd_t mtd, loff_t addr, size_t len) | ||
{ | ||
of_nor_t nor; | ||
|
||
nor = (of_nor_t)mtd; | ||
return nor->ops->erase(nor, addr, len); | ||
} | ||
|
||
static int _nor_read(of_mtd_t mtd, loff_t from, struct of_mtd_io_desc *desc) | ||
{ | ||
of_nor_t nor; | ||
int ret; | ||
|
||
nor = (of_nor_t)mtd; | ||
ret = nor->ops->read(nor, from, desc->datbuf, desc->datlen); | ||
if (ret > 0) | ||
{ | ||
desc->datretlen = ret; | ||
ret = 0; | ||
} | ||
|
||
return ret; | ||
} | ||
|
||
static int _nor_write(of_mtd_t mtd, loff_t to, struct of_mtd_io_desc *desc) | ||
{ | ||
of_nor_t nor; | ||
int ret; | ||
|
||
nor = (of_nor_t)mtd; | ||
ret = nor->ops->write(nor, to, desc->datbuf, desc->datlen); | ||
if (ret > 0) | ||
{ | ||
desc->datretlen = ret; | ||
ret = 0; | ||
} | ||
|
||
return ret; | ||
} | ||
|
||
static const struct of_mtd_ops _ops = | ||
{ | ||
_nor_erase, | ||
_nor_read, | ||
_nor_write, | ||
0, | ||
0 | ||
}; | ||
|
||
int of_mtd_nor_init(struct of_nor* nor, const char* devname, uint32_t block_size, uint32_t block_count) | ||
{ | ||
if (!nor->ops) return -1; | ||
if (!devname || !devname[0]) return -2; | ||
|
||
nor->parent.ops = &_ops; | ||
nor->parent.type = OF_MTD_TYPE_NOR; | ||
nor->parent.block_size = block_size; | ||
nor->parent.size = block_size * block_count; | ||
nor->parent.offset = 0; | ||
|
||
return of_mtd_register(devname, &nor->parent); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
/* | ||
* Copyright (c) 2021-2031, OF(OpenFree) Development Team | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* Change Logs: | ||
* Date Author Notes | ||
* 2021-01-14 geniusgogo first version | ||
* | ||
*/ | ||
|
||
#ifndef _OF_NOR_H_ | ||
#define _OF_NOR_H_ | ||
|
||
#include <of_mtd.h> | ||
|
||
struct of_nor_ops; | ||
|
||
struct of_nor | ||
{ | ||
struct of_mtd_info parent; | ||
const struct of_nor_ops *ops; | ||
}; | ||
typedef struct of_nor* of_nor_t; | ||
|
||
struct of_nor_ops | ||
{ | ||
int (*erase)(of_nor_t nor, loff_t addr, size_t len); /* return success erased len or error code */ | ||
int (*read)(of_nor_t nor, loff_t addr, uint8_t *buf, size_t len); /* return success data size or error code */ | ||
int (*write)(of_nor_t nor, loff_t addr, const uint8_t *buf, size_t len); /* return success data size or error code */ | ||
}; | ||
typedef struct of_nor_ops* of_nor_ops_t; | ||
|
||
int of_mtd_nor_init(struct of_nor* nor, const char* devname, uint32_t block_size, uint32_t block_count); | ||
|
||
#endif |
Oops, something went wrong.