/** @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.

  SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "XenBusDxe.h"

#include <IndustryStandard/Xen/memory.h>

#include <Library/XenHypercallLib.h>
#include <Library/SynchronizationLib.h>

#include "GrantTable.h"

#define NR_RESERVED_ENTRIES  8

#define NR_GRANT_FRAMES   (FixedPcdGet32 (PcdXenGrantFrames))
#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 ((DEBUG_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 ((
        DEBUG_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 ((
      DEBUG_INFO,
      "Xen GrantTable, removing %Lx\n",
      (UINT64)Parameters.gpfn
      ));
    ReturnCode = XenHypercallMemoryOp (XENMEM_remove_from_physmap, &Parameters);
    if (ReturnCode != 0) {
      DEBUG ((
        DEBUG_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);
}
