flash: read only alias
Similar as virtual flash but has write/erase suppressed. 'virtual' flash driver name check in flash_free_all_banks() was replaced by a customized free_driver_priv() Change-Id: I528760aad0ba55ebc57fc1fabfdfdf07c92cac94 Signed-off-by: Tomas Vanek <vanekt@fbl.cz> Reviewed-on: https://review.openocd.org/c/openocd/+/5107 Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> Tested-by: jenkins
This commit is contained in:
committed by
Antonio Borneo
parent
8ee7cb12cf
commit
2b986178cf
@@ -6160,7 +6160,7 @@ Some drivers also activate driver-specific commands.
|
||||
This is a special driver that maps a previously defined bank to another
|
||||
address. All bank settings will be copied from the master physical bank.
|
||||
|
||||
The @var{virtual} driver defines one mandatory parameters,
|
||||
The @var{virtual} driver defines one mandatory parameter,
|
||||
|
||||
@itemize
|
||||
@item @var{master_bank} The bank that this virtual address refers to.
|
||||
@@ -6178,6 +6178,18 @@ flash bank vbank1 virtual 0x9fc00000 0 0 0 \
|
||||
@end example
|
||||
@end deffn
|
||||
|
||||
@deffn {Flash Driver} ro_alias
|
||||
Similar as @var{virtual} driver but suppresses write
|
||||
and erase. Use to build a complete memory map for gdb.
|
||||
Bank size will be copied from the master physical bank.
|
||||
|
||||
The @var{virtual} driver defines one mandatory parameter,
|
||||
|
||||
@itemize
|
||||
@item @var{master_bank} The bank that this virtual address refers to.
|
||||
@end itemize
|
||||
@end deffn
|
||||
|
||||
@deffn {Flash Driver} read_only
|
||||
A stub driver without write and erase.
|
||||
Use to define a ROM region for the gdb memory map.
|
||||
|
||||
@@ -223,15 +223,8 @@ void flash_free_all_banks(void)
|
||||
else
|
||||
LOG_WARNING("Flash driver of %s does not support free_driver_priv()", bank->name);
|
||||
|
||||
/* For 'virtual' flash driver bank->sectors and bank->prot_blocks pointers are copied from
|
||||
* master flash_bank structure. They point to memory locations allocated by master flash driver
|
||||
* so master driver is responsible for releasing them.
|
||||
* Avoid UB caused by double-free memory corruption if flash bank is 'virtual'. */
|
||||
|
||||
if (strcmp(bank->driver->name, "virtual") != 0) {
|
||||
free(bank->sectors);
|
||||
free(bank->prot_blocks);
|
||||
}
|
||||
free(bank->sectors);
|
||||
free(bank->prot_blocks);
|
||||
|
||||
free(bank->name);
|
||||
free(bank);
|
||||
|
||||
@@ -294,6 +294,7 @@ extern const struct flash_driver psoc6_flash;
|
||||
extern const struct flash_driver qn908x_flash;
|
||||
extern const struct flash_driver read_only_flash;
|
||||
extern const struct flash_driver renesas_rpchf_flash;
|
||||
extern const struct flash_driver ro_alias_flash;
|
||||
extern const struct flash_driver rp2xxx_flash;
|
||||
extern const struct flash_driver rsl10_flash;
|
||||
extern const struct flash_driver sh_qspi_flash;
|
||||
|
||||
@@ -72,6 +72,7 @@ static const struct flash_driver * const flash_drivers[] = {
|
||||
&psoc6_flash,
|
||||
&qn908x_flash,
|
||||
&read_only_flash,
|
||||
&ro_alias_flash,
|
||||
&renesas_rpchf_flash,
|
||||
&rp2xxx_flash,
|
||||
&rsl10_flash,
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2010 by Spencer Oliver *
|
||||
* spen@spen-soft.co.uk *
|
||||
***************************************************************************/
|
||||
/*
|
||||
* Copyright (C) 2010 by Spencer Oliver <spen@spen-soft.co.uk>
|
||||
*
|
||||
* Copyright (C) 2019 by Tomas Vanek <vanekt@fbl.cz>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
@@ -31,6 +32,9 @@ static void virtual_update_bank_info(struct flash_bank *bank)
|
||||
|
||||
/* update the info we do not have */
|
||||
bank->size = master_bank->size;
|
||||
if (bank->read_only)
|
||||
return;
|
||||
|
||||
bank->chip_width = master_bank->chip_width;
|
||||
bank->bus_width = master_bank->bus_width;
|
||||
bank->erased_value = master_bank->erased_value;
|
||||
@@ -187,6 +191,19 @@ static int virtual_flash_read(struct flash_bank *bank,
|
||||
return master_bank->driver->read(master_bank, buffer, offset, count);
|
||||
}
|
||||
|
||||
void virtual_flash_free_driver_priv(struct flash_bank *bank)
|
||||
{
|
||||
free(bank->driver_priv);
|
||||
bank->driver_priv = NULL;
|
||||
|
||||
/* For 'virtual' flash driver bank->sectors and bank->prot_blocks pointers are copied from
|
||||
* master flash_bank structure. They point to memory locations allocated by master flash driver
|
||||
* so master driver is responsible for releasing them.
|
||||
* Avoid UB caused by double-free memory corruption if flash bank is 'virtual'. */
|
||||
bank->sectors = NULL;
|
||||
bank->prot_blocks = NULL;
|
||||
}
|
||||
|
||||
const struct flash_driver virtual_flash = {
|
||||
.name = "virtual",
|
||||
.flash_bank_command = virtual_flash_bank_command,
|
||||
@@ -199,5 +216,62 @@ const struct flash_driver virtual_flash = {
|
||||
.erase_check = virtual_blank_check,
|
||||
.protect_check = virtual_protect_check,
|
||||
.info = virtual_info,
|
||||
.free_driver_priv = default_flash_free_driver_priv,
|
||||
.free_driver_priv = virtual_flash_free_driver_priv,
|
||||
};
|
||||
|
||||
FLASH_BANK_COMMAND_HANDLER(ro_alias_bank_command)
|
||||
{
|
||||
if (CMD_ARGC < 7)
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
|
||||
// get the master flash bank
|
||||
const char *bank_name = CMD_ARGV[6];
|
||||
struct flash_bank *master_bank = get_flash_bank_by_name_noprobe(bank_name);
|
||||
|
||||
if (!master_bank) {
|
||||
LOG_ERROR("master flash bank '%s' does not exist", bank_name);
|
||||
return ERROR_FLASH_OPERATION_FAILED;
|
||||
}
|
||||
|
||||
// save master bank name - use this to get settings later
|
||||
bank->driver_priv = strdup(bank_name);
|
||||
|
||||
bank->read_only = true;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int ro_alias_erase(struct flash_bank *bank,
|
||||
unsigned int first, unsigned int last)
|
||||
{
|
||||
char *bank_name = bank->driver_priv;
|
||||
|
||||
LOG_ERROR("Erase of read-only flash alias refused. Use master flash bank '%s'",
|
||||
bank_name);
|
||||
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
static int ro_alias_write(struct flash_bank *bank, const uint8_t *buffer,
|
||||
uint32_t offset, uint32_t count)
|
||||
{
|
||||
char *bank_name = bank->driver_priv;
|
||||
|
||||
LOG_ERROR("Write to read-only flash alias refused. Use master flash bank '%s'",
|
||||
bank_name);
|
||||
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
const struct flash_driver ro_alias_flash = {
|
||||
.name = "ro_alias",
|
||||
.flash_bank_command = ro_alias_bank_command,
|
||||
.erase = ro_alias_erase,
|
||||
.write = ro_alias_write,
|
||||
.read = virtual_flash_read,
|
||||
.probe = virtual_probe,
|
||||
.auto_probe = virtual_auto_probe,
|
||||
.erase_check = virtual_blank_check,
|
||||
.info = virtual_info,
|
||||
.free_driver_priv = virtual_flash_free_driver_priv,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user