loader: add rom transaction API
Image file loaders may add a series of roms. If an error occurs partway through loading there is no easy way to drop previously added roms. This patch adds a transaction mechanism that works like this: rom_transaction_begin(); ...call rom_add_*()... rom_transaction_end(ok); If ok is false then roms added in this transaction are dropped. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-id: 20180814162739.11814-5-stefanha@redhat.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
e7f5993354
commit
e2336043cc
|
@ -840,6 +840,8 @@ struct Rom {
|
||||||
char *fw_dir;
|
char *fw_dir;
|
||||||
char *fw_file;
|
char *fw_file;
|
||||||
|
|
||||||
|
bool committed;
|
||||||
|
|
||||||
hwaddr addr;
|
hwaddr addr;
|
||||||
QTAILQ_ENTRY(Rom) next;
|
QTAILQ_ENTRY(Rom) next;
|
||||||
};
|
};
|
||||||
|
@ -877,6 +879,8 @@ static void rom_insert(Rom *rom)
|
||||||
rom->as = &address_space_memory;
|
rom->as = &address_space_memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rom->committed = false;
|
||||||
|
|
||||||
/* List is ordered by load address in the same address space */
|
/* List is ordered by load address in the same address space */
|
||||||
QTAILQ_FOREACH(item, &roms, next) {
|
QTAILQ_FOREACH(item, &roms, next) {
|
||||||
if (rom_order_compare(rom, item)) {
|
if (rom_order_compare(rom, item)) {
|
||||||
|
@ -1168,6 +1172,34 @@ void rom_reset_order_override(void)
|
||||||
fw_cfg_reset_order_override(fw_cfg);
|
fw_cfg_reset_order_override(fw_cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rom_transaction_begin(void)
|
||||||
|
{
|
||||||
|
Rom *rom;
|
||||||
|
|
||||||
|
/* Ignore ROMs added without the transaction API */
|
||||||
|
QTAILQ_FOREACH(rom, &roms, next) {
|
||||||
|
rom->committed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void rom_transaction_end(bool commit)
|
||||||
|
{
|
||||||
|
Rom *rom;
|
||||||
|
Rom *tmp;
|
||||||
|
|
||||||
|
QTAILQ_FOREACH_SAFE(rom, &roms, next, tmp) {
|
||||||
|
if (rom->committed) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (commit) {
|
||||||
|
rom->committed = true;
|
||||||
|
} else {
|
||||||
|
QTAILQ_REMOVE(&roms, rom, next);
|
||||||
|
rom_free(rom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static Rom *find_rom(hwaddr addr, size_t size)
|
static Rom *find_rom(hwaddr addr, size_t size)
|
||||||
{
|
{
|
||||||
Rom *rom;
|
Rom *rom;
|
||||||
|
|
|
@ -225,6 +225,25 @@ int rom_check_and_register_reset(void);
|
||||||
void rom_set_fw(FWCfgState *f);
|
void rom_set_fw(FWCfgState *f);
|
||||||
void rom_set_order_override(int order);
|
void rom_set_order_override(int order);
|
||||||
void rom_reset_order_override(void);
|
void rom_reset_order_override(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rom_transaction_begin:
|
||||||
|
*
|
||||||
|
* Call this before of a series of rom_add_*() calls. Call
|
||||||
|
* rom_transaction_end() afterwards to commit or abort. These functions are
|
||||||
|
* useful for undoing a series of rom_add_*() calls if image file loading fails
|
||||||
|
* partway through.
|
||||||
|
*/
|
||||||
|
void rom_transaction_begin(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rom_transaction_end:
|
||||||
|
* @commit: true to commit added roms, false to drop added roms
|
||||||
|
*
|
||||||
|
* Call this after a series of rom_add_*() calls. See rom_transaction_begin().
|
||||||
|
*/
|
||||||
|
void rom_transaction_end(bool commit);
|
||||||
|
|
||||||
int rom_copy(uint8_t *dest, hwaddr addr, size_t size);
|
int rom_copy(uint8_t *dest, hwaddr addr, size_t size);
|
||||||
void *rom_ptr(hwaddr addr, size_t size);
|
void *rom_ptr(hwaddr addr, size_t size);
|
||||||
void hmp_info_roms(Monitor *mon, const QDict *qdict);
|
void hmp_info_roms(Monitor *mon, const QDict *qdict);
|
||||||
|
|
Loading…
Reference in New Issue