mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2025-05-18 23:39:17 +02:00
fygue: rework flash abstraction to reduce device-specific cases and allow future optimization
This commit is contained in:
parent
8156c8437b
commit
ba7d84dbb2
4 changed files with 106 additions and 90 deletions
|
@ -48,8 +48,9 @@ uintptr_t debug_meta = 0;
|
||||||
static int _fygue_flash_cluster_convert(
|
static int _fygue_flash_cluster_convert(
|
||||||
struct fygue_flash *flash,
|
struct fygue_flash *flash,
|
||||||
struct fygue_flash_cluster *fcluster,
|
struct fygue_flash_cluster *fcluster,
|
||||||
uintptr_t bfile_meta
|
uintptr_t meta
|
||||||
) {
|
) {
|
||||||
|
#if 0
|
||||||
static const uint8_t _constant1[] = {
|
static const uint8_t _constant1[] = {
|
||||||
0xff, 0xff, 0xff, 0xff,
|
0xff, 0xff, 0xff, 0xff,
|
||||||
0xff, 0xff, 0xff, 0xff,
|
0xff, 0xff, 0xff, 0xff,
|
||||||
|
@ -66,44 +67,49 @@ static int _fygue_flash_cluster_convert(
|
||||||
0xbb, 0xbb, 0xdd, 0xdd,
|
0xbb, 0xbb, 0xdd, 0xdd,
|
||||||
0xdd, 0xee, 0xee, 0xee,
|
0xdd, 0xee, 0xee, 0xee,
|
||||||
};
|
};
|
||||||
struct _bfile_cluster_metadata *meta;
|
#endif
|
||||||
|
struct _bfile_cluster_metadata *bfile_meta;
|
||||||
|
|
||||||
if (fcluster == NULL)
|
if (flash == NULL || fcluster == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
debug_meta = bfile_meta;
|
bfile_meta = (void*)(meta | 0xa0000000);
|
||||||
meta = (void*)(bfile_meta | 0xa0000000);
|
|
||||||
if (
|
if (
|
||||||
meta->signature[0] != 0x5a ||
|
bfile_meta->signature[0] != 0x5a ||
|
||||||
meta->signature[1] != 0x5a ||
|
bfile_meta->signature[1] != 0x5a ||
|
||||||
meta->signature[2] != 0x5a
|
bfile_meta->signature[2] != 0x5a
|
||||||
) {
|
) {
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
meta->bitmask[0] != 0x88 &&
|
bfile_meta->bitmask[0] != 0x88 &&
|
||||||
meta->bitmask[0] != 0x22 &&
|
bfile_meta->bitmask[0] != 0x22 &&
|
||||||
meta->bitmask[0] != 0x11
|
bfile_meta->bitmask[0] != 0x11
|
||||||
) {
|
) {
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
if (meta->bitmask[1] != 0x0f)
|
if (bfile_meta->bitmask[1] != 0x0f)
|
||||||
return -4;
|
return -4;
|
||||||
if (meta->bitmask[0] != 0x11 && meta->lcluster_id != 0xffff)
|
if (
|
||||||
|
bfile_meta->bitmask[0] != 0x11 &&
|
||||||
|
bfile_meta->lcluster_id != 0xffff
|
||||||
|
) {
|
||||||
return -5;
|
return -5;
|
||||||
|
}
|
||||||
// on the fxcp400, have only some flash sector with the constants used
|
// on the fxcp400, have only some flash sector with the constants used
|
||||||
// in other device. Internally, on the fxcp400, Casio only perform
|
// in other device. Internally, on the fxcp400, Casio only perform
|
||||||
// a check an CRC that is performed on the whole cluster
|
// a check an CRC that is performed on the whole cluster
|
||||||
// TODO: CRC check
|
// TODO: CRC check
|
||||||
|
#if 0
|
||||||
if (
|
if (
|
||||||
flash->integrity == FYGUE_FLASH_INTEGRITY_FULL &&
|
memcmp(&(bfile_meta->constant), _constant1, 0x18) != 0 &&
|
||||||
memcmp(&(meta->constant), _constant1, 0x18) != 0 &&
|
memcmp(&(bfile_meta->constant), _constant2, 0x18) != 0
|
||||||
memcmp(&(meta->constant), _constant2, 0x18) != 0
|
|
||||||
) {
|
) {
|
||||||
return -6;
|
return -6;
|
||||||
}
|
}
|
||||||
fcluster->lcluster_id = meta->lcluster_id;
|
#endif
|
||||||
fcluster->kind = meta->bitmask[0];
|
fcluster->lcluster_id = bfile_meta->lcluster_id;
|
||||||
fcluster->version = meta->fcluster_version;
|
fcluster->kind = bfile_meta->bitmask[0];
|
||||||
|
fcluster->version = bfile_meta->fcluster_version;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,8 +152,11 @@ static int _fygue_flash_cluster_meta(
|
||||||
* sector of 64ko merge the details sector inside the metadata cluster to
|
* 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
|
* 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
|
* use 128ko flash sector and which the first cluster should be a details
|
||||||
* one type. */
|
* one type.
|
||||||
//TODO: remove device-specific code
|
*
|
||||||
|
* for 64k cluster the 0xf3c0 offset can be calculated as:
|
||||||
|
* 0x10000 - (8*512) = 0xf000 | sector size minus cluster size
|
||||||
|
* 15 * 0x40 = 0x3c0 | skip all data cluster meta info */
|
||||||
static int _fygue_flash_cluster_details(
|
static int _fygue_flash_cluster_details(
|
||||||
struct fygue_flash *flash,
|
struct fygue_flash *flash,
|
||||||
struct fygue_flash_cluster *fcluster,
|
struct fygue_flash_cluster *fcluster,
|
||||||
|
@ -159,21 +168,18 @@ static int _fygue_flash_cluster_details(
|
||||||
uintptr_t data;
|
uintptr_t data;
|
||||||
|
|
||||||
memset(fcluster, 0x00, sizeof(struct fygue_flash_cluster));
|
memset(fcluster, 0x00, sizeof(struct fygue_flash_cluster));
|
||||||
if (gint[HWCALC] == HWCALC_G35PE2) {
|
if (geometry->fsector_size == FYGUE_FSECTOR_SIZE_64K) {
|
||||||
data = (
|
data = (
|
||||||
(geometry->phy_start | 0xa0000000) +
|
(geometry->phy_start | 0xa0000000) +
|
||||||
(fsector_id * geometry->fsector_size) +
|
(fsector_id * 0x10000) +
|
||||||
(geometry->fsector_size - (8*512)) +
|
(0xf3c0)
|
||||||
((geometry->fcluster_per_fsector - 1) * 0x40)
|
|
||||||
);
|
);
|
||||||
meta = data + 512;
|
meta = data + 512;
|
||||||
} else {
|
} else {
|
||||||
data = (
|
data = (geometry->phy_start | 0xa0000000) + (fsector_id * 0x20000);
|
||||||
(geometry->phy_start | 0xa0000000) +
|
meta = data + 0x1f000;
|
||||||
(fsector_id * geometry->fsector_size)
|
|
||||||
);
|
|
||||||
meta = data + (geometry->fsector_size) - (8*512);
|
|
||||||
}
|
}
|
||||||
|
debug_meta = meta;
|
||||||
if (_fygue_flash_cluster_convert(flash, fcluster, meta) != 0)
|
if (_fygue_flash_cluster_convert(flash, fcluster, meta) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (fcluster->version != 0xffffffff)
|
if (fcluster->version != 0xffffffff)
|
||||||
|
@ -208,20 +214,33 @@ static int _fygue_flash_cluster_data(
|
||||||
uintptr_t meta;
|
uintptr_t meta;
|
||||||
uintptr_t data;
|
uintptr_t data;
|
||||||
|
|
||||||
data = (
|
if (geometry->fsector_size == FYGUE_FSECTOR_SIZE_64K) {
|
||||||
(geometry->phy_start | 0xa0000000) +
|
data = (
|
||||||
(fsector_id * geometry->fsector_size) +
|
(geometry->phy_start | 0xa0000000) +
|
||||||
(fcluster_off * (8 * 512))
|
(fsector_id * 0x10000) +
|
||||||
);
|
(fcluster_off * (8 * 512))
|
||||||
meta = (
|
);
|
||||||
(geometry->phy_start | 0xa0000000) +
|
meta = (
|
||||||
(fsector_id * geometry->fsector_size) +
|
(geometry->phy_start | 0xa0000000) +
|
||||||
(geometry->fsector_size - (8 * 512)) +
|
(fsector_id * 0x10000) +
|
||||||
(fcluster_off * 0x40)
|
(0xf000) +
|
||||||
);
|
(fcluster_off * 0x40)
|
||||||
int rc = _fygue_flash_cluster_convert(flash, fcluster, meta);
|
);
|
||||||
if (rc != 0)
|
} else {
|
||||||
return rc;
|
data = (
|
||||||
|
(geometry->phy_start | 0xa0000000) +
|
||||||
|
(fsector_id * 0x20000) +
|
||||||
|
(fcluster_off * (8 * 512))
|
||||||
|
);
|
||||||
|
meta = (
|
||||||
|
(geometry->phy_start | 0xa0000000) +
|
||||||
|
(fsector_id * 0x20000) +
|
||||||
|
(0x1f000) +
|
||||||
|
(fcluster_off * 0x40)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (_fygue_flash_cluster_convert(flash, fcluster, meta) != 0)
|
||||||
|
return -1;
|
||||||
fcluster->data_addr = data;
|
fcluster->data_addr = data;
|
||||||
fcluster->meta_addr = meta;
|
fcluster->meta_addr = meta;
|
||||||
fcluster->fcluster_id = fcluster_id;
|
fcluster->fcluster_id = fcluster_id;
|
||||||
|
@ -247,6 +266,7 @@ int fygue_flash_cluster_get(
|
||||||
struct fygue_flash_cluster *fcluster,
|
struct fygue_flash_cluster *fcluster,
|
||||||
int fcluster_id
|
int fcluster_id
|
||||||
) {
|
) {
|
||||||
|
GAUTOTYPE geometry = &(flash->geometry);
|
||||||
int fsector_id;
|
int fsector_id;
|
||||||
int fcluster_off;
|
int fcluster_off;
|
||||||
int nb_entry;
|
int nb_entry;
|
||||||
|
@ -256,14 +276,20 @@ int fygue_flash_cluster_get(
|
||||||
if (fcluster_id >= flash->geometry.fcluster_count)
|
if (fcluster_id >= flash->geometry.fcluster_count)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
nb_entry = flash->geometry.fcluster_per_fsector;
|
if (geometry->fsector_size == FYGUE_FSECTOR_SIZE_64K) {
|
||||||
fsector_id = fcluster_id / nb_entry;
|
nb_entry = 16;
|
||||||
fcluster_off = fcluster_id % nb_entry;
|
fsector_id = fcluster_id / 16;
|
||||||
|
fcluster_off = fcluster_id % 16;
|
||||||
|
} else {
|
||||||
|
nb_entry = 32;
|
||||||
|
fsector_id = fcluster_id / 32;
|
||||||
|
fcluster_off = fcluster_id % 32;
|
||||||
|
}
|
||||||
|
|
||||||
if (fcluster_off == (nb_entry - 1))
|
|
||||||
return _fygue_flash_cluster_meta(flash, fcluster, fsector_id);
|
|
||||||
if (fcluster_off == 0)
|
if (fcluster_off == 0)
|
||||||
return _fygue_flash_cluster_details(flash, fcluster, fsector_id);
|
return _fygue_flash_cluster_details(flash, fcluster, fsector_id);
|
||||||
|
if (fcluster_off == (nb_entry - 1))
|
||||||
|
return _fygue_flash_cluster_meta(flash, fcluster, fsector_id);
|
||||||
return _fygue_flash_cluster_data(
|
return _fygue_flash_cluster_data(
|
||||||
flash,
|
flash,
|
||||||
fcluster,
|
fcluster,
|
||||||
|
|
|
@ -78,8 +78,6 @@ static int fygue_flash_cmap_update(
|
||||||
// Public
|
// Public
|
||||||
//---
|
//---
|
||||||
|
|
||||||
int debug_count = 0;
|
|
||||||
|
|
||||||
/* fygue_flash_cmap_init() - initialize fcluster translation
|
/* fygue_flash_cmap_init() - initialize fcluster translation
|
||||||
*
|
*
|
||||||
* notes:
|
* notes:
|
||||||
|
@ -122,7 +120,6 @@ int fygue_flash_cmap_init(
|
||||||
continue;
|
continue;
|
||||||
if (fcluster.kind != 0x22)
|
if (fcluster.kind != 0x22)
|
||||||
continue;
|
continue;
|
||||||
debug_count += 1;
|
|
||||||
for (j = 1 ; j < (flash->geometry.fcluster_per_fsector - 1) ; j++)
|
for (j = 1 ; j < (flash->geometry.fcluster_per_fsector - 1) ; j++)
|
||||||
{
|
{
|
||||||
rc = fygue_flash_cluster_get(flash, &fcluster, fsector_id + j);
|
rc = fygue_flash_cluster_get(flash, &fcluster, fsector_id + j);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <gint/hardware.h>
|
#include <gint/hardware.h>
|
||||||
|
#include <gint/defs/util.h>
|
||||||
#include "flash.h"
|
#include "flash.h"
|
||||||
|
|
||||||
//---
|
//---
|
||||||
|
@ -13,52 +14,46 @@
|
||||||
* we cannot easily detect the exact geometry of the flash for the Fugue
|
* we cannot easily detect the exact geometry of the flash for the Fugue
|
||||||
* FS. For now, simply pseudo-detect hardware information and setup
|
* FS. For now, simply pseudo-detect hardware information and setup
|
||||||
* hardcoded information */
|
* hardcoded information */
|
||||||
// TODO: support CRC check and try each flash sector until one work ?
|
|
||||||
// TODO: cluster integrity check seems change between device (?)
|
|
||||||
int _fygue_flash_hw_detect(struct fygue_flash *flash)
|
int _fygue_flash_hw_detect(struct fygue_flash *flash)
|
||||||
{
|
{
|
||||||
|
GAUTOTYPE geometry = &(flash->geometry);
|
||||||
|
|
||||||
switch (gint[HWCALC])
|
switch (gint[HWCALC])
|
||||||
{
|
{
|
||||||
case HWCALC_FXCP400:
|
case HWCALC_FXCP400:
|
||||||
flash->geometry.phy_start = 0x01a20000;
|
geometry->phy_start = 0x01a20000;
|
||||||
flash->geometry.fsector_count = 0xf2;
|
geometry->fsector_size = FYGUE_FSECTOR_SIZE_128K;
|
||||||
flash->geometry.fcluster_per_fsector = 32;
|
geometry->fsector_count = 0xf2;
|
||||||
flash->integrity = FYGUE_FLASH_INTEGRITY_PARTIAL;
|
|
||||||
break;
|
break;
|
||||||
case HWCALC_G35PE2:
|
case HWCALC_G35PE2:
|
||||||
flash->geometry.phy_start = 0x003f0000;
|
geometry->phy_start = 0x003f0000;
|
||||||
flash->geometry.fsector_count = 0x41;
|
geometry->fsector_size = FYGUE_FSECTOR_SIZE_64K;
|
||||||
flash->geometry.fcluster_per_fsector = 16;
|
geometry->fsector_count = 0x41;
|
||||||
flash->integrity = FYGUE_FLASH_INTEGRITY_PARTIAL;
|
|
||||||
break;
|
break;
|
||||||
case HWCALC_FXCG50:
|
case HWCALC_FXCG50:
|
||||||
flash->geometry.phy_start = 0x00c80000;
|
geometry->phy_start = 0x00c80000;
|
||||||
flash->geometry.fsector_count = 0x9c;
|
geometry->fsector_count = 0x9c;
|
||||||
flash->geometry.fcluster_per_fsector = 32;
|
geometry->fsector_size = FYGUE_FSECTOR_SIZE_128K;
|
||||||
flash->integrity = FYGUE_FLASH_INTEGRITY_FULL;
|
|
||||||
break;
|
break;
|
||||||
case HWCALC_FXCG100:
|
case HWCALC_FXCG100:
|
||||||
flash->geometry.phy_start = 0x00bc0000;
|
geometry->phy_start = 0x00bc0000;
|
||||||
flash->geometry.fsector_count = 0x26;
|
geometry->fsector_size = FYGUE_FSECTOR_SIZE_128K;
|
||||||
flash->geometry.fcluster_per_fsector = 32;
|
geometry->fsector_count = 0x26;
|
||||||
flash->integrity = FYGUE_FLASH_INTEGRITY_PARTIAL;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
errno = ENOTSUP;
|
errno = ENOTSUP;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
flash->geometry.fcluster_count = (
|
if (geometry->fsector_size == FYGUE_FSECTOR_SIZE_128K) {
|
||||||
flash->geometry.fsector_count * flash->geometry.fcluster_per_fsector
|
geometry->size = geometry->fsector_count * 0x20000;
|
||||||
);
|
geometry->fcluster_count = geometry->fsector_count * 32;
|
||||||
flash->geometry.fsector_size = (
|
geometry->fcluster_per_fsector = 32;
|
||||||
flash->geometry.fcluster_per_fsector * (8 * 512)
|
} else {
|
||||||
);
|
geometry->size = geometry->fsector_count * 0x10000;
|
||||||
flash->geometry.size = (
|
geometry->fcluster_count = geometry->fsector_count * 16;
|
||||||
flash->geometry.fsector_count * flash->geometry.fsector_size
|
geometry->fcluster_per_fsector = 16;
|
||||||
);
|
}
|
||||||
flash->geometry.phy_end = (
|
geometry->phy_end = geometry->phy_start + geometry->size;
|
||||||
flash->geometry.phy_start + flash->geometry.size
|
|
||||||
);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,8 +69,7 @@ int fygue_flash_initialize(struct fygue_flash *flash)
|
||||||
memset(flash, 0x00, sizeof(struct fygue_flash));
|
memset(flash, 0x00, sizeof(struct fygue_flash));
|
||||||
if (_fygue_flash_hw_detect(flash) != 0)
|
if (_fygue_flash_hw_detect(flash) != 0)
|
||||||
return -2;
|
return -2;
|
||||||
int rc = fygue_flash_cmap_init(flash, &(flash->cmap));
|
if (fygue_flash_cmap_init(flash, &(flash->cmap)) != 0)
|
||||||
if (rc != 0)
|
return -3;
|
||||||
return rc;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,15 +44,14 @@ struct fygue_flash
|
||||||
uintptr_t phy_start;
|
uintptr_t phy_start;
|
||||||
uintptr_t phy_end;
|
uintptr_t phy_end;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
enum {
|
||||||
|
FYGUE_FSECTOR_SIZE_64K,
|
||||||
|
FYGUE_FSECTOR_SIZE_128K,
|
||||||
|
} fsector_size;
|
||||||
int fsector_count;
|
int fsector_count;
|
||||||
size_t fsector_size;
|
|
||||||
int fcluster_per_fsector;
|
int fcluster_per_fsector;
|
||||||
int fcluster_count;
|
int fcluster_count;
|
||||||
} geometry;
|
} geometry;
|
||||||
enum {
|
|
||||||
FYGUE_FLASH_INTEGRITY_FULL,
|
|
||||||
FYGUE_FLASH_INTEGRITY_PARTIAL,
|
|
||||||
} integrity;
|
|
||||||
struct fygue_flash_cmap cmap;
|
struct fygue_flash_cmap cmap;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue