// SPDX-License-Identifier: GPL-2.0

/*
 * Copyright 2021 HabanaLabs, Ltd.
 * All Rights Reserved.
 */

#include <linux/vmalloc.h>
#include <uapi/misc/habanalabs.h>
#include "habanalabs.h"

/**
 * hl_format_as_binary - helper function, format an integer as binary
 *                       using supplied scratch buffer
 * @buf: the buffer to use
 * @buf_len: buffer capacity
 * @n: number to format
 *
 * Returns pointer to buffer
 */
char *hl_format_as_binary(char *buf, size_t buf_len, u32 n)
{
	int i;
	u32 bit;
	bool leading0 = true;
	char *wrptr = buf;

	if (buf_len > 0 && buf_len < 3) {
		*wrptr = '\0';
		return buf;
	}

	wrptr[0] = '0';
	wrptr[1] = 'b';
	wrptr += 2;
	/* Remove 3 characters from length for '0b' and '\0' termination */
	buf_len -= 3;

	for (i = 0; i < sizeof(n) * BITS_PER_BYTE && buf_len; ++i, n <<= 1) {
		/* Writing bit calculation in one line would cause a false
		 * positive static code analysis error, so splitting.
		 */
		bit = n & (1 << (sizeof(n) * BITS_PER_BYTE - 1));
		bit = !!bit;
		leading0 &= !bit;
		if (!leading0) {
			*wrptr = '0' + bit;
			++wrptr;
		}
	}

	*wrptr = '\0';

	return buf;
}

/**
 * resize_to_fit - helper function, resize buffer to fit given amount of data
 * @buf: destination buffer double pointer
 * @size: pointer to the size container
 * @desired_size: size the buffer must contain
 *
 * Returns 0 on success or error code on failure.
 * On success, the size of buffer is at least desired_size. Buffer is allocated
 * via vmalloc and must be freed with vfree.
 */
static int resize_to_fit(char **buf, size_t *size, size_t desired_size)
{
	char *resized_buf;
	size_t new_size;

	if (*size >= desired_size)
		return 0;

	/* Not enough space to print all, have to resize */
	new_size = max_t(size_t, PAGE_SIZE, round_up(desired_size, PAGE_SIZE));
	resized_buf = vmalloc(new_size);
	if (!resized_buf)
		return -ENOMEM;
	memcpy(resized_buf, *buf, *size);
	vfree(*buf);
	*buf = resized_buf;
	*size = new_size;

	return 1;
}

/**
 * hl_snprintf_resize() - print formatted data to buffer, resize as needed
 * @buf: buffer double pointer, to be written to and resized, must be either
 *       NULL or allocated with vmalloc.
 * @size: current size of the buffer
 * @offset: current offset to write to
 * @format: format of the data
 *
 * This function will write formatted data into the buffer. If buffer is not
 * large enough, it will be resized using vmalloc. Size may be modified if the
 * buffer was resized, offset will be advanced by the number of bytes written
 * not including the terminating character
 *
 * Returns 0 on success or error code on failure
 *
 * Note that the buffer has to be manually released using vfree.
 */
int hl_snprintf_resize(char **buf, size_t *size, size_t *offset,
			   const char *format, ...)
{
	va_list args;
	size_t length;
	int rc;

	if (*buf == NULL && (*size != 0 || *offset != 0))
		return -EINVAL;

	va_start(args, format);
	length = vsnprintf(*buf + *offset, *size - *offset, format, args);
	va_end(args);

	rc = resize_to_fit(buf, size, *offset + length + 1);
	if (rc < 0)
		return rc;
	else if (rc > 0) {
		/* Resize was needed, write again */
		va_start(args, format);
		length = vsnprintf(*buf + *offset, *size - *offset, format,
				   args);
		va_end(args);
	}

	*offset += length;

	return 0;
}

/**
 * hl_sync_engine_to_string - convert engine type enum to string literal
 * @engine_type: engine type (TPC/MME/DMA)
 *
 * Return the resolved string literal
 */
const char *hl_sync_engine_to_string(enum hl_sync_engine_type engine_type)
{
	switch (engine_type) {
	case ENGINE_DMA:
		return "DMA";
	case ENGINE_MME:
		return "MME";
	case ENGINE_TPC:
		return "TPC";
	}
	return "Invalid Engine Type";
}

/**
 * hl_print_resize_sync_engine - helper function, format engine name and ID
 * using hl_snprintf_resize
 * @buf: destination buffer double pointer to be used with hl_snprintf_resize
 * @size: pointer to the size container
 * @offset: pointer to the offset container
 * @engine_type: engine type (TPC/MME/DMA)
 * @engine_id: engine numerical id
 *
 * Returns 0 on success or error code on failure
 */
static int hl_print_resize_sync_engine(char **buf, size_t *size, size_t *offset,
				enum hl_sync_engine_type engine_type,
				u32 engine_id)
{
	return hl_snprintf_resize(buf, size, offset, "%s%u",
			hl_sync_engine_to_string(engine_type), engine_id);
}

/**
 * hl_state_dump_get_sync_name - transform sync object id to name if available
 * @hdev: pointer to the device
 * @sync_id: sync object id
 *
 * Returns a name literal or NULL if not resolved.
 * Note: returning NULL shall not be considered as a failure, as not all
 * sync objects are named.
 */
const char *hl_state_dump_get_sync_name(struct hl_device *hdev, u32 sync_id)
{
	struct hl_state_dump_specs *sds = &hdev->state_dump_specs;
	struct hl_hw_obj_name_entry *entry;

	hash_for_each_possible(sds->so_id_to_str_tb, entry,
				node, sync_id)
		if (sync_id == entry->id)
			return entry->name;

	return NULL;
}

/**
 * hl_state_dump_get_monitor_name - transform monitor object dump to monitor
 * name if available
 * @hdev: pointer to the device
 * @mon: monitor state dump
 *
 * Returns a name literal or NULL if not resolved.
 * Note: returning NULL shall not be considered as a failure, as not all
 * monitors are named.
 */
const char *hl_state_dump_get_monitor_name(struct hl_device *hdev,
					struct hl_mon_state_dump *mon)
{
	struct hl_state_dump_specs *sds = &hdev->state_dump_specs;
	struct hl_hw_obj_name_entry *entry;

	hash_for_each_possible(sds->monitor_id_to_str_tb,
				entry, node, mon->id)
		if (mon->id == entry->id)
			return entry->name;

	return NULL;
}

/**
 * hl_state_dump_free_sync_to_engine_map - free sync object to engine map
 * @map: sync object to engine map
 *
 * Note: generic free implementation, the allocation is implemented per ASIC.
 */
void hl_state_dump_free_sync_to_engine_map(struct hl_sync_to_engine_map *map)
{
	struct hl_sync_to_engine_map_entry *entry;
	struct hlist_node *tmp_node;
	int i;

	hash_for_each_safe(map->tb, i, tmp_node, entry, node) {
		hash_del(&entry->node);
		kfree(entry);
	}
}

/**
 * hl_state_dump_get_sync_to_engine - transform sync_id to
 * hl_sync_to_engine_map_entry if available for current id
 * @map: sync object to engine map
 * @sync_id: sync object id
 *
 * Returns the translation entry if found or NULL if not.
 * Note, returned NULL shall not be considered as a failure as the map
 * does not cover all possible, it is a best effort sync ids.
 */
static struct hl_sync_to_engine_map_entry *
hl_state_dump_get_sync_to_engine(struct hl_sync_to_engine_map *map, u32 sync_id)
{
	struct hl_sync_to_engine_map_entry *entry;

	hash_for_each_possible(map->tb, entry, node, sync_id)
		if (entry->sync_id == sync_id)
			return entry;
	return NULL;
}

/**
 * hl_state_dump_read_sync_objects - read sync objects array
 * @hdev: pointer to the device
 * @index: sync manager block index starting with E_N
 *
 * Returns array of size SP_SYNC_OBJ_AMOUNT on success or NULL on failure
 */
static u32 *hl_state_dump_read_sync_objects(struct hl_device *hdev, u32 index)
{
	struct hl_state_dump_specs *sds = &hdev->state_dump_specs;
	u32 *sync_objects;
	s64 base_addr; /* Base addr can be negative */
	int i;

	base_addr = sds->props[SP_SYNC_OBJ_BASE_ADDR] +
			sds->props[SP_NEXT_SYNC_OBJ_ADDR] * index;

	sync_objects = vmalloc(sds->props[SP_SYNC_OBJ_AMOUNT] * sizeof(u32));
	if (!sync_objects)
		return NULL;

	for (i = 0; i < sds->props[SP_SYNC_OBJ_AMOUNT]; ++i)
		sync_objects[i] = RREG32(base_addr + i * sizeof(u32));

	return sync_objects;
}

/**
 * hl_state_dump_free_sync_objects - free sync objects array allocated by
 * hl_state_dump_read_sync_objects
 * @sync_objects: sync objects array
 */
static void hl_state_dump_free_sync_objects(u32 *sync_objects)
{
	vfree(sync_objects);
}


/**
 * hl_state_dump_print_syncs_single_block - print active sync objects on a
 * single block
 * @hdev: pointer to the device
 * @index: sync manager block index starting with E_N
 * @buf: destination buffer double pointer to be used with hl_snprintf_resize
 * @size: pointer to the size container
 * @offset: pointer to the offset container
 * @map: sync engines names map
 *
 * Returns 0 on success or error code on failure
 */
static int
hl_state_dump_print_syncs_single_block(struct hl_device *hdev, u32 index,
				char **buf, size_t *size, size_t *offset,
				struct hl_sync_to_engine_map *map)
{
	struct hl_state_dump_specs *sds = &hdev->state_dump_specs;
	const char *sync_name;
	u32 *sync_objects = NULL;
	int rc = 0, i;

	if (sds->sync_namager_names) {
		rc = hl_snprintf_resize(
			buf, size, offset, "%s\n",
			sds->sync_namager_names[index]);
		if (rc)
			goto out;
	}

	sync_objects = hl_state_dump_read_sync_objects(hdev, index);
	if (!sync_objects) {
		rc = -ENOMEM;
		goto out;
	}

	for (i = 0; i < sds->props[SP_SYNC_OBJ_AMOUNT]; ++i) {
		struct hl_sync_to_engine_map_entry *entry;
		u64 sync_object_addr;

		if (!sync_objects[i])
			continue;

		sync_object_addr = sds->props[SP_SYNC_OBJ_BASE_ADDR] +
				sds->props[SP_NEXT_SYNC_OBJ_ADDR] * index +
				i * sizeof(u32);

		rc = hl_snprintf_resize(buf, size, offset, "sync id: %u", i);
		if (rc)
			goto free_sync_objects;
		sync_name = hl_state_dump_get_sync_name(hdev, i);
		if (sync_name) {
			rc = hl_snprintf_resize(buf, size, offset, " %s",
						sync_name);
			if (rc)
				goto free_sync_objects;
		}
		rc = hl_snprintf_resize(buf, size, offset, ", value: %u",
					sync_objects[i]);
		if (rc)
			goto free_sync_objects;

		/* Append engine string */
		entry = hl_state_dump_get_sync_to_engine(map,
			(u32)sync_object_addr);
		if (entry) {
			rc = hl_snprintf_resize(buf, size, offset,
						", Engine: ");
			if (rc)
				goto free_sync_objects;
			rc = hl_print_resize_sync_engine(buf, size, offset,
						entry->engine_type,
						entry->engine_id);
			if (rc)
				goto free_sync_objects;
		}

		rc = hl_snprintf_resize(buf, size, offset, "\n");
		if (rc)
			goto free_sync_objects;
	}

free_sync_objects:
	hl_state_dump_free_sync_objects(sync_objects);
out:
	return rc;
}

/**
 * hl_state_dump_print_syncs - print active sync objects
 * @hdev: pointer to the device
 * @buf: destination buffer double pointer to be used with hl_snprintf_resize
 * @size: pointer to the size container
 * @offset: pointer to the offset container
 *
 * Returns 0 on success or error code on failure
 */
static int hl_state_dump_print_syncs(struct hl_device *hdev,
					char **buf, size_t *size,
					size_t *offset)

{
	struct hl_state_dump_specs *sds = &hdev->state_dump_specs;
	struct hl_sync_to_engine_map *map;
	u32 index;
	int rc = 0;

	map = kzalloc(sizeof(*map), GFP_KERNEL);
	if (!map)
		return -ENOMEM;

	rc = sds->funcs.gen_sync_to_engine_map(hdev, map);
	if (rc)
		goto free_map_mem;

	rc = hl_snprintf_resize(buf, size, offset, "Non zero sync objects:\n");
	if (rc)
		goto out;

	if (sds->sync_namager_names) {
		for (index = 0; sds->sync_namager_names[index]; ++index) {
			rc = hl_state_dump_print_syncs_single_block(
				hdev, index, buf, size, offset, map);
			if (rc)
				goto out;
		}
	} else {
		for (index = 0; index < sds->props[SP_NUM_CORES]; ++index) {
			rc = hl_state_dump_print_syncs_single_block(
				hdev, index, buf, size, offset, map);
			if (rc)
				goto out;
		}
	}

out:
	hl_state_dump_free_sync_to_engine_map(map);
free_map_mem:
	kfree(map);

	return rc;
}

/**
 * hl_state_dump_alloc_read_sm_block_monitors - read monitors for a specific
 * block
 * @hdev: pointer to the device
 * @index: sync manager block index starting with E_N
 *
 * Returns an array of monitor data of size SP_MONITORS_AMOUNT or NULL
 * on error
 */
static struct hl_mon_state_dump *
hl_state_dump_alloc_read_sm_block_monitors(struct hl_device *hdev, u32 index)
{
	struct hl_state_dump_specs *sds = &hdev->state_dump_specs;
	struct hl_mon_state_dump *monitors;
	s64 base_addr; /* Base addr can be negative */
	int i;

	monitors = vmalloc(sds->props[SP_MONITORS_AMOUNT] *
			   sizeof(struct hl_mon_state_dump));
	if (!monitors)
		return NULL;

	base_addr = sds->props[SP_NEXT_SYNC_OBJ_ADDR] * index;

	for (i = 0; i < sds->props[SP_MONITORS_AMOUNT]; ++i) {
		monitors[i].id = i;
		monitors[i].wr_addr_low =
			RREG32(base_addr + sds->props[SP_MON_OBJ_WR_ADDR_LOW] +
				i * sizeof(u32));

		monitors[i].wr_addr_high =
			RREG32(base_addr + sds->props[SP_MON_OBJ_WR_ADDR_HIGH] +
				i * sizeof(u32));

		monitors[i].wr_data =
			RREG32(base_addr + sds->props[SP_MON_OBJ_WR_DATA] +
				i * sizeof(u32));

		monitors[i].arm_data =
			RREG32(base_addr + sds->props[SP_MON_OBJ_ARM_DATA] +
				i * sizeof(u32));

		monitors[i].status =
			RREG32(base_addr + sds->props[SP_MON_OBJ_STATUS] +
				i * sizeof(u32));
	}

	return monitors;
}

/**
 * hl_state_dump_free_monitors - free the monitors structure
 * @monitors: monitors array created with
 *            hl_state_dump_alloc_read_sm_block_monitors
 */
static void hl_state_dump_free_monitors(struct hl_mon_state_dump *monitors)
{
	vfree(monitors);
}

/**
 * hl_state_dump_print_monitors_single_block - print active monitors on a
 * single block
 * @hdev: pointer to the device
 * @index: sync manager block index starting with E_N
 * @buf: destination buffer double pointer to be used with hl_snprintf_resize
 * @size: pointer to the size container
 * @offset: pointer to the offset container
 *
 * Returns 0 on success or error code on failure
 */
static int hl_state_dump_print_monitors_single_block(struct hl_device *hdev,
						u32 index,
						char **buf, size_t *size,
						size_t *offset)
{
	struct hl_state_dump_specs *sds = &hdev->state_dump_specs;
	struct hl_mon_state_dump *monitors = NULL;
	int rc = 0, i;

	if (sds->sync_namager_names) {
		rc = hl_snprintf_resize(
			buf, size, offset, "%s\n",
			sds->sync_namager_names[index]);
		if (rc)
			goto out;
	}

	monitors = hl_state_dump_alloc_read_sm_block_monitors(hdev, index);
	if (!monitors) {
		rc = -ENOMEM;
		goto out;
	}

	for (i = 0; i < sds->props[SP_MONITORS_AMOUNT]; ++i) {
		if (!(sds->funcs.monitor_valid(&monitors[i])))
			continue;

		/* Monitor is valid, dump it */
		rc = sds->funcs.print_single_monitor(buf, size, offset, hdev,
							&monitors[i]);
		if (rc)
			goto free_monitors;

		hl_snprintf_resize(buf, size, offset, "\n");
	}

free_monitors:
	hl_state_dump_free_monitors(monitors);
out:
	return rc;
}

/**
 * hl_state_dump_print_monitors - print active monitors
 * @hdev: pointer to the device
 * @buf: destination buffer double pointer to be used with hl_snprintf_resize
 * @size: pointer to the size container
 * @offset: pointer to the offset container
 *
 * Returns 0 on success or error code on failure
 */
static int hl_state_dump_print_monitors(struct hl_device *hdev,
					char **buf, size_t *size,
					size_t *offset)
{
	struct hl_state_dump_specs *sds = &hdev->state_dump_specs;
	u32 index;
	int rc = 0;

	rc = hl_snprintf_resize(buf, size, offset,
		"Valid (armed) monitor objects:\n");
	if (rc)
		goto out;

	if (sds->sync_namager_names) {
		for (index = 0; sds->sync_namager_names[index]; ++index) {
			rc = hl_state_dump_print_monitors_single_block(
				hdev, index, buf, size, offset);
			if (rc)
				goto out;
		}
	} else {
		for (index = 0; index < sds->props[SP_NUM_CORES]; ++index) {
			rc = hl_state_dump_print_monitors_single_block(
				hdev, index, buf, size, offset);
			if (rc)
				goto out;
		}
	}

out:
	return rc;
}

/**
 * hl_state_dump_print_engine_fences - print active fences for a specific
 * engine
 * @hdev: pointer to the device
 * @engine_type: engine type to use
 * @buf: destination buffer double pointer to be used with hl_snprintf_resize
 * @size: pointer to the size container
 * @offset: pointer to the offset container
 */
static int
hl_state_dump_print_engine_fences(struct hl_device *hdev,
				  enum hl_sync_engine_type engine_type,
				  char **buf, size_t *size, size_t *offset)
{
	struct hl_state_dump_specs *sds = &hdev->state_dump_specs;
	int rc = 0, i, n_fences;
	u64 base_addr, next_fence;

	switch (engine_type) {
	case ENGINE_TPC:
		n_fences = sds->props[SP_NUM_OF_TPC_ENGINES];
		base_addr = sds->props[SP_TPC0_CMDQ];
		next_fence = sds->props[SP_NEXT_TPC];
		break;
	case ENGINE_MME:
		n_fences = sds->props[SP_NUM_OF_MME_ENGINES];
		base_addr = sds->props[SP_MME_CMDQ];
		next_fence = sds->props[SP_NEXT_MME];
		break;
	case ENGINE_DMA:
		n_fences = sds->props[SP_NUM_OF_DMA_ENGINES];
		base_addr = sds->props[SP_DMA_CMDQ];
		next_fence = sds->props[SP_DMA_QUEUES_OFFSET];
		break;
	default:
		return -EINVAL;
	}
	for (i = 0; i < n_fences; ++i) {
		rc = sds->funcs.print_fences_single_engine(
			hdev,
			base_addr + next_fence * i +
				sds->props[SP_FENCE0_CNT_OFFSET],
			base_addr + next_fence * i +
				sds->props[SP_CP_STS_OFFSET],
			engine_type, i, buf, size, offset);
		if (rc)
			goto out;
	}
out:
	return rc;
}

/**
 * hl_state_dump_print_fences - print active fences
 * @hdev: pointer to the device
 * @buf: destination buffer double pointer to be used with hl_snprintf_resize
 * @size: pointer to the size container
 * @offset: pointer to the offset container
 */
static int hl_state_dump_print_fences(struct hl_device *hdev, char **buf,
				      size_t *size, size_t *offset)
{
	int rc = 0;

	rc = hl_snprintf_resize(buf, size, offset, "Valid (armed) fences:\n");
	if (rc)
		goto out;

	rc = hl_state_dump_print_engine_fences(hdev, ENGINE_TPC, buf, size, offset);
	if (rc)
		goto out;

	rc = hl_state_dump_print_engine_fences(hdev, ENGINE_MME, buf, size, offset);
	if (rc)
		goto out;

	rc = hl_state_dump_print_engine_fences(hdev, ENGINE_DMA, buf, size, offset);
	if (rc)
		goto out;

out:
	return rc;
}

/**
 * hl_state_dump() - dump system state
 * @hdev: pointer to device structure
 */
int hl_state_dump(struct hl_device *hdev)
{
	char *buf = NULL;
	size_t offset = 0, size = 0;
	int rc;

	rc = hl_snprintf_resize(&buf, &size, &offset,
				"Timestamp taken on: %llu\n\n",
				ktime_to_ns(ktime_get()));
	if (rc)
		goto err;

	rc = hl_state_dump_print_syncs(hdev, &buf, &size, &offset);
	if (rc)
		goto err;

	hl_snprintf_resize(&buf, &size, &offset, "\n");

	rc = hl_state_dump_print_monitors(hdev, &buf, &size, &offset);
	if (rc)
		goto err;

	hl_snprintf_resize(&buf, &size, &offset, "\n");

	rc = hl_state_dump_print_fences(hdev, &buf, &size, &offset);
	if (rc)
		goto err;

	hl_snprintf_resize(&buf, &size, &offset, "\n");

	hl_debugfs_set_state_dump(hdev, buf, size);

	return 0;
err:
	vfree(buf);
	return rc;
}
