/***************************************************************************
* Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de> *
* Copyright (C) 2007,2008 Øyvind Harboe <oyvind.harboe@zylin.com> *
* Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk> *
* Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "imp.h"
#include <helper/time_support.h>
#include <target/image.h>
/**
* @file
* Implements Tcl commands used to access NOR flash facilities.
*/
COMMAND_HELPER(flash_command_get_bank_maybe_probe, unsigned name_index,
struct flash_bank **bank, bool do_probe)
{
const char *name = CMD_ARGV[name_index];
int retval;
if (do_probe) {
retval = get_flash_bank_by_name(name, bank);
} else {
*bank = get_flash_bank_by_name_noprobe(name);
retval = ERROR_OK;
}
if (retval != ERROR_OK)
return retval;
if (*bank)
return ERROR_OK;
unsigned bank_num;
COMMAND_PARSE_NUMBER(uint, name, bank_num);
if (do_probe) {
return get_flash_bank_by_num(bank_num, bank);
} else {
*bank = get_flash_bank_by_num_noprobe(bank_num);
retval = (bank) ? ERROR_OK : ERROR_FAIL;
return retval;
}
}
COMMAND_HELPER(flash_command_get_bank, unsigned name_index,
struct flash_bank **bank)
{
return CALL_COMMAND_HANDLER(flash_command_get_bank_maybe_probe,
name_index, bank, true);
}
COMMAND_HANDLER(handle_flash_info_command)
{
struct flash_bank *p;
int j = 0;
int retval;
bool show_sectors = false;
bool prot_block_available;
if (CMD_ARGC < 1 || CMD_ARGC > 2)
return ERROR_COMMAND_SYNTAX_ERROR;
if (CMD_ARGC == 2) {
if (strcmp("sectors", CMD_ARGV[1]) == 0)
show_sectors = true;
else
return ERROR_COMMAND_SYNTAX_ERROR;
}
retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);
if (retval != ERROR_OK)
return retval;
if (p != NULL) {
char buf[1024];
int num_blocks;
struct flash_sector *block_array;
/* attempt auto probe */
retval = p->driver->auto_probe(p);
if (retval != ERROR_OK)
return retval;
/* We must query the hardware to avoid printing stale information! */
retval = p->driver->protect_check(p);
if (retval != ERROR_OK)
return retval;
command_print(CMD_CTX,
"#%d : %s at 0x%8.8" PRIx32 ", size 0x%8.8" PRIx32
", buswidth %i, chipwidth %i",
p->bank_number,
p->driver->name,
p->base,
p->size,
p->bus_width,
p->chip_width);
prot_block_available = p->num_prot_blocks && p->prot_blocks;
if (!show_sectors && prot_block_available) {
block_array = p->prot_blocks;
num_blocks =