Beispiel #1
0
static int
intel_flash_lock_block (urj_flash_cfi_array_t *cfi_array, uint32_t adr)
{
    uint16_t sr;
    urj_bus_t *bus = cfi_array->bus;

    URJ_BUS_WRITE (bus, cfi_array->address,
                   CFI_INTEL_CMD_CLEAR_STATUS_REGISTER);
    URJ_BUS_WRITE (bus, adr, CFI_INTEL_CMD_LOCK_SETUP);
    URJ_BUS_WRITE (bus, adr, CFI_INTEL_CMD_LOCK_BLOCK);

    while (!((sr = URJ_BUS_READ (bus, cfi_array->address) & 0xFE) & CFI_INTEL_SR_READY));     /* TODO: add timeout */

    if (sr != CFI_INTEL_SR_READY)
    {
        urj_error_set (URJ_ERROR_FLASH_LOCK,
                       _("unknown error while locking block"));
        return URJ_STATUS_FAIL;
    }

    URJ_BUS_WRITE (bus, adr + 0x02, CFI_INTEL_CMD_READ_IDENTIFIER);

    sr = URJ_BUS_READ (bus, cfi_array->address & 0x01);
    if (!sr)
    {
        urj_error_set (URJ_ERROR_FLASH_LOCK,
                       _("locking block failed"));
        return URJ_STATUS_FAIL;
    }

    return URJ_STATUS_OK;
}
Beispiel #2
0
static int
intel_flash_program_buffer (urj_flash_cfi_array_t *cfi_array,
                            uint32_t adr, uint32_t *buffer, int count)
{
    /* NOTE: Write-to-buffer programming operation according to [5], Figure 9 */
    uint16_t sr;
    urj_bus_t *bus = cfi_array->bus;
    urj_flash_cfi_chip_t *cfi_chip = cfi_array->cfi_chips[0];
    int wb_bytes = cfi_chip->cfi.device_geometry.max_bytes_write;
    int chip_width = cfi_chip->width;
    int offset = 0;

    while (count > 0)
    {
        int wcount, idx;
        uint32_t block_adr = adr;

        /* determine length of next multi-byte write */
        wcount = wb_bytes - (adr % wb_bytes);
        wcount /= chip_width;
        if (wcount > count)
            wcount = count;

        /* issue command WRITE_TO_BUFFER */
        URJ_BUS_WRITE (bus, cfi_array->address,
                       CFI_INTEL_CMD_CLEAR_STATUS_REGISTER);
        /* poll XSR7 == 1 */
        do {
            URJ_BUS_WRITE (bus, adr, CFI_INTEL_CMD_WRITE_TO_BUFFER);
        } while (!((sr = URJ_BUS_READ (bus, cfi_array->address) & 0xFE) & CFI_INTEL_SR_READY)); /* TODO: add timeout */

        /* write count value (number of upcoming writes - 1) */
        URJ_BUS_WRITE (bus, adr, wcount - 1);

        /* write payload to buffer */
        for (idx = 0; idx < wcount; idx++)
        {
            URJ_BUS_WRITE (bus, adr, buffer[offset + idx]);
            adr += cfi_array->bus_width;
        }
        offset += wcount;

        /* issue command WRITE_CONFIRM */
        URJ_BUS_WRITE (bus, block_adr, CFI_INTEL_CMD_WRITE_CONFIRM);

        count -= wcount;
    }

    /* poll SR7 == 1 */
    while (!((sr = URJ_BUS_READ (bus, cfi_array->address) & 0xFE) & CFI_INTEL_SR_READY));     /* TODO: add timeout */
    if (sr != CFI_INTEL_SR_READY)
    {
        urj_error_set (URJ_ERROR_FLASH_PROGRAM,
                       _("unknown error while programming"));
        return URJ_STATUS_FAIL;
    }

    return URJ_STATUS_OK;
}
Beispiel #3
0
static int
intel_flash_program32_single (urj_flash_cfi_array_t *cfi_array,
                              uint32_t adr, uint32_t data)
{
    uint32_t sr;
    urj_bus_t *bus = cfi_array->bus;

    URJ_BUS_WRITE (bus, cfi_array->address,
                   (CFI_INTEL_CMD_CLEAR_STATUS_REGISTER << 16) |
                   CFI_INTEL_CMD_CLEAR_STATUS_REGISTER);
    URJ_BUS_WRITE (bus, adr,
                   (CFI_INTEL_CMD_PROGRAM1 << 16) | CFI_INTEL_CMD_PROGRAM1);
    URJ_BUS_WRITE (bus, adr, data);

    while (((sr = URJ_BUS_READ (bus, cfi_array->address) & 0x00FE00FE) & ((CFI_INTEL_SR_READY << 16) | CFI_INTEL_SR_READY)) != ((CFI_INTEL_SR_READY << 16) | CFI_INTEL_SR_READY));    /* TODO: add timeout */

    if (sr != ((CFI_INTEL_SR_READY << 16) | CFI_INTEL_SR_READY))
    {
        urj_error_set (URJ_ERROR_FLASH_PROGRAM, "sr = 0x%08lX",
                       (long unsigned) sr);
        return URJ_STATUS_FAIL;
    }

    return URJ_STATUS_OK;
}
Beispiel #4
0
static int
intel_flash_unlock_block32 (urj_flash_cfi_array_t *cfi_array,
                            uint32_t adr)
{
    uint32_t sr;
    urj_bus_t *bus = cfi_array->bus;

    URJ_BUS_WRITE (bus, cfi_array->address,
                   (CFI_INTEL_CMD_CLEAR_STATUS_REGISTER << 16) |
                   CFI_INTEL_CMD_CLEAR_STATUS_REGISTER);
    URJ_BUS_WRITE (bus, adr,
                   (CFI_INTEL_CMD_LOCK_SETUP << 16) |
                   CFI_INTEL_CMD_LOCK_SETUP);
    URJ_BUS_WRITE (bus, adr,
                   (CFI_INTEL_CMD_UNLOCK_BLOCK << 16) |
                   CFI_INTEL_CMD_UNLOCK_BLOCK);

    while (((sr = URJ_BUS_READ (bus, cfi_array->address) & 0x00FE00FE) & ((CFI_INTEL_SR_READY << 16) | CFI_INTEL_SR_READY)) != ((CFI_INTEL_SR_READY << 16) | CFI_INTEL_SR_READY));    /* TODO: add timeout */

    if (sr != ((CFI_INTEL_SR_READY << 16) | CFI_INTEL_SR_READY))
    {
        urj_error_set (URJ_ERROR_FLASH_UNLOCK, "sr = 0x%08lX",
                       (long unsigned) sr);
        return URJ_STATUS_FAIL;
    }

    return URJ_STATUS_OK;
}
Beispiel #5
0
static int
intel_flash_erase_block (urj_flash_cfi_array_t *cfi_array, uint32_t adr)
{
    uint16_t sr;
    urj_bus_t *bus = cfi_array->bus;

    URJ_BUS_WRITE (bus, cfi_array->address,
                   CFI_INTEL_CMD_CLEAR_STATUS_REGISTER);
    URJ_BUS_WRITE (bus, adr, CFI_INTEL_CMD_BLOCK_ERASE);
    URJ_BUS_WRITE (bus, adr, CFI_INTEL_CMD_CONFIRM);

    while (!((sr = URJ_BUS_READ (bus, cfi_array->address) & 0xFE) & CFI_INTEL_SR_READY));     /* TODO: add timeout */

    switch (sr & ~CFI_INTEL_SR_READY)
    {
    case 0:
        return URJ_STATUS_OK;
    case CFI_INTEL_SR_ERASE_ERROR | CFI_INTEL_SR_PROGRAM_ERROR:
        urj_error_set (URJ_ERROR_FLASH_ERASE, _("invalid command seq"));
        return URJ_STATUS_FAIL;
    case CFI_INTEL_SR_ERASE_ERROR | CFI_INTEL_SR_VPEN_ERROR:
        urj_error_set (URJ_ERROR_FLASH_ERASE, _("low vpen"));
        return URJ_STATUS_FAIL;
    case CFI_INTEL_SR_ERASE_ERROR | CFI_INTEL_SR_BLOCK_LOCKED:
        urj_error_set (URJ_ERROR_FLASH_ERASE, _("block locked"));
        return URJ_STATUS_FAIL;
    default:
        break;
    }

    urj_error_set (URJ_ERROR_FLASH, "unknown error");
    return URJ_STATUS_FAIL;
}
Beispiel #6
0
static int
intel_flash_program_single (urj_flash_cfi_array_t *cfi_array,
                            uint32_t adr, uint32_t data)
{
    uint16_t sr;
    urj_bus_t *bus = cfi_array->bus;

    URJ_BUS_WRITE (bus, cfi_array->address,
                   CFI_INTEL_CMD_CLEAR_STATUS_REGISTER);
    URJ_BUS_WRITE (bus, adr, CFI_INTEL_CMD_PROGRAM1);
    URJ_BUS_WRITE (bus, adr, data);

    while (!((sr = URJ_BUS_READ (bus, cfi_array->address) & 0xFE) & CFI_INTEL_SR_READY));     /* TODO: add timeout */

    URJ_BUS_WRITE (bus, cfi_array->address, 0x00FF00FF);

    if (sr != CFI_INTEL_SR_READY)
    {
        urj_error_set (URJ_ERROR_FLASH_PROGRAM,
                       _("unknown error while programming"));
        return URJ_STATUS_FAIL;
    }

    return URJ_STATUS_OK;
}
Beispiel #7
0
static void
_intel_flash_print_info (urj_log_level_t ll, urj_flash_cfi_array_t *cfi_array,
                        int o)
{
    uint32_t mid, cid;
    urj_bus_t *bus = cfi_array->bus;

    mid = (URJ_BUS_READ (bus, cfi_array->address + (0x00 << o)) & 0xFF);
    switch (mid)
    {
    case STD_MIC_INTEL:
        urj_log (ll, _("Manufacturer: %s\n"), STD_MICN_INTEL);
        break;
    case STD_MIC_MITSUBISHI:
        urj_log (ll, _("Manufacturer: %s\n"), STD_MICN_MITSUBISHI);
        break;
    case STD_MIC_MICRON_TECHNOLOGY:
        urj_log (ll, _("Manufacturer: %s\n"), STD_MICN_MICRON_TECHNOLOGY);
        break;
    default:
        urj_log (ll, _("Unknown manufacturer (0x%04lX)!\n"),
                 (long unsigned) mid);
        break;
    }

    urj_log (ll, _("Chip: "));
    cid = (URJ_BUS_READ (bus, cfi_array->address + (0x01 << o)) & 0xFFFF);
    switch (cid)
    {
    case 0x0016:
        urj_log (ll, "28F320J3A\n");
        break;
    case 0x0017:
        urj_log (ll, "28F640J3A\n");
        break;
    case 0x0018:
        urj_log (ll, "28F128J3A\n");
        break;
    case 0x001D:
        urj_log (ll, "28F256J3A\n");
        break;
    case 0x8801:
        urj_log (ll, "28F640K3\n");
        break;
    case 0x8802:
        urj_log (ll, "28F128K3\n");
        break;
    case 0x8803:
        urj_log (ll, "28F256K3\n");
        break;
    case 0x8805:
        urj_log (ll, "28F640K18\n");
        break;
    case 0x8806:
        urj_log (ll, "28F128K18\n");
        break;
    case 0x8807:
        urj_log (ll, "28F256K18\n");
        break;
    case 0x880B:
        urj_log (ll, "GE28F640L18T\n");
        break;
    case 0x880C:
        urj_log (ll, "GE28F128L18T\n");
        break;
    case 0x880D:
        urj_log (ll, "GE28F256L18T\n");
        break;
    case 0x880E:
        urj_log (ll, "GE28F640L18B\n");
        break;
    case 0x880F:
        urj_log (ll, "GE28F128L18B\n");
        break;
    case 0x8810:
        urj_log (ll, "GE28F256L18B\n");
        break;
    case 0x891F:
        urj_log (ll, "28F256P33\n");
        break;
    default:
        urj_log (ll, _("Unknown (0x%02lX)!\n"), (long unsigned) cid);
        break;
    }

    /* Read Array */
    URJ_BUS_WRITE (bus, cfi_array->address + (0 << o), 0x00FF00FF);
}