From 29a94dd442f88d4cc53d79b9627bb6c9a8a2e22d Mon Sep 17 00:00:00 2001 From: mappu Date: Wed, 28 Dec 2022 13:59:35 +1300 Subject: [PATCH] cpu: use EEI terminology --- cmd/riscvrun/main.go | 2 +- cpu.go | 4 ++-- cpu_test.go | 2 +- memoryWorld.go | 45 ------------------------------------------ virtualEei.go | 47 ++++++++++++++++++++++++++++++++++++++++++++ world.go | 4 +++- 6 files changed, 54 insertions(+), 50 deletions(-) delete mode 100644 memoryWorld.go create mode 100644 virtualEei.go diff --git a/cmd/riscvrun/main.go b/cmd/riscvrun/main.go index 9c02259..2e59675 100644 --- a/cmd/riscvrun/main.go +++ b/cmd/riscvrun/main.go @@ -20,7 +20,7 @@ func main() { os.Exit(1) } - sw := riscvemu.MemoryWorld{ + sw := riscvemu.VirtualEEI{ Ram: make([]byte, *memorySize), } diff --git a/cpu.go b/cpu.go index 70cf04d..1695baf 100644 --- a/cpu.go +++ b/cpu.go @@ -11,10 +11,10 @@ func (e ErrInvalidOpcode) Error() string { return "invalid opcode" } type CPUState struct { Registers [32]uint32 Pc uint32 - w World + w EEI } -func NewCPU(w World) CPUState { +func NewCPU(w EEI) CPUState { return CPUState{w: w} } diff --git a/cpu_test.go b/cpu_test.go index cb89695..c9a58e0 100644 --- a/cpu_test.go +++ b/cpu_test.go @@ -6,7 +6,7 @@ import ( func TestCPU(t *testing.T) { - sw := MemoryWorld{ + sw := VirtualEEI{ Ram: make([]byte, 1024), } _ = sw.Write32(0, 0b00000000000100000000000001110011) // EBREAK diff --git a/memoryWorld.go b/memoryWorld.go deleted file mode 100644 index 3684ee4..0000000 --- a/memoryWorld.go +++ /dev/null @@ -1,45 +0,0 @@ -package riscvemu - -type MemoryWorld struct { - Ram []byte -} - -func (mw *MemoryWorld) ReadByte(addr uint32) (byte, error) { - if addr >= uint32(len(mw.Ram)) { - panic("out of bounds") - } - - return mw.Ram[addr], nil -} - -func (mw *MemoryWorld) Read32(addr uint32) (uint32, error) { - // n.b. will panic on overflow - return (uint32(mw.Ram[addr]) << 24) | (uint32(mw.Ram[addr+1]) << 16) | (uint32(mw.Ram[addr+2]) << 8) | uint32(mw.Ram[addr+3]), nil -} - -func (mw *MemoryWorld) WriteByte(addr uint32, value byte) error { - if addr >= uint32(len(mw.Ram)) { - panic("out of bounds") - } - - mw.Ram[addr] = value - return nil -} - -func (mw *MemoryWorld) Write32(addr, value uint32) error { - // n.b. will panic on overflow - mw.Ram[addr] = byte((value >> 24) & 0b11111111) - mw.Ram[addr+1] = byte((value >> 16) & 0b11111111) - mw.Ram[addr+2] = byte((value >> 8) & 0b11111111) - mw.Ram[addr+3] = byte(value & 0b11111111) - - return nil -} - -func (mw *MemoryWorld) Syscall() { - panic("syscall") -} - -func (mw *MemoryWorld) Trap() (bool, error) { - panic("trap") -} diff --git a/virtualEei.go b/virtualEei.go new file mode 100644 index 0000000..1ace7ac --- /dev/null +++ b/virtualEei.go @@ -0,0 +1,47 @@ +package riscvemu + +type VirtualEEI struct { + Ram []byte +} + +func (ve *VirtualEEI) ReadByte(addr uint32) (byte, error) { + if addr >= uint32(len(ve.Ram)) { + panic("out of bounds") + } + + return ve.Ram[addr], nil +} + +func (ve *VirtualEEI) Read32(addr uint32) (uint32, error) { + // n.b. will panic on overflow + // RISC-V allows 32-bit load/stores to be implemented as either little-endian + // or big-endian. This is the little-endian version + return (uint32(ve.Ram[addr]) << 24) | (uint32(ve.Ram[addr+1]) << 16) | (uint32(ve.Ram[addr+2]) << 8) | uint32(ve.Ram[addr+3]), nil +} + +func (ve *VirtualEEI) WriteByte(addr uint32, value byte) error { + if addr >= uint32(len(ve.Ram)) { + panic("out of bounds") + } + + ve.Ram[addr] = value + return nil +} + +func (ve *VirtualEEI) Write32(addr, value uint32) error { + // n.b. will panic on overflow + ve.Ram[addr] = byte((value >> 24) & 0b11111111) + ve.Ram[addr+1] = byte((value >> 16) & 0b11111111) + ve.Ram[addr+2] = byte((value >> 8) & 0b11111111) + ve.Ram[addr+3] = byte(value & 0b11111111) + + return nil +} + +func (ve *VirtualEEI) Syscall() { + panic("syscall") +} + +func (ve *VirtualEEI) Trap() (bool, error) { + panic("trap") +} diff --git a/world.go b/world.go index 4276a7b..31aa592 100644 --- a/world.go +++ b/world.go @@ -1,6 +1,8 @@ package riscvemu -type World interface { +// EEI (Execution Environment Interface) is the enivronment in which RISC-V +// code is run. +type EEI interface { ReadByte(addr uint32) (byte, error) Read32(addr uint32) (uint32, error) WriteByte(addr uint32, value byte) error