// File: /workspace/github_c_makefile_star2_O1/blasphemy[P]mmc-utils/mmc_cmds.c
// Function: do_create_gp_partition
int do_create_gp_partition(int nargs, char **argv)
{
	__u8 value;
	__u8 ext_csd[512];
	__u8 address;
	int fd, ret;
	char *device;
	int dry_run = 1;
	int partition, enh_attr, ext_attr;
	unsigned int length_kib, gp_size_mult;
	unsigned long align;

	if (nargs != 7) {
		fprintf(stderr, "Usage: mmc gp create <-y|-n|-c> <length KiB> <partition> <enh_attr> <ext_attr> </path/to/mmcblkX>\n");
		exit(1);
	}

	if (!strcmp("-y", argv[1])) {
		dry_run = 0;
        } else if (!strcmp("-c", argv[1])) {
		dry_run = 2;
	}

	length_kib = strtol(argv[2], NULL, 10);
	partition = strtol(argv[3], NULL, 10);
	enh_attr = strtol(argv[4], NULL, 10);
	ext_attr = strtol(argv[5], NULL, 10);
	device = argv[6];

	if (partition < 1 || partition > 4) {
		printf("Invalid gp partition number; valid range [1-4].\n");
		exit(1);
	}

	if (enh_attr && ext_attr) {
		printf("Not allowed to set both enhanced attribute and extended attribute\n");
		exit(1);
	}

	fd = open(device, O_RDWR);
	if (fd < 0) {
		perror("open");
		exit(1);
	}

	ret = read_extcsd(fd, ext_csd);
	if (ret) {
		fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
		exit(1);
	}

	/* assert not PARTITION_SETTING_COMPLETED */
	if (ext_csd[EXT_CSD_PARTITION_SETTING_COMPLETED]) {
		printf(" Device is already partitioned\n");
		exit(1);
	}

	align = 512l * get_hc_wp_grp_size(ext_csd) * get_hc_erase_grp_size(ext_csd);
	gp_size_mult = (length_kib + align/2l) / align;

	/* set EXT_CSD_ERASE_GROUP_DEF bit 0 */
	ret = write_extcsd_value(fd, EXT_CSD_ERASE_GROUP_DEF, 0x1);
	if (ret) {
		fprintf(stderr, "Could not write 0x1 to EXT_CSD[%d] in %s\n",
			EXT_CSD_ERASE_GROUP_DEF, device);
		exit(1);
	}

	value = (gp_size_mult >> 16) & 0xff;
	address = EXT_CSD_GP_SIZE_MULT_1_2 + (partition - 1) * 3;
	ret = write_extcsd_value(fd, address, value);
	if (ret) {
		fprintf(stderr, "Could not write 0x%02x to EXT_CSD[%d] in %s\n",
			value, address, device);
		exit(1);
	}
	value = (gp_size_mult >> 8) & 0xff;
	address = EXT_CSD_GP_SIZE_MULT_1_1 + (partition - 1) * 3;
	ret = write_extcsd_value(fd, address, value);
	if (ret) {
		fprintf(stderr, "Could not write 0x%02x to EXT_CSD[%d] in %s\n",
			value, address, device);
		exit(1);
	}
	value = gp_size_mult & 0xff;
	address = EXT_CSD_GP_SIZE_MULT_1_0 + (partition - 1) * 3;
	ret = write_extcsd_value(fd, address, value);
	if (ret) {
		fprintf(stderr, "Could not write 0x%02x to EXT_CSD[%d] in %s\n",
			value, address, device);
		exit(1);
	}

	value = ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE];
	if (enh_attr)
		value |= (1 << partition);
	else
		value &= ~(1 << partition);

	ret = write_extcsd_value(fd, EXT_CSD_PARTITIONS_ATTRIBUTE, value);
	if (ret) {
		fprintf(stderr, "Could not write EXT_CSD_ENH_%x to EXT_CSD[%d] in %s\n",
			partition, EXT_CSD_PARTITIONS_ATTRIBUTE, device);
		exit(1);
	}

	address = EXT_CSD_EXT_PARTITIONS_ATTRIBUTE_0 + (partition - 1) / 2;
	value = ext_csd[address];
	if (ext_attr)
		value |= (ext_attr << (4 * ((partition - 1) % 2)));
	else
		value &= (0xF << (4 * ((partition % 2))));

	ret = write_extcsd_value(fd, address, value);
	if (ret) {
		fprintf(stderr, "Could not write 0x%x to EXT_CSD[%d] in %s\n",
			value, address, device);
		exit(1);
	}

	ret = check_enhanced_area_total_limit(device, fd);
	if (ret)
		exit(1);

	if (set_partitioning_setting_completed(dry_run, device, fd))
		exit(1);

	return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x238, %rsp            # imm = 0x238
cmpl $0x7, %edi
jne 0x57c4
movq %rsi, %rbx
movq 0x8(%rsi), %r14
leaq 0x9c97(%rip), %rdi      # 0xf1c3
movq %r14, %rsi
callq 0x3150
testl %eax, %eax
je 0x5553
leaq 0x9c87(%rip), %rdi      # 0xf1c6
movq %r14, %rsi
callq 0x3150
xorl %r14d, %r14d
cmpl $0x1, %eax
adcl $0x1, %r14d
jmp 0x5556
xorl %r14d, %r14d
movq 0x10(%rbx), %rdi
xorl %esi, %esi
movl $0xa, %edx
callq 0x3180
movq %rax, %rbp
movq 0x18(%rbx), %rdi
xorl %esi, %esi
movl $0xa, %edx
callq 0x3180
movq %rax, %r12
movq 0x20(%rbx), %rdi
xorl %esi, %esi
movl $0xa, %edx
callq 0x3180
movq %rax, %r15
movq 0x28(%rbx), %rdi
xorl %esi, %esi
movl $0xa, %edx
callq 0x3180
movq %rax, %r13
leal -0x5(%r12), %eax
cmpl $-0x5, %eax
jbe 0x57e6
movq %r15, 0x28(%rsp)
testl %r15d, %r15d
setne %al
testl %r13d, %r13d
setne %cl
andb %al, %cl
cmpb $0x1, %cl
je 0x57ef
movq 0x30(%rbx), %rbx
movq %rbx, %rdi
movl $0x2, %esi
xorl %eax, %eax
callq 0x31d0
testl %eax, %eax
js 0x57f8
movl %eax, %r15d
leaq 0x30(%rsp), %rsi
movl %eax, %edi
callq 0x3ef8
testl %eax, %eax
jne 0x57fd
cmpb $0x0, 0xcb(%rsp)
jne 0x5822
movq %r13, 0x18(%rsp)
movl %r14d, 0x14(%rsp)
movq %rbx, 0x8(%rsp)
movzbl 0x10d(%rsp), %eax
shll $0x9, %eax
movzbl 0x110(%rsp), %ecx
imulq %rax, %rcx
movl %ebp, %edx
movl %ecx, %eax
shrl %eax
addq %rdx, %rax
xorl %edx, %edx
divq %rcx
movq %rax, %r14
movl %r15d, %edi
movl $0xaf, %esi
movl $0x1, %edx
callq 0x3f8e
testl %eax, %eax
jne 0x583a
movq %r14, %rbx
shrq $0x10, %rbx
movq %r12, 0x20(%rsp)
leal -0x1(%r12), %ebp
leal (%rbp,%rbp,2), %r12d
leal -0x6f(%r12), %eax
movzbl %al, %r13d
movzbl %bl, %edx
movl %r15d, %edi
movl %r13d, %esi
callq 0x3f8e
testl %eax, %eax
jne 0x57b2
movq %r14, %rbx
shrq $0x8, %rbx
leal -0x70(%r12), %eax
movzbl %al, %r13d
movzbl %bl, %edx
movl %r15d, %edi
movl %r13d, %esi
callq 0x3f8e
testl %eax, %eax
jne 0x57b2
addb $-0x71, %r12b
movzbl %r14b, %edx
movzbl %r12b, %r13d
movl %r15d, %edi
movl %r13d, %esi
callq 0x3f8e
testl %eax, %eax
jne 0x5863
movl $0x1, %eax
movq 0x20(%rsp), %r12
movl %r12d, %ecx
shll %cl, %eax
movb 0xcc(%rsp), %cl
movl %ecx, %edx
orb %al, %dl
notb %al
andb %cl, %al
cmpl $0x0, 0x28(%rsp)
movzbl %dl, %ecx
movzbl %al, %eax
cmovnel %ecx, %eax
movzbl %al, %edx
movl %r15d, %edi
movl $0x9c, %esi
callq 0x3f8e
testl %eax, %eax
jne 0x5882
movl %ebp, %eax
shrl %eax
addb $0x34, %al
movzbl %al, %ebx
movb 0x30(%rsp,%rbx), %al
movq 0x18(%rsp), %rdx
testl %edx, %edx
movl 0x14(%rsp), %r14d
je 0x5745
shll $0x2, %ebp
andb $0x4, %bpl
movl %ebp, %ecx
shll %cl, %edx
orb %dl, %al
jmp 0x5759
shll $0x2, %r12d
andb $0x4, %r12b
movl $0xf, %edx
movl %r12d, %ecx
shll %cl, %edx
andb %dl, %al
movzbl %al, %ebp
movl %r15d, %edi
movl %ebx, %esi
movl %ebp, %edx
callq 0x3f8e
testl %eax, %eax
jne 0x58a3
movq 0x8(%rsp), %rbx
movq %rbx, %rdi
movl %r15d, %esi
callq 0x51aa
testl %eax, %eax
jne 0x58ca
movl %r14d, %edi
movq %rbx, %rsi
movl %r15d, %edx
callq 0x5071
testl %eax, %eax
jne 0x58ca
xorl %eax, %eax
addq $0x238, %rsp            # imm = 0x238
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x11837(%rip), %rax     # 0x16ff0
movq (%rax), %rdi
movzbl %bl, %ecx
jmp 0x5871
movq 0x11825(%rip), %rax     # 0x16ff0
movq (%rax), %rdi
leaq 0x998b(%rip), %rdx      # 0xf160
movl $0x1, %esi
xorl %eax, %eax
callq 0x3240
jmp 0x58ca
leaq 0x99dc(%rip), %rsi      # 0xf1c9
jmp 0x5829
leaq 0x9a04(%rip), %rsi      # 0xf1fa
jmp 0x5829
callq 0x33bf
movq 0x117ec(%rip), %rax     # 0x16ff0
movq (%rax), %rdi
leaq 0x8ef7(%rip), %rdx      # 0xe705
movl $0x1, %esi
movq %rbx, %rcx
xorl %eax, %eax
callq 0x3240
jmp 0x58ca
leaq 0x9a14(%rip), %rsi      # 0xf23d
movl $0x1, %edi
xorl %eax, %eax
callq 0x31c0
jmp 0x58ca
movq 0x117af(%rip), %rax     # 0x16ff0
movq (%rax), %rdi
leaq 0x95ca(%rip), %rdx      # 0xee15
movl $0x1, %esi
movl $0xaf, %ecx
movq 0x8(%rsp), %r8
xorl %eax, %eax
callq 0x3240
jmp 0x58ca
movq 0x11786(%rip), %rax     # 0x16ff0
movq (%rax), %rdi
movzbl %r14b, %ecx
leaq 0x8ee2(%rip), %rdx      # 0xe75a
movl $0x1, %esi
movl %r13d, %r8d
jmp 0x58be
movq 0x11767(%rip), %rax     # 0x16ff0
movq (%rax), %rdi
leaq 0x99ca(%rip), %rdx      # 0xf25d
movl $0x1, %esi
movl %r12d, %ecx
movl $0x9c, %r8d
jmp 0x58be
movq 0x11746(%rip), %rax     # 0x16ff0
movq (%rax), %rdi
leaq 0x99de(%rip), %rdx      # 0xf292
movl $0x1, %esi
movl %ebp, %ecx
movl %ebx, %r8d
movq 0x8(%rsp), %r9
xorl %eax, %eax
callq 0x3240
movl $0x1, %edi
callq 0x3220