From 9896d141d4c5506dfea588a85127c1002f7615d1 Mon Sep 17 00:00:00 2001 From: Zero Tang Date: Sun, 20 Sep 2020 02:06:10 +0800 Subject: [PATCH] Update by Sept.20th, 2020 Implemented many essential instructions. Implemented Memory Virtualization. --- .gitattributes | 3 + LICENSE | 2 +- README.md | 2 + compchk_win7x64.bat | 10 +- src/entry.c | 7 +- src/include/midef.h | 2 +- src/include/mipsdef.h | 12 +- src/include/simulation.h | 225 +++++++++++++++++++++++++++++ src/include/vmcb.h | 147 ++++++++++++++++++- src/sim-i.c | 250 ++++++++++++++++++++++++++++++++ src/sim-j.c | 36 +++++ src/sim-r.c | 302 +++++++++++++++++++++++++++++++++++++++ src/vcpu.c | 49 ++++++- 13 files changed, 1030 insertions(+), 17 deletions(-) create mode 100644 src/include/simulation.h create mode 100644 src/sim-i.c create mode 100644 src/sim-j.c create mode 100644 src/sim-r.c diff --git a/.gitattributes b/.gitattributes index dfe0770..4227428 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,5 @@ # Auto detect text files and perform LF normalization * text=auto +*.c linguist-language=C +*.h linguist-language=C +*.asm linguist-language=Assembly \ No newline at end of file diff --git a/LICENSE b/LICENSE index 37c9175..b595e92 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019 Zero Tang +Copyright (c) 2019-2020 Zero Tang Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index ced74f0..16c15bd 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,8 @@ To virtualize the processor, we implement the VMCB structure. VMCB is the acrony - Register File, including GPR and FPU - Execution Control, controlling the behavior of vCPU +Duly note that mipsivm simulates in LE byte order. + ### Glossary of Processor Virtualization | Acronyms | Abbreviated for | Explanation | | --------- | ----------------------------- | --------------------------------- | diff --git a/compchk_win7x64.bat b/compchk_win7x64.bat index 3d58559..bfa2736 100644 --- a/compchk_win7x64.bat +++ b/compchk_win7x64.bat @@ -14,9 +14,15 @@ pause echo ============Start Compiling============ %ddkpath%\amd64\cl.exe .\src\entry.c /I"%incpath%\api" /I"%incpath%\crt" /I".\src\include" /Zi /nologo /W3 /WX /Od /D"_msvc" /D"_amd64" /Zc:wchar_t /Zc:forScope /FAcs /Fa"%objpath%\entry.cod" /Fo"%objpath%\entry.obj" /Fd"%objpath%\vc90.pdb" /GS- /Gd /TC /c /errorReport:queue -%ddkpath%\amd64\cl.exe .\src\vcpu.c /I".\src\include" /Zi /nologo /W3 /WX /Oi /Od /D"_msvc" /D"_amd64" /Zc:wchar_t /Zc:forScope /FAcs /Fa"%objpath%\vcpu.cod" /Fo"%objpath%\vcpu.obj" /Fd"%objpath%\vc90.pdb" /GS- /Gd /TC /c /errorReport:queue +%ddkpath%\amd64\cl.exe .\src\vcpu.c /I".\src\include" /Zi /nologo /W3 /WX /Oi /Od /D"_msvc" /D"_amd64" /D"_mips_hvm" /Zc:wchar_t /Zc:forScope /FAcs /Fa"%objpath%\vcpu.cod" /Fo"%objpath%\vcpu.obj" /Fd"%objpath%\vc90.pdb" /GS- /Gd /TC /c /errorReport:queue + +%ddkpath%\amd64\cl.exe .\src\sim-r.c /I".\src\include" /Zi /nologo /W3 /WX /Oi /Od /D"_msvc" /D"_amd64" /D"_mips_simr" /Zc:wchar_t /Zc:forScope /FAcs /Fa"%objpath%\sim-r.cod" /Fo"%objpath%\sim-r.obj" /Fd"%objpath%\vc90.pdb" /GS- /Gd /TC /c /errorReport:queue + +%ddkpath%\amd64\cl.exe .\src\sim-i.c /I".\src\include" /Zi /nologo /W3 /WX /Oi /Od /D"_msvc" /D"_amd64" /D"_mips_simi" /Zc:wchar_t /Zc:forScope /FAcs /Fa"%objpath%\sim-i.cod" /Fo"%objpath%\sim-i.obj" /Fd"%objpath%\vc90.pdb" /GS- /Gd /TC /c /errorReport:queue + +%ddkpath%\amd64\cl.exe .\src\sim-j.c /I".\src\include" /Zi /nologo /W3 /WX /Oi /Od /D"_msvc" /D"_amd64" /D"_mips_simj" /Zc:wchar_t /Zc:forScope /FAcs /Fa"%objpath%\sim-j.cod" /Fo"%objpath%\sim-j.obj" /Fd"%objpath%\vc90.pdb" /GS- /Gd /TC /c /errorReport:queue echo ============Start Linking============ -%ddkpath%\amd64\link.exe "%objpath%\vcpu.obj" "%objpath%\entry.obj" /LIBPATH:"%libpath%\win7\amd64" /LIBPATH:"%libpath%\Crt\amd64" /NODEFAULTLIB "msvcrt.lib" /NOLOGO /DEBUG /PDB:"%objpath%\mipsivm.pdb" /INCREMENTAL:NO /OUT:"%binpath%\mipsivm.exe" /SUBSYSTEM:CONSOLE /ENTRY:"main" /Machine:X64 /ERRORREPORT:QUEUE +%ddkpath%\amd64\link.exe "%objpath%\vcpu.obj" "%objpath%\entry.obj" "%objpath%\sim-r.obj" "%objpath%\sim-i.obj" "%objpath%\sim-j.obj" /LIBPATH:"%libpath%\win7\amd64" /LIBPATH:"%libpath%\Crt\amd64" /NODEFAULTLIB "msvcrt.lib" /NOLOGO /DEBUG /PDB:"%objpath%\mipsivm.pdb" /INCREMENTAL:NO /OUT:"%binpath%\mipsivm.exe" /SUBSYSTEM:CONSOLE /ENTRY:"main" /Machine:X64 /ERRORREPORT:QUEUE pause \ No newline at end of file diff --git a/src/entry.c b/src/entry.c index c327c5e..ee6217b 100644 --- a/src/entry.c +++ b/src/entry.c @@ -1,7 +1,7 @@ /* mipsivm - MIPS Interpreting Virtual Machine - Copyright 2018-2019, Yaotian "Zero" Tang. All rights reserved. + Copyright 2018-2020, Yaotian "Zero" Tang. All rights reserved. This file is the entry module of mipsivm program. @@ -9,14 +9,17 @@ without any warranty (no matter implied warranty or merchantability or fitness for a particular purpose, etc.). - File Location: /include/entry.c + File Location: /entry.c */ #include #include #include +#include void main() { printf("Welcome to mipsivm!\n"); + printf("Powered by Yaotian \"Zero\" Tang. All rights reserved.\n"); + system("pause"); } \ No newline at end of file diff --git a/src/include/midef.h b/src/include/midef.h index bfb2578..f9ce0d6 100644 --- a/src/include/midef.h +++ b/src/include/midef.h @@ -1,7 +1,7 @@ /* mipsivm - MIPS Interpreting Virtual Machine - Copyright 2018-2019, Yaotian "Zero" Tang. All rights reserved. + Copyright 2018-2020, Yaotian "Zero" Tang. All rights reserved. This file defines basic types, constants, etc. diff --git a/src/include/mipsdef.h b/src/include/mipsdef.h index 3004caa..5c48e47 100644 --- a/src/include/mipsdef.h +++ b/src/include/mipsdef.h @@ -1,7 +1,7 @@ /* mipsivm - MIPS Interpreting Virtual Machine - Copyright 2018-2019, Yaotian "Zero" Tang. All rights reserved. + Copyright 2018-2020, Yaotian "Zero" Tang. All rights reserved. This file defines instructions of MIPS. @@ -69,6 +69,7 @@ typedef union _mips_instruction #define j_format 3 #define f_format 4 +#if defined(_mips_hvm) u8 mips_opcode_class[64]= { r_format, // 0x00 @@ -376,4 +377,11 @@ char* mips_fpu_funct_string[64]= "c.nge.f", // 0x3D "c.le.f", // 0x3E "c.ngt.f" // 0x3F -}; \ No newline at end of file +}; +#else +extern u8* mips_opcode_class; +extern char** mips_gpr_string; +extern char** mips_cpu_opcode_string; +extern char** mips_cpu_funct_string; +extern char** mips_fpu_funct_string; +#endif \ No newline at end of file diff --git a/src/include/simulation.h b/src/include/simulation.h new file mode 100644 index 0000000..3232ff2 --- /dev/null +++ b/src/include/simulation.h @@ -0,0 +1,225 @@ +/* + mipsivm - MIPS Interpreting Virtual Machine + + Copyright 2018-2020, Yaotian "Zero" Tang. All rights reserved. + + This file declares all simulated procedures. + + This program is distributed in the hope that it will be useful, but + without any warranty (no matter implied warranty or merchantability + or fitness for a particular purpose, etc.). + + File Location: /include/simulation.h +*/ + +#include "midef.h" + +typedef void (*mips_interpreter_procedure) +( + vmcb_p vcpu, + mips_instruction instruction +); + +// R-Format Instructions +void mips_interpreter_r_sll(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_srl(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_sra(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_sllv(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_srlv(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_srav(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_jr(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_jalr(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_movz(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_movn(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_syscall(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_break(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_sync(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_mfhi(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_mthi(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_mflo(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_mtlo(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_mult(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_multu(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_div(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_divu(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_add(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_addu(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_sub(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_subu(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_and(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_or(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_xor(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_nor(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_slt(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_sltu(vmcb_p vcpu,mips_instruction instruction); + +// I-Format Instructions +void mips_interpreter_i_beq(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_i_bne(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_i_blez(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_i_bgtz(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_i_addi(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_i_addiu(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_i_slti(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_i_sltiu(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_i_andi(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_i_ori(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_i_xori(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_i_lui(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_i_lb(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_i_lh(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_i_lw(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_i_lbu(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_i_lhu(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_i_sb(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_i_sh(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_i_sw(vmcb_p vcpu,mips_instruction instruction); + +// J-Format Instructions +void mips_interpreter_j_j(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_j_jal(vmcb_p vcpu,mips_instruction instruction); + +// Miscellaneous +void mips_interpreter_unhandled_instruction(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_r_format(vmcb_p vcpu,mips_instruction instruction); +void mips_interpreter_fpu(vmcb_p vcpu,mips_instruction instruction); + +#if defined(_mips_hvm) +mips_interpreter_procedure cpu_interpreter_by_opcode[64]= +{ + mips_interpreter_r_format, + mips_interpreter_unhandled_instruction, + mips_interpreter_j_j, + mips_interpreter_j_jal, + mips_interpreter_i_beq, + mips_interpreter_i_bne, + mips_interpreter_i_blez, + mips_interpreter_i_bgtz, + mips_interpreter_i_addi, + mips_interpreter_i_addiu, + mips_interpreter_i_slti, + mips_interpreter_i_sltiu, + mips_interpreter_i_andi, + mips_interpreter_i_ori, + mips_interpreter_i_xori, + mips_interpreter_i_lui, + mips_interpreter_unhandled_instruction, + mips_interpreter_fpu, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_i_lb, + mips_interpreter_i_lh, + mips_interpreter_unhandled_instruction, + mips_interpreter_i_lw, + mips_interpreter_i_lbu, + mips_interpreter_i_lhu, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_i_sb, + mips_interpreter_i_sh, + mips_interpreter_unhandled_instruction, + mips_interpreter_i_sw, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction +}; + +mips_interpreter_procedure cpu_interpreter_r_funct[64]= +{ + mips_interpreter_r_sll, + mips_interpreter_unhandled_instruction, + mips_interpreter_r_srl, + mips_interpreter_r_sra, + mips_interpreter_r_sllv, + mips_interpreter_unhandled_instruction, + mips_interpreter_r_srlv, + mips_interpreter_r_srav, + mips_interpreter_r_jr, + mips_interpreter_r_jalr, + mips_interpreter_r_movz, + mips_interpreter_r_movn, + mips_interpreter_r_syscall, + mips_interpreter_r_break, + mips_interpreter_unhandled_instruction, + mips_interpreter_r_sync, + mips_interpreter_r_mfhi, + mips_interpreter_r_mthi, + mips_interpreter_r_mflo, + mips_interpreter_r_mtlo, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_r_mult, + mips_interpreter_r_multu, + mips_interpreter_r_div, + mips_interpreter_r_divu, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_r_add, + mips_interpreter_r_addu, + mips_interpreter_r_sub, + mips_interpreter_r_subu, + mips_interpreter_r_and, + mips_interpreter_r_or, + mips_interpreter_r_xor, + mips_interpreter_r_nor, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_r_slt, + mips_interpreter_r_sltu, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction, + mips_interpreter_unhandled_instruction +}; + +mips_interpreter_procedure fpu_interpreter[64]; +#endif \ No newline at end of file diff --git a/src/include/vmcb.h b/src/include/vmcb.h index 56489ab..c484e97 100644 --- a/src/include/vmcb.h +++ b/src/include/vmcb.h @@ -1,7 +1,7 @@ /* mipsivm - MIPS Interpreting Virtual Machine - Copyright 2018-2019, Yaotian "Zero" Tang. All rights reserved. + Copyright 2018-2020, Yaotian "Zero" Tang. All rights reserved. This file defines the VMCB - Virtual Machine Control Block @@ -14,15 +14,150 @@ #include "midef.h" +// We use paging to virtualize memory. +// In this way, we may virtualize memory with finest granularity of 4KiB. +// Principle: Unreadable Page is Not Present. Page not-present grants NO-ACCESS. +#if defined(_amd64) +// If mipsivm is built as a 64-bit program. We are using 3-Level Paging. +typedef union _l3p_address +{ + struct + { + u32 pdpte:2; + u32 pde:9; + u32 pte:9; + u32 offset:12; + }; + u32 value; +}l3p_address,*l3p_address_p; + +// Page-Directory Pointer Table Entry (PDPTE) is the top level. +// Each L3P PDPTE supervises 1GiB of memory. +typedef union _l3p_pdpte +{ + struct + { + u64 r:1; // Permission for Read. + u64 w:1; // Permission for Write + u64 x:1; // Permission for Execute + u64 a:1; // This Page was Accessed + u64 rsvd:8; // Reserved + u64 pde_page:52; // Points to 512 Entries of PDE + }; + u64 value; +}l3p_pdpte,*l3p_pdpte_p; + +// Page Directory Entry (PDE) is the second level. +// Each L3P PDE supervises 2MiB of memory. +typedef union _l3p_pde +{ + struct + { + u64 r:1; // Permission for Read + u64 w:1; // Permission for Write + u64 x:1; // Permission for Execute + u64 a:1; // This Page was Accessed + u64 rsvd:8; // Reserved + u64 pte_page:52; // Points to 512 Entries of PTE + }; + u64 value; +}l3p_pde,*l3p_pde_p; + +// Page Table Entry (PTE) is the final level. +// Each L3P PTE supervises 4KiB of memory. +typedef union _l3p_pte +{ + struct + { + u64 r:1; // Permission for Read + u64 w:1; // Permission for Write + u64 x:1; // Permission for Execute + u64 a:1; // This Page was Accessed + u64 d:1; // This Page was Dirty. This is a PTE-only field. + u64 rsvd:7; // Reserved + u64 page_base:52; // Points to the Address of Page + }; + u64 value; +}l3p_pte,*l3p_pte_p; +#else +// If mipsivm is built as a 32-bit program. We are using 2-Level Paging. +typedef union _l2p_address +{ + struct + { + u32 pde:10; + u32 pte:10; + u32 offset:12; + }; + u32 value; +}l2p_address,*l2p_address_p; + +// Page Directory Entry (PDE) is the first level. +// Each L2P PDE supervises 4MiB of memory. +typedef union _l2p_pde +{ + struct + { + u32 r:1; // Permission for Read + u32 w:1; // Permission for Write + u32 x:1; // Permission for Execute + u32 a:1; // This Page was Accessed + u32 d:1; // This Page was Dirty + u32 rsvd:7; // Reserved + u32 pte_page:20; // Points to 512 Entries of PTE + }; + u32 value; +}l2p_pde,*l2p_pde_p; + +// Page Table Entry (PTE) is the final level. +// Each L2P PTE supervises 4KiB of memory. +typedef union _l2p_pte +{ + struct + { + u32 r:1; // Permission for Read + u32 w:1; // Permission for Write + u32 x:1; // Permission for Execute + u32 a:1; // This Page was Accessed + u32 d:1; // This Page was Dirty + u32 rsvd:7; // Reserved + u32 page_base:20; // Points to the Address of Page + }; + u32 value; +}l2p_pte,*l2p_pte_p; +#endif + // VMCB - Virtual Machine Control Block // This is Core Structure of vCPU. typedef struct _vmcb { struct { - u32 reg[32]; - large_integer v; - u32 pc; + union + { + u32 ureg[32]; // 32-bit Unsigned General-Purpose Registers + i32 ireg[32]; // 32-bit Signed General-Purpose Registers + }; + large_integer v; // 64-bit Multiply-Divide Register + u32 pc; // 32-bit Program-Counter Register }gpr; - u32 fpr[32]; -}vmcb,*vmcb_p; \ No newline at end of file + u32 flags; // vCPU Running Flags. + u32 fpr[32]; // 32-bit Floating-Point Registers. + // NPT is acronym that stands for "Nested Page Table" +#if defined(_amd64) + l3p_pdpte_p npt_base; // Points to 4 Entries of PDPTE +#else + l2p_pde_p npt_base; // Points to 512 Entries of PDE +#endif + u64 tsc; // Time-Stamp Counter, aka TSC, Processor Ticks. +}vmcb,*vmcb_p; + +// Virtual Machine. +// This is abstraction of a machine +typedef struct _mips_vm +{ + vmcb vcpu; // We support one vCPU right now. + void* mem; // All memory. +}mips_vm,*mips_vm_p; + +void* mips_ref_hmem(vmcb_p vcpu,u32 gpa,bool r,bool w,bool x); \ No newline at end of file diff --git a/src/sim-i.c b/src/sim-i.c new file mode 100644 index 0000000..752b6ac --- /dev/null +++ b/src/sim-i.c @@ -0,0 +1,250 @@ +/* + mipsivm - MIPS Interpreting Virtual Machine + + Copyright 2018-2020, Yaotian "Zero" Tang. All rights reserved. + + This file simulates I-Format instructions for the virtual CPU. + + This program is distributed in the hope that it will be useful, but + without any warranty (no matter implied warranty or merchantability + or fitness for a particular purpose, etc.). + + File Location: /sim-i.c +*/ + +#include +#include +#include + +void mips_interpreter_i_beq(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Branch if Equal + // Formula: if rs==rt then pc+=(imm<<2)+4 + const i32 imm=(i32)instruction.i.imm; + const u32 rs=instruction.i.rs,rt=instruction.i.rt; + if(vcpu->gpr.ireg[rs]==vcpu->gpr.ireg[rt]) + vcpu->gpr.pc+=(imm<<2); + vcpu->gpr.pc+=4; +} + +void mips_interpreter_i_bne(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Branch if Not Equal + // Formula: if rs!=rt then pc+=(imm<<2)+4 + const i32 imm=(i32)instruction.i.imm; + const u32 rs=instruction.i.rs,rt=instruction.i.rt; + if(vcpu->gpr.ireg[rs]!=vcpu->gpr.ireg[rt]) + vcpu->gpr.pc+=(imm<<2); + vcpu->gpr.pc+=4; +} + +void mips_interpreter_i_blez(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Branch if Less than or Equal to Zero + // Formula: if rs<=0 then pc+=(imm<<2)+4 + const i32 imm=(i32)instruction.i.imm; + const u32 rs=instruction.i.rs; + if(vcpu->gpr.ireg[rs]<=0)vcpu->gpr.pc+=(imm<<2); + vcpu->gpr.pc+=4; +} + +void mips_interpreter_i_bgtz(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Branch if Greater Than Zero + // Formula: if rs>0 then pc+=(imm<<2)+4 + const i32 imm=(i32)instruction.i.imm; + const u32 rs=instruction.i.rs; + if(vcpu->gpr.ireg[rs]>0)vcpu->gpr.pc+=(imm<<2); + vcpu->gpr.pc+=4; +} + +void mips_interpreter_i_addi(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Add Immediate + // Formula: rt=rs+imm + const i32 imm=(i32)instruction.i.imm; + const u32 rs=instruction.i.rs,rt=instruction.i.rt; + vcpu->gpr.ireg[rt]=vcpu->gpr.ireg[rs]+imm; + vcpu->gpr.pc+=4; +} + +void mips_interpreter_i_addiu(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Add Immediate Unsigned + // Formula: rt=rs+imm + const u32 imm=(u32)instruction.i.imm; + const u32 rs=instruction.i.rs,rt=instruction.i.rt; + vcpu->gpr.ureg[rt]=vcpu->gpr.ureg[rs]+imm; + vcpu->gpr.pc+=4; +} + +void mips_interpreter_i_slti(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Set if Less Than Immediate + // Formula: rt=(rsgpr.ireg[rt]=vcpu->gpr.ireg[rs]gpr.pc+=4; +} + +void mips_interpreter_i_sltiu(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Set if Less Than Immediate Unsigned + // Formula: rt=(rsgpr.ureg[rt]=vcpu->gpr.ureg[rs]gpr.pc+=4; +} + +void mips_interpreter_i_andi(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Logical And Immediate + // Formula: rt=(rs&imm) + const u32 imm=(u32)instruction.i.imm; + const u32 rs=instruction.i.rs,rt=instruction.i.rt; + vcpu->gpr.ureg[rt]=vcpu->gpr.ureg[rs]&imm; + vcpu->gpr.pc+=4; +} + +void mips_interpreter_i_ori(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Logical Or Immediate + // Formula: rt=(rs|imm) + const u32 imm=(u32)instruction.i.imm; + const u32 rs=instruction.i.rs,rt=instruction.i.rt; + vcpu->gpr.ureg[rt]=vcpu->gpr.ureg[rs]|imm; + vcpu->gpr.pc+=4; +} + +void mips_interpreter_i_xori(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Logical Exclusive Or Immediate + // Formula: rt=(rs^imm) + const u32 imm=(u32)instruction.i.imm; + const u32 rs=instruction.i.rs,rt=instruction.i.rt; + vcpu->gpr.ureg[rt]=vcpu->gpr.ureg[rs]^imm; + vcpu->gpr.pc+=4; +} + +void mips_interpreter_i_lui(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Load Upper Immediate + // Formula: rt=imm<<16 + const u32 imm=(u32)instruction.i.imm; + const u32 rt=instruction.i.rt; + vcpu->gpr.ureg[rt]=imm<<16; + vcpu->gpr.pc+=4; +} + +void mips_interpreter_i_lb(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Load Byte Signed + // Formula (x86 Asm): movsx rt,byte ptr[rs+imm] + const i32 imm=(i32)instruction.i.imm; + const u32 rs=instruction.i.rs,rt=instruction.i.rt; + const u32 gpa=(u32)(vcpu->gpr.ureg[rs]+imm); + i8* hva=(i8*)mips_ref_hmem(vcpu,gpa,true,false,false); + if(hva)vcpu->gpr.ireg[rt]=(i32)(*hva); + vcpu->gpr.pc+=4; +} + +void mips_interpreter_i_lh(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Load Halfword Signed + // Formula (x86 Asm): movsx rt,word ptr[rs+imm] + const i32 imm=(i32)instruction.i.imm; + const u32 rs=instruction.i.rs,rt=instruction.i.rt; + const u32 gpa=(u32)(vcpu->gpr.ureg[rs]+imm); + if((gpa & 1)==0) // Alignment Check + { + i16* hva=(i16*)mips_ref_hmem(vcpu,gpa,true,false,false); + if(hva)vcpu->gpr.ireg[rt]=(i32)(*hva); + } + vcpu->gpr.pc+=4; +} + +void mips_interpreter_i_lw(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Load Word + // Formula (x86 Asm): mov rt,dword ptr[rs+imm] + const i32 imm=(i32)instruction.i.imm; + const u32 rs=instruction.i.rs,rt=instruction.i.rt; + const u32 gpa=(u32)(vcpu->gpr.ureg[rs]+imm); + if((gpa & 3)==0) // Alignment Check + { + i32* hva=(i32*)mips_ref_hmem(vcpu,gpa,true,false,false); + if(hva)vcpu->gpr.ireg[rt]=*hva; + } + vcpu->gpr.pc+=4; +} + +void mips_interpreter_i_lbu(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Load Byte Unsigned + // Formula (x86 Asm): movzx rt,byte ptr[rs+imm] + const i32 imm=(i32)instruction.i.imm; + const u32 rs=instruction.i.rs,rt=instruction.i.rt; + const u32 gpa=(u32)(vcpu->gpr.ureg[rs]+imm); + u8* hva=(u8*)mips_ref_hmem(vcpu,gpa,true,false,false); + if(hva)vcpu->gpr.ureg[rt]=(u32)(*hva); + vcpu->gpr.pc+=4; +} + +void mips_interpreter_i_lhu(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Load Halfword Unsigned + // Formula (x86 Asm): movzx rt,word ptr[rs+imm] + const i32 imm=(i32)instruction.i.imm; + const u32 rs=instruction.i.rs,rt=instruction.i.rt; + const u32 gpa=(u32)(vcpu->gpr.ureg[rs]+imm); + if((gpa & 1)==0) // Alignment Check + { + u16* hva=(u16*)mips_ref_hmem(vcpu,gpa,true,false,false); + if(hva)vcpu->gpr.ureg[rt]=(u32)(*hva); + } + vcpu->gpr.pc+=4; +} + +void mips_interpreter_i_sb(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Store Byte + // Formula (x86 Asm): mov byte ptr[rs+imm],rtb + const i32 imm=(i32)instruction.i.imm; + const u32 rs=instruction.i.rs,rt=instruction.i.rt; + const u32 gpa=(u32)(vcpu->gpr.ureg[rs]+imm); + u8* hva=(u8*)mips_ref_hmem(vcpu,gpa,true,true,false); + if(hva)*hva=(u8)vcpu->gpr.ureg[rt]; + vcpu->gpr.pc+=4; +} + +void mips_interpreter_i_sh(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Store Halfword + // Formula (x86 Asm): mov word ptr[rs+imm],rtw + const i32 imm=(i32)instruction.i.imm; + const u32 rs=instruction.i.rs,rt=instruction.i.rt; + const u32 gpa=(u32)(vcpu->gpr.ureg[rs]+imm); + if((gpa & 1)==0) // Alignment Check + { + u16* hva=(u16*)mips_ref_hmem(vcpu,gpa,true,true,false); + if(hva)*hva=(u16)vcpu->gpr.ureg[rt]; + } + vcpu->gpr.pc+=4; +} + +void mips_interpreter_i_sw(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Store Word + // Formula (x86 Asm): mov dword ptr[rs+imm],rt + const i32 imm=(i32)instruction.i.imm; + const u32 rs=instruction.i.rs,rt=instruction.i.rt; + const u32 gpa=(u32)(vcpu->gpr.ureg[rs]+imm); + if((gpa & 3)==0) // Alignment Check + { + u32* hva=(u32*)mips_ref_hmem(vcpu,gpa,true,true,false); + if(hva)*hva=vcpu->gpr.ureg[rt]; + } + vcpu->gpr.pc+=4; +} \ No newline at end of file diff --git a/src/sim-j.c b/src/sim-j.c new file mode 100644 index 0000000..8359525 --- /dev/null +++ b/src/sim-j.c @@ -0,0 +1,36 @@ +/* + mipsivm - MIPS Interpreting Virtual Machine + + Copyright 2018-2020, Yaotian "Zero" Tang. All rights reserved. + + This file simulates J-Format instructions for the virtual CPU. + + This program is distributed in the hope that it will be useful, but + without any warranty (no matter implied warranty or merchantability + or fitness for a particular purpose, etc.). + + File Location: /sim-j.c +*/ + +#include +#include +#include + +void mips_interpreter_j_j(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Jump + // Formula: pc[0:27]=addr<<2 + const u32 offset=instruction.j.addr<<2; + vcpu->gpr.pc&=0xf0000000; + vcpu->gpr.pc|=offset; +} + +void mips_interpreter_j_jal(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Jump And Link + // Formula: ra=pc+8,pc[0:27]=addr<<2 + const u32 offset=instruction.j.addr<<2; + vcpu->gpr.ureg[31]=vcpu->gpr.pc+4; + vcpu->gpr.pc&=0xf0000000; + vcpu->gpr.pc|=offset; +} \ No newline at end of file diff --git a/src/sim-r.c b/src/sim-r.c new file mode 100644 index 0000000..93d6462 --- /dev/null +++ b/src/sim-r.c @@ -0,0 +1,302 @@ +/* + mipsivm - MIPS Interpreting Virtual Machine + + Copyright 2018-2020, Yaotian "Zero" Tang. All rights reserved. + + This file simulates R-Format instructions for the virtual CPU. + + This program is distributed in the hope that it will be useful, but + without any warranty (no matter implied warranty or merchantability + or fitness for a particular purpose, etc.). + + File Location: /sim-r.c +*/ + +#include +#include +#include + +void mips_interpreter_r_sll(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: sll - Shift Left Logical. + // Formula: rd=rt<gpr.ureg[rd]=vcpu->gpr.ureg[rt]<gpr.pc+=4; +} + +void mips_interpreter_r_srl(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: srl - Shift Right Logical. + // Formula: rd=rt>>shamt + const u32 rd=instruction.r.rd,rt=instruction.r.rt; + const u32 shamt=instruction.r.shamt; + vcpu->gpr.ureg[rd]=vcpu->gpr.ureg[rt]>>shamt; + vcpu->gpr.pc+=4; +} + +void mips_interpreter_r_sra(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: sra - Shift Right Arithmetical. + // Formula: rd=(Signed)rt>>shamt + const u32 rd=instruction.r.rd,rt=instruction.r.rt; + const u32 shamt=instruction.r.shamt; + vcpu->gpr.ireg[rd]=vcpu->gpr.ireg[rt]>>shamt; + vcpu->gpr.pc+=4; +} + +void mips_interpreter_r_sllv(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: sllv - Shift Left Logical Variable + // Formula: rd=rt<gpr.ureg[rd]=vcpu->gpr.ureg[rt]<gpr.ureg[rs]; + vcpu->gpr.pc+=4; +} + +void mips_interpreter_r_srlv(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: srlv - Shift Right Logical Variable + // Formula: rd=rt>>rs + const u32 rd=instruction.r.rd,rt=instruction.r.rt,rs=instruction.r.rs; + const u32 shamt=instruction.r.shamt; + vcpu->gpr.ureg[rd]=vcpu->gpr.ureg[rt]>>vcpu->gpr.ureg[rs]; + vcpu->gpr.pc+=4; +} + +void mips_interpreter_r_srav(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: sllv - Shift Right Arithmetical Variable + // Formula: rd=(Signed)rt>>rs + const u32 rd=instruction.r.rd,rt=instruction.r.rt,rs=instruction.r.rs; + const u32 shamt=instruction.r.shamt; + vcpu->gpr.ireg[rd]=vcpu->gpr.ireg[rt]>>vcpu->gpr.ureg[rs]; + vcpu->gpr.pc+=4; +} + +void mips_interpreter_r_jr(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: jr - Jump uregister + // Formula: pc=rs + const u32 rs=instruction.r.rs; + vcpu->gpr.pc=vcpu->gpr.ureg[rs]; +} + +void mips_interpreter_r_jalr(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: jalr - Jump And Link uregister + // Formula: rd=pc+8;pc=rs + const u32 rd=instruction.r.rd,rs=instruction.r.rs; + vcpu->gpr.ureg[rd]=vcpu->gpr.pc+4; + vcpu->gpr.pc=vcpu->gpr.ureg[rs]; +} + +void mips_interpreter_r_movz(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Move if Zero + // Formula: if rt==0 then rd=rs + const u32 rd=instruction.r.rd,rt=instruction.r.rt,rs=instruction.r.rs; + if(vcpu->gpr.ureg[rt]==0) + vcpu->gpr.ureg[rd]=vcpu->gpr.ureg[rs]; + vcpu->gpr.pc+=4; +} + +void mips_interpreter_r_movn(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Move if Non-Zero + // Formula: if rt!=0 then rd=rs + const u32 rd=instruction.r.rd,rt=instruction.r.rt,rs=instruction.r.rs; + if(vcpu->gpr.ureg[rt]) + vcpu->gpr.ureg[rd]=vcpu->gpr.ureg[rs]; + vcpu->gpr.pc+=4; +} + +void mips_interpreter_r_syscall(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Call to System + // Formula: trap into syscall exception handler + // FIXME: Complete Syscall Handler + vcpu->gpr.pc+=4; +} + +void mips_interpreter_r_break(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Breakpoint + // Formula: trap into break exception handler + // FIXME: Complete Break Handler + vcpu->gpr.pc+=4; +} + +void mips_interpreter_r_sync(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Synchronize + // Formula: Synchronize the Cache for memory consistency. + // We don't have to simulate this instruction! + vcpu->gpr.pc+=4; +} + +void mips_interpreter_r_mfhi(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Move From Hi + // Formula: rd=hi + const u32 rd=instruction.r.rd; + vcpu->gpr.ureg[rd]=vcpu->gpr.v.hi; + vcpu->gpr.pc+=4; +} + +void mips_interpreter_r_mthi(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Move To Hi + // Formula: hi=rs + const u32 rs=instruction.r.rs; + vcpu->gpr.v.hi=vcpu->gpr.ureg[rs]; + vcpu->gpr.pc+=4; +} + +void mips_interpreter_r_mflo(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Move From Lo + // Formula: rd=lo + const u32 rd=instruction.r.rd; + vcpu->gpr.ureg[rd]=vcpu->gpr.v.lo; + vcpu->gpr.pc+=4; +} + +void mips_interpreter_r_mtlo(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Move To Lo + // Formula: hi=lo + const u32 rs=instruction.r.rs; + vcpu->gpr.v.lo=vcpu->gpr.ureg[rs]; + vcpu->gpr.pc+=4; +} + +void mips_interpreter_r_mult(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Multiply Signed + // Formula: hi:lo=rs*rt + const u32 rs=instruction.r.rs,rt=instruction.r.rt; + vcpu->gpr.v.value=__emul(vcpu->gpr.ireg[rs],vcpu->gpr.ireg[rt]); + vcpu->gpr.pc+=4; +} + +void mips_interpreter_r_multu(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Multiply Unsigned + // Formula: hi:lo=rs*rt + const u32 rs=instruction.r.rs,rt=instruction.r.rt; + vcpu->gpr.v.value=__emulu(vcpu->gpr.ureg[rs],vcpu->gpr.ureg[rt]); + vcpu->gpr.pc+=4; +} + +void mips_interpreter_r_div(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Divide Signed + // Formula: hi=rs%rt,lo=rs/rt + const u32 rs=instruction.r.rs,rt=instruction.r.rt; + vcpu->gpr.v.lo=(u32)(vcpu->gpr.ireg[rs]/vcpu->gpr.ireg[rt]); + vcpu->gpr.v.hi=(u32)(vcpu->gpr.ireg[rs]%vcpu->gpr.ireg[rt]); + vcpu->gpr.pc+=4; +} + +void mips_interpreter_r_divu(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Divide Unsigned + // Formula: hi=rs%rt,lo=rs/rt + const u32 rs=instruction.r.rs,rt=instruction.r.rt; + vcpu->gpr.v.lo=vcpu->gpr.ureg[rs]/vcpu->gpr.ureg[rt]; + vcpu->gpr.v.hi=vcpu->gpr.ureg[rs]%vcpu->gpr.ureg[rt]; + vcpu->gpr.pc+=4; +} + +void mips_interpreter_r_add(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Add Signed + // Formula: rd=rs+rt + const u32 rd=instruction.r.rd,rs=instruction.r.rs,rt=instruction.r.rt; + vcpu->gpr.ireg[rd]=vcpu->gpr.ireg[rs]+vcpu->gpr.ireg[rt]; + vcpu->gpr.pc+=4; +} + +void mips_interpreter_r_addu(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Add Unsigned + // Formula: rd=rs+rt + const u32 rd=instruction.r.rd,rs=instruction.r.rs,rt=instruction.r.rt; + vcpu->gpr.ureg[rd]=vcpu->gpr.ureg[rs]+vcpu->gpr.ureg[rt]; + vcpu->gpr.pc+=4; +} + +void mips_interpreter_r_sub(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Subtract Signed + // Formula: rd=rs-rt + const u32 rd=instruction.r.rd,rs=instruction.r.rs,rt=instruction.r.rt; + vcpu->gpr.ireg[rd]=vcpu->gpr.ireg[rs]-vcpu->gpr.ireg[rt]; + vcpu->gpr.pc+=4; +} + +void mips_interpreter_r_subu(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Subtract Unsigned + // Formula: rd=rs-rt + const u32 rd=instruction.r.rd,rs=instruction.r.rs,rt=instruction.r.rt; + vcpu->gpr.ureg[rd]=vcpu->gpr.ureg[rs]-vcpu->gpr.ureg[rt]; + vcpu->gpr.pc+=4; +} + +void mips_interpreter_r_and(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Logical And + // Formula: rd=rs&rt + const u32 rd=instruction.r.rd,rs=instruction.r.rs,rt=instruction.r.rt; + vcpu->gpr.ureg[rd]=vcpu->gpr.ureg[rs]&vcpu->gpr.ureg[rt]; + vcpu->gpr.pc+=4; +} + +void mips_interpreter_r_or(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Logical Or + // Formula: rd=rs|rt + const u32 rd=instruction.r.rd,rs=instruction.r.rs,rt=instruction.r.rt; + vcpu->gpr.ureg[rd]=vcpu->gpr.ureg[rs]|vcpu->gpr.ureg[rt]; + vcpu->gpr.pc+=4; +} + +void mips_interpreter_r_xor(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Logical Exclusive Or + // Formula: rd=rs^rt + const u32 rd=instruction.r.rd,rs=instruction.r.rs,rt=instruction.r.rt; + vcpu->gpr.ureg[rd]=vcpu->gpr.ureg[rs]^vcpu->gpr.ureg[rt]; + vcpu->gpr.pc+=4; +} + +void mips_interpreter_r_nor(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Logical Not Or + // Formula: rd=~(rs|rt) + const u32 rd=instruction.r.rd,rs=instruction.r.rs,rt=instruction.r.rt; + vcpu->gpr.ureg[rd]=~(vcpu->gpr.ureg[rs]|vcpu->gpr.ureg[rt]); + vcpu->gpr.pc+=4; +} + +void mips_interpreter_r_slt(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Set if Less Than + // Formula: rd=(rsgpr.ireg[rd]=vcpu->gpr.ireg[rs]gpr.ireg[rt]?1:0; + vcpu->gpr.pc+=1; +} + +void mips_interpreter_r_sltu(vmcb_p vcpu,mips_instruction instruction) +{ + // Definition: Set if Less Than Unsigned + // Formula: rd=(rsgpr.ureg[rd]=vcpu->gpr.ureg[rs]gpr.ureg[rt]?1:0; + vcpu->gpr.pc+=1; +} \ No newline at end of file diff --git a/src/vcpu.c b/src/vcpu.c index df6a02e..216e761 100644 --- a/src/vcpu.c +++ b/src/vcpu.c @@ -1,7 +1,7 @@ /* mipsivm - MIPS Interpreting Virtual Machine - Copyright 2018-2019, Yaotian "Zero" Tang. All rights reserved. + Copyright 2018-2020, Yaotian "Zero" Tang. All rights reserved. This file drives the virtual CPU. @@ -9,9 +9,52 @@ without any warranty (no matter implied warranty or merchantability or fitness for a particular purpose, etc.). - File Location: /include/vcpu.c + File Location: /vcpu.c */ #include #include -#include \ No newline at end of file +#include +#include + +// Translates and References the Guest Physical Address to Host Virtual Address. +void* mips_ref_hmem(vmcb_p vcpu,u32 gpa,bool r,bool w,bool x) +{ +#if defined(_amd64) + l3p_address addr; + l3p_pdpte_p pdpteb=vcpu->npt_base; + addr.value=gpa; + if(pdpteb[addr.pdpte].r>=r && pdpteb[addr.pdpte].w>=w && pdpteb[addr.pdpte].x>=x) + { + l3p_pde_p pdeb=(l3p_pde_p)(pdpteb[addr.pde].pde_page<<12); + if(pdeb[addr.pde].r>=r && pdeb[addr.pde].w>=w && pdeb[addr.pde].x>=x) + { + l3p_pte_p pteb=(l3p_pte_p)(pdeb[addr.pte].pte_page<<12); + if(pteb[addr.pte].r>=r && pteb[addr.pte].w>=w && pteb[addr.pte].x>=x) + { + u64 p=(pteb[addr.pte].page_base<<12)+addr.offset; + pteb[addr.pte].a=true; // This Entry is now Accessed. + if(w)pteb[addr.pte].d=true; // This Page is now Dirty. + return (void*)p; + } + } + } +#endif + // Nested Page Fault occured. + return null; +} + +void mips_interpreter_unhandled_instruction(vmcb_p vcpu,mips_instruction instruction) +{ + ; +} + +void mips_interpreter_r_format(vmcb_p vcpu,mips_instruction instruction) +{ + cpu_interpreter_r_funct[instruction.r.funct](vcpu,instruction); +} + +void mips_interpreter_fpu(vmcb_p vcpu,mips_instruction instruction) +{ + ; +} \ No newline at end of file