/*
 * Copyright (C) 2022 Apple Inc. All rights reserved.
 *
 * This document is the property of Apple Inc.
 * It is considered confidential and proprietary.
 *
 * This document may not be reproduced or transmitted in any form,
 * in whole or in part, without the express written permission of
 * Apple Inc.
 */

#pragma once

#include <platform/platform.h>

/* xnu upcall handlers are identfied via badge from unwrapped endpoint
 * cap sent in this CR */
#define XNUPROXY_UPCALL_REQUEST_ENDPOINT(b) (L4_IpcBuffer()->scr[0])

/* Extract xnuproxy_upcalls_t identifer from badge value */
#define XNUPROXY_UPCALL_REQUEST_ENDPOINT_ID(badge) (((badge) >> 16) & 0xff)
#define XNUPROXY_UPCALL_REQUEST_ENDPOINT_VALID(badge) (((badge) & 0xffff) == 0xca11)

static inline L4_Error_t
xnuproxy_upcall_request(
	L4_Cap_t xnuproxy_endpoint,
	L4_Cap_t upcall_endpoint,
	L4_MessageTag_t *tag
) {
	L4_MessageTag_t data_tag = L4_MessageTag(
		L4_MessageTag_Mrs(*tag),
		1,
		L4_MessageTag_Label(*tag),
		L4_False
	);

	/* Pass the upcall endpoint to be unwrapped */
	L4_SetCr(0, upcall_endpoint, L4_False);
	L4_Error_t error = L4_Endpoint_call(xnuproxy_endpoint, &data_tag);

	/* Return the result of the call */
	*tag = data_tag;
	return error;
}
