// File: /workspace/github_c_makefile_star2_O2/blasphemy[P]mmc-utils/mmc_cmds.c
// Function: do_enh_area_set
int do_enh_area_set(int nargs, char **argv)
{
	__u8 value;
	__u8 ext_csd[512];
	int fd, ret;
	char *device;
	int dry_run = 1;
	unsigned int start_kib, length_kib, enh_start_addr, enh_size_mult;
	unsigned long align;

	if (nargs != 5) {
		fprintf(stderr, "Usage: mmc enh_area set <-y|-n|-c> <start KiB> <length KiB> </path/to/mmcblkX>\n");
		exit(1);
	}

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

	start_kib = strtol(argv[2], NULL, 10);
	length_kib = strtol(argv[3], NULL, 10);
	device = argv[4];

	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 ENH_ATTRIBUTE_EN */
	if (!(ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & EXT_CSD_ENH_ATTRIBUTE_EN))
	{
		printf(" Device cannot have enhanced tech.\n");
		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);

	enh_size_mult = (length_kib + align/2l) / align;

	enh_start_addr = start_kib * (1024 / (is_blockaddresed(ext_csd) ? 512 : 1));
	enh_start_addr /= align;
	enh_start_addr *= 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);
	}

	/* write to ENH_START_ADDR and ENH_SIZE_MULT and PARTITIONS_ATTRIBUTE's ENH_USR bit */
	value = (enh_start_addr >> 24) & 0xff;
	ret = write_extcsd_value(fd, EXT_CSD_ENH_START_ADDR_3, value);
	if (ret) {
		fprintf(stderr, "Could not write 0x%02x to "
			"EXT_CSD[%d] in %s\n", value,
			EXT_CSD_ENH_START_ADDR_3, device);
		exit(1);
	}
	value = (enh_start_addr >> 16) & 0xff;
	ret = write_extcsd_value(fd, EXT_CSD_ENH_START_ADDR_2, value);
	if (ret) {
		fprintf(stderr, "Could not write 0x%02x to "
			"EXT_CSD[%d] in %s\n", value,
			EXT_CSD_ENH_START_ADDR_2, device);
		exit(1);
	}
	value = (enh_start_addr >> 8) & 0xff;
	ret = write_extcsd_value(fd, EXT_CSD_ENH_START_ADDR_1, value);
	if (ret) {
		fprintf(stderr, "Could not write 0x%02x to "
			"EXT_CSD[%d] in %s\n", value,
			EXT_CSD_ENH_START_ADDR_1, device);
		exit(1);
	}
	value = enh_start_addr & 0xff;
	ret = write_extcsd_value(fd, EXT_CSD_ENH_START_ADDR_0, value);
	if (ret) {
		fprintf(stderr, "Could not write 0x%02x to "
			"EXT_CSD[%d] in %s\n", value,
			EXT_CSD_ENH_START_ADDR_0, device);
		exit(1);
	}

	value = (enh_size_mult >> 16) & 0xff;
	ret = write_extcsd_value(fd, EXT_CSD_ENH_SIZE_MULT_2, value);
	if (ret) {
		fprintf(stderr, "Could not write 0x%02x to "
			"EXT_CSD[%d] in %s\n", value,
			EXT_CSD_ENH_SIZE_MULT_2, device);
		exit(1);
	}
	value = (enh_size_mult >> 8) & 0xff;
	ret = write_extcsd_value(fd, EXT_CSD_ENH_SIZE_MULT_1, value);
	if (ret) {
		fprintf(stderr, "Could not write 0x%02x to "
			"EXT_CSD[%d] in %s\n", value,
			EXT_CSD_ENH_SIZE_MULT_1, device);
		exit(1);
	}
	value = enh_size_mult & 0xff;
	ret = write_extcsd_value(fd, EXT_CSD_ENH_SIZE_MULT_0, value);
	if (ret) {
		fprintf(stderr, "Could not write 0x%02x to "
			"EXT_CSD[%d] in %s\n", value,
			EXT_CSD_ENH_SIZE_MULT_0, device);
		exit(1);
	}
	value = ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] | EXT_CSD_ENH_USR;
	ret = write_extcsd_value(fd, EXT_CSD_PARTITIONS_ATTRIBUTE, value);
	if (ret) {
		fprintf(stderr, "Could not write EXT_CSD_ENH_USR to "
			"EXT_CSD[%d] in %s\n",
			EXT_CSD_PARTITIONS_ATTRIBUTE, device);
		exit(1);
	}

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

	printf("Done setting ENH_USR area on %s\n", device);

	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 $0x208, %rsp            # imm = 0x208
cmpl $0x5, %edi
jne 0x5615
movq %rsi, %rbx
movq 0x8(%rsi), %rcx
movzbl (%rcx), %edx
leal -0x2d(%rdx), %eax
negl %eax
cmpl $0x2d, %edx
jne 0x53f8
movzbl 0x1(%rcx), %esi
subl $0x79, %esi
jne 0x53da
movzbl 0x2(%rcx), %esi
negl %esi
testl %esi, %esi
je 0x560e
cmpb $0x2d, %dl
jne 0x53f8
movzbl 0x1(%rcx), %eax
subl $0x63, %eax
jne 0x53f6
movzbl 0x2(%rcx), %eax
negl %eax
xorl %ebp, %ebp
cmpl $0x1, %eax
adcl $0x1, %ebp
movq 0x10(%rbx), %rdi
pushq $0xa
popq %r14
xorl %esi, %esi
movl %r14d, %edx
callq 0x3180
movq %rax, %r15
movq 0x18(%rbx), %rdi
xorl %esi, %esi
movl %r14d, %edx
callq 0x3180
movq %rax, %r12
movq 0x20(%rbx), %rbx
pushq $0x2
popq %rsi
movq %rbx, %rdi
xorl %eax, %eax
callq 0x31e0
testl %eax, %eax
js 0x5634
movl %eax, %r14d
movq %rsp, %rsi
movl %eax, %edi
callq 0x39b8
testl %eax, %eax
jne 0x5648
testb $0x2, 0xa0(%rsp)
je 0x566d
cmpb $0x0, 0x9b(%rsp)
jne 0x5676
movzbl 0xdd(%rsp), %eax
movzbl 0xe0(%rsp), %esi
imull %eax, %esi
shll $0x9, %esi
movl %r12d, %ecx
movl %esi, %eax
shrl %eax
addq %rcx, %rax
xorl %edx, %edx
divq %rsi
movq %rax, %r12
xorl %eax, %eax
cmpl $0x400001, 0xd4(%rsp) # imm = 0x400001
setb %al
leal (%rax,%rax,8), %ecx
incl %ecx
shll %cl, %r15d
movl %r15d, %eax
xorl %edx, %edx
divl %esi
movl %edx, %r13d
pushq $0x1
popq %rdx
movl %r14d, %edi
movl $0xaf, %esi
callq 0x3a43
testl %eax, %eax
jne 0x5690
subl %r13d, %r15d
movl %r15d, %r13d
shrl $0x18, %r13d
movl %r14d, %edi
movl $0x8b, %esi
movl %r13d, %edx
callq 0x3a43
testl %eax, %eax
jne 0x56b0
movl %r15d, %r13d
shrl $0x10, %r13d
movzbl %r13b, %edx
movl %r14d, %edi
movl $0x8a, %esi
callq 0x3a43
testl %eax, %eax
jne 0x56d4
movl %r15d, %r13d
shrl $0x8, %r13d
movzbl %r13b, %edx
movl %r14d, %edi
movl $0x89, %esi
callq 0x3a43
testl %eax, %eax
jne 0x56f9
movzbl %r15b, %edx
movl %r14d, %edi
movl $0x88, %esi
callq 0x3a43
testl %eax, %eax
jne 0x571e
movq %r12, %r15
shrq $0x10, %r15
movzbl %r15b, %edx
movl %r14d, %edi
movl $0x8e, %esi
callq 0x3a43
testl %eax, %eax
jne 0x5740
movq %r12, %r15
shrq $0x8, %r15
movzbl %r15b, %edx
movl %r14d, %edi
movl $0x8d, %esi
callq 0x3a43
testl %eax, %eax
jne 0x5762
movzbl %r12b, %edx
movl %r14d, %edi
movl $0x8c, %esi
callq 0x3a43
testl %eax, %eax
jne 0x5784
movzbl 0x9c(%rsp), %edx
orl $0x1, %edx
movl %r14d, %edi
movl $0x9c, %esi
callq 0x3a43
testl %eax, %eax
jne 0x57b0
movq %rbx, %rdi
movl %r14d, %esi
callq 0x4cac
testl %eax, %eax
jne 0x5640
leaq 0x9d7c(%rip), %rsi      # 0xf358
pushq $0x1
popq %rdi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x31d0
movl %ebp, %edi
movq %rbx, %rsi
movl %r14d, %edx
callq 0x4b8b
testl %eax, %eax
jne 0x5640
xorl %eax, %eax
addq $0x208, %rsp            # imm = 0x208
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorl %ebp, %ebp
jmp 0x5400
movq 0x129d4(%rip), %rax     # 0x17ff0
movq (%rax), %rdi
leaq 0x9c88(%rip), %rdx      # 0xf2ae
pushq $0x1
popq %rbx
movl %ebx, %esi
xorl %eax, %eax
callq 0x3250
jmp 0x5689
leaq 0xb9aa(%rip), %rdi      # 0x10fe5
callq 0x31f0
pushq $0x1
popq %rdi
callq 0x3230
movq 0x129a1(%rip), %rax     # 0x17ff0
movq (%rax), %rdi
leaq 0x90ac(%rip), %rdx      # 0xe705
pushq $0x1
popq %rbp
movl %ebp, %esi
movq %rbx, %rcx
xorl %eax, %eax
callq 0x3250
jmp 0x57d5
leaq 0x9c8a(%rip), %rsi      # 0xf2fe
jmp 0x567d
leaq 0x9bb1(%rip), %rsi      # 0xf22e
pushq $0x1
popq %rbx
movl %ebx, %edi
xorl %eax, %eax
callq 0x31d0
movl %ebx, %edi
callq 0x3230
movq 0x12959(%rip), %rax     # 0x17ff0
movq (%rax), %rdi
leaq 0x976b(%rip), %rdx      # 0xee0c
pushq $0x1
popq %rbp
movl %ebp, %esi
movl $0xaf, %ecx
jmp 0x57cb
movq 0x12939(%rip), %rax     # 0x17ff0
movq (%rax), %rdi
leaq 0x9099(%rip), %rdx      # 0xe75a
pushq $0x1
popq %rbp
movl %ebp, %esi
movl %r13d, %ecx
movl $0x8b, %r8d
jmp 0x57a4
movq 0x12915(%rip), %rax     # 0x17ff0
movq (%rax), %rdi
movzbl %r13b, %ecx
leaq 0x9071(%rip), %rdx      # 0xe75a
pushq $0x1
popq %rbp
movl %ebp, %esi
movl $0x8a, %r8d
jmp 0x57a4
movq 0x128f0(%rip), %rax     # 0x17ff0
movq (%rax), %rdi
movzbl %r13b, %ecx
leaq 0x904c(%rip), %rdx      # 0xe75a
pushq $0x1
popq %rbp
movl %ebp, %esi
movl $0x89, %r8d
jmp 0x57a4
movq 0x128cb(%rip), %rax     # 0x17ff0
movq (%rax), %rdi
movzbl %r15b, %ecx
leaq 0x9027(%rip), %rdx      # 0xe75a
pushq $0x1
popq %rbp
movl %ebp, %esi
movl $0x88, %r8d
jmp 0x57a4
movq 0x128a9(%rip), %rax     # 0x17ff0
movq (%rax), %rdi
movzbl %r15b, %ecx
leaq 0x9005(%rip), %rdx      # 0xe75a
pushq $0x1
popq %rbp
movl %ebp, %esi
movl $0x8e, %r8d
jmp 0x57a4
movq 0x12887(%rip), %rax     # 0x17ff0
movq (%rax), %rdi
movzbl %r15b, %ecx
leaq 0x8fe3(%rip), %rdx      # 0xe75a
pushq $0x1
popq %rbp
movl %ebp, %esi
movl $0x8d, %r8d
jmp 0x57a4
movq 0x12865(%rip), %rax     # 0x17ff0
movq (%rax), %rdi
movzbl %r12b, %ecx
leaq 0x8fc1(%rip), %rdx      # 0xe75a
pushq $0x1
popq %rbp
movl %ebp, %esi
movl $0x8c, %r8d
movq %rbx, %r9
xorl %eax, %eax
callq 0x3250
jmp 0x57d5
movq 0x12839(%rip), %rax     # 0x17ff0
movq (%rax), %rdi
leaq 0x9b61(%rip), %rdx      # 0xf322
pushq $0x1
popq %rbp
movl %ebp, %esi
movl $0x9c, %ecx
movq %rbx, %r8
xorl %eax, %eax
callq 0x3250
movl %ebp, %edi
callq 0x3230