diff --git a/drivers/virtio.cc b/drivers/virtio.cc index cb31bb80838db90f8be4db9b14844c328612425c..3de066c112ed68005d9f2f6083bccec8fce245ab 100644 --- a/drivers/virtio.cc +++ b/drivers/virtio.cc @@ -35,6 +35,12 @@ Virtio::Init(Device* dev) { _bars[0]->write(VIRTIO_PCI_STATUS, (u8)(VIRTIO_CONFIG_S_ACKNOWLEDGE | VIRTIO_CONFIG_S_DRIVER)); + probe_virt_queues(); + + for (int i=0;i<32;i++) + debug(fmt("%d:%d ") % i % get_device_feature_bit(i), false); + debug(fmt("\n"), false); + _bars[0]->write(VIRTIO_PCI_STATUS, (u8)(VIRTIO_CONFIG_S_DRIVER_OK)); return true; @@ -75,3 +81,50 @@ Virtio::vring_need_event(u16 event_idx, u16 new_idx, u16 old) { return (u16)(new_idx - event_idx - 1) < (u16)(new_idx - old); } +bool +Virtio::get_device_feature_bit(int bit) { + u32 features = _bars[0]->read(VIRTIO_PCI_HOST_FEATURES); + return bool(features & (1 << bit)); +} + +void +Virtio::set_guest_feature_bit(int bit, bool on) { + u32 features = _bars[0]->read(VIRTIO_PCI_GUEST_FEATURES); + features = (on)? features | (1 << bit) : features & ~(1 << bit); + _bars[0]->write(VIRTIO_PCI_GUEST_FEATURES, features); +} + +void +Virtio::set_guest_features(u32 features) { + _bars[0]->write(VIRTIO_PCI_GUEST_FEATURES, features); +} + +void +Virtio::pci_conf_write(int offset, void* buf, int length) { + u8* ptr = reinterpret_cast<u8*>(buf); + for (int i=0;i<length;i++) + _bars[0]->write(offset, ptr[i]); +} + +void +Virtio::pci_conf_read(int offset, void* buf, int length) { + unsigned char* ptr = reinterpret_cast<unsigned char*>(buf); + for (int i=0;i<length;i++) + ptr[i] = _bars[0]->readb(offset); + +} + +void +Virtio::probe_virt_queues() { + u16 queuesel = 0; + u16 qsize; + + do { + pci_conf_write(VIRTIO_PCI_QUEUE_SEL, &queuesel, sizeof(queuesel)); + pci_conf_read(VIRTIO_PCI_QUEUE_NUM, &qsize, sizeof(qsize)); + debug(fmt("queue %d, size %d") % queuesel % qsize); + + if (!qsize) break; + queuesel++; + } while (1); +} diff --git a/drivers/virtio.hh b/drivers/virtio.hh index ece9f9c3b796beddba4003185fff378d83780a86..b794dc80b1a147794d714d880423a7ae8c3f9b1f 100644 --- a/drivers/virtio.hh +++ b/drivers/virtio.hh @@ -194,6 +194,14 @@ protected: unsigned vring_size(unsigned int num, unsigned long align); int vring_need_event(u16 event_idx, u16 new_idx, u16 old); + virtual bool get_device_feature_bit(int bit); + virtual void set_guest_feature_bit(int bit, bool on); + virtual void set_guest_features(u32 features); + void pci_conf_read(int offset, void* buf, int length); + void pci_conf_write(int offset, void* buf, int length); + + void probe_virt_queues(); + private: };