/*
 * Copyright (c) 2015 Intel Corporation
 *
 * 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.
 */

/**
 * @file
 * @brief Kernel event logger support.
 */


#include <misc/kernel_event_logger.h>
#include <misc/util.h>
#include <init.h>
#include <nano_private.h>
#include <kernel_event_logger_arch.h>

uint32_t _sys_k_event_logger_buffer[CONFIG_KERNEL_EVENT_LOGGER_BUFFER_SIZE];

#ifdef CONFIG_KERNEL_EVENT_LOGGER_CONTEXT_SWITCH
void *_collector_fiber;
#endif

#ifdef CONFIG_KERNEL_EVENT_LOGGER_SLEEP
uint32_t _sys_k_event_logger_sleep_start_time;
#endif


/**
 * @brief Initialize the kernel event logger system.
 *
 * @details Initialize the ring buffer and the sync semaphore.
 *
 * @return No return value.
 */
static int _sys_k_event_logger_init(struct device *arg)
{
	ARG_UNUSED(arg);

	sys_event_logger_init(&sys_k_event_logger, _sys_k_event_logger_buffer,
		CONFIG_KERNEL_EVENT_LOGGER_BUFFER_SIZE);

	return 0;
}
SYS_INIT(_sys_k_event_logger_init,
		NANOKERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);


void sys_k_event_logger_put_timed(uint16_t event_id)
{
	uint32_t data[1];

	data[0] = sys_tick_get_32();

	sys_event_logger_put(&sys_k_event_logger, event_id, data,
		ARRAY_SIZE(data));
}

#ifdef CONFIG_KERNEL_EVENT_LOGGER_CONTEXT_SWITCH
void _sys_k_event_logger_context_switch(void)
{
	extern tNANO _nanokernel;
	uint32_t data[2];

	extern void _sys_event_logger_put_non_preemptible(
		struct event_logger *logger,
		uint16_t event_id,
		uint32_t *event_data,
		uint8_t data_size);

	/* if the kernel event logger has not been initialized, we do nothing */
	if (sys_k_event_logger.ring_buf.buf == NULL) {
		return;
	}

	if (_collector_fiber != _nanokernel.current) {
		data[0] = sys_tick_get_32();
		data[1] = (uint32_t)_nanokernel.current;

		/*
		 * The mechanism we use to log the kernel events uses a sync semaphore
		 * to inform that there are available events to be collected. The
		 * context switch event can be triggered from a task. When we
		 * signal a semaphore from a task and a fiber is waiting for
		 * that semaphore, a context switch is generated immediately. Due to
		 * the fact that we register the context switch event while the context
		 * switch is being processed, a new context switch can be generated
		 * before the kernel finishes processing the current context switch. We
		 * need to prevent this because the kernel is not able to handle it.
		 * The _sem_give_non_preemptible function does not trigger a context
		 * switch when we signal the semaphore from any type of thread. Using
		 * _sys_event_logger_put_non_preemptible function, that internally uses
		 * _sem_give_non_preemptible function for signaling the sync semaphore,
		 * allow us registering the context switch event without triggering any
		 * new context switch during the process.
		 */
		_sys_event_logger_put_non_preemptible(&sys_k_event_logger,
			KERNEL_EVENT_LOGGER_CONTEXT_SWITCH_EVENT_ID, data,
			ARRAY_SIZE(data));
	}
}

void sys_k_event_logger_register_as_collector(void)
{
	_collector_fiber = _nanokernel.current;
}
#endif /* CONFIG_KERNEL_EVENT_LOGGER_CONTEXT_SWITCH */


#ifdef CONFIG_KERNEL_EVENT_LOGGER_INTERRUPT
void _sys_k_event_logger_interrupt(void)
{
	uint32_t data[2];

	/* if the kernel event logger has not been initialized, we do nothing */
	if (sys_k_event_logger.ring_buf.buf == NULL) {
		return;
	}

	data[0] = sys_tick_get_32();
	data[1] = _sys_current_irq_key_get();

	sys_k_event_logger_put(KERNEL_EVENT_LOGGER_INTERRUPT_EVENT_ID, data,
		ARRAY_SIZE(data));
}
#endif /* CONFIG_KERNEL_EVENT_LOGGER_INTERRUPT */


#ifdef CONFIG_KERNEL_EVENT_LOGGER_SLEEP
void _sys_k_event_logger_enter_sleep(void)
{
	_sys_k_event_logger_sleep_start_time = sys_cycle_get_32();
}

void _sys_k_event_logger_exit_sleep(void)
{
	uint32_t data[3];

	if (_sys_k_event_logger_sleep_start_time != 0) {
		data[0] = sys_tick_get_32();
		data[1] = (sys_cycle_get_32() - _sys_k_event_logger_sleep_start_time)
			/ sys_clock_hw_cycles_per_tick;
		/* register the cause of exiting sleep mode */
		data[2] = _sys_current_irq_key_get();

		/*
		 * if _sys_k_event_logger_sleep_start_time is different to zero, means
		 * that the CPU was sleeping, so we reset it to identify that the event
		 * was processed and that any the next interrupt is no awaing the CPU.
		 */
		_sys_k_event_logger_sleep_start_time = 0;

		sys_k_event_logger_put(KERNEL_EVENT_LOGGER_SLEEP_EVENT_ID, data,
			ARRAY_SIZE(data));
	}
}
#endif /* CONFIG_KERNEL_EVENT_LOGGER_SLEEP */
