mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2025-05-18 15:29:16 +02:00
fygue: rework flash abstraction + support FAT12 (untested) + support G35PE2 device + support Math+ device (untested)
This commit is contained in:
parent
fc358c2fb1
commit
f1bf037a18
7 changed files with 323 additions and 118 deletions
|
@ -4,6 +4,88 @@
|
|||
#include "fat.h"
|
||||
#include "../flash/flash.h"
|
||||
|
||||
//---
|
||||
// Internals
|
||||
//---
|
||||
|
||||
/* _fygue_fat16_cluster_get_next(): FAT16 cluster handling */
|
||||
static int _fygue_fat16_cluster_get_next(
|
||||
struct fygue_fat *fat,
|
||||
int *cluster
|
||||
) {
|
||||
uint16_t *fat0;
|
||||
int nb_entry_per_sector;
|
||||
int cluster_sector;
|
||||
int cluster_real;
|
||||
int rc;
|
||||
|
||||
nb_entry_per_sector = fat->SectorSize / 2;
|
||||
cluster_sector = *cluster / nb_entry_per_sector;
|
||||
cluster_real = *cluster - (cluster_sector * nb_entry_per_sector);
|
||||
rc = fygue_fat_sector_get_addr(
|
||||
fat,
|
||||
(void*)&fat0,
|
||||
fat->FAT0SectorID + cluster_sector
|
||||
);
|
||||
if (rc < 0)
|
||||
return -1;
|
||||
*cluster = FAT_WORD(fat0[cluster_real]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* _fygue_fat12_cluster_get_next(): FAT12 cluster handling */
|
||||
// TODO: assume fixed sector size to 512
|
||||
// TODO: better calculus
|
||||
static int _fygue_fat12_cluster_get_next(
|
||||
struct fygue_fat *fat,
|
||||
int *cluster
|
||||
) {
|
||||
int fat_index0;
|
||||
int fat_index1;
|
||||
int fat_offset0;
|
||||
int fat_offset1;
|
||||
int fat_sector0;
|
||||
int fat_sector1;
|
||||
uintptr_t fat_data0;
|
||||
uintptr_t fat_data1;
|
||||
|
||||
fat_index0 = *cluster + (*cluster / 2);
|
||||
fat_index1 = fat_index0 + 1;
|
||||
fat_sector0 = fat->FAT0SectorID + (fat_index0 / fat->SectorSize);
|
||||
fat_sector1 = fat->FAT0SectorID + (fat_index1 / fat->SectorSize);
|
||||
|
||||
if (fat_sector0 == fat_sector1) {
|
||||
if (fygue_fat_sector_get_addr(fat, &fat_data0, fat_sector0) != 0)
|
||||
return -1;
|
||||
fat_data1 = fat_data0;
|
||||
fat_offset0 = fat_index0 - (fat_sector0 * fat->SectorSize);
|
||||
fat_offset1 = fat_offset0 + 1;
|
||||
} else {
|
||||
if (fygue_fat_sector_get_addr(fat, &fat_data0, fat_sector0) != 0)
|
||||
return -1;
|
||||
if (fygue_fat_sector_get_addr(fat, &fat_data1, fat_sector1) != 0)
|
||||
return -1;
|
||||
fat_offset0 = fat_index0 - (fat_sector0 * fat->SectorSize);
|
||||
fat_offset1 = fat_index1 - (fat_sector1 * fat->SectorSize);
|
||||
}
|
||||
|
||||
if (*cluster & 1) {
|
||||
*cluster = (
|
||||
((((uint8_t*)fat_data0)[fat_offset0] & 0xf0) >> 4) |
|
||||
((((uint8_t*)fat_data1)[fat_offset1] & 0xff) << 4)
|
||||
);
|
||||
} else {
|
||||
*cluster = (
|
||||
((((uint8_t*)fat_data0)[fat_offset0] & 0xff) >> 0) |
|
||||
((((uint8_t*)fat_data1)[fat_offset1] & 0xf0) << 8)
|
||||
);
|
||||
}
|
||||
|
||||
if (*cluster == 0x0fff)
|
||||
*cluster = 0xffff;
|
||||
return -1;
|
||||
}
|
||||
|
||||
//---
|
||||
// Public
|
||||
//---
|
||||
|
@ -24,10 +106,6 @@
|
|||
* - ensure FAT1 information is the same ? */
|
||||
int fygue_fat_cluster_get_next(struct fygue_fat *fat, int *cluster_current)
|
||||
{
|
||||
uint16_t *fat0;
|
||||
int nb_entry_per_sector;
|
||||
int cluster_sector;
|
||||
int cluster_real;
|
||||
int cluster;
|
||||
int rc;
|
||||
|
||||
|
@ -42,18 +120,12 @@ int fygue_fat_cluster_get_next(struct fygue_fat *fat, int *cluster_current)
|
|||
return -2;
|
||||
if (cluster >= fat->ClusterCount)
|
||||
return -2;
|
||||
nb_entry_per_sector = fat->SectorSize / 2;
|
||||
cluster_sector = cluster / nb_entry_per_sector;
|
||||
cluster_real = cluster - (cluster_sector * nb_entry_per_sector);
|
||||
rc = fygue_fat_sector_get_addr(
|
||||
fat,
|
||||
(void*)&fat0,
|
||||
fat->FAT0SectorID + cluster_sector
|
||||
);
|
||||
if (rc < 0)
|
||||
if (fat->Type == FYGUE_FAT_TYPE_FAT12)
|
||||
rc = _fygue_fat12_cluster_get_next(fat, &cluster);
|
||||
if (fat->Type == FYGUE_FAT_TYPE_FAT16)
|
||||
rc = _fygue_fat16_cluster_get_next(fat, &cluster);
|
||||
if (rc != 0)
|
||||
return -5;
|
||||
rc = 0;
|
||||
cluster = FAT_WORD(fat0[cluster_real]);
|
||||
if (cluster == 0xffff)
|
||||
rc = -6;
|
||||
if (cluster == 0x0000)
|
||||
|
|
|
@ -100,7 +100,6 @@ static int _fygue_fat_configure(struct fygue_fat *fat)
|
|||
struct _fat_bpb *bpb;
|
||||
int RootDirSectors;
|
||||
int DataSec;
|
||||
int CountofClusters;
|
||||
|
||||
bpb = (void *)fat->BPB;
|
||||
|
||||
|
@ -111,13 +110,13 @@ static int _fygue_fat_configure(struct fygue_fat *fat)
|
|||
DataSec += FAT_WORD(bpb->BPB_FATSz16) * bpb->BPB_NumFATs;
|
||||
DataSec += RootDirSectors;
|
||||
DataSec = FAT_WORD(bpb->BPB_TotSec16) - DataSec;
|
||||
CountofClusters = DataSec / bpb->BPB_SecPerClus;
|
||||
if (CountofClusters < 4085) {
|
||||
fat->ClusterCount = DataSec / bpb->BPB_SecPerClus;
|
||||
if (fat->ClusterCount < 4085) {
|
||||
fat->Type = FYGUE_FAT_TYPE_FAT12;
|
||||
} else if (CountofClusters < 65525) {
|
||||
} else if (fat->ClusterCount < 65525) {
|
||||
fat->Type = FYGUE_FAT_TYPE_FAT16;
|
||||
} else {
|
||||
// TODO: maybe gint panic ?
|
||||
// TODO: (FAT32) maybe gint panic ?
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
@ -126,11 +125,6 @@ static int _fygue_fat_configure(struct fygue_fat *fat)
|
|||
fat->SectorSize = FAT_WORD(bpb->BPB_BytsPerSec);
|
||||
fat->SectorPerClus = bpb->BPB_SecPerClus;
|
||||
|
||||
// todo : FAT12-specific operation
|
||||
fat->ClusterCount = FAT_WORD(bpb->BPB_FATSz16);
|
||||
fat->ClusterCount *= FAT_WORD(bpb->BPB_BytsPerSec);
|
||||
fat->ClusterCount /= 2;
|
||||
|
||||
fat->FAT0SectorID = fat->SectorHiddenCount;
|
||||
fat->FAT0SectorID += FAT_WORD(bpb->BPB_RsvdSecCnt);
|
||||
fat->FAT1SectorID = fat->FAT0SectorID;
|
||||
|
@ -167,13 +161,12 @@ int fygue_fat_init_cold(struct fygue_fat *fat)
|
|||
memset(fat, 0x00, sizeof(struct fygue_fat));
|
||||
if (fygue_flash_initialize(&(fat->_flash)) != 0)
|
||||
return -2;
|
||||
if (
|
||||
_fygue_fat_sector0(fat) != 0 ||
|
||||
_fygue_fat_configure(fat) != 0 ||
|
||||
_fygue_fat_prepare(fat) != 0
|
||||
) {
|
||||
if (_fygue_fat_sector0(fat) != 0)
|
||||
return -3;
|
||||
}
|
||||
if (_fygue_fat_configure(fat) != 0)
|
||||
return -4;
|
||||
if (_fygue_fat_prepare(fat) != 0)
|
||||
return -5;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include <string.h>
|
||||
|
||||
#include <gint/defs/attributes.h>
|
||||
#include <gint/defs/util.h>
|
||||
#include <gint/hardware.h>
|
||||
|
||||
#include "flash.h"
|
||||
|
||||
|
@ -23,6 +25,8 @@ struct _bfile_cluster_metadata
|
|||
uint8_t ecc_bitmask_position[3];
|
||||
} GPACKED(1);
|
||||
|
||||
uintptr_t debug_meta = 0;
|
||||
|
||||
/* _fygue_flash_cluster_convert - ensure that the provided meta is valid
|
||||
*
|
||||
* notes
|
||||
|
@ -66,6 +70,7 @@ static int _fygue_flash_cluster_convert(
|
|||
|
||||
if (fcluster == NULL)
|
||||
return -1;
|
||||
debug_meta = bfile_meta;
|
||||
meta = (void*)(bfile_meta | 0xa0000000);
|
||||
if (
|
||||
meta->signature[0] != 0x5a ||
|
||||
|
@ -102,10 +107,172 @@ static int _fygue_flash_cluster_convert(
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* _fygue_flash_cluster_meta(): special metadata cluster handling
|
||||
*
|
||||
* notes:
|
||||
* metadata cluster are the last flash cluster of a flash sector it does
|
||||
* not have Bfile information. Generate a fake flash cluster with a
|
||||
* special custom kind to allow quick identification */
|
||||
static int _fygue_flash_cluster_meta(
|
||||
struct fygue_flash *flash,
|
||||
struct fygue_flash_cluster *fcluster,
|
||||
int fsector_id
|
||||
) {
|
||||
GAUTOTYPE geometry = &(flash->geometry);
|
||||
|
||||
memset(fcluster, 0x00, sizeof(struct fygue_flash_cluster));
|
||||
fcluster->kind = FYGUE_FCLUSTER_KIND_METADATA;
|
||||
fcluster->lcluster_id = 0xffff;
|
||||
fcluster->fcluster_id = 0xffff;
|
||||
fcluster->fcluster_id_bfile = 0xffff;
|
||||
fcluster->version = 0xffffffff;
|
||||
fcluster->meta_addr = 0xffffffff;
|
||||
fcluster->data_addr = (
|
||||
(geometry->phy_start | 0xa0000000) +
|
||||
((fsector_id + 1) * geometry->fsector_size) -
|
||||
(8 * 512)
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* _fygue_flash_cluster_details(): special flash sector details handling
|
||||
*
|
||||
* notes:
|
||||
* flash sector details is a particular flash cluster that contains
|
||||
* critical versioning information needed to rebuild Casio's flash
|
||||
* mapping.
|
||||
* However, this particular flash cluster are not represented in the
|
||||
* same way between machines. For example, the G35EII that use flash
|
||||
* sector of 64ko merge the details sector inside the metadata cluster to
|
||||
* keep some space which is not the case with the FXCP400 or CG50 that
|
||||
* use 128ko flash sector and which the first cluster should be a details
|
||||
* one type. */
|
||||
//TODO: remove device-specific code
|
||||
static int _fygue_flash_cluster_details(
|
||||
struct fygue_flash *flash,
|
||||
struct fygue_flash_cluster *fcluster,
|
||||
int fsector_id
|
||||
) {
|
||||
GAUTOTYPE geometry = &(flash->geometry);
|
||||
volatile uint32_t *data32;
|
||||
uintptr_t meta;
|
||||
uintptr_t data;
|
||||
|
||||
memset(fcluster, 0x00, sizeof(struct fygue_flash_cluster));
|
||||
if (gint[HWCALC] == HWCALC_G35PE2) {
|
||||
data = (
|
||||
(geometry->phy_start | 0xa0000000) +
|
||||
(fsector_id * geometry->fsector_size) +
|
||||
(geometry->fsector_size - (8*512)) +
|
||||
((geometry->fcluster_per_fsector - 1) * 0x40)
|
||||
);
|
||||
meta = data + 512;
|
||||
} else {
|
||||
data = (
|
||||
(geometry->phy_start | 0xa0000000) +
|
||||
(fsector_id * geometry->fsector_size)
|
||||
);
|
||||
meta = data + (geometry->fsector_size) - (8*512);
|
||||
}
|
||||
if (_fygue_flash_cluster_convert(flash, fcluster, meta) != 0)
|
||||
return -1;
|
||||
if (fcluster->version != 0xffffffff)
|
||||
return -2;
|
||||
data32 = (void*)data;
|
||||
if (
|
||||
((data32[0] ^ data32[1]) != 0xffffffff) ||
|
||||
((data32[2] ^ data32[3]) != 0xffffffff) ||
|
||||
((data32[4] ^ data32[5]) != 0xffffffff)
|
||||
) {
|
||||
return -1;
|
||||
}
|
||||
fcluster->data_addr = data;
|
||||
fcluster->meta_addr = meta;
|
||||
fcluster->version = data32[0];
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* _fygue_flash_cluster_data(): handle generic data flash cluster
|
||||
*
|
||||
* notes
|
||||
* flash cluster data (0x11 or 0x88) are handled in the same way between
|
||||
* all device */
|
||||
static int _fygue_flash_cluster_data(
|
||||
struct fygue_flash *flash,
|
||||
struct fygue_flash_cluster *fcluster,
|
||||
int fcluster_id,
|
||||
int fsector_id,
|
||||
int fcluster_off
|
||||
) {
|
||||
GAUTOTYPE geometry = &(flash->geometry);
|
||||
uintptr_t meta;
|
||||
uintptr_t data;
|
||||
|
||||
data = (
|
||||
(geometry->phy_start | 0xa0000000) +
|
||||
(fsector_id * geometry->fsector_size) +
|
||||
(fcluster_off * (8 * 512))
|
||||
);
|
||||
meta = (
|
||||
(geometry->phy_start | 0xa0000000) +
|
||||
(fsector_id * geometry->fsector_size) +
|
||||
(geometry->fsector_size - (8 * 512)) +
|
||||
(fcluster_off * 0x40)
|
||||
);
|
||||
int rc = _fygue_flash_cluster_convert(flash, fcluster, meta);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
fcluster->data_addr = data;
|
||||
fcluster->meta_addr = meta;
|
||||
fcluster->fcluster_id = fcluster_id;
|
||||
fcluster->fcluster_id_bfile = (
|
||||
(fsector_id * (geometry->fcluster_per_fsector - 1)) +
|
||||
(fcluster_off)
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//---
|
||||
// Public
|
||||
//---
|
||||
|
||||
/* fygue_flash_cluster_get() - get flash cluster information
|
||||
*
|
||||
* return
|
||||
* -1 if the provided `fline` is not valid
|
||||
* -2 if the provided `fline` have invalid Bfile metadata
|
||||
* 0 if the meta information has been generated */
|
||||
int fygue_flash_cluster_get(
|
||||
struct fygue_flash *flash,
|
||||
struct fygue_flash_cluster *fcluster,
|
||||
int fcluster_id
|
||||
) {
|
||||
int fsector_id;
|
||||
int fcluster_off;
|
||||
int nb_entry;
|
||||
|
||||
if (flash == NULL || fcluster == NULL)
|
||||
return -1;
|
||||
if (fcluster_id >= flash->geometry.fcluster_count)
|
||||
return -1;
|
||||
|
||||
nb_entry = flash->geometry.fcluster_per_fsector;
|
||||
fsector_id = fcluster_id / nb_entry;
|
||||
fcluster_off = fcluster_id % nb_entry;
|
||||
|
||||
if (fcluster_off == (nb_entry - 1))
|
||||
return _fygue_flash_cluster_meta(flash, fcluster, fsector_id);
|
||||
if (fcluster_off == 0)
|
||||
return _fygue_flash_cluster_details(flash, fcluster, fsector_id);
|
||||
return _fygue_flash_cluster_data(
|
||||
flash,
|
||||
fcluster,
|
||||
fcluster_id,
|
||||
fsector_id,
|
||||
fcluster_off
|
||||
);
|
||||
}
|
||||
|
||||
/* fygue_flash_cluster_geometry() - get geometry information
|
||||
*
|
||||
* notes
|
||||
|
@ -123,72 +290,19 @@ int fygue_flash_cluster_geometry(
|
|||
uint16_t *fsector_id,
|
||||
uint16_t *fcluster_off
|
||||
) {
|
||||
int nb_cluster;
|
||||
|
||||
if ((addr & 0x0fffffff) < flash->geometry.phy_start)
|
||||
return -1;
|
||||
nb_cluster = flash->geometry.fcluster_per_fsector;
|
||||
addr = (addr & 0x0fffffff) - flash->geometry.phy_start;
|
||||
if (fcluster_id != NULL) {
|
||||
*fcluster_id = ((addr & 0xfffe0000) >> 17) * 32;
|
||||
*fcluster_id = ((addr & 0xfffe0000) >> 17) * nb_cluster;
|
||||
*fcluster_id += ((addr & 0x0001ffff) >> 12);
|
||||
}
|
||||
if (fsector_id != NULL)
|
||||
*fsector_id = ((addr & 0xfffe0000) >> 17) * 32;
|
||||
*fsector_id = ((addr & 0xfffe0000) >> 17) * nb_cluster;
|
||||
if (fcluster_off != NULL)
|
||||
*fcluster_off = ((addr & 0x0001ffff) >> 12);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* fygue_flash_cluster_get() - get flash cluster information
|
||||
*
|
||||
* return
|
||||
* -1 if the provided `fline` is not valid
|
||||
* -2 if the provided `fline` have invalid Bfile metadata
|
||||
* 0 if the meta information has been generated */
|
||||
int fygue_flash_cluster_get(
|
||||
struct fygue_flash *flash,
|
||||
uint16_t fcluster_id,
|
||||
struct fygue_flash_cluster *fcluster
|
||||
) {
|
||||
uintptr_t bfile_meta;
|
||||
uintptr_t bfile_data;
|
||||
int fsector_id;
|
||||
int fcluster_off;
|
||||
|
||||
if (flash == NULL || fcluster == NULL)
|
||||
return -1;
|
||||
if (fcluster_id >= flash->geometry.fcluster_count)
|
||||
return -1;
|
||||
fsector_id = fcluster_id / 32;
|
||||
fcluster_off = fcluster_id % 32;
|
||||
if (fcluster_off == 31)
|
||||
{
|
||||
fcluster->kind = 0x667;
|
||||
fcluster->lcluster_id = 0xffff;
|
||||
fcluster->version = 0xffffffff;
|
||||
} else {
|
||||
bfile_meta = flash->geometry.phy_start;
|
||||
bfile_meta += (fsector_id * 0x20000) + 0x1f000;
|
||||
bfile_meta += (fcluster_off * 0x40);
|
||||
if (_fygue_flash_cluster_convert(flash, fcluster, bfile_meta) != 0)
|
||||
return -2;
|
||||
}
|
||||
bfile_data = flash->geometry.phy_start;
|
||||
bfile_data += (fsector_id * 0x20000);
|
||||
bfile_data += (fcluster_off * 0x1000);
|
||||
fcluster->data_p1 = bfile_data | 0xa0000000;
|
||||
fcluster->data_p2 = bfile_data | 0xa0000000;
|
||||
fcluster->fcluster_id_bfile = (fsector_id * 31) + fcluster_off;
|
||||
fcluster->fcluster_id = fcluster_id;
|
||||
if (fcluster->kind == 0x22)
|
||||
{
|
||||
uint32_t *data = (void*)fcluster->data_p1;
|
||||
if (
|
||||
((data[0] ^ data[1]) != 0xffffffff) ||
|
||||
((data[2] ^ data[3]) != 0xffffffff) ||
|
||||
((data[4] ^ data[5]) != 0xffffffff)
|
||||
) {
|
||||
return -2;
|
||||
}
|
||||
fcluster->version = data[0];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -61,8 +61,7 @@ static int fygue_flash_cmap_update(
|
|||
) {
|
||||
cmap->lcluster[i].fcluster_id = 0xffff;
|
||||
cmap->lcluster[i].fcluster_id_bfile = 0xffff;
|
||||
cmap->lcluster[i].fcluster_data_p1 = 0xffffffff;
|
||||
cmap->lcluster[i].fcluster_data_p2 = 0xffffffff;
|
||||
cmap->lcluster[i].fcluster_addr = 0xffffffff;
|
||||
cmap->lcluster[i].version = 0xffffffff;
|
||||
}
|
||||
cmap->lcluster_id_max = fcluster->lcluster_id + 1;
|
||||
|
@ -70,8 +69,7 @@ static int fygue_flash_cmap_update(
|
|||
entry = &(cmap->lcluster[fcluster->lcluster_id]);
|
||||
entry->fcluster_id = fcluster->fcluster_id;
|
||||
entry->fcluster_id_bfile = fcluster->fcluster_id_bfile;
|
||||
entry->fcluster_data_p1 = fcluster->data_p1;
|
||||
entry->fcluster_data_p2 = fcluster->data_p2;
|
||||
entry->fcluster_addr = fcluster->data_addr;
|
||||
entry->version = fcluster->version;
|
||||
return 0;
|
||||
}
|
||||
|
@ -80,6 +78,8 @@ static int fygue_flash_cmap_update(
|
|||
// Public
|
||||
//---
|
||||
|
||||
int debug_count = 0;
|
||||
|
||||
/* fygue_flash_cmap_init() - initialize fcluster translation
|
||||
*
|
||||
* notes:
|
||||
|
@ -102,28 +102,30 @@ int fygue_flash_cmap_init(
|
|||
struct fygue_flash_cmap *cmap
|
||||
) {
|
||||
struct fygue_flash_cluster fcluster;
|
||||
int fsector_id;
|
||||
int fsector;
|
||||
int rc;
|
||||
int j;
|
||||
|
||||
if (flash == NULL || cmap == NULL)
|
||||
return -1;
|
||||
fsector_id = 0;
|
||||
memset(cmap, 0x00, sizeof(struct fygue_flash_cmap));
|
||||
for (
|
||||
fsector = 0 ;
|
||||
fsector < flash->geometry.fsector_count ;
|
||||
fsector++
|
||||
) {
|
||||
if (fygue_flash_cluster_get(flash, fsector * 32, &fcluster) != 0)
|
||||
if (fsector != 0)
|
||||
fsector_id += flash->geometry.fcluster_per_fsector;
|
||||
if (fygue_flash_cluster_get(flash, &fcluster, fsector_id) != 0)
|
||||
continue;
|
||||
if (fcluster.kind != 0x22)
|
||||
continue;
|
||||
for (int j = 0 ; j < 31 ; j++)
|
||||
debug_count += 1;
|
||||
for (j = 1 ; j < (flash->geometry.fcluster_per_fsector - 1) ; j++)
|
||||
{
|
||||
rc = fygue_flash_cluster_get(
|
||||
flash,
|
||||
(fsector * 32) + j,
|
||||
&fcluster
|
||||
);
|
||||
rc = fygue_flash_cluster_get(flash, &fcluster, fsector_id + j);
|
||||
if (rc != 0)
|
||||
continue;
|
||||
if (fcluster.kind != 0x11)
|
||||
|
@ -159,7 +161,7 @@ int fygue_flash_cmap_lsector_get_addr(
|
|||
) {
|
||||
return -2;
|
||||
}
|
||||
fsector_addr = cmap->lcluster[lcluster_id].fcluster_data_p1;
|
||||
fsector_addr = cmap->lcluster[lcluster_id].fcluster_addr;
|
||||
fsector_addr += (lsector_id % 8) * 512;
|
||||
*sector = fsector_addr;
|
||||
return 0;
|
||||
|
|
|
@ -15,33 +15,50 @@
|
|||
* hardcoded information */
|
||||
// TODO: support CRC check and try each flash sector until one work ?
|
||||
// TODO: cluster integrity check seems change between device (?)
|
||||
static int _fygue_flash_hw_detect(struct fygue_flash *flash)
|
||||
int _fygue_flash_hw_detect(struct fygue_flash *flash)
|
||||
{
|
||||
switch (gint[HWCALC])
|
||||
{
|
||||
case HWCALC_FXCP400:
|
||||
flash->geometry.phy_start = 0x01a20000;
|
||||
flash->geometry.fsector_count = 0xf2;
|
||||
flash->geometry.fcluster_per_fsector = 32;
|
||||
flash->integrity = FYGUE_FLASH_INTEGRITY_PARTIAL;
|
||||
break;
|
||||
case HWCALC_G35PE2:
|
||||
flash->geometry.phy_start = 0x003f0000;
|
||||
flash->geometry.fsector_count = 0x00;
|
||||
flash->integrity = FYGUE_FLASH_INTEGRITY_FULL;
|
||||
flash->geometry.fsector_count = 0x41;
|
||||
flash->geometry.fcluster_per_fsector = 16;
|
||||
flash->integrity = FYGUE_FLASH_INTEGRITY_PARTIAL;
|
||||
break;
|
||||
case HWCALC_FXCG50:
|
||||
flash->geometry.phy_start = 0x00c80000;
|
||||
flash->geometry.fsector_count = 0x9c;
|
||||
flash->geometry.fcluster_per_fsector = 32;
|
||||
flash->integrity = FYGUE_FLASH_INTEGRITY_FULL;
|
||||
break;
|
||||
case HWCALC_FXCG100:
|
||||
flash->geometry.phy_start = 0x00bc0000;
|
||||
flash->geometry.fsector_count = 0x26;
|
||||
flash->geometry.fcluster_per_fsector = 32;
|
||||
flash->integrity = FYGUE_FLASH_INTEGRITY_PARTIAL;
|
||||
break;
|
||||
default:
|
||||
errno = ENOTSUP;
|
||||
return -1;
|
||||
}
|
||||
flash->geometry.fcluster_count = flash->geometry.fsector_count * 32;
|
||||
flash->geometry.size = flash->geometry.fsector_count * 0x20000;
|
||||
flash->geometry.phy_end = flash->geometry.phy_start;
|
||||
flash->geometry.phy_end += flash->geometry.size;
|
||||
flash->geometry.fcluster_count = (
|
||||
flash->geometry.fsector_count * flash->geometry.fcluster_per_fsector
|
||||
);
|
||||
flash->geometry.fsector_size = (
|
||||
flash->geometry.fcluster_per_fsector * (8 * 512)
|
||||
);
|
||||
flash->geometry.size = (
|
||||
flash->geometry.fsector_count * flash->geometry.fsector_size
|
||||
);
|
||||
flash->geometry.phy_end = (
|
||||
flash->geometry.phy_start + flash->geometry.size
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -57,7 +74,8 @@ int fygue_flash_initialize(struct fygue_flash *flash)
|
|||
memset(flash, 0x00, sizeof(struct fygue_flash));
|
||||
if (_fygue_flash_hw_detect(flash) != 0)
|
||||
return -2;
|
||||
if (fygue_flash_cmap_init(flash, &(flash->cmap)) != 0)
|
||||
return -3;
|
||||
int rc = fygue_flash_cmap_init(flash, &(flash->cmap));
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -7,13 +7,18 @@
|
|||
/* fygue_fcluster - generic flash cluster information */
|
||||
struct fygue_flash_cluster
|
||||
{
|
||||
uint32_t kind;
|
||||
enum {
|
||||
FYGUE_FCLUSTER_KIND_DATA = 0x11,
|
||||
FYGUE_FCLUSTER_KIND_FINFO = 0x22,
|
||||
FYGUE_FCLUSTER_KIND_DETAILS = 0x88,
|
||||
FYGUE_FCLUSTER_KIND_METADATA = 0x667,
|
||||
} kind;
|
||||
uint16_t fcluster_id;
|
||||
uint16_t fcluster_id_bfile;
|
||||
uint16_t lcluster_id;
|
||||
uint32_t version;
|
||||
uintptr_t data_p1;
|
||||
uintptr_t data_p2;
|
||||
uintptr_t data_addr;
|
||||
uintptr_t meta_addr;
|
||||
};
|
||||
|
||||
/* fygue_fcluster_map_entry - cmap list entry */
|
||||
|
@ -21,8 +26,7 @@ struct fygue_flash_cmap_entry
|
|||
{
|
||||
uint16_t fcluster_id;
|
||||
uint16_t fcluster_id_bfile;
|
||||
uintptr_t fcluster_data_p1;
|
||||
uintptr_t fcluster_data_p2;
|
||||
uintptr_t fcluster_addr;
|
||||
uint32_t version;
|
||||
};
|
||||
|
||||
|
@ -33,6 +37,7 @@ struct fygue_flash_cmap
|
|||
int lcluster_id_max;
|
||||
};
|
||||
|
||||
/* fygue_flash - flash information */
|
||||
struct fygue_flash
|
||||
{
|
||||
struct {
|
||||
|
@ -40,6 +45,8 @@ struct fygue_flash
|
|||
uintptr_t phy_end;
|
||||
size_t size;
|
||||
int fsector_count;
|
||||
size_t fsector_size;
|
||||
int fcluster_per_fsector;
|
||||
int fcluster_count;
|
||||
} geometry;
|
||||
enum {
|
||||
|
@ -97,8 +104,8 @@ extern int fygue_flash_cluster_geometry(
|
|||
/* fygue_flash_cluster_get() - get cluster information */
|
||||
extern int fygue_flash_cluster_get(
|
||||
struct fygue_flash *flash,
|
||||
uint16_t fcluster_id,
|
||||
struct fygue_flash_cluster *fcluster
|
||||
struct fygue_flash_cluster *fcluster,
|
||||
int fcluster_id
|
||||
);
|
||||
|
||||
#endif /* FS_FYGUE_FLASH_H */
|
||||
|
|
|
@ -13,7 +13,6 @@ static struct fygue_fsinfo *__fygue_fsinfo = NULL;
|
|||
// Primitives
|
||||
//---
|
||||
|
||||
|
||||
/* fygue_mount() - mount (if needed) and return the filesystem information
|
||||
*
|
||||
* notes
|
||||
|
|
Loading…
Add table
Reference in a new issue