Cpu instructions, Os syscalls

This commit is contained in:
Vinicius Silva 2024-07-10 17:03:10 -03:00
parent cacbb05b39
commit c3ff7ea4aa
9 changed files with 354 additions and 60 deletions

View File

@ -3,8 +3,6 @@ module main
import vm
fn main() {
println('Hello World!')
vm.start_vm()
}

View File

@ -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()
{
}

19
src/os/os.v Normal file
View File

@ -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() }
}

View File

@ -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)
}

View File

@ -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() }
}

View File

@ -1,8 +1,3 @@
fn start_assembler()
{

View File

@ -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--
}
}

View File

@ -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() {

View File

@ -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()
}