Skip to content

Commit 4f9ff4c

Browse files
committed
persist extflash
1 parent 18a11f6 commit 4f9ff4c

1 file changed

Lines changed: 25 additions & 0 deletions

File tree

hw/misc/pebble_extflash.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,15 @@
2323

2424
#include "qemu/osdep.h"
2525
#include "qemu/log.h"
26+
#include "qemu/notify.h"
2627
#include "qemu/units.h"
2728
#include "qapi/error.h"
2829
#include "hw/sysbus.h"
2930
#include "hw/qdev-properties.h"
3031
#include "hw/qdev-properties-system.h"
3132
#include "hw/block/block.h"
3233
#include "system/block-backend.h"
34+
#include "system/runstate.h"
3335

3436
#define TYPE_PEBBLE_EXTFLASH "pebble-extflash"
3537
OBJECT_DECLARE_SIMPLE_TYPE(PblExtFlash, PEBBLE_EXTFLASH)
@@ -51,8 +53,11 @@ struct PblExtFlash {
5153
BlockBackend *blk;
5254
uint8_t *storage;
5355
uint32_t size;
56+
uint32_t backed_size;
5457

5558
uint32_t ctrl;
59+
60+
Notifier shutdown_notifier;
5661
};
5762

5863
static uint64_t pbl_extflash_regs_read(void *opaque, hwaddr offset,
@@ -100,6 +105,19 @@ static const MemoryRegionOps pbl_extflash_regs_ops = {
100105
.valid.max_access_size = 4,
101106
};
102107

108+
static void pbl_extflash_shutdown_notify(Notifier *n, void *data)
109+
{
110+
PblExtFlash *s = container_of(n, PblExtFlash, shutdown_notifier);
111+
112+
if (!s->blk || !blk_is_writable(s->blk) || s->backed_size == 0) {
113+
return;
114+
}
115+
if (blk_pwrite(s->blk, 0, s->backed_size, s->storage, 0) < 0) {
116+
qemu_log_mask(LOG_GUEST_ERROR,
117+
"pebble-extflash: failed to flush storage on shutdown\n");
118+
}
119+
}
120+
103121
static void pbl_extflash_realize(DeviceState *dev, Error **errp)
104122
{
105123
PblExtFlash *s = PEBBLE_EXTFLASH(dev);
@@ -127,7 +145,14 @@ static void pbl_extflash_realize(DeviceState *dev, Error **errp)
127145
error_setg(errp, "pebble-extflash: failed to read drive");
128146
return;
129147
}
148+
s->backed_size = blk_size;
130149
}
150+
151+
/* Persist guest writes back to the file before bdrv_close_all()
152+
* tears the block layer down. Fires for graceful shutdown,
153+
* `(qemu) quit`, and SIGINT (Ctrl+C). */
154+
s->shutdown_notifier.notify = pbl_extflash_shutdown_notify;
155+
qemu_register_shutdown_notifier(&s->shutdown_notifier);
131156
}
132157

133158
s->ctrl = 1; /* XIP enabled by default */

0 commit comments

Comments
 (0)