Index: sys/dev/virtio/virtio.h =================================================================== --- sys/dev/virtio/virtio.h +++ sys/dev/virtio/virtio.h @@ -33,6 +33,7 @@ #include #include +#include struct vq_alloc_info; @@ -84,14 +85,15 @@ /* * Read/write a variable amount from the device specific (ie, network) - * configuration region. This region is encoded in the same endian as - * the guest. + * configuration region. According to virtio-1.0 section 2.4, this + * region uses little-endian format for multi-byte fields */ void virtio_read_device_config(device_t dev, bus_size_t offset, void *dst, int length); void virtio_write_device_config(device_t dev, bus_size_t offset, void *src, int length); + /* Inlined device specific read/write functions for common lengths. */ #define VIRTIO_RDWR_DEVICE_CONFIG(size, type) \ static inline type \ Index: sys/dev/virtio/virtio.c =================================================================== --- sys/dev/virtio/virtio.c +++ sys/dev/virtio/virtio.c @@ -250,17 +250,65 @@ void virtio_read_device_config(device_t dev, bus_size_t offset, void *dst, int len) { - VIRTIO_BUS_READ_DEVICE_CONFIG(device_get_parent(dev), offset, dst, len); +#if _BYTE_ORDER != _LITTLE_ENDIAN + switch(len){ + case 1: + break; + case 2: { + uint16_t *val = dst; + *val = le16toh(*val); + } + break; + case 4: { + uint32_t *val = dst; + *val = le32toh(*val); + } + break; + case 8: { + uint64_t *val = dst; + *val = le64toh(*val); + } + default: + device_printf(dev, "WARNING: unhandled len %d. \ + Byte ordering may be incorrect.", len); + } +#endif } void virtio_write_device_config(device_t dev, bus_size_t offset, void *dst, int len) { - +#if _BYTE_ORDER != _LITTLE_ENDIAN + switch(len){ + case 1: + break; + case 2: { + uint16_t val = htole16(*(uint16_t*)dst); + VIRTIO_BUS_WRITE_DEVICE_CONFIG(device_get_parent(dev), + offset, &val, len); + } + return; + case 4: { + uint32_t val = htole32(*(uint32_t*)dst); + VIRTIO_BUS_WRITE_DEVICE_CONFIG(device_get_parent(dev), + offset, &val, len); + } + return; + case 8: { + uint64_t val = htole64(*(uint64_t*)dst); + VIRTIO_BUS_WRITE_DEVICE_CONFIG(device_get_parent(dev), + offset, &val, len); + } + return; + default: + device_printf(dev, "WARNING: unhandled len %d. \ + Byte ordering may be incorrect.", len); + } +#endif VIRTIO_BUS_WRITE_DEVICE_CONFIG(device_get_parent(dev), - offset, dst, len); + offset, dst, len); } static int Index: sys/powerpc/conf/GENERIC64 =================================================================== --- sys/powerpc/conf/GENERIC64 +++ sys/powerpc/conf/GENERIC64 @@ -252,3 +252,12 @@ options EVDEV_SUPPORT # evdev support in legacy drivers device evdev # input event device support device uinput # install /dev/uinput cdev + +# VirtIO support +device virtio # Generic VirtIO bus (required) +device virtio_pci # VirtIO PCI device +device vtnet # VirtIO Ethernet device +device virtio_blk # VirtIO Block device +device virtio_scsi # VirtIO SCSI device +device virtio_balloon # VirtIO Memory Balloon device +