Cpu instructions, Os syscalls
This commit is contained in:
parent
cacbb05b39
commit
c3ff7ea4aa
|
|
@ -3,8 +3,6 @@ module main
|
||||||
import vm
|
import vm
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println('Hello World!')
|
|
||||||
|
|
||||||
vm.start_vm()
|
vm.start_vm()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,53 @@
|
||||||
module main
|
module main
|
||||||
|
|
||||||
import vm
|
import vm
|
||||||
|
import readline
|
||||||
|
|
||||||
|
mut kernel := none
|
||||||
|
|
||||||
mut stdin := [1024]u8;
|
fn start_kernel(){
|
||||||
mut stdout := [1024]u8;
|
kernel = Kernel{}
|
||||||
|
|
||||||
|
|
||||||
fn read(input [u8])
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn exit() {
|
fn kill(){
|
||||||
exit(0)
|
kernel = none
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write(input [u8])
|
struct Kernel{
|
||||||
{
|
|
||||||
|
|
||||||
|
pub mut:
|
||||||
|
stdin := []u8{};
|
||||||
|
stdout := []u8{};
|
||||||
|
|
||||||
|
input_device := 'keyboard'
|
||||||
|
output_device := 'screen'
|
||||||
}
|
}
|
||||||
|
|
||||||
fn request_control()
|
|
||||||
|
fn (mut kernel Kernel) read()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
mut input := none
|
||||||
|
|
||||||
|
match kernel.input_device {
|
||||||
|
'keyboard' {
|
||||||
|
|
||||||
|
mut r := readline.Readline{}
|
||||||
|
input = r.read_line('')!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
kernel.stdin = input.bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut kernel Kernel) exit() { exit(0) }
|
||||||
|
|
||||||
|
fn (mut kernel Kernel) write()
|
||||||
|
{
|
||||||
|
kernel.stdout = output
|
||||||
|
|
||||||
|
match kernel.output_device {
|
||||||
|
|
||||||
|
'screen' { print(stdout.bytestr()) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
|
||||||
|
module main
|
||||||
|
|
||||||
|
import sh
|
||||||
|
import kernel
|
||||||
|
|
||||||
|
os_usermode := '__user__'
|
||||||
|
os_kernelmode := '__kernel__'
|
||||||
|
|
||||||
|
fn boot(){
|
||||||
|
kernel.start_kernel()
|
||||||
|
start_up()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn shutdown() { kernel.kill() }
|
||||||
|
|
||||||
|
fn start_up(){
|
||||||
|
for { sh.sh() }
|
||||||
|
}
|
||||||
10
src/os/sh.v
10
src/os/sh.v
|
|
@ -2,13 +2,7 @@ module main
|
||||||
|
|
||||||
import readline { read_line }
|
import readline { read_line }
|
||||||
|
|
||||||
import kernel
|
import syscall
|
||||||
|
|
||||||
cmds := {
|
|
||||||
'EXIT' : 0
|
|
||||||
'READ' : 1
|
|
||||||
'WRITE' : 2
|
|
||||||
}
|
|
||||||
|
|
||||||
fn sh(){
|
fn sh(){
|
||||||
|
|
||||||
|
|
@ -16,6 +10,6 @@ fn sh(){
|
||||||
mut read_line := readline.Readline{}
|
mut read_line := readline.Readline{}
|
||||||
cmd := read_line()!
|
cmd := read_line()!
|
||||||
|
|
||||||
sys_code := cmds[cmd] or { panic('Command not found:\n')}
|
sys_code := syscall[cmd] or { panic('Command not found:\n') }
|
||||||
kernel.do_syscall(sys_code)
|
kernel.do_syscall(sys_code)
|
||||||
}
|
}
|
||||||
|
|
@ -1,17 +1,17 @@
|
||||||
module main
|
module main
|
||||||
|
|
||||||
import kernel
|
import kernel as os
|
||||||
|
|
||||||
enum syscalls {
|
cmds := {
|
||||||
EXIT,
|
'EXIT' : 0
|
||||||
READ,
|
'READ' : 1
|
||||||
WRITE
|
'WRITE' : 2
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_syscall(sys_code int)
|
fn do_syscall(sys_code int)
|
||||||
{
|
{
|
||||||
match sys_code :
|
match sys_code :
|
||||||
0 { kernel.exit() }
|
0 { os.kernel.exit() }
|
||||||
1 { kernel.read() }
|
1 { os.kernel.read() }
|
||||||
2 { kernel.write() }
|
2 { os.kernel.write() }
|
||||||
}
|
}
|
||||||
|
|
@ -1,8 +1,3 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fn start_assembler()
|
fn start_assembler()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
||||||
255
src/vm/cpu.v
255
src/vm/cpu.v
|
|
@ -2,6 +2,7 @@
|
||||||
module main
|
module main
|
||||||
|
|
||||||
import vm
|
import vm
|
||||||
|
import instruction
|
||||||
|
|
||||||
struct Alu{
|
struct Alu{
|
||||||
pub mut:
|
pub mut:
|
||||||
|
|
@ -29,26 +30,33 @@ struct CPU{
|
||||||
num_of_registers := 32
|
num_of_registers := 32
|
||||||
|
|
||||||
pub mut:
|
pub mut:
|
||||||
pc u32
|
pc u32 := 0
|
||||||
|
ic u32 := 0
|
||||||
registers[num_of_registers]u8
|
registers[num_of_registers]u8
|
||||||
alu Alu
|
alu Alu
|
||||||
cpu_control = none
|
cpu_control := none
|
||||||
|
current_instruction := Instruction{
|
||||||
|
fmt_r: R{},
|
||||||
|
fmt_i: I{},
|
||||||
|
fmt_b: B{},
|
||||||
|
fmt_u: U{},
|
||||||
|
fmt_j: J{},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn (cpu CPU) start_cpu()
|
fn (cpu CPU) start_cpu()
|
||||||
{
|
{
|
||||||
cpu.pc := 0
|
for
|
||||||
|
|
||||||
while(true)
|
|
||||||
{
|
{
|
||||||
u32 instruction := cpu.fetch()
|
if cpu.ic != 0 {
|
||||||
cpu.decode(instruction)
|
u32 instruction := cpu.fetch()
|
||||||
cpu.run()
|
cpu.decode(instruction)
|
||||||
|
cpu.run()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (cpu CPU) fetch()
|
fn (cpu CPU) fetch() u32
|
||||||
{
|
{
|
||||||
u32 instruction := vm.RAM[cpu.pc];
|
u32 instruction := vm.RAM[cpu.pc];
|
||||||
cpu.pc += 4
|
cpu.pc += 4
|
||||||
|
|
@ -58,10 +66,237 @@ fn (cpu CPU) fetch()
|
||||||
|
|
||||||
fn (cpu CPU) decode(u32 instruction)
|
fn (cpu CPU) decode(u32 instruction)
|
||||||
{
|
{
|
||||||
|
mut opcode := (instruction & 0x7F)
|
||||||
|
|
||||||
|
match opcode {
|
||||||
|
|
||||||
|
0x33 {
|
||||||
|
|
||||||
|
mut funct3 := (instruction & 0x7000) >> 12
|
||||||
|
mut rd := (instruction & 0x7000) >> 12
|
||||||
|
mut rs1 :=
|
||||||
|
mut rs2 :=
|
||||||
|
mut funct7 :=
|
||||||
|
|
||||||
|
cpu.current_instruction.fmt_r.opcode := opcode
|
||||||
|
cpu.current_instruction.fmt_r.funct3 := funct3
|
||||||
|
cpu.current_instruction.fmt_r.funct7 := funct7
|
||||||
|
cpu.current_instruction.fmt_r.rs1 := rs1
|
||||||
|
cpu.current_instruction.fmt_r.rs2 := rs2
|
||||||
|
cpu.current_instruction.fmt_r.rd := rd
|
||||||
|
|
||||||
|
cpu.current_instruction.fmt_i = none
|
||||||
|
cpu.current_instruction.fmt_j = none
|
||||||
|
cpu.current_instruction.fmt_s = none
|
||||||
|
cpu.current_instruction.fmt_b = none
|
||||||
|
cpu.current_instruction.fmt_u = none
|
||||||
|
}
|
||||||
|
|
||||||
|
0x13, 0x03, 0x37, 0x73 {
|
||||||
|
|
||||||
|
// I
|
||||||
|
|
||||||
|
mut funct3 := (instruction & 0x7000) >> 12
|
||||||
|
|
||||||
|
opcode u8;
|
||||||
|
funct3 u8;
|
||||||
|
rd u8;
|
||||||
|
rs1 u8;
|
||||||
|
imm u16;
|
||||||
|
|
||||||
|
cpu.current_instruction.fmt_i.opcode := opcode
|
||||||
|
cpu.current_instruction.fmt_i.funct3 := funct3
|
||||||
|
cpu.current_instruction.fmt_i.imm := imm
|
||||||
|
cpu.current_instruction.fmt_i.rs1 := rs1
|
||||||
|
cpu.current_instruction.fmt_i.rs2 := rs2
|
||||||
|
cpu.current_instruction.fmt_i.rd := rd
|
||||||
|
|
||||||
|
cpu.current_instruction.fmt_r = none
|
||||||
|
cpu.current_instruction.fmt_j = none
|
||||||
|
cpu.current_instruction.fmt_s = none
|
||||||
|
cpu.current_instruction.fmt_b = none
|
||||||
|
cpu.current_instruction.fmt_u = none
|
||||||
|
}
|
||||||
|
|
||||||
|
0x23 {
|
||||||
|
// S
|
||||||
|
|
||||||
|
opcode u8;
|
||||||
|
funct3 u8;
|
||||||
|
rs1 u8;
|
||||||
|
rs2 u8;
|
||||||
|
imm2 u8;
|
||||||
|
imm1 u8;
|
||||||
|
|
||||||
|
cpu.current_instruction.fmt_s.opcode := opcode
|
||||||
|
cpu.current_instruction.fmt_s.funct3 := funct3
|
||||||
|
cpu.current_instruction.fmt_s.imm2 := imm2
|
||||||
|
cpu.current_instruction.fmt_s.imm1 := imm1
|
||||||
|
cpu.current_instruction.fmt_s.rs1 := rs1
|
||||||
|
cpu.current_instruction.fmt_s.rs2 := rs2
|
||||||
|
|
||||||
|
cpu.current_instruction.fmt_r = none
|
||||||
|
cpu.current_instruction.fmt_j = none
|
||||||
|
cpu.current_instruction.fmt_i = none
|
||||||
|
cpu.current_instruction.fmt_b = none
|
||||||
|
cpu.current_instruction.fmt_u = none
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
0x63 {
|
||||||
|
// B
|
||||||
|
|
||||||
|
opcode u8;
|
||||||
|
funct3 u8;
|
||||||
|
rs1 u8;
|
||||||
|
rs2 u8;
|
||||||
|
imm1 u8;
|
||||||
|
imm2 u8;
|
||||||
|
|
||||||
|
cpu.current_instruction.fmt_b.opcode := opcode
|
||||||
|
cpu.current_instruction.fmt_b.funct3 := funct3
|
||||||
|
cpu.current_instruction.fmt_b.imm2 := imm2
|
||||||
|
cpu.current_instruction.fmt_b.imm1 := imm1
|
||||||
|
cpu.current_instruction.fmt_b.rs1 := rs1
|
||||||
|
cpu.current_instruction.fmt_b.rs2 := rs2
|
||||||
|
|
||||||
|
cpu.current_instruction.fmt_r = none
|
||||||
|
cpu.current_instruction.fmt_j = none
|
||||||
|
cpu.current_instruction.fmt_s = none
|
||||||
|
cpu.current_instruction.fmt_i = none
|
||||||
|
cpu.current_instruction.fmt_u = none
|
||||||
|
}
|
||||||
|
|
||||||
|
0x6F {
|
||||||
|
// J
|
||||||
|
|
||||||
|
opcode u8;
|
||||||
|
rd u8;
|
||||||
|
imm u32;
|
||||||
|
|
||||||
|
cpu.current_instruction.fmt_j.opcode := opcode
|
||||||
|
cpu.current_instruction.fmt_j.imm := imm
|
||||||
|
cpu.current_instruction.fmt_j.rd := rd
|
||||||
|
|
||||||
|
cpu.current_instruction.fmt_r = none
|
||||||
|
cpu.current_instruction.fmt_i = none
|
||||||
|
cpu.current_instruction.fmt_s = none
|
||||||
|
cpu.current_instruction.fmt_b = none
|
||||||
|
cpu.current_instruction.fmt_u = none
|
||||||
|
}
|
||||||
|
|
||||||
|
0x17 {
|
||||||
|
// U
|
||||||
|
opcode u8;
|
||||||
|
rd u8;
|
||||||
|
imm u32;
|
||||||
|
|
||||||
|
cpu.current_instruction.fmt_u.opcode := opcode
|
||||||
|
cpu.current_instruction.fmt_u.rd := rd
|
||||||
|
cpu.current_instruction.fmt_u.imm := imm
|
||||||
|
|
||||||
|
cpu.current_instruction.fmt_r = none
|
||||||
|
cpu.current_instruction.fmt_j = none
|
||||||
|
cpu.current_instruction.fmt_s = none
|
||||||
|
cpu.current_instruction.fmt_b = none
|
||||||
|
cpu.current_instruction.fmt_i = none
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (cpu CPU) run(u32 instruction)
|
fn (cpu CPU) run(u32 instruction)
|
||||||
{
|
{
|
||||||
|
if cpu.current_instruction.fmt_j != none {
|
||||||
|
|
||||||
|
// inserir elementos
|
||||||
|
cpu.jal()
|
||||||
|
|
||||||
|
}else if cpu.current_instruction.fmt_r != none {
|
||||||
|
|
||||||
|
match cpu.current_instruction.funct3 {
|
||||||
|
|
||||||
|
0x0 {
|
||||||
|
|
||||||
|
match cpu.current_instruction.funct7 {
|
||||||
|
0x00 { cpu.current_instruction.add() }
|
||||||
|
0x20 { cpu.current_instruction.sub() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
0x4 { cpu.current_instruction.xor() }
|
||||||
|
0x6 { cpu.current_instruction._or() }
|
||||||
|
0x7 { cpu.current_instruction.and() }
|
||||||
|
0x1 { cpu.current_instruction.sll() }
|
||||||
|
|
||||||
|
0x5 {
|
||||||
|
|
||||||
|
match cpu.current_instruction.funct7 {
|
||||||
|
0x00 { cpu.current_instruction.srl() }
|
||||||
|
0x20 { cpu.current_instruction.sra() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
0x2 { cpu.current_instruction.slt() }
|
||||||
|
0x3 { cpu.current_instruction.sltu() }
|
||||||
|
}
|
||||||
|
|
||||||
|
}else if cpu.current_instruction.fmt_s != none {
|
||||||
|
|
||||||
|
match cpu.current_instruction.funct3 {
|
||||||
|
0x0 { cpu.current_instruction.sb() }
|
||||||
|
0x1 { cpu.current_instruction.sh() }
|
||||||
|
0x2 { cpu.current_instruction.sw() }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}else if cpu.current_instruction.fmt_b != none {
|
||||||
|
|
||||||
|
match cpu.current_instruction.funct3 {
|
||||||
|
|
||||||
|
0x0 { cpu.current_instruction.beq() }
|
||||||
|
0x1 { cpu.current_instruction.bne() }
|
||||||
|
0x4 { cpu.current_instruction.blt() }
|
||||||
|
0x5 { cpu.current_instruction.bge() }
|
||||||
|
0x6 { cpu.current_instruction.bltu() }
|
||||||
|
0x7 { cpu.current_instruction.bgeu() }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}else if chip.current_instruction.fmt_i != none {
|
||||||
|
|
||||||
|
match cpu.current_instruction.opcode {
|
||||||
|
|
||||||
|
0x13 {
|
||||||
|
|
||||||
|
match cpu.current_instruction.funct3 {
|
||||||
|
|
||||||
|
0x0 { cpu.current_instruction.addi() }
|
||||||
|
0x4 { cpu.current_instruction.xori() }
|
||||||
|
0x6 { cpu.current_instruction.ori() }
|
||||||
|
0x7 { cpu.current_instruction.andi() }
|
||||||
|
0x1 { cpu.current_instruction.slli() }
|
||||||
|
|
||||||
|
0x5 {
|
||||||
|
cpu.current_instruction.srli()
|
||||||
|
cpu.current_instruction.srai()
|
||||||
|
}
|
||||||
|
|
||||||
|
0x2 { cpu.current_instruction.slti() }
|
||||||
|
0x3 { cpu.current_instruction.sltiu() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
0x73 {
|
||||||
|
|
||||||
|
match cpu.current_instruction.imm {
|
||||||
|
|
||||||
|
0x0 { cpu.current_instruction.ecall() }
|
||||||
|
0x1 { cpu.current_instruction.ebreak() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
chip.ic--
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,38 +1,59 @@
|
||||||
module main
|
module main
|
||||||
|
|
||||||
import vm.hardware as vm
|
import vm.hardware as vm
|
||||||
|
import os
|
||||||
|
|
||||||
struct J{
|
struct J{
|
||||||
pub mut:
|
pub mut:
|
||||||
rd i8
|
opcode u8;
|
||||||
imm u32
|
rd u8;
|
||||||
|
imm u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct R{
|
struct R{
|
||||||
pub mut:
|
pub mut:
|
||||||
rd u8;
|
opcode u8;
|
||||||
rs1 u8;
|
funct7 u8;
|
||||||
rs2 u8;
|
funct3 u8;
|
||||||
|
rd u8;
|
||||||
|
rs1 u8;
|
||||||
|
rs2 u8;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct I{
|
struct I{
|
||||||
pub mut:
|
pub mut:
|
||||||
rd u8;
|
opcode u8;
|
||||||
rs1 u8;
|
funct3 u8;
|
||||||
imm u16;
|
rd u8;
|
||||||
|
rs1 u8;
|
||||||
|
imm u16;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct U{
|
struct U{
|
||||||
pub mut:
|
pub mut:
|
||||||
rd u8;
|
opcode u8;
|
||||||
imm u32;
|
rd u8;
|
||||||
|
imm u32;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct S{
|
||||||
|
pub mut:
|
||||||
|
opcode u8;
|
||||||
|
funct3 u8;
|
||||||
|
rs1 u8;
|
||||||
|
rs2 u8;
|
||||||
|
imm2 u8;
|
||||||
|
imm1 u8;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct B{
|
struct B{
|
||||||
pub mut:
|
pub mut:
|
||||||
rs1 u8;
|
opcode u8;
|
||||||
rs2 u8;
|
funct3 u8;
|
||||||
imm u16;
|
rs1 u8;
|
||||||
|
rs2 u8;
|
||||||
|
imm1 u8;
|
||||||
|
imm2 u8;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Instruction{
|
struct Instruction{
|
||||||
|
|
@ -208,7 +229,7 @@ fn (inst Instruction) auipc() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (inst Instruction) ecall() {
|
fn (inst Instruction) ecall() {
|
||||||
vm.cpu.cpu_control = 'kernel'
|
vm.cpu.cpu_control = '__kernel__'
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (inst Instruction) addi() {
|
fn (inst Instruction) addi() {
|
||||||
|
|
|
||||||
|
|
@ -39,8 +39,14 @@ fn start_assembler()
|
||||||
|
|
||||||
fn start_vm()
|
fn start_vm()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
// Load asm instructions, converts to machine instructions and save in memory
|
// Load asm instructions, converts to machine instructions and save in memory
|
||||||
start_assembler()
|
start_assembler()
|
||||||
// Get in memory, decode and run instructions
|
// Get in memory, decode and run instructions
|
||||||
cpu.start_cpu()
|
|
||||||
|
mut threads := []thread{}
|
||||||
|
|
||||||
|
threads << spawn cpu.start_cpu()
|
||||||
|
threads << spawn os.boot()
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue