summaryrefslogtreecommitdiff
path: root/firmware/target/arm/tms320dm320/creative-zvm/ata-creativezvm.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/tms320dm320/creative-zvm/ata-creativezvm.c')
-rw-r--r--firmware/target/arm/tms320dm320/creative-zvm/ata-creativezvm.c174
1 files changed, 104 insertions, 70 deletions
diff --git a/firmware/target/arm/tms320dm320/creative-zvm/ata-creativezvm.c b/firmware/target/arm/tms320dm320/creative-zvm/ata-creativezvm.c
index a55cda4c14..b945d47b4b 100644
--- a/firmware/target/arm/tms320dm320/creative-zvm/ata-creativezvm.c
+++ b/firmware/target/arm/tms320dm320/creative-zvm/ata-creativezvm.c
@@ -203,7 +203,7 @@ static unsigned long cfs_start;
203static unsigned long *sectors; 203static unsigned long *sectors;
204 204
205#define CFS_START ( ((hdr->partitions[1].start*hdr->sector_size) & ~0xFFFF) + 0x10000 ) 205#define CFS_START ( ((hdr->partitions[1].start*hdr->sector_size) & ~0xFFFF) + 0x10000 )
206#define CFS_CLUSTER2CLUSTER(x) ( CFS_START+((x)-1)*64 ) 206#define CFS_CLUSTER2CLUSTER(x) ( (CFS_START/512)+((x)-1)*64 )
207 207
208/* Limited version of UCS -> ASCII */ 208/* Limited version of UCS -> ASCII */
209static char* ucs2letostring(unsigned char* s) 209static char* ucs2letostring(unsigned char* s)
@@ -211,7 +211,7 @@ static char* ucs2letostring(unsigned char* s)
211 static char res[256]; 211 static char res[256];
212 int i; 212 int i;
213 213
214 for(i=0; (s[i] == 0 && s[i+1] == 0); i++) 214 for(i=0; (s[i] == 0 && s[i+1] == 0 && i<256); i++)
215 res[i] = s[i*2]; 215 res[i] = s[i*2];
216 216
217 return (char*)&res; 217 return (char*)&res;
@@ -236,111 +236,134 @@ static void cfs_init(void)
236 _ata_read_sectors(0, 1, &sector); 236 _ata_read_sectors(0, 1, &sector);
237 hdr = (struct main_header*)&sector; 237 hdr = (struct main_header*)&sector;
238 238
239 //printf("CFS is at 0x%x", CFS_START); 239 logf("CFS is at 0x%x [0x%x]", CFS_START, CFS_START/512);
240 240
241 /* Read CFS header */ 241 /* Read CFS header */
242 _ata_read_sectors(CFS_START/512, 64, &sector2); 242 _ata_read_sectors(CFS_START/512, 64, &sector2);
243 cfs = (struct cfs_header*)&sector2; 243 cfs = (struct cfs_header*)&sector2;
244 244
245 //printf("First inode = %d", cfs->first_inode); 245 logf("First inode = 0x%x", cfs->first_inode);
246 246
247 /* Read root inode */ 247 /* Read root inode */
248 _ata_read_sectors(CFS_CLUSTER2CLUSTER(cfs->first_inode), 64, &sector2); 248 _ata_read_sectors(CFS_CLUSTER2CLUSTER(cfs->first_inode), 64, &sector2);
249 root_inode = (struct cfs_inode*)&sector2; 249 root_inode = (struct cfs_inode*)&sector2;
250
251 logf("Root inode = 0x%x", root_inode);
252
253 logf("0x%x 0x%x", CFS_CLUSTER2CLUSTER(root_inode->first_class_chain[0]), root_inode->first_class_chain[0]);
250 254
251 /* Read root inode's first sector */ 255 /* Read root inode's first sector */
252 _ata_read_sectors(CFS_CLUSTER2CLUSTER(root_inode->first_class_chain[0]), 64, &sector2); 256 _ata_read_sectors(CFS_CLUSTER2CLUSTER(root_inode->first_class_chain[0]), 64, &sector2);
253 root_direntry = (struct cfs_direntry*)&sector2; 257 root_direntry = (struct cfs_direntry*)&sector2;
254 root_direntry_items = (struct cfs_direntry_item*)(&sector2+sizeof(struct cfs_direntry)); 258 root_direntry_items = (struct cfs_direntry_item*)(&sector2+sizeof(struct cfs_direntry));
255 259
260 logf("0x%x", root_direntry->identifier);
261
262 logf("%d", root_direntry->items);
263
256 /* Search VFAT inode */ 264 /* Search VFAT inode */
257 for(i=0; i < root_direntry->items; i++) 265 for(i=0; i < root_direntry->items; i++)
258 { 266 {
259 //printf(" * [%s] at 0x%x\n", ucs2letostring(&root_direntry_items[i].string[0]), root_direntry_items[i].inode_number); 267 if(root_direntry_items[i].inode_number != 0)
260 if(strcmp(ucs2letostring(&root_direntry_items[i].string[0]), "VFAT") == 0) 268 {
261 vfat_inode_nr = root_direntry_items[i].inode_number; 269 //logf(" * [%s] at 0x%x", ucs2letostring(&root_direntry_items[i].string[0]), root_direntry_items[i].inode_number);
270 if(strcmp(ucs2letostring(&root_direntry_items[i].string[0]), "VFAT") == 0)
271 vfat_inode_nr = root_direntry_items[i].inode_number;
272 }
262 } 273 }
263 274
264 /* Read VFAT inode */ 275 logf("VFAT inode = 0x%x", vfat_inode_nr);
265 _ata_read_sectors(CFS_CLUSTER2CLUSTER(vfat_inode_nr), 64, &sector2); 276
266 vfat_inode = (struct cfs_inode*)&sector2; 277 if(vfat_inode_nr != 0)
267
268 /* Read VFAT inode's first sector */
269 _ata_read_sectors(CFS_CLUSTER2CLUSTER(vfat_inode->first_class_chain[0]), 64, &sector2);
270 vfat_direntry = (struct cfs_direntry*)&sector2;
271 vfat_direntry_items = (struct cfs_direntry_item*)(&sector2+sizeof(struct cfs_direntry));
272
273 /* Search for VFAT's subinodes */
274 for(i=0; i < vfat_direntry->items; i++)
275 { 278 {
276 //printf(" * [%s] at 0x%x\n", ucs2letostring(&vfat_direntry_items[i].string[0]), vfat_direntry_items[i].inode_number); 279 /* Read VFAT inode */
277 if(i > 0) 280 _ata_read_sectors(CFS_CLUSTER2CLUSTER(vfat_inode_nr), 64, &sector2);
278 vfat_inodes_nr[i-1] = vfat_direntry_items[i].inode_number; 281 vfat_inode = (struct cfs_inode*)&sector2;
279 }
280 282
281 /* Determine size of VFAT file */ 283 /* Read VFAT inode's first sector */
282 _ata_read_sectors(CFS_CLUSTER2CLUSTER(vfat_inodes_nr[1]), 1, &sector); 284 _ata_read_sectors(CFS_CLUSTER2CLUSTER(vfat_inode->first_class_chain[0]), 64, &sector2);
283 inode = (struct cfs_inode*)&sector; 285 vfat_direntry = (struct cfs_direntry*)&sector2;
284 sectors = (unsigned long*)buffer_alloc(VFAT_SECTOR_SIZE(inode->filesize)); 286 vfat_direntry_items = (struct cfs_direntry_item*)(&sector2+sizeof(struct cfs_direntry));
285 287
286 //printf("VFAT file size: 0x%x", inode->filesize); 288 /* Search for VFAT's subinodes */
287 289 for(i=0; i < vfat_direntry->items; i++)
288 /* Clear data sectors */ 290 {
289 memset(&sectors, 0, VFAT_SECTOR_SIZE(inode->filesize)*sizeof(unsigned long)); 291 logf(" * [%s] at 0x%x\n", ucs2letostring(&vfat_direntry_items[i].string[0]), vfat_direntry_items[i].inode_number);
292 if(i > 0)
293 vfat_inodes_nr[i-1] = vfat_direntry_items[i].inode_number;
294 }
290 295
291 /* Read all data sectors' addresses in memory */ 296 /* Determine size of VFAT file */
292 vfat_sector_count = 0; 297 _ata_read_sectors(CFS_CLUSTER2CLUSTER(vfat_inodes_nr[1]), 1, &sector);
293 for(i=0; vfat_inodes_nr[i] != 0; i++)
294 {
295 _ata_read_sectors(CFS_CLUSTER2CLUSTER(vfat_inodes_nr[i]), 1, &sector);
296 inode = (struct cfs_inode*)&sector; 298 inode = (struct cfs_inode*)&sector;
299#ifndef BOOTLOADER
300 sectors = (unsigned long*)buffer_alloc(VFAT_SECTOR_SIZE(inode->filesize));
301#else
302 static unsigned long _sector[VFAT_SECTOR_SIZE(1024*1024*1024)]; /* 1GB guess */
303 sectors = _sector;
304#endif
297 305
298 /* Read second & third class chain */ 306 logf("VFAT file size: 0x%x", inode->filesize);
299 _ata_read_sectors(CFS_CLUSTER2CLUSTER(inode->second_class_chain_first_cluster), 64, &vfat_data[0]);
300 _ata_read_sectors(CFS_CLUSTER2CLUSTER(inode->second_class_chain_second_cluster), 64, &vfat_data[1]);
301 307
302 /* First class chain */ 308 /* Clear data sectors */
303 for(j=0; j<12; j++) 309 memset(&sectors, 0, VFAT_SECTOR_SIZE(inode->filesize)*sizeof(unsigned long));
304 {
305 if( (inode->first_class_chain[j] & 0xFFFF) != 0xFFFF &&
306 inode->first_class_chain[j] != 0
307 )
308 sectors[vfat_sector_count++] = inode->first_class_chain[j];
309 }
310 310
311 /* Second class chain */ 311 /* Read all data sectors' addresses in memory */
312 for(j=0; j<0x8000/4; j++) 312 vfat_sector_count = 0;
313 for(i=0; vfat_inodes_nr[i] != 0; i++)
313 { 314 {
314 if( (vfat_data[0][j] & 0xFFFF) != 0xFFFF && 315 _ata_read_sectors(CFS_CLUSTER2CLUSTER(vfat_inodes_nr[i]), 1, &sector);
315 vfat_data[0][j] != 0 316 inode = (struct cfs_inode*)&sector;
316 )
317 sectors[vfat_sector_count++] = vfat_data[0][j];
318 }
319 317
320 /* Third class chain */ 318 /* Read second & third class chain */
321 for(j=0; j<0x8000/4; j++) 319 _ata_read_sectors(CFS_CLUSTER2CLUSTER(inode->second_class_chain_first_cluster), 64, &vfat_data[0]);
322 { 320 _ata_read_sectors(CFS_CLUSTER2CLUSTER(inode->second_class_chain_second_cluster), 64, &vfat_data[1]);
323 if( (vfat_data[1][j] & 0xFFFF) != 0xFFFF && 321
324 vfat_data[1][j] != 0 322 /* First class chain */
325 ) 323 for(j=0; j<12; j++)
326 { 324 {
327 memset(&vfat_data[0], 0, 0x8000*sizeof(unsigned int)); 325 if( (inode->first_class_chain[j] & 0xFFFF) != 0xFFFF &&
326 inode->first_class_chain[j] != 0
327 )
328 sectors[vfat_sector_count++] = inode->first_class_chain[j];
329 }
328 330
329 /* Read third class subchain(s) */ 331 /* Second class chain */
330 _ata_read_sectors(CFS_CLUSTER2CLUSTER(vfat_data[1][j]), 64, &vfat_data[0]); 332 for(j=0; j<0x8000/4; j++)
333 {
334 if( (vfat_data[0][j] & 0xFFFF) != 0xFFFF &&
335 vfat_data[0][j] != 0
336 )
337 sectors[vfat_sector_count++] = vfat_data[0][j];
338 }
331 339
332 for(k=0; k<0x8000/4; k++) 340 /* Third class chain */
341 for(j=0; j<0x8000/4; j++)
342 {
343 if( (vfat_data[1][j] & 0xFFFF) != 0xFFFF &&
344 vfat_data[1][j] != 0
345 )
333 { 346 {
334 if( (vfat_data[0][k] & 0xFFFF) != 0xFFFF && 347 memset(&vfat_data[0], 0, 0x8000*sizeof(unsigned int));
335 vfat_data[0][k] != 0 348
336 ) 349 /* Read third class subchain(s) */
337 sectors[vfat_sector_count++] = vfat_data[0][k]; 350 _ata_read_sectors(CFS_CLUSTER2CLUSTER(vfat_data[1][j]), 64, &vfat_data[0]);
351
352 for(k=0; k<0x8000/4; k++)
353 {
354 if( (vfat_data[0][k] & 0xFFFF) != 0xFFFF &&
355 vfat_data[0][k] != 0
356 )
357 sectors[vfat_sector_count++] = vfat_data[0][k];
358 }
338 } 359 }
339 } 360 }
340 } 361 }
341 }
342 362
343 //printf("Sector count: %d 0x%x", vfat_sector_count, vfat_sector_count); 363 logf("Sector count: %d 0x%x", vfat_sector_count, vfat_sector_count);
364 }
365 else
366 logf("Cannot find virtual FAT filesystem!"); //TODO: panicf
344 367
345 cfs_inited = true; 368 cfs_inited = true;
346} 369}
@@ -386,6 +409,7 @@ int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count, const v
386 if(!cfs_inited) 409 if(!cfs_inited)
387 cfs_init(); 410 cfs_init();
388 411
412#if 0 /* Disabled for now */
389 /* Check if count is lesser than or equal to 1 native CFS sector */ 413 /* Check if count is lesser than or equal to 1 native CFS sector */
390 if(count <= 64) 414 if(count <= 64)
391 return _ata_write_sectors(IF_MV2(drive,) map_sector(start), count, buf); 415 return _ata_write_sectors(IF_MV2(drive,) map_sector(start), count, buf);
@@ -406,8 +430,16 @@ int ata_write_sectors(IF_MV2(int drive,) unsigned long start, int count, const v
406 430
407 return ret; 431 return ret;
408 } 432 }
433#else
434 (void)start;
435 (void)count;
436 (void)buf;
437 return 0;
438#endif
409} 439}
410 440
441#ifdef BOOTLOADER
442
411/* 443/*
412 --------------------------------------------------------------------------- 444 ---------------------------------------------------------------------------
413 MiniFileSystem parsing code 445 MiniFileSystem parsing code
@@ -487,3 +519,5 @@ int load_minifs_file(char* filename, unsigned char* location)
487 519
488 return files[found].size; 520 return files[found].size;
489} 521}
522
523#endif