// File: /workspace/github_c_makefile_star2_O3/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 0x5728
movq %rsi, %rbx
movq 0x8(%rsi), %rcx
movzbl (%rcx), %edx
leal -0x2d(%rdx), %eax
negl %eax
cmpl $0x2d, %edx
jne 0x54a0
movzbl 0x1(%rcx), %esi
subl $0x79, %esi
jne 0x5482
movzbl 0x2(%rcx), %esi
negl %esi
testl %esi, %esi
je 0x570d
cmpb $0x2d, %dl
jne 0x54a0
movzbl 0x1(%rcx), %eax
subl $0x63, %eax
jne 0x549e
movzbl 0x2(%rcx), %eax
negl %eax
xorl %r14d, %r14d
cmpl $0x1, %eax
adcl $0x1, %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 0x574a
movq %r15, 0x28(%rsp)
testl %r15d, %r15d
setne %al
testl %r13d, %r13d
setne %cl
andb %al, %cl
cmpb $0x1, %cl
je 0x5753
movq 0x30(%rbx), %rbx
movq %rbx, %rdi
movl $0x2, %esi
xorl %eax, %eax
callq 0x31d0
testl %eax, %eax
js 0x575c
movl %eax, %r15d
leaq 0x30(%rsp), %rsi
movl %eax, %edi
callq 0x3eac
testl %eax, %eax
jne 0x5761
cmpb $0x0, 0xcb(%rsp)
jne 0x5786
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 0x3f3a
testl %eax, %eax
jne 0x579e
movq %r14, %rbp
shrq $0x10, %rbp
movq %r12, 0x20(%rsp)
leal -0x1(%r12), %ebx
leal (%rbx,%rbx,2), %r12d
leal -0x6f(%r12), %eax
movzbl %al, %r13d
movzbl %bpl, %edx
movl %r15d, %edi
movl %r13d, %esi
callq 0x3f3a
testl %eax, %eax
jne 0x5715
movq %r14, %rbp
shrq $0x8, %rbp
leal -0x70(%r12), %eax
movzbl %al, %r13d
movzbl %bpl, %edx
movl %r15d, %edi
movl %r13d, %esi
callq 0x3f3a
testl %eax, %eax
jne 0x5715
addb $-0x71, %r12b
movzbl %r14b, %edx
movzbl %r12b, %r13d
movl %r15d, %edi
movl %r13d, %esi
callq 0x3f3a
testl %eax, %eax
jne 0x57c7
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 0x3f3a
testl %eax, %eax
jne 0x57e6
movl %ebx, %eax
shrl %eax
movzbl %al, %ecx
leaq 0x34(%rcx), %rax
movb 0x64(%rsp,%rcx), %dl
movq 0x18(%rsp), %rsi
testl %esi, %esi
movl 0x14(%rsp), %r14d
je 0x569c
shll $0x2, %ebx
andb $0x4, %bl
movl %ebx, %ecx
shll %cl, %esi
orb %sil, %dl
jmp 0x56b1
shll $0x2, %r12d
andb $0x4, %r12b
movl $0xf, %esi
movl %r12d, %ecx
shll %cl, %esi
andb %sil, %dl
movzbl %al, %ebx
movzbl %dl, %ebp
movl %r15d, %edi
movl %ebx, %esi
movl %ebp, %edx
callq 0x3f3a
testl %eax, %eax
jne 0x5807
movq 0x8(%rsp), %rbx
movq %rbx, %rdi
movl %r15d, %esi
callq 0x514d
testl %eax, %eax
jne 0x582e
movl %r14d, %edi
movq %rbx, %rsi
movl %r15d, %edx
callq 0x5014
testl %eax, %eax
jne 0x582e
xorl %eax, %eax
addq $0x238, %rsp            # imm = 0x238
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorl %r14d, %r14d
jmp 0x54aa
movq 0x118d4(%rip), %rax     # 0x16ff0
movq (%rax), %rdi
movzbl %bpl, %ecx
jmp 0x57d5
movq 0x118c1(%rip), %rax     # 0x16ff0
movq (%rax), %rdi
leaq 0x9a1e(%rip), %rdx      # 0xf157
movl $0x1, %esi
xorl %eax, %eax
callq 0x3240
jmp 0x582e
leaq 0x9a69(%rip), %rsi      # 0xf1ba
jmp 0x578d
leaq 0x9a91(%rip), %rsi      # 0xf1eb
jmp 0x578d
callq 0x33d3
movq 0x11888(%rip), %rax     # 0x16ff0
movq (%rax), %rdi
leaq 0x8f93(%rip), %rdx      # 0xe705
movl $0x1, %esi
movq %rbx, %rcx
xorl %eax, %eax
callq 0x3240
jmp 0x582e
leaq 0x9aa1(%rip), %rsi      # 0xf22e
movl $0x1, %edi
xorl %eax, %eax
callq 0x31c0
jmp 0x582e
movq 0x1184b(%rip), %rax     # 0x16ff0
movq (%rax), %rdi
leaq 0x965d(%rip), %rdx      # 0xee0c
movl $0x1, %esi
movl $0xaf, %ecx
movq 0x8(%rsp), %r8
xorl %eax, %eax
callq 0x3240
jmp 0x582e
movq 0x11822(%rip), %rax     # 0x16ff0
movq (%rax), %rdi
movzbl %r14b, %ecx
leaq 0x8f7e(%rip), %rdx      # 0xe75a
movl $0x1, %esi
movl %r13d, %r8d
jmp 0x5822
movq 0x11803(%rip), %rax     # 0x16ff0
movq (%rax), %rdi
leaq 0x9a57(%rip), %rdx      # 0xf24e
movl $0x1, %esi
movl %r12d, %ecx
movl $0x9c, %r8d
jmp 0x5822
movq 0x117e2(%rip), %rax     # 0x16ff0
movq (%rax), %rdi
leaq 0x9a6b(%rip), %rdx      # 0xf283
movl $0x1, %esi
movl %ebp, %ecx
movl %ebx, %r8d
movq 0x8(%rsp), %r9
xorl %eax, %eax
callq 0x3240
movl $0x1, %edi
callq 0x3220