// File: /workspace/github_cpp_makefile_star2_O1/CMU-SAFARI[P]MQSim/src/host/SATA_HBA.cpp
// Function: Host_Components::SATA_HBA::Execute_simulator_event(MQSimEngine::Sim_Event*)
void SATA_HBA::Execute_simulator_event(MQSimEngine::Sim_Event* event)
	{
		switch ((HBA_Sim_Events)event->Type)
		{
			case HBA_Sim_Events::CONSUME_IO_REQUEST:
			{
				Completion_Queue_Entry* cqe = consume_requests.front();
				consume_requests.pop();
				//Find the request and update statistics
				Host_IO_Request* request = sata_ncq.queue[cqe->Command_Identifier];
				sata_ncq.queue.erase(cqe->Command_Identifier);
				available_command_ids.insert(cqe->Command_Identifier);
				sata_ncq.Submission_queue_head = cqe->SQ_Head;

				((*IO_flows)[request->Source_flow_id])->SATA_consume_io_request(request);

				Update_and_submit_ncq_completion_info();

				//If the submission queue is not full anymore, then enqueue waiting requests
				while (waiting_requests_for_submission.size() > 0) {
					if (!SATA_SQ_FULL(sata_ncq) && available_command_ids.size() > 0)
					{
						Host_IO_Request* new_req = waiting_requests_for_submission.front();
						waiting_requests_for_submission.pop_front();
						if (sata_ncq.queue[*available_command_ids.begin()] != NULL) {
							PRINT_ERROR("Unexpteced situation in SATA_HBA! Overwriting a waiting I/O request in the queue!")
						} else {
							new_req->IO_queue_info = *available_command_ids.begin();
							sata_ncq.queue[*available_command_ids.begin()] = new_req;
							available_command_ids.erase(available_command_ids.begin());
							request_queue_in_memory[sata_ncq.Submission_queue_tail] = new_req;
							SATA_UPDATE_SQ_TAIL(sata_ncq);
						}
						new_req->Enqueue_time = Simulator->Time();
						pcie_root_complex->Write_to_device(sata_ncq.Submission_tail_register_address_on_device, sata_ncq.Submission_queue_tail);//Based on NVMe protocol definition, the updated tail pointer should be informed to the device
					} else {
						break;
					}
				}

				delete cqe;

				if(consume_requests.size() > 0) {
					Simulator->Register_sim_event(Simulator->Time() + hba_processing_delay, this, NULL, static_cast<int>(HBA_Sim_Events::CONSUME_IO_REQUEST));
				}
				break;
			}
			case HBA_Sim_Events::SUBMIT_IO_REQUEST:
			{
				Host_IO_Request* request = host_requests.front();
				host_requests.pop();

				//If the hardware queue is full
				if (SATA_SQ_FULL(sata_ncq) || available_command_ids.size() == 0) {
					waiting_requests_for_submission.push_back(request);
				} else {
					if (sata_ncq.queue[*available_command_ids.begin()] != NULL) {
						PRINT_ERROR("Unexpteced situation in IO_Flow_Base! Overwriting an unhandled I/O request in the queue!")
					} else {
						request->IO_queue_info = *available_command_ids.begin();
						sata_ncq.queue[*available_command_ids.begin()] = request;
						available_command_ids.erase(available_command_ids.begin());
						request_queue_in_memory[sata_ncq.Submission_queue_tail] = request;
						SATA_UPDATE_SQ_TAIL(sata_ncq);
					}
					request->Enqueue_time = Simulator->Time();
					pcie_root_complex->Write_to_device(sata_ncq.Submission_tail_register_address_on_device, sata_ncq.Submission_queue_tail);//Based on NVMe protocol definition, the updated tail pointer should be informed to the device
				}

				if (host_requests.size() > 0) {
					Simulator->Register_sim_event(Simulator->Time() + hba_processing_delay, this, NULL, static_cast<int>(HBA_Sim_Events::SUBMIT_IO_REQUEST));
				}

				break;
			}
		} //switch ((HBA_Sim_Events)event->Type)
	}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdi, %r14
movl 0x18(%rsi), %ebp
testl %ebp, %ebp
je 0x256f4
cmpl $0x1, %ebp
jne 0x2588e
movl %ebp, 0xc(%rsp)
leaq 0x110(%r14), %rdi
movq 0x120(%r14), %rax
movq (%rax), %r15
callq 0x25ee8
leaq 0x78(%r14), %r12
leaq 0xc(%r15), %rbp
movzwl 0xc(%r15), %eax
movq %rsp, %r13
movq %rax, (%r13)
movq %r12, %rdi
movq %r13, %rsi
callq 0x219d8
movq (%rax), %rbx
movzwl 0xc(%r15), %eax
movq %rax, (%r13)
movq %rsp, %rsi
movq %r12, %rdi
callq 0x21cae
leaq 0xb0(%r14), %r13
movq %r13, %rdi
movq %rbp, %rsi
callq 0x2178a
movq %r15, 0x10(%rsp)
movzwl 0x8(%r15), %eax
movw %ax, 0x48(%r14)
movq 0x40(%r14), %rax
movzwl 0x22(%rbx), %ecx
movq (%rax), %rax
movq (%rax,%rcx,8), %rdi
movq (%rdi), %rax
movq %rbx, %rsi
callq *0x30(%rax)
movl 0x60(%r14), %eax
incl %eax
xorl %ecx, %ecx
cmpw 0x64(%r14), %ax
cmovel %ecx, %eax
movw %ax, 0x60(%r14)
movq 0x38(%r14), %rdi
movq 0x68(%r14), %rsi
movzwl %ax, %edx
callq 0x24fea
movq 0x108(%r14), %rax
testq %rax, %rax
je 0x2568b
movq %rsp, %rbp
movzwl 0x4a(%r14), %ecx
movzwl 0x4c(%r14), %edx
decl %edx
cmpl %ecx, %edx
jle 0x2559c
incl %ecx
movzwl 0x48(%r14), %edx
cmpl %edx, %ecx
jne 0x255a8
jmp 0x2568b
cmpw $0x0, 0x48(%r14)
je 0x2568b
cmpq $0x0, 0xd8(%r14)
je 0x2568b
movq 0xf8(%r14), %rbx
movq 0x10(%rbx), %r15
decq %rax
movq %rax, 0x108(%r14)
movq %rbx, %rdi
callq 0x7580
movq %rbx, %rdi
callq 0x7370
movq 0xc8(%r14), %rax
movzwl 0x20(%rax), %eax
movq %rax, (%rsp)
movq %r12, %rdi
movq %rbp, %rsi
callq 0x219d8
cmpq $0x0, (%rax)
jne 0x2589d
movq 0xc8(%r14), %rax
movzwl 0x20(%rax), %ecx
movw %cx, 0x20(%r15)
movzwl 0x20(%rax), %eax
movq %rax, (%rsp)
movq %r12, %rdi
movq %rbp, %rsi
callq 0x219d8
movq %r15, (%rax)
movq 0xc8(%r14), %rsi
movq %r13, %rdi
callq 0x21d98
movzwl 0x4a(%r14), %eax
movq 0xe0(%r14), %rcx
movq %r15, (%rcx,%rax,8)
incl %eax
cmpw 0x4c(%r14), %ax
movl $0x0, %ecx
cmovel %ecx, %eax
movw %ax, 0x4a(%r14)
callq 0x281b4
movq %rax, %rdi
callq 0x285a6
movq %rax, 0x8(%r15)
movq 0x38(%r14), %rdi
movq 0x50(%r14), %rsi
movzwl 0x4a(%r14), %edx
callq 0x24fea
movq 0x108(%r14), %rax
testq %rax, %rax
jne 0x2557c
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x2569a
callq 0x7370
movq 0x158(%r14), %rax
movq %rax, %rcx
subq 0x138(%r14), %rcx
shrq $0x3, %rcx
cmpq $0x1, %rax
adcq $-0x1, %rcx
shlq $0x6, %rcx
movq 0x130(%r14), %rax
movq 0x140(%r14), %rdx
subq 0x148(%r14), %rdx
sarq $0x3, %rdx
addq %rcx, %rdx
subq 0x120(%r14), %rax
sarq $0x3, %rax
addq %rdx, %rax
movl 0xc(%rsp), %ebp
jne 0x25862
jmp 0x2588e
leaq 0x160(%r14), %rdi
movq 0x170(%r14), %rax
movq (%rax), %r12
callq 0x25f32
movzwl 0x4a(%r14), %eax
movzwl 0x4c(%r14), %ecx
decl %ecx
cmpl %eax, %ecx
jle 0x2572a
incl %eax
movzwl 0x48(%r14), %ecx
cmpl %ecx, %eax
jne 0x25736
jmp 0x257ee
cmpw $0x0, 0x48(%r14)
je 0x257ee
cmpq $0x0, 0xd8(%r14)
je 0x257ee
leaq 0x78(%r14), %r15
movq 0xc8(%r14), %rax
movzwl 0x20(%rax), %eax
movq %rsp, %rsi
movq %rax, (%rsi)
movq %r15, %rdi
callq 0x219d8
cmpq $0x0, (%rax)
jne 0x258e0
leaq 0xb0(%r14), %rbx
movq 0xc8(%r14), %rax
movzwl 0x20(%rax), %ecx
movw %cx, 0x20(%r12)
movzwl 0x20(%rax), %eax
movq %rsp, %rsi
movq %rax, (%rsi)
movq %r15, %rdi
callq 0x219d8
movq %r12, (%rax)
movq 0xc8(%r14), %rsi
movq %rbx, %rdi
callq 0x21d98
movzwl 0x4a(%r14), %eax
movq 0xe0(%r14), %rcx
movq %r12, (%rcx,%rax,8)
incl %eax
xorl %ecx, %ecx
cmpw 0x4c(%r14), %ax
cmovnel %eax, %ecx
movw %cx, 0x4a(%r14)
callq 0x281b4
movq %rax, %rdi
callq 0x285a6
movq %rax, 0x8(%r12)
movq 0x38(%r14), %rdi
movq 0x50(%r14), %rsi
movzwl 0x4a(%r14), %edx
callq 0x24fea
jmp 0x25815
leaq 0xf8(%r14), %rbx
movl $0x18, %edi
callq 0x73a0
movq %r12, 0x10(%rax)
movq %rax, %rdi
movq %rbx, %rsi
callq 0x7060
incq 0x108(%r14)
movq 0x1a8(%r14), %rax
movq %rax, %rcx
subq 0x188(%r14), %rcx
shrq $0x3, %rcx
cmpq $0x1, %rax
adcq $-0x1, %rcx
shlq $0x6, %rcx
movq 0x180(%r14), %rax
movq 0x190(%r14), %rdx
subq 0x198(%r14), %rdx
sarq $0x3, %rdx
addq %rcx, %rdx
subq 0x170(%r14), %rax
sarq $0x3, %rax
addq %rdx, %rax
je 0x2588e
callq 0x281b4
movq %rax, %rbx
callq 0x281b4
movq %rax, %rdi
callq 0x285a6
addq 0x30(%r14), %rax
movq %rbx, %rdi
movq %rax, %rsi
movq %r14, %rdx
xorl %ecx, %ecx
movl %ebp, %r8d
callq 0x285aa
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x4974c(%rip), %rbx     # 0x6eff0
leaq 0x30cfd(%rip), %rsi     # 0x565a8
movq %rbx, %rdi
callq 0x7390
leaq 0x32758(%rip), %rsi     # 0x58012
movq %rbx, %rdi
callq 0x7390
movq %rax, %rdi
callq 0x71c0
movq 0x496ff(%rip), %rdi     # 0x6efd0
callq 0x7430
movl $0x1, %edi
callq 0x7440
movq 0x49709(%rip), %rbx     # 0x6eff0
leaq 0x30cba(%rip), %rsi     # 0x565a8
movq %rbx, %rdi
callq 0x7390
leaq 0x3219d(%rip), %rsi     # 0x57a9a
jmp 0x258ba
nop