/** @file
  Grant Table function implementation.

  Grant Table are used to grant access to certain page of the current
  VM to an other VM.

  Author: Steven Smith (sos22@cam.ac.uk)
  Changes: Grzegorz Milos (gm281@cam.ac.uk)
  Copyright (C) 2006, Cambridge University
  Copyright (C) 2014, Citrix Ltd.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions
  are met:
  1. Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in the
     documentation and/or other materials provided with the distribution.

  THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  SUCH DAMAGE.
**/
#include "XenBusDxe.h"

#include <IndustryStandard/Xen/memory.h>

#include <Library/XenHypercallLib.h>
#include <Library/SynchronizationLib.h>

#include "GrantTable.h"

#define NR_RESERVED_ENTRIES 8

/* NR_GRANT_FRAMES must be less than or equal to that configured in Xen */
#define NR_GRANT_FRAMES 4
#define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * EFI_PAGE_SIZE / sizeof(grant_entry_v1_t))

STATIC grant_entry_v1_t *GrantTable = NULL;
STATIC grant_ref_t GrantList[NR_GRANT_ENTRIES];
STATIC EFI_LOCK mGrantListLock;
#ifdef GNT_DEBUG
STATIC BOOLEAN GrantInUseList[NR_GRANT_ENTRIES];
#endif

STATIC
VOID
XenGrantTablePutFreeEntry (
  grant_ref_t Ref
  )
{
  EfiAcquireLock (&mGrantListLock);
#ifdef GNT_DEBUG
  ASSERT (GrantInUseList[Ref]);
  GrantInUseList[Ref] = FALSE;
#endif
  GrantList[Ref] = GrantList[0];
  GrantList[0] = Ref;
  EfiReleaseLock (&mGrantListLock);
}

STATIC
grant_ref_t
XenGrantTableGetFreeEntry (
  VOID
  )
{
  grant_ref_t Ref;

  EfiAcquireLock (&mGrantListLock);
  Ref = GrantList[0];
  ASSERT (Ref >= NR_RESERVED_ENTRIES && Ref < NR_GRANT_ENTRIES);
  GrantList[0] = GrantList[Ref];
#ifdef GNT_DEBUG
  ASSERT (!GrantInUseList[Ref]);
  GrantInUseList[Ref] = TRUE;
#endif
  EfiReleaseLock (&mGrantListLock);
  return Ref;
}

STATIC
grant_ref_t
XenGrantTableGrantAccess (
  IN domid_t  DomainId,
  IN UINTN    Frame,
  IN BOOLEAN  ReadOnly
  )
{
  grant_ref_t Ref;
  UINT16 Flags;

  ASSERT (GrantTable != NULL);
  Ref = XenGrantTableGetFreeEntry ();
  GrantTable[Ref].frame = (UINT32)Frame;
  GrantTable[Ref].domid = DomainId;
  MemoryFence ();
  Flags = GTF_permit_access;
  if (ReadOnly) {
    Flags |= GTF_readonly;
  }
  GrantTable[Ref].flags = Flags;

  return Ref;
}

STATIC
EFI_STATUS
XenGrantTableEndAccess (
  grant_ref_t Ref
  )
{
  UINT16 Flags, OldFlags;

  ASSERT (GrantTable != NULL);
  ASSERT (Ref >= NR_RESERVED_ENTRIES && Ref < NR_GRANT_ENTRIES);

  OldFlags = GrantTable[Ref].flags;
  do {
    if ((Flags = OldFlags) & (GTF_reading | GTF_writing)) {
      DEBUG ((EFI_D_WARN, "WARNING: g.e. still in use! (%x)\n", Flags));
      return EFI_NOT_READY;
    }
    OldFlags = InterlockedCompareExchange16 (&GrantTable[Ref].flags, Flags, 0);
  } while (OldFlags != Flags);

  XenGrantTablePutFreeEntry (Ref);
  return EFI_SUCCESS;
}

VOID
XenGrantTableInit (
  IN XENBUS_DEVICE  *Dev
  )
{
  xen_add_to_physmap_t Parameters;
  INTN Index;
  INTN ReturnCode;

#ifdef GNT_DEBUG
  SetMem(GrantInUseList, sizeof (GrantInUseList), 1);
#endif
  EfiInitializeLock (&mGrantListLock, TPL_NOTIFY);
  for (Index = NR_RESERVED_ENTRIES; Index < NR_GRANT_ENTRIES; Index++) {
    XenGrantTablePutFreeEntry ((grant_ref_t)Index);
  }

  GrantTable = (VOID*)(UINTN) Dev->XenIo->GrantTableAddress;
  for (Index = 0; Index < NR_GRANT_FRAMES; Index++) {
    Parameters.domid = DOMID_SELF;
    Parameters.idx = Index;
    Parameters.space = XENMAPSPACE_grant_table;
    Parameters.gpfn = (xen_pfn_t) ((UINTN) GrantTable >> EFI_PAGE_SHIFT) + Index;
    ReturnCode = XenHypercallMemoryOp (XENMEM_add_to_physmap, &Parameters);
    if (ReturnCode != 0) {
      DEBUG ((EFI_D_ERROR,
        "Xen GrantTable, add_to_physmap hypercall error: %Ld\n",
        (INT64)ReturnCode));
    }
  }
}

VOID
XenGrantTableDeinit (
  XENBUS_DEVICE *Dev
  )
{
  INTN ReturnCode, Index;
  xen_remove_from_physmap_t Parameters;

  if (GrantTable == NULL) {
    return;
  }

  for (Index = NR_GRANT_FRAMES - 1; Index >= 0; Index--) {
    Parameters.domid = DOMID_SELF;
    Parameters.gpfn = (xen_pfn_t) ((UINTN) GrantTable >> EFI_PAGE_SHIFT) + Index;
    DEBUG ((EFI_D_INFO, "Xen GrantTable, removing %Lx\n",
      (UINT64)Parameters.gpfn));
    ReturnCode = XenHypercallMemoryOp (XENMEM_remove_from_physmap, &Parameters);
    if (ReturnCode != 0) {
      DEBUG ((EFI_D_ERROR,
        "Xen GrantTable, remove_from_physmap hypercall error: %Ld\n",
        (INT64)ReturnCode));
    }
  }
  GrantTable = NULL;
}

EFI_STATUS
EFIAPI
XenBusGrantAccess (
  IN  XENBUS_PROTOCOL *This,
  IN  domid_t         DomainId,
  IN  UINTN           Frame, // MFN
  IN  BOOLEAN         ReadOnly,
  OUT grant_ref_t     *RefPtr
  )
{
  *RefPtr = XenGrantTableGrantAccess (DomainId, Frame, ReadOnly);
  return EFI_SUCCESS;
}

EFI_STATUS
EFIAPI
XenBusGrantEndAccess (
  IN XENBUS_PROTOCOL  *This,
  IN grant_ref_t      Ref
  )
{
  return XenGrantTableEndAccess (Ref);
}
