Cpu instructions, Os syscalls
This commit is contained in:
parent
cacbb05b39
commit
c3ff7ea4aa
|
|
@ -3,8 +3,6 @@ module main
|
|||
import vm
|
||||
|
||||
fn main() {
|
||||
println('Hello World!')
|
||||
|
||||
vm.start_vm()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,27 +1,53 @@
|
|||
module main
|
||||
|
||||
import vm
|
||||
import readline
|
||||
|
||||
mut kernel := none
|
||||
|
||||
fn start_kernel(){
|
||||
kernel = Kernel{}
|
||||
}
|
||||
|
||||
fn kill(){
|
||||
kernel = none
|
||||
}
|
||||
|
||||
struct Kernel{
|
||||
|
||||
pub mut:
|
||||
stdin := []u8{};
|
||||
stdout := []u8{};
|
||||
|
||||
input_device := 'keyboard'
|
||||
output_device := 'screen'
|
||||
}
|
||||
|
||||
|
||||
mut stdin := [1024]u8;
|
||||
mut stdout := [1024]u8;
|
||||
|
||||
|
||||
fn read(input [u8])
|
||||
fn (mut kernel Kernel) read()
|
||||
{
|
||||
|
||||
mut input := none
|
||||
|
||||
match kernel.input_device {
|
||||
'keyboard' {
|
||||
|
||||
mut r := readline.Readline{}
|
||||
input = r.read_line('')!
|
||||
}
|
||||
}
|
||||
|
||||
fn exit() {
|
||||
exit(0)
|
||||
kernel.stdin = input.bytes()
|
||||
}
|
||||
|
||||
fn write(input [u8])
|
||||
fn (mut kernel Kernel) exit() { exit(0) }
|
||||
|
||||
fn (mut kernel Kernel) write()
|
||||
{
|
||||
kernel.stdout = output
|
||||
|
||||
match kernel.output_device {
|
||||
|
||||
'screen' { print(stdout.bytestr()) }
|
||||
}
|
||||
|
||||
fn request_control()
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -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 kernel
|
||||
|
||||
cmds := {
|
||||
'EXIT' : 0
|
||||
'READ' : 1
|
||||
'WRITE' : 2
|
||||
}
|
||||
import syscall
|
||||
|
||||
fn sh(){
|
||||
|
||||
|
|
@ -16,6 +10,6 @@ fn sh(){
|
|||
mut read_line := readline.Readline{}
|
||||
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)
|
||||
}
|
||||
|
|
@ -1,17 +1,17 @@
|
|||
module main
|
||||
|
||||
import kernel
|
||||
import kernel as os
|
||||
|
||||
enum syscalls {
|
||||
EXIT,
|
||||
READ,
|
||||
WRITE
|
||||
cmds := {
|
||||
'EXIT' : 0
|
||||
'READ' : 1
|
||||
'WRITE' : 2
|
||||
}
|
||||
|
||||
fn do_syscall(sys_code int)
|
||||
{
|
||||
match sys_code :
|
||||
0 { kernel.exit() }
|
||||
1 { kernel.read() }
|
||||
2 { kernel.write() }
|
||||
0 { os.kernel.exit() }
|
||||
1 { os.kernel.read() }
|
||||
2 { os.kernel.write() }
|
||||
}
|
||||
|
|
@ -1,8 +1,3 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
fn start_assembler()
|
||||
{
|
||||
|
||||
|
|
|
|||
249
src/vm/cpu.v
249
src/vm/cpu.v
|
|
@ -2,6 +2,7 @@
|
|||
module main
|
||||
|
||||
import vm
|
||||
import instruction
|
||||
|
||||
struct Alu{
|
||||
pub mut:
|
||||
|
|
@ -29,26 +30,33 @@ struct CPU{
|
|||
num_of_registers := 32
|
||||
|
||||
pub mut:
|
||||
pc u32
|
||||
pc u32 := 0
|
||||
ic u32 := 0
|
||||
registers[num_of_registers]u8
|
||||
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()
|
||||
{
|
||||
cpu.pc := 0
|
||||
|
||||
while(true)
|
||||
for
|
||||
{
|
||||
if cpu.ic != 0 {
|
||||
u32 instruction := cpu.fetch()
|
||||
cpu.decode(instruction)
|
||||
cpu.run()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn (cpu CPU) fetch()
|
||||
fn (cpu CPU) fetch() u32
|
||||
{
|
||||
u32 instruction := vm.RAM[cpu.pc];
|
||||
cpu.pc += 4
|
||||
|
|
@ -58,10 +66,237 @@ fn (cpu CPU) fetch()
|
|||
|
||||
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)
|
||||
{
|
||||
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,15 +1,20 @@
|
|||
module main
|
||||
|
||||
import vm.hardware as vm
|
||||
import os
|
||||
|
||||
struct J{
|
||||
pub mut:
|
||||
rd i8
|
||||
imm u32
|
||||
opcode u8;
|
||||
rd u8;
|
||||
imm u32;
|
||||
}
|
||||
|
||||
struct R{
|
||||
pub mut:
|
||||
opcode u8;
|
||||
funct7 u8;
|
||||
funct3 u8;
|
||||
rd u8;
|
||||
rs1 u8;
|
||||
rs2 u8;
|
||||
|
|
@ -17,6 +22,8 @@ struct R{
|
|||
|
||||
struct I{
|
||||
pub mut:
|
||||
opcode u8;
|
||||
funct3 u8;
|
||||
rd u8;
|
||||
rs1 u8;
|
||||
imm u16;
|
||||
|
|
@ -24,15 +31,29 @@ struct I{
|
|||
|
||||
struct U{
|
||||
pub mut:
|
||||
opcode u8;
|
||||
rd u8;
|
||||
imm u32;
|
||||
}
|
||||
|
||||
struct B{
|
||||
struct S{
|
||||
pub mut:
|
||||
opcode u8;
|
||||
funct3 u8;
|
||||
rs1 u8;
|
||||
rs2 u8;
|
||||
imm u16;
|
||||
imm2 u8;
|
||||
imm1 u8;
|
||||
}
|
||||
|
||||
struct B{
|
||||
pub mut:
|
||||
opcode u8;
|
||||
funct3 u8;
|
||||
rs1 u8;
|
||||
rs2 u8;
|
||||
imm1 u8;
|
||||
imm2 u8;
|
||||
}
|
||||
|
||||
struct Instruction{
|
||||
|
|
@ -208,7 +229,7 @@ fn (inst Instruction) auipc() {
|
|||
}
|
||||
|
||||
fn (inst Instruction) ecall() {
|
||||
vm.cpu.cpu_control = 'kernel'
|
||||
vm.cpu.cpu_control = '__kernel__'
|
||||
}
|
||||
|
||||
fn (inst Instruction) addi() {
|
||||
|
|
|
|||
|
|
@ -39,8 +39,14 @@ fn start_assembler()
|
|||
|
||||
fn start_vm()
|
||||
{
|
||||
|
||||
|
||||
// Load asm instructions, converts to machine instructions and save in memory
|
||||
start_assembler()
|
||||
// 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