2 * pffs.c - pseudo flash filesystem
4 * author: hackbard@hackdaworld.org
14 u32 pffs_get_ptr(t_pffs *pffs,u8 sector) {
27 pffs->fr(pffs->base_addr+pffs->sec_addr[sector]+iaddr,data,6);
28 if(!((data[0]&0xff00)==PFFS_INDEX_MAGIC))
31 fnlen=(data[0]&0x00f0)>>4;
32 iaddr+=(6+fnlen+fnlen);
33 daddr=((data[0]&0x000f)<<16)|data[1];
39 pffs->index_ptr[0]=pffs->sec_addr[sector];
40 pffs->index_ptr[1]=pffs->sec_addr[sector]+iaddr;
47 int pffs_sec_empty(t_pffs *pffs,u8 sec) {
52 addr=pffs->base_addr|pffs->sec_addr[sec];
54 while(addr<(pffs->base_addr|pffs->sec_addr[sec+1])) {
55 data=*((u16 *)(addr));
64 #define pffs_sec_erase(pffs,sec) pffs->fe(pffs->base_addr|pffs->sec_addr[sec])
66 int pffs_orientate(t_pffs *pffs) {
70 /* check index sectors */
71 sec0=pffs->sec_num_index[0];
72 sec1=pffs->sec_num_index[1];
73 if(!(pffs_get_ptr(pffs,sec0)&pffs_get_ptr(pffs,sec1)))
76 /* initial run => no data + no index assumed => check whether erased! */
77 // erase index sectors
78 if(!pffs_sec_empty(pffs,sec0))
79 pffs_sec_erase(pffs,sec0);
80 if(!pffs_sec_empty(pffs,sec1))
81 pffs_sec_erase(pffs,sec1);
83 sec0=pffs->sec_num_data[0];
84 sec1=pffs->sec_num_data[1];
85 for(sec=sec0;sec<=sec1;sec++)
86 if(!pffs_sec_empty(pffs,sec))
87 pffs_sec_erase(pffs,sec);
92 int pffs_flash_register(t_pffs *pffs,u32 base_addr,u32 *sec_addr,
93 u8 sec_num_data_min,u8 sec_num_data_max,
94 u8 sec_num_index0,u8 sec_num_index1,
95 int (*fw)(u32 addr,u16 *buf,int len),
96 int (*fr)(u32 addr,u16 *buf,int len),
97 int (*fe)(u32 addr)) {
99 /* assign physical flash specs */
100 pffs->base_addr=base_addr;
101 pffs->sec_addr=sec_addr;
103 /* specified index and data sectors */
104 pffs->sec_num_data[0]=sec_num_data_min;
105 pffs->sec_num_data[1]=sec_num_data_max;
106 pffs->sec_num_index[0]=sec_num_index0;
107 pffs->sec_num_index[1]=sec_num_index1;
109 /* flash acccess function pointers */
114 pffs->state|=PFFS_REGISTERED;
119 int pffs_init(t_pffs *pffs) {
121 /* check whether a flash is registered */
122 if(!(pffs->state&PFFS_REGISTERED))
126 pffs_orientate(pffs);
131 #define pffs_check_magic(data) (((data)&PFFS_INDEX_MAGIC_MASK)==PFFS_INDEX_MAGIC)
132 #define pffs_fnlen(data) (((data)&PFFS_FNLEN_MASK)>>4)
133 #define pffs_daddr_msb(data) (((data)&))
135 int pffs_find_file(t_pffs *pffs,char *file,u32 *iaddr,u32 *daddr,u16 *len) {
138 u16 data[PFFS_MAX_FILENAME_SIZE+PFFS_HEADER_SIZE];
140 pffs->index_ptr[2]=pffs->base_addr|pffs->index_ptr[0];
142 while(pffs->index_ptr[2]<pffs->index_ptr[1])
143 pffs->fr(iaddr,data,3);
145 if(!pffs_check_magic(data[0]))
148 fnl=pffs_fnlen(data[0]);
149 pffs->fr(iaddr+6,data+3,fnl+fnl);
151 if(!strncmp(fd->file,(char *)(data+3),fnl+fnl)) {
152 *daddr=((data[0]&0x000f)<<16)|data[1];
154 pffs->index_ptr[2]=*iaddr;
155 return PFFS_FILE_EXISTS;
157 pffs->fr(iaddr,data,3);
160 return PFFS_FILE_NOT_FOUND;
163 int pffs_open_read(t_pffs *pffs,t_pffs_fd *fd) {
167 u16 data[PFFS_MAX_FILENAME+PFFS_HEADER_SIZE];
169 iaddr=pffs->base_addr|pffs->index_ptr[0];
174 int pffs_open(t_pffs *pffs,t_pffs_fd *fd,char *file,u8 mode) {
176 /* the pffs struct */
180 fd->fn_size=strlen(file);
182 return PFFS_FILENAME_TOO_LONG;
183 strncpy(fd->file,file,fd->fn_size);
185 fd->file[fd->fn_size++]='\0';
193 pffs_open_read(pffs,fd);
199 return PFFS_MODE_UNSUPPORTED;