/*
 * Copyright (c) 2015 Apple Inc. All rights reserved.
 *
 * @APPLE_APACHE_LICENSE_HEADER_START@
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @APPLE_APACHE_LICENSE_HEADER_END@
 */

#ifndef __FIREHOSE_BUFFER_PRIVATE__
#define __FIREHOSE_BUFFER_PRIVATE__

#if OS_FIREHOSE_SPI
#ifdef KERNEL
#include <stdint.h>
#else
#include <os/base.h>
#include <os/base_private.h>
#include <dispatch/dispatch.h>
#endif

#define OS_FIREHOSE_SPI_VERSION 20160318

/*!
 * @group Firehose SPI
 * SPI intended for logd only
 * Layout of structs is subject to change without notice
 */

#define FIREHOSE_BUFFER_CHUNK_SIZE				4096ul
#define FIREHOSE_BUFFER_LIBTRACE_HEADER_SIZE	2048ul
#define FIREHOSE_BUFFER_KERNEL_CHUNK_COUNT		16

typedef union {
	uint64_t fbc_atomic_pos;
#define FIREHOSE_BUFFER_POS_ENTRY_OFFS_INC		(1ULL <<  0)
#define FIREHOSE_BUFFER_POS_PRIVATE_OFFS_INC	(1ULL << 16)
#define FIREHOSE_BUFFER_POS_REFCNT_INC			(1ULL << 32)
#define FIREHOSE_BUFFER_POS_FULL_BIT			(1ULL << 56)
#define FIREHOSE_BUFFER_POS_USABLE_FOR_STREAM(pos, stream) \
		((((pos).fbc_atomic_pos >> 48) & 0x1ff) == (uint16_t)stream)
	struct {
		uint16_t fbc_next_entry_offs;
		uint16_t fbc_private_offs;
		uint8_t  fbc_refcnt;
		uint8_t  fbc_qos_bits;
		uint8_t  fbc_stream;
		uint8_t  fbc_flag_full : 1;
		uint8_t  fbc_flag_io : 1;
		uint8_t  _fbc_flag_unused : 6;
	};
} firehose_buffer_pos_u;

typedef struct firehose_buffer_chunk_s {
	uint8_t  fbc_start[0];
	firehose_buffer_pos_u volatile fbc_pos;
	uint64_t fbc_timestamp;
	uint8_t  fbc_data[FIREHOSE_BUFFER_CHUNK_SIZE
			- sizeof(firehose_buffer_pos_u)
			- sizeof(uint64_t)];
} __attribute__((aligned(8))) *firehose_buffer_chunk_t;

typedef struct firehose_buffer_range_s {
	uint16_t fbr_offset; // offset from the start of the buffer
	uint16_t fbr_length;
} *firehose_buffer_range_t;

#ifdef KERNEL

// implemented by the kernel
extern void __firehose_buffer_push_to_logd(firehose_buffer_t fb, bool for_io);
extern void __firehose_critical_region_enter(void);
extern void __firehose_critical_region_leave(void);
extern void __firehose_allocate(vm_offset_t *addr, vm_size_t size);

// exported for the kernel
firehose_tracepoint_t
__firehose_buffer_tracepoint_reserve(uint64_t stamp, firehose_stream_t stream,
		uint16_t pubsize, uint16_t privsize, uint8_t **privptr);

firehose_tracepoint_t
__firehose_buffer_tracepoint_reserve_with_chunk(firehose_buffer_chunk_t fbc,
		uint64_t stamp, firehose_stream_t stream,
		uint16_t pubsize, uint16_t privsize, uint8_t **privptr);

void
__firehose_buffer_tracepoint_flush(firehose_tracepoint_t vat,
		firehose_tracepoint_id_u vatid);

void
__firehose_buffer_tracepoint_flush_chunk(firehose_buffer_chunk_t fbc,
		firehose_tracepoint_t vat, firehose_tracepoint_id_u vatid);

firehose_buffer_t
__firehose_buffer_create(size_t *size);

void
__firehose_merge_updates(firehose_push_reply_t update);

#else

#define __firehose_critical_region_enter()
#define __firehose_critical_region_leave()

OS_EXPORT
const uint32_t _firehose_spi_version;

OS_ALWAYS_INLINE
static inline const uint8_t *
_firehose_tracepoint_reader_init(firehose_buffer_chunk_t fbc,
		const uint8_t **endptr)
{
	const uint8_t *start = fbc->fbc_data;
	const uint8_t *end = fbc->fbc_start + fbc->fbc_pos.fbc_next_entry_offs;

	if (end > fbc->fbc_start + FIREHOSE_BUFFER_CHUNK_SIZE) {
		end = start;
	}
	*endptr = end;
	return start;
}

OS_ALWAYS_INLINE
static inline firehose_tracepoint_t
_firehose_tracepoint_reader_next(const uint8_t **ptr, const uint8_t *end)
{
	const uint16_t ft_size = offsetof(struct firehose_tracepoint_s, ft_data);
	firehose_tracepoint_t ft;

	do {
		ft = (firehose_tracepoint_t)*ptr;
		if (ft->ft_data >= end) {
			// reached the end
			return NULL;
		}
		if (!ft->ft_length) {
			// tracepoint write didn't even start
			return NULL;
		}
		if (ft->ft_length > end - ft->ft_data) {
			// invalid length
			return NULL;
		}
		*ptr += roundup(ft_size + ft->ft_length, 8);
		// test whether write of the tracepoint was finished
	} while (os_unlikely(ft->ft_id.ftid_value == 0));

	return ft;
}

#define firehose_tracepoint_foreach(ft, fbc) \
		for (const uint8_t *end, *p = _firehose_tracepoint_reader_init(fbc, &end); \
				((ft) = _firehose_tracepoint_reader_next(&p, end)); )

OS_ALWAYS_INLINE
static inline bool
firehose_buffer_range_validate(firehose_buffer_chunk_t fbc,
		firehose_tracepoint_t ft, firehose_buffer_range_t range)
{
	if (range->fbr_offset + range->fbr_length > FIREHOSE_BUFFER_CHUNK_SIZE) {
		return false;
	}
	if (fbc->fbc_start + range->fbr_offset < ft->ft_data + ft->ft_length) {
		return false;
	}
	return true;
}

#endif // !KERNEL

#endif // OS_FIREHOSE_SPI

#endif // __FIREHOSE_BUFFER_PRIVATE__
