/*************************************************************************/ /*!
@File
@Title          Environment related functions
@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
@License        MIT

The contents of this file are subject to the MIT license as set out below.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

This License is also included in this distribution in the file called
"MIT-COPYING".

EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ /**************************************************************************/

#include <condition_variable>
#include <mutex>
#include <shared_mutex>
#include <thread>
#include <unordered_set>
#include <vector>

#include <lib/zx/event.h>
#include <zircon/syscalls.h>

#include "fuchsia/msd_img_connection.h"
#include "fuchsia/msd_img_device.h"
#include "fuchsia/msd_img_semaphore.h"
#include "magma_util/macros.h"
#include "platform_barriers.h"
#include "platform_bus_mapper.h"
#include "platform_semaphore.h"
#include "platform_thread.h"

extern "C" {
#include "allocmem.h"
#include "cache_km.h"
#include "img_types.h"
#include "log2.h"
#include "osfunc.h"
#include "osfunc_fuchsia.h"
#if defined(PVRSRV_ENABLE_PROCESS_STATS)
#include "process_stats.h"
#endif
#include "pvr_debug.h"
#include "pvrsrv_memallocflags.h"
}
#define NOT_IMPLEMENTED() fprintf(stderr, PVR_BUILD_DIR ": Not implemented in %s:%s:%d\n", __func__, __FILE__, __LINE__);

namespace msd_img
{

struct EventObject
{
	std::mutex mutex;
	std::condition_variable condition_variable;
	// wake_count is guarded by mutex, but clang's thread safety analysis
	// doesn't understand that.
	uint32_t wake_count = 0;

	// These are used to wake other processes.
	MAGMA_GUARDED(mutex) std::unordered_set<std::shared_ptr<MsdImgSemaphore>> semaphores;
};

struct EventObjectHandle
{
	static constexpr uint32_t kMagic = 'hEVT';

	static EventObjectHandle *FromHandle(IMG_HANDLE img_event_object)
	{
		auto event_object = reinterpret_cast<EventObjectHandle *>(img_event_object);
		assert(event_object->magic == kMagic);
		return event_object;
	}

	uint32_t magic = kMagic;
	std::shared_ptr<EventObject> object;
};

// This struct is used by a single thread to wait for a signal to happen.
struct EventObjectOpenHandle
{
	static constexpr uint32_t kMagic = 'hEVO';

	static EventObjectOpenHandle *FromHandle(IMG_HANDLE img_event_object)
	{
		auto event_object = reinterpret_cast<EventObjectOpenHandle *>(img_event_object);
		assert(event_object->magic == kMagic);
		return event_object;
	}

	~EventObjectOpenHandle()
	{
		if (semaphore)
		{
			std::lock_guard<std::mutex> lock(object->mutex);
			object->semaphores.erase(semaphore);
		}
	}

	uint32_t magic = kMagic;
	std::shared_ptr<EventObject> object;
	std::shared_ptr<MsdImgSemaphore> semaphore;

	// last_seen_wake_count is set to 0 on the new object, so the first wait
	// will succeed instantly if the object was ever signaled.
	uint32_t last_seen_wake_count = 0;
};

struct Thread
{
	static constexpr uint32_t kMagic = 'hThr';
	uint32_t magic = kMagic;
	~Thread()
	{
		if (running)
		{
			thrd_join(thread, 0);
		}
	}
	// Use C11 threads so we can get the thread handle to set the priority
	thrd_t thread = 0;
	bool running = false;
	std::string name;
	void *hData = nullptr;
	PFN_THREAD pfnThread = nullptr;

	static Thread *cast(IMG_HANDLE thr)
	{
		auto thread_ptr = static_cast<Thread *>(thr);
		assert(thread_ptr->magic == kMagic);

		return thread_ptr;
	}
};

struct PageWrapper
{
	static constexpr uint32_t kMagic = 'hPGS';
	uint32_t magic = kMagic;
	std::unique_ptr<magma::PlatformBuffer> buffer;
	std::unique_ptr<magma::PlatformBusMapper::BusMapping> mapping;

	static PageWrapper *FromHandle(PG_HANDLE *psMemHandle)
	{
		auto object = reinterpret_cast<PageWrapper *>(psMemHandle->u.pvHandle);
		DASSERT(object->magic == kMagic);
		return object;
	}
};

struct MisrHandle
{
	std::thread thread;
	// ZX_EVENT_SIGNALED is used to wake up, and ZX_USER_SIGNAL_0 is used to
	// force the handler to quit.
	zx::event event;
};


} // namespace msd_img

static PVRSRV_ERROR
ZxStatusToError(zx_status_t status)
{
	switch (status)
	{
		case ZX_OK: return PVRSRV_OK;
		case ZX_ERR_INTERNAL: return PVRSRV_ERROR_INTERNAL_ERROR;
		case ZX_ERR_NOT_SUPPORTED: return PVRSRV_ERROR_NOT_SUPPORTED;
		case ZX_ERR_NO_RESOURCES: return PVRSRV_ERROR_OUT_OF_MEMORY;
		case ZX_ERR_NO_MEMORY: return PVRSRV_ERROR_OUT_OF_MEMORY;
		case ZX_ERR_INVALID_ARGS: return PVRSRV_ERROR_INVALID_PARAMS;
		case ZX_ERR_BAD_HANDLE: return PVRSRV_ERROR_INVALID_HANDLE_TYPE;
		case ZX_ERR_OUT_OF_RANGE: return PVRSRV_ERROR_HANDLE_INDEX_OUT_OF_RANGE;
		case ZX_ERR_BUFFER_TOO_SMALL: return PVRSRV_ERROR_INVALID_PARAMS;
		case ZX_ERR_BAD_STATE: return PVRSRV_ERROR_INVALID_DEVICE;
		case ZX_ERR_TIMED_OUT: return PVRSRV_ERROR_TIMEOUT;
		case ZX_ERR_UNAVAILABLE: return PVRSRV_ERROR_INVALID_DEVICE;
		case ZX_ERR_ACCESS_DENIED: return PVRSRV_ERROR_INIT_FAILURE;
		default: return PVRSRV_ERROR_NOT_SUPPORTED;
	}
}


void
OSThreadDumpInfo(IMG_HANDLE hDbgReqestHandle, DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, void *pvDumpDebugFile)
{
}

PVRSRV_ERROR
OSPhyContigPagesAlloc(PVRSRV_DEVICE_NODE *psDevNode, size_t uiSize, PG_HANDLE *psMemHandle, IMG_DEV_PHYADDR *psDevPAddr)
{
	MsdImgDevice *device = MsdImgDevice::cast(psDevNode->psDevConfig->pvOSDevice);
	auto page_struct = std::make_unique<msd_img::PageWrapper>();
	page_struct->buffer = device->bus_mapper()->CreateContiguousBuffer(uiSize, magma::page_shift(), "IMG contig");
	if (!page_struct->buffer)
	{
		return DRET(PVRSRV_ERROR_OUT_OF_MEMORY);
	}
	page_struct->mapping = device->bus_mapper()->MapPageRangeBus(page_struct->buffer.get(), 0,
								     page_struct->buffer->size() / magma::page_size());
	if (!page_struct->mapping)
	{
		return DRET(PVRSRV_ERROR_OUT_OF_MEMORY);
	}
	psDevPAddr->uiAddr = page_struct->mapping->Get()[0];
	psMemHandle->u.pvHandle = page_struct.release();
	return PVRSRV_OK;
}
void
OSPhyContigPagesFree(PVRSRV_DEVICE_NODE *psDevNode, PG_HANDLE *psMemHandle)
{
	auto page_struct = msd_img::PageWrapper::FromHandle(psMemHandle);
	delete page_struct;
}

PVRSRV_ERROR
OSPhyContigPagesMap(PVRSRV_DEVICE_NODE *psDevNode,
		    PG_HANDLE *psMemHandle,
		    size_t uiSize,
		    IMG_DEV_PHYADDR *psDevPAddr,
		    void **pvPtr)
{
	auto page_struct = msd_img::PageWrapper::FromHandle(psMemHandle);

	if (!page_struct->buffer->MapCpu(pvPtr, 0))
	{
		return DRET(PVRSRV_ERROR_OUT_OF_MEMORY);
	}
	return PVRSRV_OK;
}

void
OSPhyContigPagesUnmap(PVRSRV_DEVICE_NODE *psDevNode, PG_HANDLE *psMemHandle, void *pvPtr)
{
	auto page_struct = msd_img::PageWrapper::FromHandle(psMemHandle);
	page_struct->buffer->UnmapCpu();
}

PVRSRV_ERROR
OSPhyContigPagesClean(PVRSRV_DEVICE_NODE *psDevNode, PG_HANDLE *psMemHandle, IMG_UINT32 uiOffset, IMG_UINT32 uiLength)
{
	auto page_struct = msd_img::PageWrapper::FromHandle(psMemHandle);
	if (!page_struct->buffer->CleanCache(uiOffset, uiLength, false))
	{
		return DRET(PVRSRV_ERROR_INVALID_PARAMS);
	}
	return PVRSRV_OK;
}

IMG_UINT32
OSCPUCacheAttributeSize(IMG_DCACHE_ATTRIBUTE eCacheAttribute)
{
        return zx_system_get_dcache_line_size();
}

IMG_UINT32
OSVSScanf(IMG_CHAR *pStr, const IMG_CHAR *pszFormat, ...)
{
        va_list args;
        va_start(args, pszFormat);
        uint32_t res = vsscanf(pStr, pszFormat, args);
        va_end(args);
        return res;
}

IMG_INT
OSMemCmp(void *pvBufA, void *pvBufB, size_t uiLen)
{
	return memcmp(pvBufA, pvBufB, uiLen);
}

size_t
OSStringLCopy(IMG_CHAR *pszDest, const IMG_CHAR *pszSrc, size_t uSize)
{
        return strlcpy(pszDest, pszSrc, uSize);
}

IMG_CHAR *
OSStringNCopy(IMG_CHAR *pszDest, const IMG_CHAR *pszSrc, size_t uSize)
{
        return strncpy(pszDest, pszSrc, uSize);
}

IMG_INT32
OSSNPrintf(IMG_CHAR *pStr, size_t ui32Size, const IMG_CHAR *pszFormat, ...)
{
        va_list args;
        va_start(args, pszFormat);
        int res = vsnprintf(pStr, ui32Size, pszFormat, args);
        va_end(args);
        return res;
}

size_t
OSStringLength(const IMG_CHAR *pStr)
{
        return strlen(pStr);
}

size_t
OSStringNLength(const IMG_CHAR *pStr, size_t uiCount)
{
        return strnlen(pStr, uiCount);
}

IMG_INT32
OSStringCompare(const IMG_CHAR *pStr1, const IMG_CHAR *pStr2)
{
        return strcmp(pStr1, pStr2);
}

IMG_INT32
OSStringNCompare(const IMG_CHAR *pStr1, const IMG_CHAR *pStr2, size_t uiSize)
{
        return strncmp(pStr1, pStr2, uiSize);
}

PVRSRV_ERROR
OSStringToUINT32(const IMG_CHAR *pStr, IMG_UINT32 ui32Base, IMG_UINT32 *ui32Result)
{
        *ui32Result = strtoul(pStr, nullptr, ui32Base);
	return PVRSRV_OK;
}

PVRSRV_ERROR
OSInitEnvData(void)
{
	return PVRSRV_OK;
}


void
OSDeInitEnvData(void)
{
	NOT_IMPLEMENTED();
}

#if defined(PVRSRV_USE_BRIDGE_LOCK)
PVRSRV_ERROR
OSGetGlobalBridgeBuffers(void **ppvBridgeInBuffer, void **ppvBridgeOutBuffer)
{
	NOT_IMPLEMENTED();
	return PVRSRV_OK;
}
#endif

void
OSReleaseThreadQuanta(void)
{
	std::this_thread::yield();
}

IMG_UINT64
OSClockns64(void)
{
	return zx_clock_get_monotonic();
}

IMG_UINT64
OSClockus64(void)
{
	return zx_clock_get_monotonic() / 1000;
}

IMG_UINT32
OSClockus(void)
{
	return zx_clock_get_monotonic() / 1000;
}

IMG_UINT32
OSClockms(void)
{
	return zx_clock_get_monotonic() / 1000000;
}


PVRSRV_ERROR
OSClockMonotonicns64(IMG_UINT64 *pui64Time)
{
	*pui64Time = zx_clock_get_monotonic();
	return PVRSRV_OK;
}

PVRSRV_ERROR
OSClockMonotonicus64(IMG_UINT64 *pui64Time)
{
	*pui64Time = zx_clock_get_monotonic() / 1000;
	return PVRSRV_OK;
}

IMG_UINT64
OSClockMonotonicRawns64(void)
{
	return zx_clock_get_monotonic();
}

IMG_UINT64
OSClockMonotonicRawus64(void)
{
	return zx_clock_get_monotonic() / 1000;
}

void
OSWaitus(IMG_UINT32 ui32Timeus)
{
        // We don't have to worry about interrupt contexts or anything like that, so it's reasonable
        // to sleep if the desired delay is long enough. 50 microseconds is a reasonable guess about
        // how long is enough time for another thread to do some useful work after being scheduled
        // in.
	if (ui32Timeus > 50)
	{
		zx_nanosleep(zx_deadline_after(ZX_USEC(ui32Timeus)));
	}
	else
	{
		uint64_t start = OSClockus64();
		while (OSClockus64() - start < ui32Timeus)
		{
#if defined(__aarch64__)
			__asm__ __volatile__("yield");
#endif
		}
	}
}

void
OSSleepms(IMG_UINT32 ui32Timems)
{
	zx_nanosleep(zx_deadline_after(ZX_MSEC(ui32Timems)));
}


IMG_UINT64
OSGetCurrentProcessVASpaceSize(void)
{
	// Currently every process on Fuchsia has the same VA space size.
	return magma::PlatformBuffer::MinimumMappableAddress() + magma::PlatformBuffer::MappableAddressRegionLength();
}

IMG_PID
OSGetCurrentProcessID(void)
{
	return magma::PlatformProcessHelper::GetCurrentProcessId();
}

IMG_CHAR *
OSGetCurrentProcessName(void)
{
	return OSGetCurrentClientProcessNameKM();
}

uintptr_t
OSGetCurrentThreadID(void)
{
	NOT_IMPLEMENTED();
	return 0;
}

IMG_PID
OSGetCurrentClientProcessIDKM(void)
{
	MsdImgConnection *connection = MsdImgConnection::GetCurrentConnection();
	// Some statistics will check for the process id on startup when there
	// is no current connection.
	if (!connection)
		return 0;
	return connection->client_id();
}

IMG_CHAR *
OSGetCurrentClientProcessNameKM(void)
{
	static char msd_name[] = "MSD";
	MsdImgConnection *connection = MsdImgConnection::GetCurrentConnection();
	// If there's no connection the current action is on the behalf of the
	// MSD.
	return connection ? connection->client_name() : msd_name;
}

uintptr_t
OSGetCurrentClientThreadIDKM(void)
{
	MsdImgConnection *connection = MsdImgConnection::GetCurrentConnection();
	// This is used only for debug logging, so it doesn't matter if it doesn't
	// exist.
	if (!connection)
		return 0;
	return connection->current_client_thread_id();
}

size_t
OSGetPageSize(void)
{
        return magma::page_size();
}

size_t
OSGetPageShift(void)
{
        return magma::page_shift();
}

size_t
OSGetPageMask(void)
{
        // Lower bits set.
        return magma::page_size() - 1;
}

size_t
OSGetOrder(size_t uSize)
{
	NOT_IMPLEMENTED();
	return 0;
}

IMG_UINT64
OSGetRAMSize(void)
{
	return zx_system_get_physmem();
}


int
PVRSRVToNativeError(PVRSRV_ERROR e)
{
	NOT_IMPLEMENTED();
	return 0;
}

PVRSRV_ERROR
OSInstallMISR(IMG_HANDLE *hMISRData, PFN_MISR pfnMISR, void *hData)
{
	auto misr_handle = std::make_unique<msd_img::MisrHandle>();
	zx_status_t status = zx::event::create(0, &misr_handle->event);
	if (status != ZX_OK)
	{
		return ZxStatusToError(status);
	}
	misr_handle->thread = std::thread(
		[](PFN_MISR pfnMISR, void *hData, msd_img::MisrHandle *misr_handle) {
			magma::PlatformThreadHelper::SetCurrentThreadName("MISR Thread");
#if !defined(NO_HARDWARE)
			std::unique_ptr<magma::PlatformHandle> profile =
				MsdImgDevice::GetGlobalDevice()->platform_device()->GetSchedulerProfile(
					magma::PlatformDevice::kPriorityHighest, "img-priority");

			magma::PlatformThreadHelper::SetProfile(profile.get());
#endif // defined(NO_HARDWARE)
			while (true)
			{
				zx_signals_t observed;
				zx_status_t status = misr_handle->event.wait_one(ZX_EVENT_SIGNALED | ZX_USER_SIGNAL_0,
										 zx::time::infinite(), &observed);
				if (status != ZX_OK)
				{
					DLOG("Failed to wait on MISR handle");
					return;
				}
				// Clear before running the callback to ensure a signal during the
				// callback won't be ignored.
				status = misr_handle->event.signal(ZX_EVENT_SIGNALED, 0);
				if (status != ZX_OK)
				{
					DLOG("Failed clear MISR handle");
					return;
				}
				if (observed & ZX_USER_SIGNAL_0)
					break;
				pfnMISR(hData);
			}
		},
		pfnMISR, hData, misr_handle.get());
	*hMISRData = misr_handle.release();
	return PVRSRV_OK;
}

PVRSRV_ERROR
OSUninstallMISR(IMG_HANDLE hMISRData)
{
	auto misr_handle = reinterpret_cast<msd_img::MisrHandle *>(hMISRData);
	if (misr_handle->event.signal(0, ZX_USER_SIGNAL_0) != ZX_OK)
	{
		DLOG("Failed to signal MISR on shutdown");
		misr_handle->thread.detach();
	}
	else
	{
		misr_handle->thread.join();
	}
	delete misr_handle;
	return PVRSRV_OK;
}

PVRSRV_ERROR
OSScheduleMISR(IMG_HANDLE hMISRData)
{
	auto misr_handle = reinterpret_cast<msd_img::MisrHandle *>(hMISRData);
	return ZxStatusToError(misr_handle->event.signal(0, ZX_EVENT_SIGNALED));
}

PVRSRV_ERROR
OSThreadCreate(IMG_HANDLE *phThread,
	       IMG_CHAR *pszThreadName,
	       PFN_THREAD pfnThread,
	       IMG_HANDLE pfnDebugDumpCB,
	       IMG_BOOL bIsSupportingThread,
	       void *hData)
{
	return OSThreadCreatePriority(phThread, pszThreadName, pfnThread, pfnDebugDumpCB, bIsSupportingThread, hData,
				      OS_THREAD_NOSET_PRIORITY);
}

namespace
{
int
thread_func(void *data)
{
	msd_img::Thread *handle = msd_img::Thread::cast(data);
	magma::PlatformThreadHelper::SetCurrentThreadName(handle->name);
	handle->pfnThread(handle->hData);
	return 0;
}
} // namespace

PVRSRV_ERROR
OSThreadCreatePriority(IMG_HANDLE *phThread,
		       IMG_CHAR *pszThreadName,
		       PFN_THREAD pfnThread,
		       IMG_HANDLE pfnDebugDumpCB,
		       IMG_BOOL bIsSupportingThread,
		       void *hData,
		       OS_THREAD_LEVEL eThreadPriority)
{
	auto handle = std::make_unique<msd_img::Thread>();
	handle->name = std::string(pszThreadName);
	handle->hData = hData;
	handle->pfnThread = pfnThread;
	int res = thrd_create(&handle->thread, thread_func, handle.get());
	if (res != thrd_success)
	{
		return PVRSRV_ERROR_INIT_FAILURE;
	}
	handle->running = true;
	*phThread = handle.release();
	if (eThreadPriority != OS_THREAD_NOSET_PRIORITY)
	{
		return OSSetThreadPriority(*phThread, eThreadPriority, 0);
	}
	return PVRSRV_OK;
}

PVRSRV_ERROR
OSThreadDestroy(IMG_HANDLE hThread)
{
	msd_img::Thread *handle = msd_img::Thread::cast(hThread);
	delete handle;
	return PVRSRV_OK;
}

void
OSPanic(void)
{
	NOT_IMPLEMENTED();
}

magma::PlatformDevice::Priority
OSThreadToMagmaPriority(IMG_UINT32 nThreadPriority)
{
	switch (nThreadPriority)
	{
		case OS_THREAD_HIGHEST_PRIORITY:
		case OS_THREAD_HIGH_PRIORITY:
			// TODO - Reduce priority of high.
			return magma::PlatformDevice::kPriorityHighest;
		case OS_THREAD_LOWEST_PRIORITY: return magma::PlatformDevice::kPriorityLowest;
		case OS_THREAD_LOW_PRIORITY: return magma::PlatformDevice::kPriorityLow;

		case OS_THREAD_NOSET_PRIORITY:
		case OS_THREAD_NORMAL_PRIORITY:
		default: return magma::PlatformDevice::kPriorityDefault;
	}
}

PVRSRV_ERROR
OSSetThreadPriority(IMG_HANDLE hThread, IMG_UINT32 nThreadPriority, IMG_UINT32 nThreadWeight)
{
	msd_img::Thread *handle = msd_img::Thread::cast(hThread);

#if defined(NO_HARDWARE)
	// With no hardware there's no platform device to read the profile
	// from.
	return PVRSRV_OK;
#endif
	std::unique_ptr<magma::PlatformHandle> profile =
		MsdImgDevice::GetGlobalDevice()->platform_device()->GetSchedulerProfile(
			OSThreadToMagmaPriority(nThreadPriority), "img-priority");
	if (!profile)
	{
		return PVRSRV_ERROR_INIT_FAILURE;
	}
	return magma::PlatformThreadHelper::SetThreadProfile(handle->thread, profile.get()) ? PVRSRV_OK
											    : PVRSRV_ERROR_INIT_FAILURE;
}

void *
OSMapPhysToLin(IMG_CPU_PHYADDR BasePAddr, size_t ui32Bytes, IMG_UINT32 ui32MappingFlags)
{
	if (BasePAddr.uiAddr == MsdImgDevice::GetRegistersPhysicalAddress())
	{
		return MsdImgDevice::GetRegistersCpuAddress();
	}

	NOT_IMPLEMENTED();
	return nullptr;
}


IMG_BOOL
OSUnMapPhysToLin(void *pvLinAddr, size_t ui32Bytes, IMG_UINT32 ui32MappingFlags)
{
	NOT_IMPLEMENTED();
	return IMG_FALSE;
}

IMG_HANDLE
OSAddTimer(PFN_TIMER_FUNC pfnTimerFunc, void *pvData, IMG_UINT32 ui32MsTimeout)
{
	NOT_IMPLEMENTED();
	return 0;
}



PVRSRV_ERROR
OSRemoveTimer(IMG_HANDLE hTimer)
{
	NOT_IMPLEMENTED();
	return PVRSRV_ERROR_NOT_SUPPORTED;
}

PVRSRV_ERROR
OSEnableTimer(IMG_HANDLE hTimer)
{
	NOT_IMPLEMENTED();
	return PVRSRV_ERROR_NOT_SUPPORTED;
}


PVRSRV_ERROR
OSDisableTimer(IMG_HANDLE hTimer)
{
	NOT_IMPLEMENTED();
	return PVRSRV_ERROR_NOT_SUPPORTED;
}

PVRSRV_ERROR
OSEventObjectCreate(const IMG_CHAR *pszName, IMG_HANDLE *hEventObject)
{
	auto handle = std::make_unique<msd_img::EventObjectHandle>();
	handle->object = std::make_shared<msd_img::EventObject>();
	*hEventObject = handle.release();
	return PVRSRV_OK;
}


PVRSRV_ERROR
OSEventObjectDestroy(IMG_HANDLE hEventObject)
{
	delete msd_img::EventObjectHandle::FromHandle(hEventObject);
	return PVRSRV_OK;
}

PVRSRV_ERROR
OSEventObjectWait(IMG_HANDLE hOSEventKM)
{
	auto handle = msd_img::EventObjectOpenHandle::FromHandle(hOSEventKM);
	std::unique_lock<std::mutex> lock(handle->object->mutex);
	handle->object->condition_variable.wait(
		lock, [&handle]() { return handle->object->wake_count != handle->last_seen_wake_count; });
	handle->last_seen_wake_count = handle->object->wake_count;
	return PVRSRV_OK;
}

PVRSRV_ERROR
OSEventObjectWaitTimeoutAndHoldBridgeLock(IMG_HANDLE hOSEventKM, IMG_UINT64 uiTimeoutus)
{
#if defined(PVRSRV_USE_BRIDGE_LOCK)
#error Bridge lock not supported
#endif
	return OSEventObjectWaitTimeout(hOSEventKM, uiTimeoutus);
}

PVRSRV_ERROR
OSEventObjectWaitAndHoldBridgeLock(IMG_HANDLE hOSEventKM)
{
#if defined(PVRSRV_USE_BRIDGE_LOCK)
#error Bridge lock not supported
#endif
	return OSEventObjectWait(hOSEventKM);
}

PVRSRV_ERROR
OSEventObjectWaitKernel(IMG_HANDLE hOSEventKM, IMG_UINT64 uiTimeoutus)
{
	auto handle = msd_img::EventObjectOpenHandle::FromHandle(hOSEventKM);
	std::unique_lock<std::mutex> lock(handle->object->mutex);
	auto timeout_time = std::chrono::steady_clock::now() + std::chrono::microseconds(uiTimeoutus);
	if (!handle->object->condition_variable.wait_until(
		    lock, timeout_time, [&handle]() { return handle->object->wake_count != handle->last_seen_wake_count; }))
	{
		DASSERT(handle->last_seen_wake_count == handle->object->wake_count);
		return PVRSRV_ERROR_TIMEOUT;
	}
	handle->last_seen_wake_count = handle->object->wake_count;
	return PVRSRV_OK;
}
PVRSRV_ERROR
OSEventObjectOpenWithConnection(IMG_HANDLE hEventObject, MsdImgConnection *connection, IMG_HANDLE *phOSEvent)
{

	auto event_object = msd_img::EventObjectHandle::FromHandle(hEventObject);
	auto event_object_open = std::make_unique<msd_img::EventObjectOpenHandle>();
	event_object_open->object = event_object->object;
	std::shared_ptr<MsdImgSemaphore> semaphore = connection ? connection->TakeAdditionalSemaphore() : nullptr;
	if (semaphore)
	{
		event_object_open->semaphore = semaphore;
		std::lock_guard<std::mutex> lock(event_object_open->object->mutex);
		event_object_open->object->semaphores.insert(semaphore);
		// Just be sure we don't barely miss a signal. Waiters should be able
		// to handle spurious wakeups.
		semaphore->platform_semaphore()->Signal();
	}

	*phOSEvent = event_object_open.release();
	return PVRSRV_OK;
}

PVRSRV_ERROR
OSEventObjectOpen(IMG_HANDLE hEventObject, IMG_HANDLE *phOSEvent)
{
	MsdImgConnection *connection = MsdImgConnection::GetCurrentConnection();
	return OSEventObjectOpenWithConnection(hEventObject, connection, phOSEvent);
}

PVRSRV_ERROR
OSEventObjectClose(IMG_HANDLE hOSEventKM)
{
	delete msd_img::EventObjectOpenHandle::FromHandle(hOSEventKM);
	return PVRSRV_OK;
}

PVRSRV_ERROR
OSEventObjectSignal(IMG_HANDLE hEventObject)
{
	auto handle = msd_img::EventObjectHandle::FromHandle(hEventObject);
	std::lock_guard<std::mutex> lock(handle->object->mutex);
	handle->object->wake_count++;
	handle->object->condition_variable.notify_all();
	for (auto &semaphore : handle->object->semaphores)
	{
		semaphore->platform_semaphore()->Signal();
	}
	return PVRSRV_OK;
}

PVRSRV_ERROR
OSCopyToUser(void *pvProcess, void __user *pvDest, const void *pvSrc, size_t ui32Bytes)
{
	PVR_UNREFERENCED_PARAMETER(pvProcess);

	// We would use pvProcess for this, but the generated code always sets it to
	// NULL.
	MsdImgConnection *connection = MsdImgConnection::GetCurrentConnection();
	return connection->CopyToUser(pvDest, pvSrc, ui32Bytes) ? PVRSRV_OK : PVRSRV_ERROR_INVALID_PARAMS;
}

PVRSRV_ERROR
OSCopyFromUser(void *pvProcess, void *pvDest, const void __user *pvSrc, size_t ui32Bytes)
{
	PVR_UNREFERENCED_PARAMETER(pvProcess);

	// We would use pvProcess for this, but the generated code always sets it to
	// NULL.
	MsdImgConnection *connection = MsdImgConnection::GetCurrentConnection();
	return connection->CopyFromUser(pvDest, pvSrc, ui32Bytes) ? PVRSRV_OK : PVRSRV_ERROR_INVALID_PARAMS;
}

IMG_UINT64
OSDivide64r64(IMG_UINT64 ui64Divident, IMG_UINT32 ui32Divisor, IMG_UINT32 *pui32Remainder)
{
	*pui32Remainder = ui64Divident % ui32Divisor;
	return ui64Divident / ui32Divisor;
}

IMG_UINT32
OSDivide64(IMG_UINT64 ui64Divident, IMG_UINT32 ui32Divisor, IMG_UINT32 *pui32Remainder)
{
	*pui32Remainder = ui64Divident % ui32Divisor;
	return ui64Divident / ui32Divisor;
}

/* One time osfunc initialisation */
PVRSRV_ERROR
PVROSFuncInit(void)
{
	NOT_IMPLEMENTED();
	return PVRSRV_ERROR_NOT_SUPPORTED;
}

/*
 * Osfunc deinitialisation.
 * Note that PVROSFuncInit may not have been called
 */
void
PVROSFuncDeInit(void)
{
	NOT_IMPLEMENTED();
}

void
OSDumpStack(void)
{
	NOT_IMPLEMENTED();
}

#if defined(PVRSRV_USE_BRIDGE_LOCK)


void
OSAcquireBridgeLock(void)
{
	NOT_IMPLEMENTED();
}

void
OSReleaseBridgeLock(void)
{
	NOT_IMPLEMENTED();
}


IMG_BOOL
BridgeLockIsLocked(void)
{
	NOT_IMPLEMENTED();
	return 0;
}

#endif

struct StatisticEntry
{
	uint32_t unused;
};

void *
OSCreateStatisticEntry(IMG_CHAR *pszName,
		       void *pvFolder,
		       OS_STATS_PRINT_FUNC *pfnStatsPrint,
		       OS_INC_STATS_MEM_REFCOUNT_FUNC *pfnIncMemRefCt,
		       OS_DEC_STATS_MEM_REFCOUNT_FUNC *pfnDecMemRefCt,
		       void *pvData)
{
	// TODO(fxbug.dev/13185): Implement.
	NOT_IMPLEMENTED();
	return new StatisticEntry;
}

void
OSRemoveStatisticEntry(void *pvEntry)
{
	delete reinterpret_cast<StatisticEntry *>(pvEntry);
}

#if defined(PVRSRV_ENABLE_MEMTRACK_STATS_FILE)
void *
OSCreateRawStatisticEntry(const IMG_CHAR *pszFileName, void *pvParentDir, OS_STATS_PRINT_FUNC *pfStatsPrint)
{
	NOT_IMPLEMENTED();
	return 0;
}

void
OSRemoveRawStatisticEntry(void *pvEntry)
{
	NOT_IMPLEMENTED();
}
#endif

/*************************************************************************/ /*!
@Function		OSCreateStatisticFolder
@Description	Create a statistic folder to hold statistic entries.
@Input			pszName   String containing the name for the folder.
@Input			pvFolder  Reference from OSCreateStatisticFolder() of the folder
						  to create the folder in, or NULL for the root.
@Return			Pointer void reference to the folder created, which can be
				passed to OSRemoveStatisticFolder() to remove the folder.
*/ /**************************************************************************/
void *
OSCreateStatisticFolder(IMG_CHAR *pszName, void *pvFolder)
{
	NOT_IMPLEMENTED();
	return 0;
} /* OSCreateStatisticFolder */


/*************************************************************************/ /*!
@Function		OSRemoveStatisticFolder
@Description	Removes a statistic folder.
@Input          ppvFolder  Reference from OSCreateStatisticFolder() of the
                           folder that should be removed.
                           This needs to be double pointer because it has to
                           be NULLed right after memory is freed to avoid
                           possible races and use-after-free situations.
*/ /**************************************************************************/
void
OSRemoveStatisticFolder(void **ppvFolder)
{
	NOT_IMPLEMENTED();
} /* OSRemoveStatisticFolder */


PVRSRV_ERROR
OSChangeSparseMemCPUAddrMap(void **psPageArray,
			    IMG_UINT64 sCpuVAddrBase,
			    IMG_CPU_PHYADDR sCpuPAHeapBase,
			    IMG_UINT32 ui32AllocPageCount,
			    IMG_UINT32 *pai32AllocIndices,
			    IMG_UINT32 ui32FreePageCount,
			    IMG_UINT32 *pai32FreeIndices,
			    IMG_BOOL bIsLMA)
{
	NOT_IMPLEMENTED();
	return PVRSRV_ERROR_NOT_SUPPORTED;
}

/*************************************************************************/ /*!
@Function       OSDebugSignalPID
@Description    Sends a SIGTRAP signal to a specific PID in user mode for
                debugging purposes. The user mode process can register a handler
                against this signal.
                This is necessary to support the Rogue debugger. If the Rogue
                debugger is not used then this function may be implemented as
                a stub.
@Input          ui32PID    The PID for the signal.
@Return         PVRSRV_OK on success, a failure code otherwise.
*/ /**************************************************************************/
PVRSRV_ERROR
OSDebugSignalPID(IMG_UINT32 ui32PID)
{
	NOT_IMPLEMENTED();
	return PVRSRV_ERROR_NOT_SUPPORTED;
}

void
OSDumpVersionInfo(DUMPDEBUG_PRINTF_FUNC *pfnDumpDebugPrintf, void *pvDumpDebugFile)
{
	NOT_IMPLEMENTED();
}

void
OSWriteMemoryBarrier(void)
{
	magma::barriers::WriteBarrier();
}

void
OSMemoryBarrier(void)
{
	magma::barriers::Barrier();
}

struct _OSWR_LOCK_ {
	std::shared_mutex mutex;
};
PVRSRV_ERROR OSWRLockCreate(POSWR_LOCK *ppsLock) {
	*ppsLock = new _OSWR_LOCK_;
	return PVRSRV_OK;
}
void OSWRLockDestroy(POSWR_LOCK psLock) {
	delete psLock;
}
void OSWRLockAcquireRead(POSWR_LOCK psLock) {
	psLock->mutex.lock_shared();
}
void OSWRLockReleaseRead(POSWR_LOCK psLock) {
	psLock->mutex.unlock_shared();
}
void OSWRLockAcquireWrite(POSWR_LOCK psLock) {
	psLock->mutex.lock();
}
void OSWRLockReleaseWrite(POSWR_LOCK psLock) {
	psLock->mutex.unlock();
}

PVRSRV_ERROR
OSBridgeCopyFromUser(void *pvProcess, void *pvDest, const void *pvSrc, size_t ui32Bytes)
{
	// pvSrv should be in the mapped payload buffer. The size of the buffer was
	// validated when the bridge command was started.
	memcpy(pvDest, pvSrc, ui32Bytes);
	return PVRSRV_OK;
}

PVRSRV_ERROR
OSBridgeCopyToUser(void *pvProcess, void *pvDest, const void *pvSrc, size_t ui32Bytes)
{
	// pvDest should be in the mapped payload buffer. The size of the buffer was
	// validated when the bridge command was started.
	memcpy(pvDest, pvSrc, ui32Bytes);
	return PVRSRV_OK;
}

#if !defined(NO_HARDWARE)
// If NO_HARDWARE is defined these are replace with no-op macros.

// The memory barriers in the following functions don't seem to necessarily be
// required by the definitions of the methods, but we have them to match linux
// in case they happen to matter.
IMG_UINT8
OSReadHWReg8(volatile void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset)
{
	uint8_t value = *(reinterpret_cast<volatile uint8_t *>(pvLinRegBaseAddr) + ui32Offset);
	magma::barriers::ReadBarrier();
	return value;
}

IMG_UINT16
OSReadHWReg16(volatile void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset)
{
	uint16_t value =
		*reinterpret_cast<volatile uint16_t *>(reinterpret_cast<volatile uint8_t *>(pvLinRegBaseAddr) + ui32Offset);
	magma::barriers::ReadBarrier();
	return value;
}

IMG_UINT32
OSReadHWReg32(volatile void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset)
{
	uint32_t value =
		*reinterpret_cast<volatile uint32_t *>(reinterpret_cast<volatile uint8_t *>(pvLinRegBaseAddr) + ui32Offset);
	magma::barriers::ReadBarrier();
	return value;
}

IMG_UINT64
OSReadHWReg64(volatile void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset)
{
	auto first_reg = reinterpret_cast<volatile uint32_t *>(reinterpret_cast<uintptr_t>(pvLinRegBaseAddr) + ui32Offset);
	uint64_t value = first_reg[0] | (static_cast<uint64_t>(first_reg[1]) << 32);
	magma::barriers::ReadBarrier();
	return value;
}


void
OSWriteHWReg8(volatile void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT8 ui8Value)
{
	magma::barriers::WriteBarrier();
	*(reinterpret_cast<volatile uint8_t *>(pvLinRegBaseAddr) + ui32Offset) = ui8Value;
}

void
OSWriteHWReg16(volatile void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT16 ui16Value)
{
	magma::barriers::WriteBarrier();
	*reinterpret_cast<volatile uint16_t *>(reinterpret_cast<volatile uint8_t *>(pvLinRegBaseAddr) + ui32Offset) =
		ui16Value;
}

void
OSWriteHWReg32(volatile void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value)
{
	magma::barriers::WriteBarrier();
	*reinterpret_cast<volatile uint32_t *>(reinterpret_cast<volatile uint8_t *>(pvLinRegBaseAddr) + ui32Offset) =
		ui32Value;
}

void
OSWriteHWReg64(volatile void *pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT64 ui64Value)
{
	magma::barriers::WriteBarrier();
	auto first_reg = reinterpret_cast<volatile uint32_t *>(reinterpret_cast<uintptr_t>(pvLinRegBaseAddr) + ui32Offset);
	first_reg[0] = ui64Value & 0xffffffff;
	first_reg[1] = (ui64Value >> 32) & 0xffffffff;
}

#endif
