// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2001
 * Raymond Lo, lo@routefree.com
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 */

/*
 * Support for harddisk partitions.
 *
 * To be compatible with LinuxPPC and Apple we use the standard Apple
 * SCSI disk partitioning scheme. For more information see:
 * http://developer.apple.com/techpubs/mac/Devices/Devices-126.html#MARKER-14-92
 */

#include <blk.h>
#include <command.h>
#include <memalign.h>
#include <vsprintf.h>
#include <asm/unaligned.h>
#include <linux/compiler.h>
#include "part_dos.h"
#include <part.h>

#define DOS_PART_DEFAULT_SECTOR 512

/* should this be configurable? It looks like it's not very common at all
 * to use large numbers of partitions */
#define MAX_EXT_PARTS 256

static inline int is_extended(int part_type)
{
    return (part_type == DOS_PART_TYPE_EXTENDED ||
	    part_type == DOS_PART_TYPE_EXTENDED_LBA ||
	    part_type == DOS_PART_TYPE_EXTENDED_LINUX);
}

static int get_bootable(dos_partition_t *p)
{
	int ret = 0;

	if (p->sys_ind == 0xef)
		ret |= PART_EFI_SYSTEM_PARTITION;
	if (p->boot_ind == 0x80)
		ret |= PART_BOOTABLE;
	return ret;
}

static void print_one_part(dos_partition_t *p, lbaint_t ext_part_sector,
			   int part_num, unsigned int disksig)
{
	lbaint_t lba_start = ext_part_sector + get_unaligned_le32(p->start4);
	lbaint_t lba_size  = get_unaligned_le32(p->size4);

	printf("%3d\t%-10" LBAFlength "u\t%-10" LBAFlength
		"u\t%08x-%02x\t%02x%s%s\n",
		part_num, lba_start, lba_size, disksig, part_num, p->sys_ind,
		(is_extended(p->sys_ind) ? " Extd" : ""),
		(get_bootable(p) ? " Boot" : ""));
}

static int test_block_type(unsigned char *buffer)
{
	int slot;
	struct dos_partition *p;
	int part_count = 0;

	if((buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) ||
	    (buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) ) {
		return (-1);
	} /* no DOS Signature at all */
	p = (struct dos_partition *)&buffer[DOS_PART_TBL_OFFSET];

	/* Check that the boot indicators are valid and count the partitions. */
	for (slot = 0; slot < 4; ++slot, ++p) {
		if (p->boot_ind != 0 && p->boot_ind != 0x80)
			break;
		if (p->sys_ind)
			++part_count;
	}

	/*
	 * If the partition table is invalid or empty,
	 * check if this is a DOS PBR
	 */
	if (slot != 4 || !part_count) {
		if (!strncmp((char *)&buffer[DOS_PBR_FSTYPE_OFFSET],
			     "FAT", 3) ||
		    !strncmp((char *)&buffer[DOS_PBR32_FSTYPE_OFFSET],
			     "FAT32", 5))
			return DOS_PBR; /* This is a DOS PBR and not an MBR */
	}
	if (slot == 4)
		return DOS_MBR;	/* This is an DOS MBR */

	/* This is neither a DOS MBR nor a DOS PBR */
	return -1;
}

static int part_test_dos(struct blk_desc *desc)
{
#ifndef CONFIG_XPL_BUILD
	ALLOC_CACHE_ALIGN_BUFFER(legacy_mbr, mbr,
			DIV_ROUND_UP(desc->blksz, sizeof(legacy_mbr)));

	if (blk_dread(desc, 0, 1, (ulong *)mbr) != 1)
		return -1;

	if (test_block_type((unsigned char *)mbr) != DOS_MBR)
		return -1;

	if (desc->sig_type == SIG_TYPE_NONE && mbr->unique_mbr_signature) {
		desc->sig_type = SIG_TYPE_MBR;
		desc->mbr_sig = mbr->unique_mbr_signature;
	}
#else
	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, desc->blksz);

	if (blk_dread(desc, 0, 1, (ulong *)buffer) != 1)
		return -1;

	if (test_block_type(buffer) != DOS_MBR)
		return -1;
#endif

	return 0;
}

/*  Print a partition that is relative to its Extended partition table
 */
static void print_partition_extended(struct blk_desc *desc,
				     lbaint_t ext_part_sector,
				     lbaint_t relative,
				     int part_num, unsigned int disksig)
{
	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, desc->blksz);
	dos_partition_t *pt;
	int i;

	/* set a maximum recursion level */
	if (part_num > MAX_EXT_PARTS)
	{
		printf("** Nested DOS partitions detected, stopping **\n");
		return;
    }

	if (blk_dread(desc, ext_part_sector, 1, (ulong *)buffer) != 1) {
		printf ("** Can't read partition table on %d:" LBAFU " **\n",
			desc->devnum, ext_part_sector);
		return;
	}
	i=test_block_type(buffer);
	if (i != DOS_MBR) {
		printf ("bad MBR sector signature 0x%02x%02x\n",
			buffer[DOS_PART_MAGIC_OFFSET],
			buffer[DOS_PART_MAGIC_OFFSET + 1]);
		return;
	}

	if (!ext_part_sector)
		disksig = get_unaligned_le32(&buffer[DOS_PART_DISKSIG_OFFSET]);

	/* Print all primary/logical partitions */
	pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
	for (i = 0; i < 4; i++, pt++) {
		/*
		 * fdisk does not show the extended partitions that
		 * are not in the MBR
		 */

		if ((pt->sys_ind != 0) &&
		    (ext_part_sector == 0 || !is_extended (pt->sys_ind)) ) {
			print_one_part(pt, ext_part_sector, part_num, disksig);
		}

		/* Reverse engr the fdisk part# assignment rule! */
		if ((ext_part_sector == 0) ||
		    (pt->sys_ind != 0 && !is_extended (pt->sys_ind)) ) {
			part_num++;
		}
	}

	/* Follows the extended partitions */
	pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
	for (i = 0; i < 4; i++, pt++) {
		if (is_extended (pt->sys_ind)) {
			lbaint_t lba_start
				= get_unaligned_le32 (pt->start4) + relative;

			print_partition_extended(desc, lba_start,
						 !ext_part_sector ? lba_start :
						 relative, part_num, disksig);
		}
	}

	return;
}

/*  Print a partition that is relative to its Extended partition table
 */
static int part_get_info_extended(struct blk_desc *desc,
				  lbaint_t ext_part_sector, lbaint_t relative,
				  int part_num, int which_part,
				  struct disk_partition *info, uint disksig)
{
	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, desc->blksz);
	struct disk_partition wdinfo = { 0 };
	dos_partition_t *pt;
	int i, ret;
	int dos_type;

	/* set a maximum recursion level */
	if (part_num > MAX_EXT_PARTS)
	{
		printf("** Nested DOS partitions detected, stopping **\n");
		return -1;
    }

	if (blk_dread(desc, ext_part_sector, 1, (ulong *)buffer) != 1) {
		printf ("** Can't read partition table on %d:" LBAFU " **\n",
			desc->devnum, ext_part_sector);
		return -1;
	}
	if (buffer[DOS_PART_MAGIC_OFFSET] != 0x55 ||
		buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) {
		printf ("bad MBR sector signature 0x%02x%02x\n",
			buffer[DOS_PART_MAGIC_OFFSET],
			buffer[DOS_PART_MAGIC_OFFSET + 1]);
		return -1;
	}

	if (CONFIG_IS_ENABLED(PARTITION_UUIDS) && !ext_part_sector)
		disksig = get_unaligned_le32(&buffer[DOS_PART_DISKSIG_OFFSET]);

	ret = part_get_info_whole_disk(desc, &wdinfo);
	if (ret)
		return ret;

	/* Print all primary/logical partitions */
	pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
	for (i = 0; i < 4; i++, pt++) {
		/*
		 * fdisk does not show the extended partitions that
		 * are not in the MBR
		 */
		if (((pt->boot_ind & ~0x80) == 0) &&
		    (pt->sys_ind != 0) &&
		    (part_num == which_part) &&
		    (ext_part_sector == 0 || is_extended(pt->sys_ind) == 0)) {
			if (wdinfo.blksz > DOS_PART_DEFAULT_SECTOR)
				info->blksz = wdinfo.blksz;
			else
				info->blksz = DOS_PART_DEFAULT_SECTOR;
			info->start = (lbaint_t)(ext_part_sector +
					get_unaligned_le32(pt->start4));
			info->size  = (lbaint_t)get_unaligned_le32(pt->size4);
			part_set_generic_name(desc, part_num,
					      (char *)info->name);
			/* sprintf(info->type, "%d, pt->sys_ind); */
			strcpy((char *)info->type, "U-Boot");
			info->bootable = get_bootable(pt);
			if (CONFIG_IS_ENABLED(PARTITION_UUIDS)) {
				char str[12];

				sprintf(str, "%08x-%02x", disksig, part_num);
				disk_partition_set_uuid(info, str);
			}
			info->sys_ind = pt->sys_ind;
			return 0;
		}

		/* Reverse engr the fdisk part# assignment rule! */
		if ((ext_part_sector == 0) ||
		    (pt->sys_ind != 0 && !is_extended (pt->sys_ind)) ) {
			part_num++;
		}
	}

	/* Follows the extended partitions */
	pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
	for (i = 0; i < 4; i++, pt++) {
		if (is_extended (pt->sys_ind)) {
			lbaint_t lba_start
				= get_unaligned_le32 (pt->start4) + relative;

			return part_get_info_extended(desc, lba_start,
				 ext_part_sector == 0 ? lba_start : relative,
				 part_num, which_part, info, disksig);
		}
	}

	/* Check for DOS PBR if no partition is found */
	dos_type = test_block_type(buffer);

	if (dos_type == DOS_PBR) {
		info->start = 0;
		info->size = desc->lba;
		if (wdinfo.blksz > DOS_PART_DEFAULT_SECTOR)
			info->blksz = wdinfo.blksz;
		else
			info->blksz = DOS_PART_DEFAULT_SECTOR;
		info->bootable = 0;
		strcpy((char *)info->type, "U-Boot");
		disk_partition_clr_uuid(info);
		return 0;
	}

	return -1;
}

static void __maybe_unused part_print_dos(struct blk_desc *desc)
{
	printf("Part\tStart Sector\tNum Sectors\tUUID\t\tType\n");
	print_partition_extended(desc, 0, 0, 1, 0);
}

static int __maybe_unused part_get_info_dos(struct blk_desc *desc, int part,
					    struct disk_partition *info)
{
	return part_get_info_extended(desc, 0, 0, 1, part, info, 0);
}

int is_valid_dos_buf(void *buf)
{
	return test_block_type(buf) == DOS_MBR ? 0 : -1;
}

#if IS_ENABLED(CONFIG_CMD_MBR)
static void lba_to_chs(lbaint_t lba, unsigned char *rc, unsigned char *rh,
		       unsigned char *rs)
{
	unsigned int c, h, s;
	/* use fixed CHS geometry */
	unsigned int sectpertrack = 63;
	unsigned int heads = 255;

	c = (lba + 1) / sectpertrack / heads;
	h = (lba + 1) / sectpertrack - c * heads;
	s = (lba + 1) - (c * heads + h) * sectpertrack;

	if (c > 1023) {
		c = 1023;
		h = 254;
		s = 63;
	}

	*rc = c & 0xff;
	*rh = h;
	*rs = s + ((c & 0x300) >> 2);
}

static void mbr_fill_pt_entry(dos_partition_t *pt, lbaint_t start,
		lbaint_t relative, lbaint_t size, uchar sys_ind, bool bootable)
{
	pt->boot_ind = bootable ? 0x80 : 0x00;
	pt->sys_ind = sys_ind;
	lba_to_chs(start, &pt->cyl, &pt->head, &pt->sector);
	lba_to_chs(start + size - 1, &pt->end_cyl, &pt->end_head, &pt->end_sector);
	put_unaligned_le32(relative, &pt->start4);
	put_unaligned_le32(size, &pt->size4);
}

int write_mbr_partitions(struct blk_desc *dev,
		struct disk_partition *p, int count, unsigned int disksig)
{
	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev->blksz);
	lbaint_t ext_part_start = 0, ext_part_size = 0, ext_part_sect = 0;
	dos_partition_t *pt;
	int i;

	memset(buffer, 0, dev->blksz);
	buffer[DOS_PART_MAGIC_OFFSET] = 0x55;
	buffer[DOS_PART_MAGIC_OFFSET + 1] = 0xaa;
	put_unaligned_le32(disksig, &buffer[DOS_PART_DISKSIG_OFFSET]);
	pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);

	/* create all primary partitions */
	for (i = 0; i < 4 && i < count; i++, pt++) {
		mbr_fill_pt_entry(pt, p[i].start, p[i].start, p[i].size,
				  p[i].sys_ind, p[i].bootable);
		if (is_extended(p[i].sys_ind)) {
			ext_part_start = p[i].start;
			ext_part_size = p[i].size;
			ext_part_sect = p[i].start;
		}
	}

	if (i < count && !ext_part_start) {
		printf("%s: extended partition is needed for more than 4 partitions\n",
		        __func__);
		return -1;
	}

	/* write MBR */
	if (blk_dwrite(dev, 0, 1, buffer) != 1) {
		printf("%s: failed writing 'MBR' (1 blks at 0x0)\n",
		       __func__);
		return -1;
	}

	/* create extended volumes */
	for (; i < count; i++) {
		lbaint_t next_ebr = 0;

		memset(buffer, 0, dev->blksz);
		buffer[DOS_PART_MAGIC_OFFSET] = 0x55;
		buffer[DOS_PART_MAGIC_OFFSET + 1] = 0xaa;
		pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);

		mbr_fill_pt_entry(pt, p[i].start, p[i].start - ext_part_sect,
				  p[i].size, p[i].sys_ind, p[i].bootable);

		if (i + 1 < count) {
			pt++;
			next_ebr = p[i].start + p[i].size;
			mbr_fill_pt_entry(pt, next_ebr,
					  next_ebr - ext_part_start,
					  p[i+1].start + p[i+1].size - next_ebr,
					  DOS_PART_TYPE_EXTENDED, 0);
		}

		/* write EBR */
		if (blk_dwrite(dev, ext_part_sect, 1, buffer) != 1) {
			printf("%s: failed writing 'EBR' (1 blks at 0x" LBAF ")\n",
			       __func__, ext_part_sect);
			return -1;
		}
		ext_part_sect = next_ebr;
	}

	/* Update the partition table entries*/
	part_init(dev);

	return 0;
}

int layout_mbr_partitions(struct disk_partition *p, int count,
			  lbaint_t total_sectors)
{
	struct disk_partition *ext = NULL;
	int i, j;
	lbaint_t ext_vol_start;

	/* calculate primary partitions start and size if needed */
	if (!p[0].start)
		p[0].start = DOS_PART_DEFAULT_GAP;
	for (i = 0; i < 4 && i < count; i++) {
		if (!p[i].start)
			p[i].start = p[i - 1].start + p[i - 1].size;
		if (!p[i].size) {
			lbaint_t end = total_sectors;
			lbaint_t allocated = 0;

			for (j = i + 1; j < 4 && j < count; j++) {
				if (p[j].start) {
					end = p[j].start;
					break;
				}
				allocated += p[j].size;
			}
			p[i].size = end - allocated - p[i].start;
		}
		if (p[i].sys_ind == 0x05)
			ext = &p[i];
	}

	if (count <= 4)
		return 0;

	if (!ext) {
		log_err("extended partition is needed for more than 4 partitions\n");
		return -EINVAL;
	}

	/* calculate extended volumes start and size if needed */
	ext_vol_start = ext->start;
	for (i = 4; i < count; i++) {
		if (!p[i].start)
			p[i].start = ext_vol_start + DOS_PART_DEFAULT_GAP;
		if (!p[i].size) {
			lbaint_t end = ext->start + ext->size;
			lbaint_t allocated = 0;

			for (j = i + 1; j < count; j++) {
				if (p[j].start) {
					end = p[j].start - DOS_PART_DEFAULT_GAP;
					break;
				}
				allocated += p[j].size + DOS_PART_DEFAULT_GAP;
			}
			p[i].size = end - allocated - p[i].start;
		}
		ext_vol_start = p[i].start + p[i].size;
	}

	return 0;
}
#endif

int write_mbr_sector(struct blk_desc *desc, void *buf)
{
	if (is_valid_dos_buf(buf))
		return -1;

	/* write MBR */
	if (blk_dwrite(desc, 0, 1, buf) != 1) {
		printf("%s: failed writing '%s' (1 blks at 0x0)\n",
		       __func__, "MBR");
		return 1;
	}

	/* Update the partition table entries*/
	part_init(desc);

	return 0;
}

U_BOOT_PART_TYPE(dos) = {
	.name		= "DOS",
	.part_type	= PART_TYPE_DOS,
	.max_entries	= DOS_ENTRY_NUMBERS,
	.get_info	= part_get_info_ptr(part_get_info_dos),
	.print		= part_print_ptr(part_print_dos),
	.test		= part_test_dos,
};
