// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
/*
 * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
 */

#include <image.h>
#include "imagetool.h"

/* magic ='S' 'T' 'M' 0x32 */
#define HEADER_MAGIC be32_to_cpu(0x53544D32)
#define VER_MAJOR_IDX	2
#define VER_MINOR_IDX	1
#define VER_VARIANT_IDX	0
#define HEADER_VERSION_V1	0x1
/* default option : bit0 => no signature */
#define HEADER_DEFAULT_OPTION	(cpu_to_le32(0x00000001))
/* default binary type for U-Boot */
#define HEADER_TYPE_UBOOT	(cpu_to_le32(0x00000000))

struct stm32_header {
	uint32_t magic_number;
	uint32_t image_signature[64 / 4];
	uint32_t image_checksum;
	uint8_t  header_version[4];
	uint32_t image_length;
	uint32_t image_entry_point;
	uint32_t reserved1;
	uint32_t load_address;
	uint32_t reserved2;
	uint32_t version_number;
	uint32_t option_flags;
	uint32_t ecdsa_algorithm;
	uint32_t ecdsa_public_key[64 / 4];
	uint32_t padding[83 / 4];
	uint32_t binary_type;
};

static struct stm32_header stm32image_header;

static void stm32image_default_header(struct stm32_header *ptr)
{
	if (!ptr)
		return;

	ptr->magic_number = HEADER_MAGIC;
	ptr->header_version[VER_MAJOR_IDX] = HEADER_VERSION_V1;
	ptr->option_flags = HEADER_DEFAULT_OPTION;
	ptr->ecdsa_algorithm = cpu_to_le32(1);
	ptr->binary_type = HEADER_TYPE_UBOOT;
}

static uint32_t stm32image_checksum(void *start, uint32_t len)
{
	uint32_t csum = 0;
	uint32_t hdr_len = sizeof(struct stm32_header);
	uint8_t *p;

	if (len < hdr_len)
		return 0;

	p = start + hdr_len;
	len -= hdr_len;

	while (len > 0) {
		csum += *p;
		p++;
		len--;
	}

	return csum;
}

static int stm32image_check_image_types(uint8_t type)
{
	if (type == IH_TYPE_STM32IMAGE)
		return EXIT_SUCCESS;
	return EXIT_FAILURE;
}

static int stm32image_verify_header(unsigned char *ptr, int image_size,
				    struct image_tool_params *params)
{
	struct stm32_header *stm32hdr = (struct stm32_header *)ptr;
	int i;

	if (image_size < sizeof(struct stm32_header))
		return -1;
	if (stm32hdr->magic_number != HEADER_MAGIC)
		return -1;
	if (stm32hdr->header_version[VER_MAJOR_IDX] != HEADER_VERSION_V1)
		return -1;
	if (stm32hdr->reserved1 || stm32hdr->reserved2)
		return -1;
	for (i = 0; i < (sizeof(stm32hdr->padding) / 4); i++) {
		if (stm32hdr->padding[i] != 0)
			return -1;
	}

	return 0;
}

static void stm32image_print_header(const void *ptr, struct image_tool_params *params)
{
	struct stm32_header *stm32hdr = (struct stm32_header *)ptr;

	printf("Image Type   : STMicroelectronics STM32 V%d.%d\n",
	       stm32hdr->header_version[VER_MAJOR_IDX],
	       stm32hdr->header_version[VER_MINOR_IDX]);
	printf("Image Size   : %lu bytes\n",
	       (unsigned long)le32_to_cpu(stm32hdr->image_length));
	printf("Image Load   : 0x%08x\n",
	       le32_to_cpu(stm32hdr->load_address));
	printf("Entry Point  : 0x%08x\n",
	       le32_to_cpu(stm32hdr->image_entry_point));
	printf("Checksum     : 0x%08x\n",
	       le32_to_cpu(stm32hdr->image_checksum));
	printf("Option     : 0x%08x\n",
	       le32_to_cpu(stm32hdr->option_flags));
	printf("BinaryType : 0x%08x\n",
	       le32_to_cpu(stm32hdr->binary_type));
}

static void stm32image_set_header(void *ptr, struct stat *sbuf, int ifd,
				  struct image_tool_params *params)
{
	struct stm32_header *stm32hdr = (struct stm32_header *)ptr;

	stm32image_default_header(stm32hdr);

	stm32hdr->load_address = cpu_to_le32(params->addr);
	stm32hdr->image_entry_point = cpu_to_le32(params->ep);
	stm32hdr->image_length = cpu_to_le32((uint32_t)sbuf->st_size -
					     sizeof(struct stm32_header));
	stm32hdr->image_checksum =
		cpu_to_le32(stm32image_checksum(ptr, sbuf->st_size));
}

/*
 * stm32image parameters
 */
U_BOOT_IMAGE_TYPE(
	stm32image,
	"STMicroelectronics STM32MP Image support",
	sizeof(struct stm32_header),
	(void *)&stm32image_header,
	NULL,
	stm32image_verify_header,
	stm32image_print_header,
	stm32image_set_header,
	NULL,
	stm32image_check_image_types,
	NULL,
	NULL
);
