virtio: feature negotiation

This commit is contained in:
Matheus
2024-03-29 13:36:48 -03:00
parent 2030ca8c5b
commit 87b0ff64b2
3 changed files with 27 additions and 5 deletions
+3
View File
@@ -46,9 +46,12 @@ typedef struct {
void virtio_init();
size_t virtio_queuesize(viodevice_t *viodevice, int queue);
void virtio_enablequeue(viodevice_t *viodevice, int queue);
uint64_t virtio_negotiatefeatures(viodevice_t *viodevice, uint64_t features);
void *virtio_createqueue(viodevice_t *viodevice, vioqueue_t *vioqueue, int queue, size_t size, int msix);
void virtio_enabledevice(viodevice_t *viodevice);
#define VIO_FEATURE_VERSION_1 (1l << 32)
#define VIO_CONFIG_STATUS_SET(x, v) (x)->config->status |= v
#define VIO_CONFIG_STATUS_ACK 1
#define VIO_CONFIG_STATUS_DRIVER 2
+1 -4
View File
@@ -151,10 +151,7 @@ int vioblk_newdevice(viodevice_t *viodevice) {
pci_initmsix(viodevice->e);
// TODO support several queues
// no extra features will be used yet
VIO_CONFIG_STATUS_SET(viodevice, VIO_CONFIG_STATUS_FEATURESOK);
if ((viodevice->config->status & VIO_CONFIG_STATUS_FEATURESOK) == 0)
return 1;
__assert(virtio_negotiatefeatures(viodevice, VIO_FEATURE_VERSION_1) == VIO_FEATURE_VERSION_1);
// initialize device object
vioblkdev_t *blkdev = alloc(sizeof(vioblkdev_t));
+23 -1
View File
@@ -17,9 +17,11 @@ static char *devname[] = {
void vioblk_init();
int vioblk_newdevice(viodevice_t *);
void vionet_init();
int vionet_newdevice(viodevice_t *);
static int (*drivedevice[]) (viodevice_t *) = {
NULL,
vionet_newdevice,
vioblk_newdevice
};
@@ -33,6 +35,24 @@ void virtio_enablequeue(viodevice_t *viodevice, int queue) {
viodevice->config->queueenable = 1;
}
uint64_t virtio_negotiatefeatures(viodevice_t *viodevice, uint64_t features) {
viodevice->config->devicefeatureselect = 0;
uint64_t offered = viodevice->config->devicefeature;
viodevice->config->devicefeatureselect = 1;
offered |= (uint64_t)viodevice->config->devicefeature << 32;
uint64_t negotiable = features & offered;
viodevice->config->driverfeatureselect = 0;
viodevice->config->driverfeature = negotiable & 0xffffffff;
viodevice->config->driverfeatureselect = 1;
viodevice->config->driverfeature = (negotiable >> 32) & 0xffffffff;
VIO_CONFIG_STATUS_SET(viodevice, VIO_CONFIG_STATUS_FEATURESOK);
__assert(viodevice->config->status & VIO_CONFIG_STATUS_FEATURESOK);
return negotiable;
}
static uint16_t *virtio_queuenotifyaddress(viodevice_t *viodevice, int queue) {
viodevice->config->queueselect = queue;
return (uint16_t *)((uintptr_t)viodevice->notify + viodevice->config->queuenotifyoffset * viodevice->notifymultiplier);
@@ -79,6 +99,7 @@ void virtio_enabledevice(viodevice_t *viodevice) {
static void virtio_newdevice(pcienum_t *e) {
pci_setcommand(e, PCI_COMMAND_MMIO, 1);
pci_setcommand(e, PCI_COMMAND_IO, 0);
pci_setcommand(e, PCI_COMMAND_BUSMASTER, 1);
pci_setcommand(e, PCI_COMMAND_IRQDISABLE, 1);
int devtype = e->deviceid - VIRTIO_DEVICE_MIN;
@@ -146,6 +167,7 @@ static void virtio_newdevice(pcienum_t *e) {
void virtio_init() {
vioblk_init();
vionet_init();
for (int dev = VIRTIO_DEVICE_MIN; dev <= VIRTIO_DEVICE_MAX; ++dev) {
int i = 0;