Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Update by Sept.21st, 2020
Implemented some unimplemented instructions.
Implemented MARS Runtime Preset.
Added Hello-World test case.
Fixed incorrect NPT reference.
Implemented Nested Paging for Memory Virtualization.
Implemented Cross-Platform (XPF) Core for Windows.
  • Loading branch information
Zero Tang committed Sep 20, 2020
1 parent 9896d14 commit 309c13a
Show file tree
Hide file tree
Showing 20 changed files with 837 additions and 38 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -36,6 +36,7 @@
*.i*86
*.x86_64
*.hex
*.bin

# Debug files
*.dSYM/
Expand Down
37 changes: 34 additions & 3 deletions README.md
Expand Up @@ -72,12 +72,43 @@ In my sophomore year, I took the CSE3666 course - Introduction to Computer Archi
### Is there a well-known open-source MIPS emulator project?
Yes, there is. The famous PCSX2 is a free and open-source PlayStation 2 (PS2) emulator project. The processor inside the PS2 is based on MIPS Architecture.

### What big difference does this project make?
- It is the access-controlled memory-virtualization feature.
### What big difference does this project make in comparison to CSE3666 assignment?
- There is access-controlled memory-virtualization feature.
- This project is written in C programming language.
- This software is implemented by inspirations from AMD64 architecture.
- This project aims to support more instructions.
- This project uses most techniques on optimizations.
- 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>
Currently, mipsivm supports 64-bit Windows.

### Windows
To build mipsivm for Windows, you will need to install [Windows Driver Kit 7.1.0](https://www.microsoft.com/en-us/download/details.aspx?id=11800) to default path on C drive. Compiler of WDK 7.1.0 can be considered as Visual C++ 2008 with a minor update. <br>
Execute `compchk_win7x64.bat` to compile mipsivm with `Debug/Checked` (unoptimized) compilation preset.

## Command-Line Argument
Here list all command-line arguments.

- `/nologo` suppresses the logo printer.
- `/runtime` specifies the runtime preset of MIPS Virtual Machine. Default runtime preset is `MARS`.

Following runtime presets are available:

### MARS Runtime Preset
MARS, acronym that stands for MIPS Assembler and Runtime Simulator, is an MIPS Assembly Development IDE written by Dr. Pete Sanderson and Dr.Ken Vollmar at Missouri State University. This preset would let mipsivm to simulate the MARS environment. <br>
MARS runtime preset simulates the program in user-mode. It is a uniprocessor preset - no multi-processing is available. <br>
Here list command-line arguments specific to MARS Runtime Preset.

- `/ds` specifies the file path to `.data` section of program.
- `/ts` specifies the file path to `.text` section of program.
- `/ss` specifies the stack size in bytes for the program. Default stack size is 64KiB.

### Example
```
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.

## License
This repository is licensed under the MIT license.
14 changes: 14 additions & 0 deletions build_prep.bat
@@ -0,0 +1,14 @@
@echo off

title Compiling mipsivm, Checked Build, 64-Bit Windows (AMD64 Architecture)
echo Project: mipsivm
echo Platform: Universal
echo Preset: Preparation
pause

mkdir .\bin
mkdir .\bin\compchk_win7x64
mkdir .\bin\compchk_win7x64\Intermediate

echo Completed!
pause.
6 changes: 5 additions & 1 deletion compchk_win7x64.bat
Expand Up @@ -12,17 +12,21 @@ echo Preset: Debug/Checked Build
pause

echo ============Start Compiling============
%ddkpath%\amd64\cl.exe .\src\xpf\windows\system.c /I"%incpath%\api" /I"%incpath%\crt" /I".\src\include" /Zi /nologo /W3 /WX /Od /D"_MBCS" /D"_WIN64" /D"_M_AMD64" /D"_AMD64_" /Zc:wchar_t /Zc:forScope /FAcs /Fa"%objpath%\system.cod" /Fo"%objpath%\system.obj" /Fd"%objpath%\vc90.pdb" /GS- /Gd /TC /c /errorReport:queue

%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" /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\mars.c /I".\src\include" /Zi /nologo /W3 /WX /Oi /Od /D"_msvc" /D"_amd64" /D"_mips_hvm_mars" /Zc:wchar_t /Zc:forScope /FAcs /Fa"%objpath%\mars.cod" /Fo"%objpath%\mars.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" "%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
%ddkpath%\amd64\link.exe "%objpath%\*.obj" /LIBPATH:"%libpath%\win7\amd64" /LIBPATH:"%libpath%\Crt\amd64" /NODEFAULTLIB "libcmt.lib" "msvcrt.lib" "kernel32.lib" /NOLOGO /DEBUG /PDB:"%objpath%\mipsivm.pdb" /INCREMENTAL:NO /OUT:"%binpath%\mipsivm.exe" /SUBSYSTEM:CONSOLE /Machine:X64 /ERRORREPORT:QUEUE

pause
143 changes: 140 additions & 3 deletions src/entry.c
Expand Up @@ -16,10 +16,147 @@
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "include/midef.h"
#include "include/devkit.h"

void main()
void cdecl sim_printf(const char* format,...)
{
printf("Welcome to mipsivm!\n");
printf("Powered by Yaotian \"Zero\" Tang. All rights reserved.\n");
va_list arg_list;
va_start(arg_list,format);
vprintf(format,arg_list);
va_end(arg_list);
}

i32 sim_readint()
{
int x=0;
scanf("%d",&x);
return x;
}

float sim_readfloat()
{
float x=0.0;
scanf("%f",&x);
return x;
}

double sim_readdouble()
{
double x=0.0;
scanf("%lf",&x);
return x;
}

void sim_readstring(char* string,u32 limit)
{
fgets(string,limit,stdin);
}

char sim_readchar()
{
return (char)getc(stdin);
}

void sim_setseed(u32 seed)
{
srand(seed);
}

u32 sim_getrand()
{
return rand();
}

void print_compiler()
{
#if defined(_msvc)
int major=_MSC_VER/100;
int minor=_MSC_VER%100;
int build=_MSC_FULL_VER%100000;
printf("Compiler Version: Microsoft Visual C++ %02d.%02d.%05d.%d\n",major,minor,build,_MSC_BUILD);
#endif
printf("Compilation Date: %s %s\n",__DATE__,__TIME__);
}

int main(int argc,char* argv[],char* envp[])
{
int i;
bool nologo=false;
char* runtime="mars";
char* data_path=null;
char* text_path=null;
int stack_size=0x10000;
for(i=1;i<argc;i++)
{
if(_stricmp(argv[i],"/nologo")==0)
nologo=true;
else if(_stricmp(argv[i],"/runtime")==0)
runtime=argv[++i];
else if(_stricmp(argv[i],"/ds")==0)
data_path=argv[++i];
else if(_stricmp(argv[i],"/ts")==0)
text_path=argv[++i];
else if(_stricmp(argv[i],"/ss")==0)
stack_size=atoi(argv[++i]);
else
printf("Warning: Unknown input Argument \"%s\"\n",argv[i]);
}
if(!nologo)
{
puts("Welcome to mipsivm!");
puts("Powered by Yaotian \"Zero\" Tang. All rights reserved.");
print_compiler();
}
if(_stricmp(runtime,"mars")==0)
{
void* ds_ptr=null;
void* ts_ptr=null;
u32 ds_size=0,ts_size=0;
puts("Simulation Preset: MARS");
if(data_path==null)
{
puts("Error P0010: No .data section file is specified!");
goto mars_final;
}
else
{
ds_ptr=load_section(data_path,&ds_size);
if(ds_ptr==null)
{
puts("Error P0011: Failed to load .data section!");
goto mars_final;
}
}
if(text_path==null)
{
puts("Error P0020: No .text section file is specified!");
goto mars_final;
}
else
{
ts_ptr=load_section(text_path,&ts_size);
if(ts_ptr==null)
{
puts("Error P0021: Failed to load .text section!");
goto mars_final;
}
}
puts("Program is loaded successfully!");
if(mips_init_mars_vm(ds_ptr,ts_ptr,ds_size,ts_size,stack_size)==false)
{
puts("Error R0000: Failed to initialize MARS Runtime VM!");
goto mars_final;
}
puts("MARS Environment is initialized successfully!");
mips_run_mars_vm();
mars_final:
unload_section(ds_ptr);
unload_section(ts_ptr);
}
else
{
printf("Error P0000: Unknown Runtime Preset \"%s\"\n",runtime);
}
system("pause");
}
37 changes: 37 additions & 0 deletions src/include/devkit.h
@@ -0,0 +1,37 @@
/*
mipsivm - MIPS Interpreting Virtual Machine
Copyright 2018-2020, Yaotian "Zero" Tang. All rights reserved.
This file defines the development kits for mipsivm project.
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/devkit.h
*/

#include "midef.h"

#define page_size 0x1000
#define pfn(x) (x>>12)

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

void cdecl sim_printf(const char* format,...);
i32 sim_readint();
float sim_readfloat();
double sim_readdouble();
void sim_readstring(char* string,u32 limit);
char sim_readchar();
void sim_setseed(u32 seed);
u32 sim_getrand();

void* load_section(char* file_path,u32* size);
bool unload_section(void* section);
void* alloc_page(u32 size);
bool free_page(void* address);
void* alloc_mem(u32 size);
bool free_mem(void* address);
45 changes: 45 additions & 0 deletions src/include/mars.h
@@ -0,0 +1,45 @@
/*
mipsivm - MIPS Interpreting Virtual Machine
Copyright 2018-2020, Yaotian "Zero" Tang. All rights reserved.
This file defines the Runtime VM based on MARS.
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: /mars.h
*/

#include "midef.h"

#define mips_mars_syscall_print_integer 1
#define mips_mars_syscall_print_float 2
#define mips_mars_syscall_print_double 3
#define mips_mars_syscall_print_string 4
#define mips_mars_syscall_read_integer 5
#define mips_mars_syscall_read_float 6
#define mips_mars_syscall_read_double 7
#define mips_mars_syscall_read_string 8
#define mips_mars_syscall_alloc_heap 9
#define mips_mars_syscall_exit 10
#define mips_mars_syscall_print_char 11
#define mips_mars_syscall_read_char 12
#define mips_mars_syscall_open_file 13
#define mips_mars_syscall_read_file 14
#define mips_mars_syscall_write_file 15
#define mips_mars_syscall_close_file 16
#define mips_mars_syscall_exit2 17
#define mips_mars_syscall_time 30
#define mips_mars_syscall_midi_out 31
#define mips_mars_syscall_sleep 32
#define mips_mars_syscall_midi_out_sync 33
#define mips_mars_syscall_print_hex 34
#define mips_mars_syscall_print_bin 35
#define mips_mars_syscall_print_unsigned 36
#define mips_mars_syscall_set_seed 40
#define mips_mars_syscall_rnd_int 41
#define mips_mars_syscall_rnd_int_range 42
#define mips_mars_syscall_rnd_float 43
#define mips_mars_syscall_rnd_double 44
34 changes: 34 additions & 0 deletions src/include/mipsdef.h
Expand Up @@ -69,6 +69,40 @@ typedef union _mips_instruction
#define j_format 3
#define f_format 4

// Registers
#define mips_gpr_zero 0x00
#define mips_gpr_at 0x01
#define mips_gpr_v0 0x02
#define mips_gpr_v1 0x03
#define mips_gpr_a0 0x04
#define mips_gpr_a1 0x05
#define mips_gpr_a2 0x06
#define mips_gpr_a3 0x07
#define mips_gpr_t0 0x08
#define mips_gpr_t1 0x09
#define mips_gpr_t2 0x0A
#define mips_gpr_t3 0x0B
#define mips_gpr_t4 0x0C
#define mips_gpr_t5 0x0D
#define mips_gpr_t6 0x0E
#define mips_gpr_t7 0x0F
#define mips_gpr_s0 0x10
#define mips_gpr_s1 0x11
#define mips_gpr_s2 0x12
#define mips_gpr_s3 0x13
#define mips_gpr_s4 0x14
#define mips_gpr_s5 0x15
#define mips_gpr_s6 0x16
#define mips_gpr_s7 0x17
#define mips_gpr_t8 0x18
#define mips_gpr_t9 0x19
#define mips_gpr_k0 0x1A
#define mips_gpr_k1 0x1B
#define mips_gpr_gp 0x1C
#define mips_gpr_sp 0x1D
#define mips_gpr_fp 0x1E
#define mips_gpr_ra 0x1F

#if defined(_mips_hvm)
u8 mips_opcode_class[64]=
{
Expand Down

0 comments on commit 309c13a

Please sign in to comment.