// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2016 Red Hat, Inc.
 * Author: Michael S. Tsirkin <mst@redhat.com>
 *
 * Partial implementation of virtio 0.9. event index is used for signalling,
 * unconditionally. Design roughly follows linux kernel implementation in order
 * to be able to judge its performance.
 */
#define _GNU_SOURCE
#include "main.h"
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <linux/virtio_ring.h>

struct data {
	void *data;
} *data;

struct vring ring;

/* enabling the below activates experimental ring polling code
 * (which skips index reads on consumer in favor of looking at
 * high bits of ring id ^ 0x8000).
 */
/* #ifdef RING_POLL */
/* enabling the below activates experimental in-order code
 * (which skips ring updates and reads and writes len in descriptor).
 */
/* #ifdef INORDER */

#if defined(RING_POLL) && defined(INORDER)
#error "RING_POLL and INORDER are mutually exclusive"
#endif

/* how much padding is needed to avoid false cache sharing */
#define HOST_GUEST_PADDING 0x80

struct guest {
	unsigned short avail_idx;
	unsigned short last_used_idx;
	unsigned short num_free;
	unsigned short kicked_avail_idx;
#ifndef INORDER
	unsigned short free_head;
#else
	unsigned short reserved_free_head;
#endif
	unsigned char reserved[HOST_GUEST_PADDING - 10];
} guest;

struct host {
	/* we do not need to track last avail index
	 * unless we have more than one in flight.
	 */
	unsigned short used_idx;
	unsigned short called_used_idx;
	unsigned char reserved[HOST_GUEST_PADDING - 4];
} host;

/* implemented by ring */
void alloc_ring(void)
{
	int ret;
	int i;
	void *p;

	ret = posix_memalign(&p, 0x1000, vring_size(ring_size, 0x1000));
	if (ret) {
		perror("Unable to allocate ring buffer.\n");
		exit(3);
	}
	memset(p, 0, vring_size(ring_size, 0x1000));
	vring_init(&ring, ring_size, p, 0x1000);

	guest.avail_idx = 0;
	guest.kicked_avail_idx = -1;
	guest.last_used_idx = 0;
#ifndef INORDER
	/* Put everything in free lists. */
	guest.free_head = 0;
#endif
	for (i = 0; i < ring_size - 1; i++)
		ring.desc[i].next = i + 1;
	host.used_idx = 0;
	host.called_used_idx = -1;
	guest.num_free = ring_size;
	data = malloc(ring_size * sizeof *data);
	if (!data) {
		perror("Unable to allocate data buffer.\n");
		exit(3);
	}
	memset(data, 0, ring_size * sizeof *data);
}

/* guest side */
int add_inbuf(unsigned len, void *buf, void *datap)
{
	unsigned head;
#ifndef INORDER
	unsigned avail;
#endif
	struct vring_desc *desc;

	if (!guest.num_free)
		return -1;

#ifdef INORDER
	head = (ring_size - 1) & (guest.avail_idx++);
#else
	head = guest.free_head;
#endif
	guest.num_free--;

	desc = ring.desc;
	desc[head].flags = VRING_DESC_F_NEXT;
	desc[head].addr = (unsigned long)(void *)buf;
	desc[head].len = len;
	/* We do it like this to simulate the way
	 * we'd have to flip it if we had multiple
	 * descriptors.
	 */
	desc[head].flags &= ~VRING_DESC_F_NEXT;
#ifndef INORDER
	guest.free_head = desc[head].next;
#endif

	data[head].data = datap;

#ifdef RING_POLL
	/* Barrier A (for pairing) */
	smp_release();
	avail = guest.avail_idx++;
	ring.avail->ring[avail & (ring_size - 1)] =
		(head | (avail & ~(ring_size - 1))) ^ 0x8000;
#else
#ifndef INORDER
	/* Barrier A (for pairing) */
	smp_release();
	avail = (ring_size - 1) & (guest.avail_idx++);
	ring.avail->ring[avail] = head;
#endif
	/* Barrier A (for pairing) */
	smp_release();
#endif
	ring.avail->idx = guest.avail_idx;
	return 0;
}

void *get_buf(unsigned *lenp, void **bufp)
{
	unsigned head;
	unsigned index;
	void *datap;

#ifdef RING_POLL
	head = (ring_size - 1) & guest.last_used_idx;
	index = ring.used->ring[head].id;
	if ((index ^ guest.last_used_idx ^ 0x8000) & ~(ring_size - 1))
		return NULL;
	/* Barrier B (for pairing) */
	smp_acquire();
	index &= ring_size - 1;
#else
	if (ring.used->idx == guest.last_used_idx)
		return NULL;
	/* Barrier B (for pairing) */
	smp_acquire();
#ifdef INORDER
	head = (ring_size - 1) & guest.last_used_idx;
	index = head;
#else
	head = (ring_size - 1) & guest.last_used_idx;
	index = ring.used->ring[head].id;
#endif

#endif
#ifdef INORDER
	*lenp = ring.desc[index].len;
#else
	*lenp = ring.used->ring[head].len;
#endif
	datap = data[index].data;
	*bufp = (void*)(unsigned long)ring.desc[index].addr;
	data[index].data = NULL;
#ifndef INORDER
	ring.desc[index].next = guest.free_head;
	guest.free_head = index;
#endif
	guest.num_free++;
	guest.last_used_idx++;
	return datap;
}

bool used_empty()
{
	unsigned short last_used_idx = guest.last_used_idx;
#ifdef RING_POLL
	unsigned short head = last_used_idx & (ring_size - 1);
	unsigned index = ring.used->ring[head].id;

	return (index ^ last_used_idx ^ 0x8000) & ~(ring_size - 1);
#else
	return ring.used->idx == last_used_idx;
#endif
}

void disable_call()
{
	/* Doing nothing to disable calls might cause
	 * extra interrupts, but reduces the number of cache misses.
	 */
}

bool enable_call()
{
	vring_used_event(&ring) = guest.last_used_idx;
	/* Flush call index write */
	/* Barrier D (for pairing) */
	smp_mb();
	return used_empty();
}

void kick_available(void)
{
	bool need;

	/* Flush in previous flags write */
	/* Barrier C (for pairing) */
	smp_mb();
	need = vring_need_event(vring_avail_event(&ring),
				guest.avail_idx,
				guest.kicked_avail_idx);

	guest.kicked_avail_idx = guest.avail_idx;
	if (need)
		kick();
}

/* host side */
void disable_kick()
{
	/* Doing nothing to disable kicks might cause
	 * extra interrupts, but reduces the number of cache misses.
	 */
}

bool enable_kick()
{
	vring_avail_event(&ring) = host.used_idx;
	/* Barrier C (for pairing) */
	smp_mb();
	return avail_empty();
}

bool avail_empty()
{
	unsigned head = host.used_idx;
#ifdef RING_POLL
	unsigned index = ring.avail->ring[head & (ring_size - 1)];

	return ((index ^ head ^ 0x8000) & ~(ring_size - 1));
#else
	return head == ring.avail->idx;
#endif
}

bool use_buf(unsigned *lenp, void **bufp)
{
	unsigned used_idx = host.used_idx;
	struct vring_desc *desc;
	unsigned head;

#ifdef RING_POLL
	head = ring.avail->ring[used_idx & (ring_size - 1)];
	if ((used_idx ^ head ^ 0x8000) & ~(ring_size - 1))
		return false;
	/* Barrier A (for pairing) */
	smp_acquire();

	used_idx &= ring_size - 1;
	desc = &ring.desc[head & (ring_size - 1)];
#else
	if (used_idx == ring.avail->idx)
		return false;

	/* Barrier A (for pairing) */
	smp_acquire();

	used_idx &= ring_size - 1;
#ifdef INORDER
	head = used_idx;
#else
	head = ring.avail->ring[used_idx];
#endif
	desc = &ring.desc[head];
#endif

	*lenp = desc->len;
	*bufp = (void *)(unsigned long)desc->addr;

#ifdef INORDER
	desc->len = desc->len - 1;
#else
	/* now update used ring */
	ring.used->ring[used_idx].id = head;
	ring.used->ring[used_idx].len = desc->len - 1;
#endif
	/* Barrier B (for pairing) */
	smp_release();
	host.used_idx++;
	ring.used->idx = host.used_idx;
	
	return true;
}

void call_used(void)
{
	bool need;

	/* Flush in previous flags write */
	/* Barrier D (for pairing) */
	smp_mb();
	need = vring_need_event(vring_used_event(&ring),
				host.used_idx,
				host.called_used_idx);

	host.called_used_idx = host.used_idx;
	if (need)
		call();
}
