aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/nvram/fw_cfg.c19
-rw-r--r--include/hw/nvram/fw_cfg.h10
2 files changed, 13 insertions, 16 deletions
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index 73b0a813a7..6e6414b723 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -252,7 +252,8 @@ static void fw_cfg_write(FWCfgState *s, uint8_t value)
static int fw_cfg_select(FWCfgState *s, uint16_t key)
{
- int ret;
+ int arch, ret;
+ FWCfgEntry *e;
s->cur_offset = 0;
if ((key & FW_CFG_ENTRY_MASK) >= FW_CFG_MAX_ENTRY) {
@@ -261,6 +262,12 @@ static int fw_cfg_select(FWCfgState *s, uint16_t key)
} else {
s->cur_entry = key;
ret = 1;
+ /* entry successfully selected, now run callback if present */
+ arch = !!(key & FW_CFG_ARCH_LOCAL);
+ e = &s->entries[arch][key & FW_CFG_ENTRY_MASK];
+ if (e->read_callback) {
+ e->read_callback(e->callback_opaque, s->cur_offset);
+ }
}
trace_fw_cfg_select(s, key, ret);
@@ -276,9 +283,6 @@ static uint8_t fw_cfg_read(FWCfgState *s)
if (s->cur_entry == FW_CFG_INVALID || !e->data || s->cur_offset >= e->len)
ret = 0;
else {
- if (e->read_callback) {
- e->read_callback(e->callback_opaque, s->cur_offset);
- }
ret = e->data[s->cur_offset++];
}
@@ -371,10 +375,6 @@ static void fw_cfg_dma_transfer(FWCfgState *s)
len = (e->len - s->cur_offset);
}
- if (e->read_callback) {
- e->read_callback(e->callback_opaque, s->cur_offset);
- }
-
/* If the access is not a read access, it will be a skip access,
* tested before.
*/
@@ -513,7 +513,8 @@ static void fw_cfg_reset(DeviceState *d)
{
FWCfgState *s = FW_CFG(d);
- fw_cfg_select(s, 0);
+ /* we never register a read callback for FW_CFG_SIGNATURE */
+ fw_cfg_select(s, FW_CFG_SIGNATURE);
}
/* Save restore 32 bit int as uint16_t
diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h
index 4b5e196d17..a1cfaa4a2f 100644
--- a/include/hw/nvram/fw_cfg.h
+++ b/include/hw/nvram/fw_cfg.h
@@ -183,13 +183,9 @@ void fw_cfg_add_file(FWCfgState *s, const char *filename, void *data,
* structure residing at key value FW_CFG_FILE_DIR, containing the item name,
* data size, and assigned selector key value.
* Additionally, set a callback function (and argument) to be called each
- * time a byte is read by the guest from this particular item, or, in the
- * case of DMA, each time a read or skip request overlaps with the valid
- * offset range of the item.
- * NOTE: In addition to the opaque argument set here, the callback function
- * takes the current data offset as an additional argument, allowing it the
- * option of only acting upon specific offset values (e.g., 0, before the
- * first data byte of the selected item is returned to the guest).
+ * time this item is selected (by having its selector key either written to
+ * the fw_cfg control register, or passed to QEMU in FWCfgDmaAccess.control
+ * with FW_CFG_DMA_CTL_SELECT).
*/
void fw_cfg_add_file_callback(FWCfgState *s, const char *filename,
FWCfgReadCallback callback, void *callback_opaque,