// 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 <common.h>
#include <blk.h>
#include <command.h>
#include <ide.h>
#include <memalign.h>
#include <asm/unaligned.h>
#include <linux/compiler.h>
#include "part_dos.h"
#include <part.h>

#ifdef CONFIG_HAVE_BLOCK_DEVICE

#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 *dev_desc)
{
#ifndef CONFIG_SPL_BUILD
	ALLOC_CACHE_ALIGN_BUFFER(legacy_mbr, mbr,
			DIV_ROUND_UP(dev_desc->blksz, sizeof(legacy_mbr)));

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

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

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

	if (blk_dread(dev_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 *dev_desc,
				     lbaint_t ext_part_sector,
				     lbaint_t relative,
				     int part_num, unsigned int disksig)
{
	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_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(dev_desc, ext_part_sector, 1, (ulong *)buffer) != 1) {
		printf ("** Can't read partition table on %d:" LBAFU " **\n",
			dev_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(dev_desc, lba_start,
				ext_part_sector == 0  ? 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 *dev_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, dev_desc->blksz);
	dos_partition_t *pt;
	int i;
	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(dev_desc, ext_part_sector, 1, (ulong *)buffer) != 1) {
		printf ("** Can't read partition table on %d:" LBAFU " **\n",
			dev_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)
	if (!ext_part_sector)
		disksig = get_unaligned_le32(&buffer[DOS_PART_DISKSIG_OFFSET]);
#endif

	/* 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)) {
			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(dev_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)
			sprintf(info->uuid, "%08x-%02x", disksig, part_num);
#endif
			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(dev_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 = dev_desc->lba;
		info->blksz = DOS_PART_DEFAULT_SECTOR;
		info->bootable = 0;
		strcpy((char *)info->type, "U-Boot");
#if CONFIG_IS_ENABLED(PARTITION_UUIDS)
		info->uuid[0] = 0;
#endif
		return 0;
	}

	return -1;
}

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

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

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

#if CONFIG_IS_ENABLED(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%lx)\n",
			       __func__, ext_part_sect);
			return -1;
		}
		ext_part_sect = next_ebr;
	}

	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 (i >= 4 && !ext) {
		printf("%s: extended partition is needed for more than 4 partitions\n",
		        __func__);
		return -1;
	}

	/* 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 *dev_desc, void *buf)
{
	if (is_valid_dos_buf(buf))
		return -1;

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

	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,
};

#endif
