riscvemu/virtualEei.go

73 lines
1.6 KiB
Go
Raw Normal View History

2022-12-28 00:59:35 +00:00
package riscvemu
2022-12-28 01:11:07 +00:00
import (
"math"
"os"
)
2022-12-28 00:59:35 +00:00
type VirtualEEI struct {
2022-12-28 01:11:07 +00:00
memPages map[uint32][4096]byte
2022-12-28 00:59:35 +00:00
}
2022-12-28 01:11:07 +00:00
func NewVirtualEEI() VirtualEEI {
return VirtualEEI{
memPages: make(map[uint32][4096]byte),
2022-12-28 00:59:35 +00:00
}
2022-12-28 01:11:07 +00:00
}
2022-12-28 00:59:35 +00:00
2022-12-28 01:11:07 +00:00
func (ve *VirtualEEI) ReadByte(addr uint32) (byte, error) {
page, _ := ve.memPages[addr>>12]
return page[addr&0b111111111111], nil
2022-12-28 00:59:35 +00:00
}
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
2022-12-28 01:11:07 +00:00
page, _ := ve.memPages[addr>>12]
inPageAddr := addr & 0b111111111111
return (uint32(page[inPageAddr]) << 24) | (uint32(page[inPageAddr+1]) << 16) | (uint32(page[inPageAddr+2]) << 8) | uint32(page[inPageAddr+3]), nil
2022-12-28 00:59:35 +00:00
}
func (ve *VirtualEEI) WriteByte(addr uint32, value byte) error {
2022-12-28 01:11:07 +00:00
page, ok := ve.memPages[addr>>12]
// Slices are reference-types, this will write-through into ve.memPages
page[addr&0b111111111111] = value
if !ok {
ve.memPages[addr>>12] = page
2022-12-28 00:59:35 +00:00
}
return nil
}
func (ve *VirtualEEI) Write32(addr, value uint32) error {
// n.b. will panic on overflow
2022-12-28 01:11:07 +00:00
page, ok := ve.memPages[addr>>12]
inPageAddr := addr & 0b111111111111
// Slices are reference-types, this will write-through into ve.memPages
page[inPageAddr] = byte((value >> 24) & 0b11111111)
page[inPageAddr+1] = byte((value >> 16) & 0b11111111)
page[inPageAddr+2] = byte((value >> 8) & 0b11111111)
page[inPageAddr+3] = byte(value & 0b11111111)
if !ok {
ve.memPages[addr>>12] = page
}
2022-12-28 00:59:35 +00:00
return nil
}
func (ve *VirtualEEI) Syscall() {
panic("syscall")
}
func (ve *VirtualEEI) Trap() (bool, error) {
panic("trap")
}