Skip to content

Commit

Permalink
Update by Sept.23rd, 2020
Browse files Browse the repository at this point in the history
Added MIPS ISA document.
Fixed memory leak and introspector.
Added showcase screenshots.
  • Loading branch information
Zero Tang committed Sep 23, 2020
1 parent 309c13a commit 79b253d
Show file tree
Hide file tree
Showing 12 changed files with 119 additions and 18 deletions.
30 changes: 19 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
# mipsivm
The name of the project "mipsivm" is an abbreviation for "MIPS Interpreting Virtual Machine".

## Showcase
* mipsivm runs Hello World
![Showcase Hello World](test/mipsivm_show_helloworld.JPG)

* mipsivm runs CSE3666 Lab 2
![Showcase CSE3666 Lab2](test/mipsivm_show_lab2.JPG)

## Introduction
The "mipsivm" is a software-based Emulator project aiming to virtualize the minimum MIPS-based machine and efficient virtualized memory. <br>
This project is an interpreting emulator project - providing the accurate emulation.
Expand All @@ -14,14 +21,15 @@ To virtualize the processor, we implement the VMCB structure. VMCB is the acrony
Duly note that mipsivm simulates in LE byte order.

### Glossary of Processor Virtualization
| Acronyms | Abbreviated for | Explanation |
| --------- | ----------------------------- | --------------------------------- |
| vCPU | Virtual CPU | The virtual processor |
| FPU | Floating Processing Unit | Co-processor for floating number |
| RF | Register File | Storage of Registers |
| GPR | General Purpose Register | Register of CPU |
| VMCB | Virtual Machine Control Block | Controlling Structure for a vCPU |
| MPT | MIPS Page Table | Address of Root of Paging |
| Acronyms | Abbreviated for | Explanation |
| --------- | ----------------------------- | ------------------------------------- |
| vCPU | Virtual CPU | The virtual processor |
| FPU | Floating Processing Unit | Co-processor for floating number |
| RF | Register File | Storage of Registers |
| GPR | General Purpose Register | Register of CPU |
| VMCB | Virtual Machine Control Block | Controlling Structure for a vCPU |
| NPT | Nested Page Table | Page Table that translates GPA to HVA |
| MPT | MIPS Page Table | Page Table that translates GVA to GPA |

## Memory Virtualization
The memory virtualization is the special feature of the project. This project uses paging as inspired by AMD64 architecture. <br>
Expand Down Expand Up @@ -66,7 +74,7 @@ Each PTE is an 8-byte entry. There are 512 PTEs. For each entry, there are 64 bi
## FAQ
Following lists the frequently asked questions, and corresponding answers.

### Why the Project?
### Why did I create this project?
In my sophomore year, I took the CSE3666 course - Introduction to Computer Architecture. In the final month of the semester, there is an emulator project - emulate an MIPS machine. The emulator skeleton is in either python or java implemention. I considered the implementation is not quite efficient. So this project is given birth by me - implement the emulator in an efficient interpreting method.

### Is there a well-known open-source MIPS emulator project?
Expand All @@ -80,7 +88,7 @@ Yes, there is. The famous PCSX2 is a free and open-source PlayStation 2 (PS2) em
- This project is designed to support multiple presets for simulation. With different preset, mipsivm may support multi-processing system.

## Build
If it is your first time to build mipsivm, you will have execute `build_prep.bat` script file to prepare for compilation prior to execute any build scripts. <br>
If it is your first time to build mipsivm, you will have to execute `build_prep.bat` script file to prepare for compilation prior to execute any build scripts. <br>
Currently, mipsivm supports 64-bit Windows.

### Windows
Expand Down Expand Up @@ -108,7 +116,7 @@ Here list command-line arguments specific to MARS Runtime Preset.
```
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 stack, and run the program.
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.

## License
This repository is licensed under the MIT license.
File renamed without changes.
Binary file added ref/mips-isa.pdf
Binary file not shown.
1 change: 1 addition & 0 deletions src/entry.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ int main(int argc,char* argv[],char* envp[])
}
puts("MARS Environment is initialized successfully!");
mips_run_mars_vm();
mips_final_mars_vm();
mars_final:
unload_section(ds_ptr);
unload_section(ts_ptr);
Expand Down
2 changes: 2 additions & 0 deletions src/include/devkit.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

bool mips_init_mars_vm(void* ds,void* ts,u32 ds_size,u32 ts_size,u32 stack_size);
void mips_run_mars_vm();
void mips_final_mars_vm();

void cdecl sim_printf(const char* format,...);
i32 sim_readint();
Expand All @@ -29,6 +30,7 @@ char sim_readchar();
void sim_setseed(u32 seed);
u32 sim_getrand();

void report_memory_introspection();
void* load_section(char* file_path,u32* size);
bool unload_section(void* section);
void* alloc_page(u32 size);
Expand Down
42 changes: 39 additions & 3 deletions src/include/mipsdef.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,8 @@ char* mips_cpu_opcode_string[64]=
null, // 0x13
null, // 0x14
null, // 0x15
null, // 0x16
null, // 0x17
"blezl", // 0x16
"bgtzl", // 0x17
null, // 0x18
null, // 0x19
null, // 0x1A
Expand All @@ -250,7 +250,7 @@ char* mips_cpu_opcode_string[64]=
"lbu", // 0x24
"lhu", // 0x25
"lwr", // 0x26
null, // 0x27
"lwu", // 0x27
"sb", // 0x28
"sh", // 0x29
"swl", // 0x2A
Expand All @@ -277,6 +277,42 @@ char* mips_cpu_opcode_string[64]=
null // 0x3F
};

char* mips_cpu_regimm_string[32]=
{
"bltz", // 0x00
"bgez", // 0x01
"bltzl", // 0x02
"bgezl", // 0x03
null, // 0x04
null, // 0x05
null, // 0x06
null, // 0x07
"tgei", // 0x08
"tgeiu", // 0x09
"tlti", // 0x0A
"tltiu", // 0x0B
"teqi", // 0x0C
null, // 0x0D
"tnei", // 0x0E
null, // 0x0F
"bltzal", // 0x10
"bgezal", // 0x11
"bltzall", // 0x12
"bgezall", // 0x13
null, // 0x14
null, // 0x15
null, // 0x16
null, // 0x17
null, // 0x18
null, // 0x19
null, // 0x1A
null, // 0x1B
null, // 0x1C
null, // 0x1D
null, // 0x1E
null // 0x1F
}

char* mips_cpu_funct_string[64]=
{
"sll", // 0x00
Expand Down
3 changes: 2 additions & 1 deletion src/include/vmcb.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ typedef struct _vmcb
#else
l2p_pde_p npt_base; // Points to 512 Entries of PDE
#endif
u64 tsc; // Time-Stamp Counter, aka TSC, Processor Ticks.
u64 tsc; // Guest Time-Stamp Counter, aka TSC, Processor Ticks.
u64 eic; // Executed Instruction Counter.
u32 vm_type;
}vmcb,*vmcb_p;
Expand All @@ -177,6 +177,7 @@ typedef struct _mips_mars_vm

void* mips_ref_hmem(vmcb_p vcpu,u32 gpa,bool r,bool w,bool x);
bool mips_npt_edit_entry(vmcb_p vcpu,u32 gpa,void* hva,bool r,bool w,bool x);
void mips_npt_cleanup(vmcb_p vcpu);
void mips_vcpu_start_interpretation(vmcb_p vcpu);
void mips_vcpu_dump_state(vmcb_p vcpu);

Expand Down
7 changes: 7 additions & 0 deletions src/mars.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,4 +193,11 @@ void mips_run_mars_vm()
ghr=(double)vm.vcpu.tsc/(double)tsc_diff;
sim_printf("Guest/Host TSC Rate: %f (Higher TSC Rate indicates better simulation performance)\n",ghr);
mips_vcpu_dump_state(&vm.vcpu);
}

void mips_final_mars_vm()
{
free_page(vm.stack.address);
mips_npt_cleanup(&vm.vcpu);
report_memory_introspection();
}
24 changes: 23 additions & 1 deletion src/vcpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,28 @@ bool mips_npt_edit_entry(vmcb_p vcpu,u32 gpa,void* hva,bool r,bool w,bool x)
#endif
}

void mips_npt_cleanup(vmcb_p vcpu)
{
#if defined(_amd64)
u32 i=0;
for(;i<4;i++)
{
l3p_pde_p pdeb=(l3p_pde_p)(vcpu->npt_base[i].pde_page<<12);
if(pdeb)
{
u32 j=0;
for(;j<512;j++)
{
l3p_pte_p pteb=(l3p_pte_p)(pdeb[j].pte_page<<12);
if(pteb)free_page(pteb);
}
free_page(pdeb);
}
}
free_mem(vcpu->npt_base);
#endif
}

void mips_interpreter_unhandled_instruction(vmcb_p vcpu,mips_instruction instruction)
{
sim_printf("#UD Exception! (Unknown Instruction)\n");
Expand Down Expand Up @@ -115,7 +137,7 @@ void mips_vcpu_start_interpretation(vmcb_p vcpu)
// Reference HVA by GPA.
u32* ip=(u32*)mips_ref_hmem(vcpu,vcpu->gpr.pc,true,false,true);
mips_instruction mi;
if(ip==null) // Either the page is not present, or page does not exist.
if(ip==null) // Either the page is not present, or page is not executable.
{
sim_printf("Nested Page Fault on Execution! pc=0x%08X\n",vcpu->gpr.pc);
break;
Expand Down
28 changes: 26 additions & 2 deletions src/xpf/windows/system.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@

#include <Windows.h>

void __cdecl sim_printf(const char* format,...);

ULONG PageCountAllocated=0;
ULONG HeapCountAllocated=0;

PVOID load_section(IN PSTR FilePath,OUT PULONG Size)
{
PVOID Buffer=NULL;
Expand Down Expand Up @@ -49,21 +54,40 @@ BOOL unload_section(IN PVOID SectionAddress)
PVOID alloc_page(IN ULONG Size)
{
PVOID p=VirtualAlloc(NULL,Size,MEM_COMMIT,PAGE_READWRITE);
if(p)RtlZeroMemory(p,Size);
if(p)
{
RtlZeroMemory(p,Size);
PageCountAllocated++;
}
return p;
}

BOOL free_page(IN PVOID Address)
{
PageCountAllocated--;
return VirtualFree(Address,0,MEM_RELEASE);
}

PVOID alloc_mem(IN ULONG Size)
{
return HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,Size);
PVOID p=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,Size);
if(p)HeapCountAllocated++;
return p;
}

BOOL free_mem(IN PVOID Address)
{
HeapCountAllocated--;
return HeapFree(GetProcessHeap(),0,Address);
}

void report_memory_introspection()
{
sim_printf("[Memory Introspection] Unreleased Pages: %d\n",PageCountAllocated);
sim_printf("[Memory Introspection] Unreleased Heaps: %d\n",HeapCountAllocated);
if(PageCountAllocated>0 || HeapCountAllocated>0)
sim_printf("[Memory Introspection] Status: there is memory leak!\n");
else
sim_printf("[Memory Introspection] Status: No memory leak!\n");
sim_printf("[Memory Introspection] Introspection Completed!\n");
}
Binary file added test/mipsivm_show_helloworld.JPG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added test/mipsivm_show_lab2.JPG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 79b253d

Please sign in to comment.