// File: /workspace/github_c_makefile_star2_O1/blasphemy[P]mmc-utils/mmc_cmds.c
// Function: check_enhanced_area_total_limit
int check_enhanced_area_total_limit(const char * const device, int fd)
{
	__u8 ext_csd[512];
	__u32 regl;
	unsigned long max_enh_area_sz, user_area_sz, enh_area_sz = 0;
	unsigned long gp4_part_sz, gp3_part_sz, gp2_part_sz, gp1_part_sz;
	unsigned long total_sz, total_gp_user_sz;
	unsigned int wp_sz, erase_sz;
	int ret;

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

	regl = (ext_csd[EXT_CSD_GP_SIZE_MULT_4_2] << 16) |
		(ext_csd[EXT_CSD_GP_SIZE_MULT_4_1] << 8) |
		ext_csd[EXT_CSD_GP_SIZE_MULT_4_0];
	gp4_part_sz = 512l * regl * erase_sz * wp_sz;
	if (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & EXT_CSD_ENH_4) {
		enh_area_sz += gp4_part_sz;
		printf("Enhanced GP4 Partition Size [GP_SIZE_MULT_4]: 0x%06x\n", regl);
		printf(" i.e. %lu KiB\n", gp4_part_sz);
	}

	regl = (ext_csd[EXT_CSD_GP_SIZE_MULT_3_2] << 16) |
		(ext_csd[EXT_CSD_GP_SIZE_MULT_3_1] << 8) |
		ext_csd[EXT_CSD_GP_SIZE_MULT_3_0];
	gp3_part_sz = 512l * regl * erase_sz * wp_sz;
	if (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & EXT_CSD_ENH_3) {
		enh_area_sz += gp3_part_sz;
		printf("Enhanced GP3 Partition Size [GP_SIZE_MULT_3]: 0x%06x\n", regl);
		printf(" i.e. %lu KiB\n", gp3_part_sz);
	}

	regl = (ext_csd[EXT_CSD_GP_SIZE_MULT_2_2] << 16) |
		(ext_csd[EXT_CSD_GP_SIZE_MULT_2_1] << 8) |
		ext_csd[EXT_CSD_GP_SIZE_MULT_2_0];
	gp2_part_sz = 512l * regl * erase_sz * wp_sz;
	if (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & EXT_CSD_ENH_2) {
		enh_area_sz += gp2_part_sz;
		printf("Enhanced GP2 Partition Size [GP_SIZE_MULT_2]: 0x%06x\n", regl);
		printf(" i.e. %lu KiB\n", gp2_part_sz);
	}

	regl = (ext_csd[EXT_CSD_GP_SIZE_MULT_1_2] << 16) |
		(ext_csd[EXT_CSD_GP_SIZE_MULT_1_1] << 8) |
		ext_csd[EXT_CSD_GP_SIZE_MULT_1_0];
	gp1_part_sz = 512l * regl * erase_sz * wp_sz;
	if (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & EXT_CSD_ENH_1) {
		enh_area_sz += gp1_part_sz;
		printf("Enhanced GP1 Partition Size [GP_SIZE_MULT_1]: 0x%06x\n", regl);
		printf(" i.e. %lu KiB\n", gp1_part_sz);
	}

	regl = (ext_csd[EXT_CSD_ENH_SIZE_MULT_2] << 16) |
		(ext_csd[EXT_CSD_ENH_SIZE_MULT_1] << 8) |
		ext_csd[EXT_CSD_ENH_SIZE_MULT_0];
	user_area_sz = 512l * regl * erase_sz * wp_sz;
	if (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & EXT_CSD_ENH_USR) {
		enh_area_sz += user_area_sz;
		printf("Enhanced User Data Area Size [ENH_SIZE_MULT]: 0x%06x\n", regl);
		printf(" i.e. %lu KiB\n", user_area_sz);
	}

	regl = (ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT_2] << 16) |
		(ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT_1] << 8) |
		ext_csd[EXT_CSD_MAX_ENH_SIZE_MULT_0];
	max_enh_area_sz = 512l * regl * erase_sz * wp_sz;
	printf("Max Enhanced Area Size [MAX_ENH_SIZE_MULT]: 0x%06x\n", regl);
	printf(" i.e. %lu KiB\n", max_enh_area_sz);
	if (enh_area_sz > max_enh_area_sz) {
		fprintf(stderr,
			"Programmed total enhanced size %lu KiB cannot exceed max enhanced area %lu KiB %s\n",
			enh_area_sz, max_enh_area_sz, device);
		return 1;
	}
	total_sz = get_sector_count(ext_csd) / 2;
	total_gp_user_sz = gp4_part_sz + gp3_part_sz + gp2_part_sz +
				gp1_part_sz + user_area_sz;
	if (total_gp_user_sz > total_sz) {
		fprintf(stderr,
			"requested total partition size %lu KiB cannot exceed card capacity %lu KiB %s\n",
			total_gp_user_sz, total_sz, device);
		return 1;
	}

	return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x228, %rsp            # imm = 0x228
movl %esi, %eax
movq %rdi, %rbx
leaq 0x20(%rsp), %rsi
movl %eax, %edi
callq 0x3ef8
testl %eax, %eax
jne 0x54da
movzbl 0xfd(%rsp), %eax
movzbl 0x100(%rsp), %r13d
imulq %rax, %r13
movzbl 0xba(%rsp), %eax
shll $0x10, %eax
movzbl 0xb9(%rsp), %ecx
shll $0x8, %ecx
orl %eax, %ecx
movzbl 0xb8(%rsp), %edx
orl %ecx, %edx
movq %rdx, %r14
imulq %r13, %r14
shlq $0x9, %r14
testb $0x10, 0xbc(%rsp)
jne 0x5225
xorl %r15d, %r15d
jmp 0x5251
leaq 0x9d41(%rip), %rsi      # 0xef6d
movl $0x1, %edi
xorl %eax, %eax
callq 0x31c0
leaq 0x9d64(%rip), %rsi      # 0xefa3
movl $0x1, %edi
movq %r14, %rdx
xorl %eax, %eax
callq 0x31c0
movq %r14, %r15
movzbl 0xb7(%rsp), %eax
shll $0x10, %eax
movzbl 0xb6(%rsp), %ecx
shll $0x8, %ecx
orl %eax, %ecx
movzbl 0xb5(%rsp), %edx
orl %ecx, %edx
movq %r13, %r12
imulq %rdx, %r12
shlq $0x9, %r12
testb $0x8, 0xbc(%rsp)
je 0x52b4
addq %r12, %r15
leaq 0x9d20(%rip), %rsi      # 0xefb2
movl $0x1, %edi
xorl %eax, %eax
callq 0x31c0
leaq 0x9cfe(%rip), %rsi      # 0xefa3
movl $0x1, %edi
movq %r12, %rdx
xorl %eax, %eax
callq 0x31c0
movzbl 0xb4(%rsp), %eax
shll $0x10, %eax
movzbl 0xb3(%rsp), %ecx
shll $0x8, %ecx
orl %eax, %ecx
movzbl 0xb2(%rsp), %edx
orl %ecx, %edx
movq %r13, %rbp
imulq %rdx, %rbp
shlq $0x9, %rbp
testb $0x4, 0xbc(%rsp)
movq %rbx, 0x8(%rsp)
je 0x531c
addq %rbp, %r15
leaq 0x9cee(%rip), %rsi      # 0xefe8
movl $0x1, %edi
xorl %eax, %eax
callq 0x31c0
leaq 0x9c96(%rip), %rsi      # 0xefa3
movl $0x1, %edi
movq %rbp, %rdx
xorl %eax, %eax
callq 0x31c0
movzbl 0xb1(%rsp), %eax
shll $0x10, %eax
movzbl 0xb0(%rsp), %ecx
shll $0x8, %ecx
orl %eax, %ecx
movzbl 0xaf(%rsp), %edx
orl %ecx, %edx
movq %r13, %rbx
imulq %rdx, %rbx
shlq $0x9, %rbx
testb $0x2, 0xbc(%rsp)
movq %r14, 0x18(%rsp)
je 0x5384
addq %rbx, %r15
leaq 0x9cbc(%rip), %rsi      # 0xf01e
movl $0x1, %edi
xorl %eax, %eax
callq 0x31c0
leaq 0x9c2e(%rip), %rsi      # 0xefa3
movl $0x1, %edi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x31c0
movzbl 0xae(%rsp), %eax
shll $0x10, %eax
movzbl 0xad(%rsp), %ecx
shll $0x8, %ecx
orl %eax, %ecx
movzbl 0xac(%rsp), %edx
orl %ecx, %edx
movq %r13, %r14
imulq %rdx, %r14
shlq $0x9, %r14
testb $0x1, 0xbc(%rsp)
movq %r12, 0x10(%rsp)
je 0x53ec
addq %r14, %r15
leaq 0x9c8a(%rip), %rsi      # 0xf054
movl $0x1, %edi
xorl %eax, %eax
callq 0x31c0
leaq 0x9bc6(%rip), %rsi      # 0xefa3
movl $0x1, %edi
movq %r14, %rdx
xorl %eax, %eax
callq 0x31c0
movzbl 0xbf(%rsp), %eax
shll $0x10, %eax
movzbl 0xbe(%rsp), %ecx
shll $0x8, %ecx
orl %eax, %ecx
movzbl 0xbd(%rsp), %edx
orl %ecx, %edx
imulq %rdx, %r13
shlq $0x9, %r13
leaq 0x9c6d(%rip), %rsi      # 0xf08a
xorl %r12d, %r12d
movl $0x1, %edi
xorl %eax, %eax
callq 0x31c0
leaq 0x9b70(%rip), %rsi      # 0xefa3
movl $0x1, %edi
movq %r13, %rdx
xorl %eax, %eax
callq 0x31c0
cmpq %r13, %r15
jbe 0x5477
movq 0x11ba2(%rip), %rax     # 0x16ff0
movq (%rax), %rdi
leaq 0x9c66(%rip), %rdx      # 0xf0be
movl $0x1, %esi
movq %r15, %rcx
movq %r13, %r8
movq 0x8(%rsp), %r9
xorl %eax, %eax
callq 0x3240
movl $0x1, %r12d
jmp 0x54c5
movl 0xf4(%rsp), %r8d
shrl %r8d
movq 0x10(%rsp), %rax
addq 0x18(%rsp), %rax
addq %rbx, %rbp
addq %rax, %rbp
addq %r14, %rbp
cmpq %r8, %rbp
jbe 0x54c5
movq 0x11b4f(%rip), %rax     # 0x16ff0
movq (%rax), %rdi
leaq 0x9c66(%rip), %rdx      # 0xf111
movl $0x1, %r12d
movl $0x1, %esi
movq %rbp, %rcx
movq 0x8(%rsp), %r9
xorl %eax, %eax
callq 0x3240
movl %r12d, %eax
addq $0x228, %rsp            # imm = 0x228
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x11b0f(%rip), %rax     # 0x16ff0
movq (%rax), %rdi
leaq 0x921a(%rip), %rdx      # 0xe705
movl $0x1, %esi
movq %rbx, %rcx
xorl %eax, %eax
callq 0x3240
movl $0x1, %edi
callq 0x3220