X-Git-Url: https://hackdaworld.org/gitweb/?p=my-code%2Farm.git;a=blobdiff_plain;f=betty%2Fpffs.c;h=93351bd7cbaf921711149ae185374a36e94d0c7a;hp=7b3b5e8b78a5e213d0a55ea3d03c2e8e24a1b2b8;hb=6a1c483e9c2da2e1affde2a7f3b40ff1c3b09a5f;hpb=e9e1115af8d1609165b3e5baf0aef838f29e91a1 diff --git a/betty/pffs.c b/betty/pffs.c index 7b3b5e8..93351bd 100644 --- a/betty/pffs.c +++ b/betty/pffs.c @@ -11,36 +11,23 @@ * functions */ -u32 pffs_get_ptr(t_pffs *pffs,u8 sector) { - - u16 data[3]; - u32 iaddr; - u32 daddr; - u8 fnlen; - u8 found; +#define pffs_check_magic(data) (((data)&PFFS_INDEX_MAGIC_MASK)==PFFS_INDEX_MAGIC) +#define pffs_fnlen(data) (((data)&PFFS_FNLEN_MASK)>>4) +#define pffs_daddr_msb(data) (((data)&PFFS_LEN_MSB_MASK)) +#define pffs_sec_erase(pffs,sec) pffs->fe(pffs->base_addr|pffs->sec_addr[sec]) - iaddr=0; - daddr=0; - found=0; +u32 pffs_find_index(t_pffs *pffs,u8 sector) { - while(1) { - pffs->fr(pffs->base_addr+pffs->sec_addr[sector]+iaddr,data,6); - if(!((data[0]&0xff00)==PFFS_INDEX_MAGIC)) - break; - found=1; - fnlen=(data[0]&0x00f0)>>4; - iaddr+=(6+fnlen+fnlen); - daddr=((data[0]&0x000f)<<16)|data[1]; - } + u16 data; - pffs->data_ptr=daddr; + pffs->fr(pffs->base_addr+pffs->sec_addr[sector],&data,2); - if(found) { - pffs->index_ptr=pffs->sec_addr[sector]+iaddr; - return 0; + if((data&0xf000)==PFFS_INDEX_MAGIC) { + pffs->index_sec=sector; + return PFFS_INDEX_FOUND; } - else - return -1; + + return PFFS_NO_INDEX_FOUND; } int pffs_sec_empty(t_pffs *pffs,u8 sec) { @@ -51,26 +38,71 @@ int pffs_sec_empty(t_pffs *pffs,u8 sec) { addr=pffs->base_addr|pffs->sec_addr[sec]; while(addr<(pffs->base_addr|pffs->sec_addr[sec+1])) { - data=*((u16 *)(addr)); + pffs->fr(addr,&data,2); if(data!=0xffff) - return 0; + return PFFS_SEC_NOT_EMPTY; addr+=2; } - return 1; + return PFFS_SEC_EMPTY; } -#define pffs_sec_erase(pffs,sec) pffs->fe(pffs->base_addr|pffs->sec_addr[sec]) +int pffs_find_data_tmp(t_pffs *pffs,u8 sector) { -int pffs_reorientate(t_pffs *pffs) { + u32 iaddr,daddr,dend,dstart; + u16 data[3]; + u8 fnlen; - u8 sec,sec0,sec1; + iaddr=pffs->base_addr|pffs->sec_addr[pffs->index_sec]; + dstart=pffs->sec_addr[sector]; + dend=pffs->sec_addr[sector+1]; + + while(iaddr<(pffs->base_addr|pffs->sec_addr[sector+1])) { + pffs->fr(iaddr,data,6); + if(pffs_check_magic(data[0])) + break; + daddr=pffs_daddr_msb(data[0])|data[1]; + if((daddr+data[2]=dend)) { + fnlen=pffs_fnlen(data[0]); + iaddr+=(6+fnlen+fnlen); + continue; + } + else + return PFFS_NO_DATA_TMP; + } + + pffs->data_tmp_sec=sector; + if(pffs_sec_empty(pffs,sector)!=PFFS_SEC_EMPTY) + pffs->fe(pffs->base_addr|dstart); + + return PFFS_DATA_TMP_FOUND;; +} + +int pffs_orientate(t_pffs *pffs) { + + u8 sec,sec0,sec1,found; - /* check index sectors */ sec0=pffs->sec_num_index[0]; sec1=pffs->sec_num_index[1]; - if(!(pffs_get_ptr(pffs,sec0)&pffs_get_ptr(pffs,sec1))) - return 0; + + found=0; + + /* check index sectors */ + if(pffs_find_index(pffs,sec0)==PFFS_INDEX_FOUND) + found=1; + else if(pffs_find_index(pffs,sec1)==PFFS_INDEX_FOUND) + found=1; + + /* chose temp data sector */ + if(found) { + sec0=pffs->sec_num_data[0]; + sec1=pffs->sec_num_data[1]; + for(sec=sec1;sec>=sec0;sec--) + if(pffs_find_data_tmp(pffs,sec)==PFFS_DATA_TMP_FOUND) + break; + + return PFFS_INDEX_FOUND; + } /* initial run => no data + no index assumed => check whether erased! */ // erase index sectors @@ -78,9 +110,11 @@ int pffs_reorientate(t_pffs *pffs) { pffs_sec_erase(pffs,sec0); if(!pffs_sec_empty(pffs,sec1)) pffs_sec_erase(pffs,sec1); + pffs->index_sec=sec0; // erase data sectors sec0=pffs->sec_num_data[0]; sec1=pffs->sec_num_data[1]; + pffs->data_tmp_sec=sec1; for(sec=sec0;sec<=sec1;sec++) if(!pffs_sec_empty(pffs,sec)) pffs_sec_erase(pffs,sec); @@ -88,32 +122,47 @@ int pffs_reorientate(t_pffs *pffs) { return 0; } -int pffs_flash_register(t_pffs *pffs,u32 base_addr,u8 sec_num,u32 *sec_addr, - u8 sec_num_data_min,u8 sec_num_data_max, - u8 sec_num_index0,u8 sec_num_index1, +int pffs_get_data_sec(t_pffs_fd *fd) { + + t_pffs *pffs; + u8 sec,sec0,sec1; + + pffs->fd->pffs; + sec0=pffs->sec_num_data[0]; + sec1=pffs->sec_num_data[1]; + + for(sec=sec0;secsec_addr[sec+1])&(addr>=pffs->sec_addr[sec])) { + fd->data_sec=sec; + break; + } + } + + return 0; +} + +int pffs_rearrange(t_pffs *pffs) { + + + + return 0; +} + +int pffs_flash_register(t_pffs *pffs,u32 base_addr,u32 *sec_addr,u8 sec_num, int (*fw)(u32 addr,u16 *buf,int len), int (*fr)(u32 addr,u16 *buf,int len), int (*fe)(u32 addr)) { /* assign physical flash specs */ pffs->base_addr=base_addr; - pffs->sec_num=sec_num; pffs->sec_addr=sec_addr; - - /* specified index and data sectors */ - pffs->sec_num_data[0]=sec_num_data_min; - pffs->sec_num_data[1]=sec_num_data_max; - pffs->sec_num_index[0]=sec_num_index0; - pffs->sec_num_index[1]=sec_num_index1; + pffs->sec_num=sec_num; /* flash acccess function pointers */ pffs->fw=fw; pffs->fr=fr; pffs->fe=fe; - /* orientate */ - pffs_reorientate(pffs); - pffs->state|=PFFS_REGISTERED; return 0; @@ -121,9 +170,188 @@ int pffs_flash_register(t_pffs *pffs,u32 base_addr,u8 sec_num,u32 *sec_addr, int pffs_init(t_pffs *pffs) { + /* check whether a flash is registered */ if(!(pffs->state&PFFS_REGISTERED)) return -1; + /* orientate */ + pffs_orientate(pffs); + return 0; } +int pffs_find_file(t_pffs *pffs,char *file,u32 *iaddr,u32 *daddr,u16 *len) { + + u8 fnl; + u16 data[PFFS_MAX_FILENAME_SIZE+PFFS_HEADER_SIZE]; + + *iaddr=pffs->base_addr|pffs->sec_addr[pffs->index_sec]; + + while(*iaddrsec_addr[pffs->index_sec+1]) { + pffs->fr(*iaddr,data,3); + + if(!pffs_check_magic(data[0])) + break; + + fnl=pffs_fnlen(data[0]); + pffs->fr(*iaddr+6,data+3,fnl+fnl); + + if(!strncmp(file,(char *)(data+3),fnl+fnl)) { + *daddr=pffs->base_addr|((data[0]&0x000f)<<16)|data[1]; + *len=data[2]; + return PFFS_FILE_FOUND; + } + + *iaddr+=(6+fnl+fnl); + } + + return PFFS_FILE_NOT_FOUND; +} + +int pffs_open_read(t_pffs_fd *fd) { + + int ret; + + ret=pffs_find_file(fd->pffs,fd->file, + &(fd->iaddr),&(fd->daddr),&(fd->len)); + + if(ret==PFFS_FILE_FOUND) { + fd->dptr=fd->daddr; + fd->mode=PFFS_READ; + } + + return ret; +} + +int pffs_write_index_init(t_pffs_fd *fd) { + + t_pffs *pffs; + u16 data[PFFS_HEADER_SIZE+PFFS_MAX_FILENAME_SIZE]; + + pffs=fd->pffs; + fns=fd->fn-size; + + if(fd->iaddr+6+fns+fns>=pffs->sec_addr[pffs->index_sec+1]) + return PFFS_NO_INDEX_SPACE_LEFT; + + data[0]=0x7f00|(fns<<4)|((fd->daddr>>16)&0xf); + data[1]=fd->daddr&0xffff; + pffs->fw(fd->iaddr,data,4); + pffs->fw(fd->iaddr+6,fd->file,fns+fns); + + return PFFS_INDEX_WROTE_INIT; +} + +int pffs_write_finish(t_pffs_fd *fd) { + + fd->pffs->fw(fd->iaddr+4,&(fd->len),2); + + return 0; +} + +int pffs_open_write(t_pffs_fd *fd) { + + int ret; + + ret=pffs_find_file(fd->pffs,fd->file, + &(fd->iaddr),&(fd->daddr),&(fd->len)); + + switch(ret) { + case PFFS_FILE_NOT_FOUND: + ret=pffs_write_index_init(); + if(ret!=PFFS_INDEX_WROTE_INIT) + break; + fd->dptr=fd->daddr; + fd->len=0; + fd->mode=PFFS_WRITE; + break; + case PFFS_FILE_FOUND: + default: + break; + } + + return ret; +} + +int pffs_open(t_pffs *pffs,t_pffs_fd *fd,char *file,u8 mode) { + + int ret; + + /* the pffs struct */ + fd->pffs=pffs; + + /* filename */ + fd->fn_size=strlen(file); + if(fd->fn_size&1) + fd->file[fd->fn_size++]='\0'; + fd->fn_size>>1; + if(fd->fn_size>PFFS_MAX_FILENAME_SIZE) + return PFFS_FILENAME_TOO_LONG; + strncpy(fd->file,file,fd->fn_size+fd->fn_size); + + /* clear fd mode */ + fd->mode=0; + + /* action */ + switch(mode) { + case PFFS_READ: + ret=pffs_open_read(fd); + break; + case PFFS_WRITE: + ret=pffs_open_write(fd); + break; + case PFFS_RDWR: + default: + return PFFS_MODE_UNSUPPORTED; + } + + return ret; +} + +int pffs_read(t_pffs_fd *fd,u8 *buf,int len) { + + int missing; + int sec_end; + + /* check whether valid */ + if(!(fd->mode&PFFS_READ)) + return PFFS_EINVAL; + + /* check len */ + if(len&1) + return PFFS_INVALID_LEN; + + /* check how much we read */ + missing=fd->len-(fd->dptr-fd->daddr); + if(len>missing) + len=missing; + + if((fd->dptr+len)>=pffs->sec_addr[pffs->sec_num_data[1]+1]) + sec_end=pffs->sec_addr[pffs->sec_num_data[1]+1]-fd->dptr; + + + /* read */ + fd->pffs->fr(fd->dptr,(u16 *)buf,len); + fd->dptr+=len;; + + return len; +} + +int pffs_write(t_pffs_fd *fd,u8 buf,int len) { + + /* check whether valid */ + if(!(fd->mode&PFFS_WRITE)) + return PFFS_EINVAL; + + /* check len */ + if(len&1) + return PFFS_INVALID_LEN; + + missing=PFFS_MAX_FILE_SIZE-fd->len; + if(len>missing) + len=missing; + + /* check for */ + if(fd->dptr+len>=pffs->) +} +