From 0ea1d6be749cfa0650102b5d4651621781d348e1 Mon Sep 17 00:00:00 2001 From: yat17006 Date: Sat, 9 Jan 2021 00:51:27 +0800 Subject: [PATCH] Implement XTLB. Accelerate instruction fetching by adding XTLB. This may slow down Data Read/Write instructions. Add source code of fibonacci test case. --- .gitignore | 2 +- README.md | 2 +- src/include/mipsdef.h | 2 +- src/include/vmcb.h | 25 ++++++++++++++++++++++++ src/vcpu.c | 37 +++++++++++++++++++++++++++--------- test/fibonacci/build.bat | 7 +++++++ test/fibonacci/fibonacci.asm | 25 ++++++++++++++++++++++++ test/readme.md | 8 ++++++-- 8 files changed, 94 insertions(+), 14 deletions(-) create mode 100644 test/fibonacci/build.bat create mode 100644 test/fibonacci/fibonacci.asm diff --git a/.gitignore b/.gitignore index 57ec230..49a815f 100644 --- a/.gitignore +++ b/.gitignore @@ -51,4 +51,4 @@ modules.order Module.symvers Mkfile.old -dkms.conf +dkms.conf \ No newline at end of file diff --git a/README.md b/README.md index ee3c558..d6115c3 100644 --- a/README.md +++ b/README.md @@ -113,7 +113,7 @@ Here list command-line arguments specific to MARS Runtime Preset. - `/ss` specifies the stack size in bytes for the program. Default stack size is 64KiB. ### Example -``` +```bat mipsivm /nologo /runtime mars /ds helloworld.data.bin /ts helloworld.text.bin ``` This code would suppress the logo printer then load `helloworld.data.bin` as `.data` section and `helloworld.text.bin` as `.text` section of the program, with 64KiB default stack, and run the program. diff --git a/src/include/mipsdef.h b/src/include/mipsdef.h index 1ef90ae..1ee0d6d 100644 --- a/src/include/mipsdef.h +++ b/src/include/mipsdef.h @@ -311,7 +311,7 @@ char* mips_cpu_regimm_string[32]= null, // 0x1D null, // 0x1E null // 0x1F -} +}; char* mips_cpu_funct_string[64]= { diff --git a/src/include/vmcb.h b/src/include/vmcb.h index 61bc7cc..334105c 100644 --- a/src/include/vmcb.h +++ b/src/include/vmcb.h @@ -129,6 +129,30 @@ typedef union _l2p_pte }l2p_pte,*l2p_pte_p; #endif +// Simple definition of Translation Lookaside Buffer +typedef struct _npt_tlb +{ + union + { + struct + { + ulong_ptr r:1; // Permission for Read + ulong_ptr w:1; // Permission for Write + ulong_ptr x:1; // Permission for Execute + ulong_ptr rsvd:9; // Reserved +#if defined(_amd64) + u64 page_base:52; // Address of Page +#else + u32 page_base:20; // Address of Page +#endif + }; + ulong_ptr value; + }tl_info; + u32 page_base; // This is GPA. + u64 hits; + u64 misses; +}npt_tlb,*npt_tlb_p; + // VMCB - Virtual Machine Control Block // This is Core Structure of vCPU. typedef struct _vmcb @@ -151,6 +175,7 @@ typedef struct _vmcb #else l2p_pde_p npt_base; // Points to 512 Entries of PDE #endif + npt_tlb xtlb; // Reduce Lookaside Time for Execution. u64 tsc; // Guest Time-Stamp Counter, aka TSC, Processor Ticks. u64 eic; // Executed Instruction Counter. u32 vm_type; diff --git a/src/vcpu.c b/src/vcpu.c index d0c312a..a4e1f84 100644 --- a/src/vcpu.c +++ b/src/vcpu.c @@ -25,18 +25,35 @@ void* mips_ref_hmem(vmcb_p vcpu,u32 gpa,bool r,bool w,bool x) 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) + if((vcpu->xtlb.tl_info.r>=r && vcpu->xtlb.tl_info.w>=w && vcpu->xtlb.tl_info.x>=x) && (gpa>=vcpu->xtlb.page_base && gpaxtlb.page_base+page_size)) { - l3p_pde_p pdeb=(l3p_pde_p)(pdpteb[addr.pdpte].pde_page<<12); - if(pdeb[addr.pde].r>=r && pdeb[addr.pde].w>=w && pdeb[addr.pde].x>=x) + ulong_ptr b=vcpu->xtlb.tl_info.page_base<<12; + b+=addr.offset; + vcpu->xtlb.hits++; + return (void*)b; + } + else + { + if(pdpteb[addr.pdpte].r>=r && pdpteb[addr.pdpte].w>=w && pdpteb[addr.pdpte].x>=x) { - l3p_pte_p pteb=(l3p_pte_p)(pdeb[addr.pde].pte_page<<12); - if(pteb[addr.pte].r>=r && pteb[addr.pte].w>=w && pteb[addr.pte].x>=x) + l3p_pde_p pdeb=(l3p_pde_p)(pdpteb[addr.pdpte].pde_page<<12); + if(pdeb[addr.pde].r>=r && pdeb[addr.pde].w>=w && pdeb[addr.pde].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; + l3p_pte_p pteb=(l3p_pte_p)(pdeb[addr.pde].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. + vcpu->xtlb.misses++; + if(x) + { + // Put this page entry into XTLB. + vcpu->xtlb.tl_info.value=pteb[addr.pte].value; + vcpu->xtlb.page_base=gpa&0xFFFFF000; + } + return (void*)p; + } } } } @@ -45,6 +62,7 @@ void* mips_ref_hmem(vmcb_p vcpu,u32 gpa,bool r,bool w,bool x) return null; } +// Modify the translation from Guest Physical Address to Host Virtual Address. bool mips_npt_edit_entry(vmcb_p vcpu,u32 gpa,void* hva,bool r,bool w,bool x) { #if defined(_amd64) @@ -127,6 +145,7 @@ void mips_vcpu_dump_state(vmcb_p vcpu) sim_printf("hi\t\t0x%08X\n",vcpu->gpr.v.hi); sim_printf("lo\t\t0x%08X\n",vcpu->gpr.v.lo); sim_printf("pc\t\t0x%08X\n",vcpu->gpr.pc); + sim_printf("XTLB Hits: %lld\tMisses: %lld\n",vcpu->xtlb.hits,vcpu->xtlb.misses); sim_printf("======================Dump Complete======================\n"); } diff --git a/test/fibonacci/build.bat b/test/fibonacci/build.bat new file mode 100644 index 0000000..be18ef5 --- /dev/null +++ b/test/fibonacci/build.bat @@ -0,0 +1,7 @@ +@echo off + +echo Assembling... +java -jar ..\mars.jar nc a .\fibonacci.asm dump .text Binary .\fib.text.bin dump .data Binary .\fib.data.bin +echo Completed! + +pause. \ No newline at end of file diff --git a/test/fibonacci/fibonacci.asm b/test/fibonacci/fibonacci.asm new file mode 100644 index 0000000..686b055 --- /dev/null +++ b/test/fibonacci/fibonacci.asm @@ -0,0 +1,25 @@ +.data +strp: +.asciiz "10th Fibonacci Number: " +.text +addi $t9, $zero, 10 +addi $t1, $zero, 0 +addi $t2, $zero, 1 +j fibonacci + +fibonacci: +add $t3, $t2, $t1 +add $t1, $zero, $t2 +add $t2, $zero, $t3 +addi $t5, $t5, 1 +bne $t5, $t9, fibonacci + +over: +la $a0, strp +addi $v0, $zero, 4 +syscall +move $a0, $t3 +addi $v0, $zero, 1 +syscall +addi $v0, $zero, 10 +syscall \ No newline at end of file diff --git a/test/readme.md b/test/readme.md index d138729..05ba5d2 100644 --- a/test/readme.md +++ b/test/readme.md @@ -3,10 +3,14 @@ This directory will include a set of test cases. ## Use of MARS MARS, acronym that stands for MIPS Assembler and Runtime Simulator, is an IDE written in java. Hence, to run MARS, you will have to install Java SE.
-To test the functionality of mipsivm, we will edit Assembly code with MARS and assemble it. You have to dump the assembled code and data to file so that you can run it. To dump mipsivm, run the following command: -``` +To test the functionality of mipsivm, we will edit Assembly code with MARS and assemble it. You have to dump the assembled code and data to file so that you can run it. To dump code and data for mipsivm, run the following command: +```bat java -jar mars.jar nc a dump .text Binary .text.bin dump .data Binary .data.bin ``` +After you dumped your code and data, run mipsivm with following command: +```bat +mipsivm /runtime mars /ds .data.bin /ts .text.bin +``` ## Available Test Cases - Hello World \ No newline at end of file