Implement GC for data pool in flash memory.

This commit is contained in:
NIIBE Yutaka
2010-11-08 13:17:30 +09:00
parent bb16bc47bb
commit 749a7a1d35
6 changed files with 248 additions and 72 deletions

View File

@@ -34,30 +34,47 @@
static uint32_t digital_signature_counter;
static const uint8_t *
gpg_write_digital_signature_counter (const uint8_t *p, uint32_t dsc)
{
uint16_t hw0, hw1;
if ((dsc >> 10) == 0)
{ /* no upper bits */
hw1 = NR_COUNTER_DS_LSB | ((dsc & 0x0300) >> 8) | ((dsc & 0x00ff) << 8);
flash_put_data_internal (p, hw1);
return p+2;
}
else
{
hw0 = NR_COUNTER_DS | ((dsc & 0xfc0000) >> 18) | ((dsc & 0x03fc00) >> 2);
hw1 = NR_COUNTER_DS_LSB;
flash_put_data_internal (p, hw0);
flash_put_data_internal (p+2, hw1);
return p+4;
}
}
void
gpg_increment_digital_signature_counter (void)
{
uint16_t hw0, hw1;
uint32_t dsc = (digital_signature_counter + 1) & 0x00ffffff;
digital_signature_counter++;
digital_signature_counter &= 0x00ffffff;
if ((digital_signature_counter & 0x03ff) == 0)
if ((dsc & 0x03ff) == 0)
{ /* carry occurs from l10 to h14 */
hw0 = NR_COUNTER_DS
| ((digital_signature_counter & 0x00fc0000) >> 18)
| ((digital_signature_counter & 0x0003fc00) >> 2);
hw1 = NR_COUNTER_DS_LSB;
hw0 = NR_COUNTER_DS | ((dsc & 0xfc0000) >> 18) | ((dsc & 0x03fc00) >> 2);
hw1 = NR_COUNTER_DS_LSB; /* zero */
flash_put_data (hw0);
flash_put_data (hw1);
}
else
{
hw1 = NR_COUNTER_DS_LSB
| ((digital_signature_counter & 0x0300) >> 8)
| ((digital_signature_counter & 0x00ff) << 8);
hw1 = NR_COUNTER_DS_LSB | ((dsc & 0x0300) >> 8) | ((dsc & 0x00ff) << 8);
flash_put_data (hw1);
}
digital_signature_counter = dsc;
}
#define PASSWORD_ERRORS_MAX 3 /* >= errors, it will be locked */
@@ -901,16 +918,14 @@ gpg_do_table[] = {
/*
* Reading data from Flash ROM, initialize DO_PTR, PW_ERR_COUNTERS, etc.
*/
int
gpg_do_table_init (void)
void
gpg_data_scan (const uint8_t *p_start)
{
const uint8_t *p, *p_start;
const uint8_t *p;
int i;
const uint8_t *dsc_h14_p, *dsc_l10_p;
int dsc_h14, dsc_l10;
p_start = flash_data_pool ();
dsc_h14_p = dsc_l10_p = NULL;
pw1_lifetime_p = NULL;
pw_err_counter_p[PW_ERR_PW1] = NULL;
@@ -999,7 +1014,46 @@ gpg_do_table_init (void)
}
digital_signature_counter = (dsc_h14 << 10) | dsc_l10;
return 0;
}
void
gpg_data_copy (const uint8_t *p_start)
{
const uint8_t *p;
int i;
int v;
p = gpg_write_digital_signature_counter (p_start, digital_signature_counter);
if (pw1_lifetime_p != NULL)
{
flash_bool_write_internal (p, NR_BOOL_PW1_LIFETIME);
pw1_lifetime_p = p;
p += 2;
}
for (i = 0; i < 3; i++)
if ((v = flash_cnt123_get_value (pw_err_counter_p[i])) != 0)
{
flash_cnt123_write_internal (p, i, v);
pw_err_counter_p[i] = p + 2;
p += 4;
}
data_objects_number_of_bytes = 0;
for (i = NR_DO__FIRST__; i < NR_DO__LAST__; i++)
if (do_ptr[i - NR_DO__FIRST__] != NULL)
{
const uint8_t *do_data = do_ptr[i - NR_DO__FIRST__];
int len = do_data[0];
flash_do_write_internal (p, i, &do_data[1], len);
do_ptr[i - NR_DO__FIRST__] = p + 1;
p += 2 + ((len + 1) & ~1);
data_objects_number_of_bytes += len;
}
flash_set_data_pool_last (p);
}
static const struct do_table_entry *