e100 savevm/loadvm support
PATCH 1/1 e100 savevm/loadvm support
The attached patch adds loadvm and savevm support to the e100 driver.
One note about this patch is that the image is not portable across big/little endian hosts. Since it already appeared that the save/load images in general are not portable between a big/little endian hosts I just took the short cut of pushing the struct members that were not being saved directly into the save buffer. If it is the case that the save/load images are supposed to be endian agnostic, there is definitely some more work that needs to be done in all the simulated hw drivers.
Jason.
Quoted 7 lines
One note about this patch is that the image is not portable across
big/little endian hosts. Since it already appeared that the save/load
images in general are not portable between a big/little endian hosts I just took the short cut of pushing the struct members that were not being saved directly into the save buffer. If it is the case that the save/load images are supposed to be endian agnostic, there is definitely some more work that needs to be done in all the simulated hw drivers.
Save/load images definitely are supports to be host-independent. Do you have examples of where they are not?
Paul
Quoted 7 lines · Jason Wessel
The attached patch adds loadvm and savevm support to the e100 driver.
One note about this patch is that the image is not portable across
big/little endian hosts. Since it already appeared that the save/load
images in general are not portable between a big/little endian hosts I just took the short cut of pushing the struct members that were not being saved directly into the save buffer.
Looks like a bug to me.
Quoted 5 lines
If it is the case that the
save/load images are supposed to be endian agnostic, there is definitely some more work that needs to be done in all the simulated hw drivers.Signed-off-by Jason Wessel <[email protected]>
Patch is missing.
Thiemo
Quoted 12 lines · Thiemo Seufer
Quoted 4 lines · Jason Wessel
The attached patch adds loadvm and savevm support to the e100 driver.
One note about this patch is that the image is not portable across big/little endian hosts. Since it already appeared that the save/load images in general are not portable between a big/little endian hosts I just took the short cut of pushing the struct members that were not being saved directly into the save buffer.
Looks like a bug to me.
Quoted 2 lines
If it is the case that the save/load images are supposed to be endian agnostic, there is definitely some more work that needs to be done in all the simulated hw drivers.
Quoted 8 lines
Quoted 2 lines
Signed-off-by Jason Wessel <[email protected]>Patch is missing.
Thiemo
Since the first patch was missing, I created a new one which does not have any endian issues. In this patch there is a #if 0 which matches the member of the struct that has the #if 0 in it. Once again I tested it to confirm it works with a single or multiple enet cards of different types.
Originally I thought I had seen a place in the code where there was a put buffer on a series of long values, but I can no longer find the reference to it. In the original patch I had just saved the structs outright via the put_buffer which clearly would not have been endian agnostic. The patch attached here fixes that.
Jason.
--- hw/eepro100.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 98 insertions(+), 4 deletions(-)
hw/eepro100.c +98 -4
@@ -1571,10 +1571,9 @@ static void nic_receive(void *opaque, costatic int nic_load (QEMUFile * f,void *opaque,int version_id) {EEPRO100State *s = (EEPRO100State *) opaque; +int i;int ret; -missing ("NIC load" ); -if (version_id >3 )return -EINVAL ;
@@ -1608,14 +1607,61 @@ static int nic_load(QEMUFile * f, void *qemu_get_buffer (f, s->mult,8 );qemu_get_buffer (f, s->mem,sizeof (s->mem)); +/* Restore all members of struct between scv_stat and mem */ +qemu_get_8s (f, &s->scb_stat); +qemu_get_8s (f, &s->int_stat); +for (i =0 ; i <3 ; i++) +qemu_get_be32s (f, &s->region[i]); +qemu_get_buffer (f, s->macaddr,6 ); +for (i =0 ; i <19 ; i++) +qemu_get_be32s (f, &s->statcounter[i]); +for (i =0 ; i <32 ; i++) +qemu_get_be16s (f, &s->mdimem[i]); +/* The eeprom should be saved and restored by its own routines */ +qemu_get_be32s (f, &s->device); +qemu_get_be32s (f, &s->pointer); +qemu_get_be32s (f, &s->cu_base); +qemu_get_be32s (f, &s->cu_offset); +qemu_get_be32s (f, &s->ru_base); +qemu_get_be32s (f, &s->ru_offset); +qemu_get_be32s (f, &s->statsaddr); +/* Restore epro100_stats_t statistics */ +qemu_get_be32s (f, &s->statistics.tx_good_frames); +qemu_get_be32s (f, &s->statistics.tx_max_collisions); +qemu_get_be32s (f, &s->statistics.tx_late_collisions); +qemu_get_be32s (f, &s->statistics.tx_underruns); +qemu_get_be32s (f, &s->statistics.tx_lost_crs); +qemu_get_be32s (f, &s->statistics.tx_deferred); +qemu_get_be32s (f, &s->statistics.tx_single_collisions); +qemu_get_be32s (f, &s->statistics.tx_multiple_collisions); +qemu_get_be32s (f, &s->statistics.tx_total_collisions); +qemu_get_be32s (f, &s->statistics.rx_good_frames); +qemu_get_be32s (f, &s->statistics.rx_crc_errors); +qemu_get_be32s (f, &s->statistics.rx_alignment_errors); +qemu_get_be32s (f, &s->statistics.rx_resource_errors); +qemu_get_be32s (f, &s->statistics.rx_overrun_errors); +qemu_get_be32s (f, &s->statistics.rx_cdt_errors); +qemu_get_be32s (f, &s->statistics.rx_short_frame_errors); +qemu_get_be32s (f, &s->statistics.fc_xmt_pause); +qemu_get_be32s (f, &s->statistics.fc_rcv_pause); +qemu_get_be32s (f, &s->statistics.fc_rcv_unsupported); +qemu_get_be16s (f, &s->statistics.xmt_tco_frames); +qemu_get_be16s (f, &s->statistics.rcv_tco_frames); +qemu_get_be32s (f, &s->statistics.complete); +#if 0 +qemu_get_be16s (f, &s->status); +#endif + +/* Configuration bytes. */ +qemu_get_buffer (f, s->configuration,sizeof (s->configuration)); +return 0 ; }static void nic_save (QEMUFile * f,void *opaque) {EEPRO100State *s = (EEPRO100State *) opaque; - -missing ("NIC save" ); +int i;if (s->pci_dev)pci_device_save (s->pci_dev, f);
@@ -1639,6 +1685,54 @@ static void nic_save(QEMUFile * f, voidqemu_put_8s (f, &s->curpag);qemu_put_buffer (f, s->mult,8 );qemu_put_buffer (f, s->mem,sizeof (s->mem)); + +/* Save all members of struct between scv_stat and mem */ +qemu_put_8s (f, &s->scb_stat); +qemu_put_8s (f, &s->int_stat); +for (i =0 ; i <3 ; i++) +qemu_put_be32s (f, &s->region[i]); +qemu_put_buffer (f, s->macaddr,6 ); +for (i =0 ; i <19 ; i++) +qemu_put_be32s (f, &s->statcounter[i]); +for (i =0 ; i <32 ; i++) +qemu_put_be16s (f, &s->mdimem[i]); +/* The eeprom should be saved and restored by its own routines */ +qemu_put_be32s (f, &s->device); +qemu_put_be32s (f, &s->pointer); +qemu_put_be32s (f, &s->cu_base); +qemu_put_be32s (f, &s->cu_offset); +qemu_put_be32s (f, &s->ru_base); +qemu_put_be32s (f, &s->ru_offset); +qemu_put_be32s (f, &s->statsaddr); +/* Save epro100_stats_t statistics */ +qemu_put_be32s (f, &s->statistics.tx_good_frames); +qemu_put_be32s (f, &s->statistics.tx_max_collisions); +qemu_put_be32s (f, &s->statistics.tx_late_collisions); +qemu_put_be32s (f, &s->statistics.tx_underruns); +qemu_put_be32s (f, &s->statistics.tx_lost_crs); +qemu_put_be32s (f, &s->statistics.tx_deferred); +qemu_put_be32s (f, &s->statistics.tx_single_collisions); +qemu_put_be32s (f, &s->statistics.tx_multiple_collisions); +qemu_put_be32s (f, &s->statistics.tx_total_collisions); +qemu_put_be32s (f, &s->statistics.rx_good_frames); +qemu_put_be32s (f, &s->statistics.rx_crc_errors); +qemu_put_be32s (f, &s->statistics.rx_alignment_errors); +qemu_put_be32s (f, &s->statistics.rx_resource_errors); +qemu_put_be32s (f, &s->statistics.rx_overrun_errors); +qemu_put_be32s (f, &s->statistics.rx_cdt_errors); +qemu_put_be32s (f, &s->statistics.rx_short_frame_errors); +qemu_put_be32s (f, &s->statistics.fc_xmt_pause); +qemu_put_be32s (f, &s->statistics.fc_rcv_pause); +qemu_put_be32s (f, &s->statistics.fc_rcv_unsupported); +qemu_put_be16s (f, &s->statistics.xmt_tco_frames); +qemu_put_be16s (f, &s->statistics.rcv_tco_frames); +qemu_put_be32s (f, &s->statistics.complete); +#if 0 +qemu_put_be16s (f, &s->status); +#endif + +/* Configuration bytes. */ +qemu_put_buffer (f, s->configuration,sizeof (s->configuration)); } static void nic_init(PCIBus * bus, NICInfo * nd,