// File: /workspace/github_c_makefile_star2_O1/blasphemy[P]mmc-utils/mmc_cmds.c
// Function: do_rpmb_op
static int do_rpmb_op(int fd,
					  const struct rpmb_frame *frame_in,
					  struct rpmb_frame *frame_out,
					  unsigned int out_cnt)
{
#ifndef MMC_IOC_MULTI_CMD
	fprintf(stderr, "mmc-utils has been compiled without MMC_IOC_MULTI_CMD"
		" support, needed by RPMB operation.\n");
	exit(1);
#else
	int err;
	u_int16_t rpmb_type;
	struct mmc_ioc_multi_cmd *mioc;
	struct mmc_ioc_cmd *ioc;
	struct rpmb_frame frame_status = {0};

	if (!frame_in || !frame_out || !out_cnt)
		return -EINVAL;

	/* prepare arguments for MMC_IOC_MULTI_CMD ioctl */
	mioc = (struct mmc_ioc_multi_cmd *)
		malloc(sizeof (struct mmc_ioc_multi_cmd) +
		       RPMB_MULTI_CMD_MAX_CMDS * sizeof (struct mmc_ioc_cmd));
	if (!mioc) {
		return -ENOMEM;
	}

	rpmb_type = be16toh(frame_in->req_resp);

	switch(rpmb_type) {
	case MMC_RPMB_WRITE:
	case MMC_RPMB_WRITE_KEY:
		if (out_cnt != 1) {
			err = -EINVAL;
			goto out;
		}

		mioc->num_of_cmds = 3;

		/* Write request */
		ioc = &mioc->cmds[0];
		set_single_cmd(ioc, MMC_WRITE_MULTIPLE_BLOCK, (1 << 31) | 1, 1);
		mmc_ioc_cmd_set_data((*ioc), frame_in);

		/* Result request */
		ioc = &mioc->cmds[1];
		frame_status.req_resp = htobe16(MMC_RPMB_READ_RESP);
		set_single_cmd(ioc, MMC_WRITE_MULTIPLE_BLOCK, 1, 1);
		mmc_ioc_cmd_set_data((*ioc), &frame_status);

		/* Get response */
		ioc = &mioc->cmds[2];
		set_single_cmd(ioc, MMC_READ_MULTIPLE_BLOCK, 0, 1);
		mmc_ioc_cmd_set_data((*ioc), frame_out);

		break;
	case MMC_RPMB_READ_CNT:
		if (out_cnt != 1) {
			err = -EINVAL;
			goto out;
		}
		/* fall through */

	case MMC_RPMB_READ:
		mioc->num_of_cmds = 2;

		/* Read request */
		ioc = &mioc->cmds[0];
		set_single_cmd(ioc, MMC_WRITE_MULTIPLE_BLOCK, 1, 1);
		mmc_ioc_cmd_set_data((*ioc), frame_in);

		/* Get response */
		ioc = &mioc->cmds[1];
		set_single_cmd(ioc, MMC_READ_MULTIPLE_BLOCK, 0, out_cnt);
		mmc_ioc_cmd_set_data((*ioc), frame_out);

		break;
	default:
		err = -EINVAL;
		goto out;
	}

	err = ioctl(fd, MMC_IOC_MULTI_CMD, mioc);

out:
	free(mioc);
	return err;
#endif /* !MMC_IOC_MULTI_CMD */
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x228, %rsp            # imm = 0x228
movl %ecx, %ebp
movq %rdx, %r14
movq %rsi, %r12
movl %edi, %r15d
leaq 0x28(%rsp), %r13
movl $0x200, %edx            # imm = 0x200
movq %r13, %rdi
xorl %esi, %esi
callq 0x30e0
testq %r12, %r12
sete %al
testq %r14, %r14
sete %cl
movl $0xffffffea, %ebx       # imm = 0xFFFFFFEA
orb %al, %cl
jne 0x74e0
movl %r15d, 0xc(%rsp)
movl $0xe0, %edi
callq 0x31a0
testq %rax, %rax
je 0x73ed
movq %rax, %r15
movzwl 0x1fe(%r12), %eax
rolw $0x8, %ax
movzwl %ax, %eax
movl $0xffffffea, %ebx       # imm = 0xFFFFFFEA
decl %eax
cmpl $0x3, %eax
ja 0x74d8
leaq 0x7322(%rip), %rcx      # 0xe65c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
cmpl $0x1, %ebp
jne 0x74d8
movq $0x3, (%r15)
movq $0x19, 0x10(%r15)
movl $0x80000001, 0x8(%r15)  # imm = 0x80000001
movl $0x1, 0x30(%r15)
movabsq $0x200000000b5, %rax    # imm = 0x200000000B5
movq %rax, 0x28(%r15)
movq %r12, 0x48(%r15)
movq %r15, %rsi
addq $0x50, %rsi
movw $0x500, 0x226(%rsp)     # imm = 0x500
movl $0xd8, %eax
movq %rax, 0x20(%rsp)
movl $0xb8, %eax
movq %rax, 0x18(%rsp)
movl $0x1, %ebp
movl $0xc0, %eax
movq %rax, 0x10(%rsp)
movl $0xbc, %edi
movl $0xa4, %r8d
movl $0xa0, %r9d
movl $0x98, %r10d
movl $0x90, %r11d
movl $0x70, %ebx
movl $0x78, %eax
movl $0x74, %ecx
movl $0x5c, %edx
movq %r13, %r12
movl $0x58, %r13d
jmp 0x7463
movl $0xfffffff4, %ebx       # imm = 0xFFFFFFF4
jmp 0x74e0
cmpl $0x1, %ebp
jne 0x74d8
movq $0x2, (%r15)
movq %r15, %rsi
addq $0x8, %rsi
movl $0x90, %eax
movq %rax, 0x20(%rsp)
movl $0x70, %eax
movq %rax, 0x18(%rsp)
movl $0x78, %eax
movq %rax, 0x10(%rsp)
movl $0x74, %edi
movl $0x5c, %r8d
movl $0x58, %r9d
movl $0x50, %r10d
movl $0x48, %r11d
movl $0x28, %ebx
movl $0x30, %eax
movl $0x2c, %ecx
movl $0x14, %edx
movl $0x10, %r13d
movl $0x19, (%r15,%r13)
movl $0x1, %r13d
movl %r13d, (%rsi)
xorl %esi, %esi
movl %esi, (%r15,%rdx)
movl $0x200, %edx            # imm = 0x200
movl %edx, (%r15,%rcx)
movl %r13d, (%r15,%rax)
movl $0xb5, %eax
movl %eax, (%r15,%rbx)
movq %r12, (%r15,%r11)
movl $0x12, (%r15,%r9)
movl %esi, (%r15,%r10)
movl %esi, (%r15,%r8)
movl %edx, (%r15,%rdi)
movq 0x10(%rsp), %rcx
movl %ebp, (%r15,%rcx)
movq 0x18(%rsp), %rcx
movl %eax, (%r15,%rcx)
movq 0x20(%rsp), %rax
movq %r14, (%r15,%rax)
movl $0xc008b301, %esi       # imm = 0xC008B301
movl 0xc(%rsp), %edi
movq %r15, %rdx
xorl %eax, %eax
callq 0x30f0
movl %eax, %ebx
movq %r15, %rdi
callq 0x3030
movl %ebx, %eax
addq $0x228, %rsp            # imm = 0x228
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq