// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2013 The Chromium OS Authors.
 * Coypright (c) 2013 Guntermann & Drunck GmbH
 */

#include <common.h>
#include <dm.h>
#include <asm/unaligned.h>
#include <tpm-common.h>
#include "tpm-utils.h"

int pack_byte_string(u8 *str, size_t size, const char *format, ...)
{
	va_list args;
	size_t offset = 0, length = 0;
	u8 *data = NULL;
	u32 value = 0;

	va_start(args, format);
	for (; *format; format++) {
		switch (*format) {
		case 'b':
			offset = va_arg(args, size_t);
			value = va_arg(args, int);
			length = 1;
			break;
		case 'w':
			offset = va_arg(args, size_t);
			value = va_arg(args, int);
			length = 2;
			break;
		case 'd':
			offset = va_arg(args, size_t);
			value = va_arg(args, u32);
			length = 4;
			break;
		case 's':
			offset = va_arg(args, size_t);
			data = va_arg(args, u8 *);
			length = va_arg(args, u32);
			break;
		default:
			debug("Couldn't recognize format string\n");
			va_end(args);
			return -1;
		}

		if (offset + length > size) {
			va_end(args);
			return -1;
		}

		switch (*format) {
		case 'b':
			str[offset] = value;
			break;
		case 'w':
			put_unaligned_be16(value, str + offset);
			break;
		case 'd':
			put_unaligned_be32(value, str + offset);
			break;
		case 's':
			memcpy(str + offset, data, length);
			break;
		}
	}
	va_end(args);

	return 0;
}

int unpack_byte_string(const u8 *str, size_t size, const char *format, ...)
{
	va_list args;
	size_t offset = 0, length = 0;
	u8 *ptr8 = NULL;
	u16 *ptr16 = NULL;
	u32 *ptr32 = NULL;

	va_start(args, format);
	for (; *format; format++) {
		switch (*format) {
		case 'b':
			offset = va_arg(args, size_t);
			ptr8 = va_arg(args, u8 *);
			length = 1;
			break;
		case 'w':
			offset = va_arg(args, size_t);
			ptr16 = va_arg(args, u16 *);
			length = 2;
			break;
		case 'd':
			offset = va_arg(args, size_t);
			ptr32 = va_arg(args, u32 *);
			length = 4;
			break;
		case 's':
			offset = va_arg(args, size_t);
			ptr8 = va_arg(args, u8 *);
			length = va_arg(args, u32);
			break;
		default:
			va_end(args);
			debug("Couldn't recognize format string\n");
			return -1;
		}

		if (offset + length > size) {
			va_end(args);
			return -1;
		}

		switch (*format) {
		case 'b':
			*ptr8 = str[offset];
			break;
		case 'w':
			*ptr16 = get_unaligned_be16(str + offset);
			break;
		case 'd':
			*ptr32 = get_unaligned_be32(str + offset);
			break;
		case 's':
			memcpy(ptr8, str + offset, length);
			break;
		}
	}
	va_end(args);

	return 0;
}

u32 tpm_command_size(const void *command)
{
	const size_t command_size_offset = 2;

	return get_unaligned_be32(command + command_size_offset);
}

u32 tpm_return_code(const void *response)
{
	const size_t return_code_offset = 6;

	return get_unaligned_be32(response + return_code_offset);
}

u32 tpm_sendrecv_command(const void *command, void *response, size_t *size_ptr)
{
	struct udevice *dev;
	int err, ret;
	u8 response_buffer[COMMAND_BUFFER_SIZE];
	size_t response_length;
	int i;

	if (response) {
		response_length = *size_ptr;
	} else {
		response = response_buffer;
		response_length = sizeof(response_buffer);
	}

	ret = uclass_first_device_err(UCLASS_TPM, &dev);
	if (ret)
		return ret;
	err = tpm_xfer(dev, command, tpm_command_size(command),
		       response, &response_length);

	if (err < 0)
		return err;

	if (size_ptr)
		*size_ptr = response_length;

	ret = tpm_return_code(response);

	log(LOGC_NONE, LOGL_DEBUG, "TPM response [ret:%d]: ", ret);
	for (i = 0; i < response_length; i++)
		log(LOGC_NONE, LOGL_DEBUG, "%02x ", ((u8 *)response)[i]);
	log(LOGC_NONE, LOGL_DEBUG, "\n");

	return ret;
}

int tpm_init(void)
{
	struct udevice *dev;
	int err;

	err = uclass_first_device_err(UCLASS_TPM, &dev);
	if (err)
		return err;

	return tpm_open(dev);
}
