// File: CMU-SAFARI[P]MQSim/src/exec/Host_System.cpp
// Function: Host_System::Start_simulation()
void Host_System::Start_simulation()
{
	switch (ssd_device->Host_interface->GetType()) {
		case HostInterface_Types::NVME:
			for (uint16_t flow_cntr = 0; flow_cntr < IO_flows.size(); flow_cntr++) {
				((SSD_Components::Host_Interface_NVMe*) ssd_device->Host_interface)->Create_new_stream(
					IO_flows[flow_cntr]->Priority_class(),
					IO_flows[flow_cntr]->Get_start_lsa_on_device(), IO_flows[flow_cntr]->Get_end_lsa_address_on_device(),
					IO_flows[flow_cntr]->Get_nvme_queue_pair_info()->Submission_queue_memory_base_address, IO_flows[flow_cntr]->Get_nvme_queue_pair_info()->Completion_queue_memory_base_address);
			}
			break;
		case HostInterface_Types::SATA:
			((SSD_Components::Host_Interface_SATA*) ssd_device->Host_interface)->Set_ncq_address(
				SATA_hba->Get_sata_ncq_info()->Submission_queue_memory_base_address, SATA_hba->Get_sata_ncq_info()->Completion_queue_memory_base_address);
		default:
			break;
	}

	if (preconditioning_required) {
		std::vector<Utils::Workload_Statistics*> workload_stats = get_workloads_statistics();
		ssd_device->Perform_preconditioning(workload_stats);
		for (auto &stat : workload_stats) {
			delete stat;
		}
	}
}

// Assembly:
subq $0xd8, %rsp
movq %rdi, 0xd0(%rsp)
movq 0xd0(%rsp), %rax
movq %rax, 0x58(%rsp)
movq 0x70(%rax), %rax
movq 0x40(%rax), %rdi
callq 0x1fe10
movl %eax, %ecx
movl %ecx, 0x64(%rsp)
testl %eax, %eax
je 0x1f60e
jmp 0x1f4c9
movl 0x64(%rsp), %eax
subl $0x1, %eax
jne 0x1f656
jmp 0x1f4d8
movw $0x0, 0xce(%rsp)
movq 0x58(%rsp), %rdi
movzwl 0xce(%rsp), %eax
movq %rax, 0x50(%rsp)
addq $0x58, %rdi
callq 0xcdb0
movq %rax, %rcx
movq 0x50(%rsp), %rax
cmpq %rcx, %rax
jae 0x1f60c
movq 0x58(%rsp), %rdi
movq 0x70(%rdi), %rax
movq 0x40(%rax), %rax
movq %rax, 0x28(%rsp)
addq $0x58, %rdi
movzwl 0xce(%rsp), %eax
movl %eax, %esi
callq 0xcdd0
movq (%rax), %rdi
callq 0x20110
movq 0x58(%rsp), %rdi
movl %eax, 0x34(%rsp)
addq $0x58, %rdi
movzwl 0xce(%rsp), %eax
movl %eax, %esi
callq 0xcdd0
movq (%rax), %rdi
callq 0x32420
movq 0x58(%rsp), %rdi
movq %rax, 0x38(%rsp)
addq $0x58, %rdi
movzwl 0xce(%rsp), %eax
movl %eax, %esi
callq 0xcdd0
movq (%rax), %rdi
callq 0x32430
movq 0x58(%rsp), %rdi
movq %rax, 0x40(%rsp)
addq $0x58, %rdi
movzwl 0xce(%rsp), %eax
movl %eax, %esi
callq 0xcdd0
movq (%rax), %rdi
callq 0x32400
movq 0x58(%rsp), %rdi
movq 0x10(%rax), %rax
movq %rax, 0x48(%rsp)
addq $0x58, %rdi
movzwl 0xce(%rsp), %eax
movl %eax, %esi
callq 0xcdd0
movq (%rax), %rdi
callq 0x32400
movq 0x28(%rsp), %rdi
movl 0x34(%rsp), %esi
movq 0x38(%rsp), %rdx
movq 0x40(%rsp), %rcx
movq 0x48(%rsp), %r8
movq 0x28(%rax), %r9
callq 0x86cd0
movw 0xce(%rsp), %ax
addw $0x1, %ax
movw %ax, 0xce(%rsp)
jmp 0x1f4e2
jmp 0x1f658
movq 0x58(%rsp), %rax
movq 0x70(%rax), %rcx
movq 0x40(%rcx), %rcx
movq %rcx, 0x18(%rsp)
movq 0x50(%rax), %rdi
callq 0x40890
movq %rax, %rcx
movq 0x58(%rsp), %rax
movq 0x10(%rcx), %rcx
movq %rcx, 0x20(%rsp)
movq 0x50(%rax), %rdi
callq 0x40890
movq 0x18(%rsp), %rdi
movq 0x20(%rsp), %rsi
movq 0x28(%rax), %rdx
callq 0x8a520
jmp 0x1f658
movq 0x58(%rsp), %rax
testb $0x1, 0x78(%rax)
je 0x1f7a2
movq 0x58(%rsp), %rsi
leaq 0xb0(%rsp), %rdi
movq %rdi, 0x8(%rsp)
callq 0x1f7c0
movq 0x58(%rsp), %rax
movq 0x8(%rsp), %rsi
movq 0x70(%rax), %rax
movq %rax, 0x10(%rsp)
leaq 0x98(%rsp), %rdi
callq 0x20120
jmp 0x1f6a0
movq 0x10(%rsp), %rdi
leaq 0x98(%rsp), %rsi
callq 0x2c930
jmp 0x1f6b4
leaq 0x98(%rsp), %rdi
callq 0x20220
leaq 0xb0(%rsp), %rax
movq %rax, 0x80(%rsp)
movq 0x80(%rsp), %rdi
callq 0x20280
movq %rax, 0x78(%rsp)
movq 0x80(%rsp), %rdi
callq 0x202b0
movq %rax, 0x70(%rsp)
leaq 0x78(%rsp), %rdi
leaq 0x70(%rsp), %rsi
callq 0x202e0
testb $0x1, %al
jne 0x1f70a
jmp 0x1f784
leaq 0x78(%rsp), %rdi
callq 0x20320
movq %rax, 0x68(%rsp)
movq 0x68(%rsp), %rax
movq (%rax), %rax
movq %rax, (%rsp)
cmpq $0x0, %rax
je 0x1f73d
movq (%rsp), %rdi
callq 0x20330
movq (%rsp), %rdi
callq 0x8410
jmp 0x1f73f
leaq 0x78(%rsp), %rdi
callq 0x203c0
jmp 0x1f6f5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x90(%rsp)
movl %eax, 0x8c(%rsp)
jmp 0x1f793
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x90(%rsp)
movl %eax, 0x8c(%rsp)
leaq 0x98(%rsp), %rdi
callq 0x20220
jmp 0x1f793
leaq 0xb0(%rsp), %rdi
callq 0x20220
jmp 0x1f7a2
leaq 0xb0(%rsp), %rdi
callq 0x20220
jmp 0x1f7aa
addq $0xd8, %rsp
retq
movq 0x90(%rsp), %rdi
callq 0x8770
nopw (%rax,%rax)