return 0;
}
+#ifdef V3_CONFIG_CHECKPOINT
+
+#include <palacios/vmm_sprintf.h>
+
+static int pci_save(struct v3_chkpt_ctx * ctx, void * private_data) {
+ struct pci_internal * pci = (struct pci_internal *)private_data;
+ char buf[128];
+ int i = 0;
+
+ v3_chkpt_save_32(ctx, "ADDR_REG", &(pci->addr_reg.val));
+ v3_chkpt_save_16(ctx, "IO_BASE", &(pci->dev_io_base));
+
+ for (i = 0; i < PCI_BUS_COUNT; i++) {
+ struct pci_bus * bus = &(pci->bus_list[i]);
+ struct rb_node * node = v3_rb_first(&(bus->devices));
+ struct pci_device * dev = NULL;
+ struct v3_chkpt_ctx * bus_ctx = NULL;
+
+ snprintf(buf, 128, "pci-%d\n", i);
+
+ bus_ctx = v3_chkpt_open_ctx(ctx->chkpt, ctx, buf);
+
+ while (node) {
+ struct v3_chkpt_ctx * dev_ctx = NULL;
+ int bar_idx = 0;
+ dev = rb_entry(node, struct pci_device, dev_tree_node);
+
+ snprintf(buf, 128, "pci-%d.%d-%d", i, dev->dev_num, dev->fn_num);
+ dev_ctx = v3_chkpt_open_ctx(bus_ctx->chkpt, bus_ctx, buf);
+
+ v3_chkpt_save(dev_ctx, "CONFIG_SPACE", 256, dev->config_space);
+
+ for (bar_idx = 0; bar_idx < 6; bar_idx++) {
+ snprintf(buf, 128, "BAR-%d", bar_idx);
+ v3_chkpt_save_32(dev_ctx, buf, &(dev->bar[bar_idx].val));
+ }
+
+ node = v3_rb_next(node);
+ }
+ }
+
+
+ return 0;
+}
+
+
+static int pci_load(struct v3_chkpt_ctx * ctx, void * private_data) {
+ struct pci_internal * pci = (struct pci_internal *)private_data;
+ char buf[128];
+ int i = 0;
+
+ v3_chkpt_load_32(ctx, "ADDR_REG", &(pci->addr_reg.val));
+ v3_chkpt_load_16(ctx, "IO_BASE", &(pci->dev_io_base));
+
+ for (i = 0; i < PCI_BUS_COUNT; i++) {
+ struct pci_bus * bus = &(pci->bus_list[i]);
+ struct rb_node * node = v3_rb_first(&(bus->devices));
+ struct pci_device * dev = NULL;
+ struct v3_chkpt_ctx * bus_ctx = NULL;
+
+ snprintf(buf, 128, "pci-%d\n", i);
+
+ bus_ctx = v3_chkpt_open_ctx(ctx->chkpt, ctx, buf);
+
+ while (node) {
+ struct v3_chkpt_ctx * dev_ctx = NULL;
+ int bar_idx = 0;
+ dev = rb_entry(node, struct pci_device, dev_tree_node);
+
+ snprintf(buf, 128, "pci-%d.%d-%d", i, dev->dev_num, dev->fn_num);
+ dev_ctx = v3_chkpt_open_ctx(bus_ctx->chkpt, bus_ctx, buf);
+
+ v3_chkpt_load(dev_ctx, "CONFIG_SPACE", 256, dev->config_space);
+
+ for (bar_idx = 0; bar_idx < 6; bar_idx++) {
+ snprintf(buf, 128, "BAR-%d", bar_idx);
+ v3_chkpt_load_32(dev_ctx, buf, &(dev->bar[bar_idx].val));
+ }
+
+ node = v3_rb_next(node);
+ }
+ }
+
+
+ return 0;
+}
+
+
+#endif
+
+
+
static struct v3_device_ops dev_ops = {
.free = (int (*)(void *))pci_free,
-
+#ifdef V3_CONFIG_CHECKPOINT
+ .save = pci_save,
+ .load = pci_load
+#endif
};