cpu: implement ECALL/EBREAK

This commit is contained in:
mappu 2022-12-28 14:46:41 +13:00
parent b5809d4689
commit 396cece705
3 changed files with 20 additions and 9 deletions

19
cpu.go
View File

@ -8,6 +8,10 @@ type ErrInvalidOpcode struct{}
func (e ErrInvalidOpcode) Error() string { return "invalid opcode" }
type ErrBreak struct{}
func (e ErrBreak) Error() string { return "EBREAK" }
type CPUState struct {
Registers [32]uint32
Pc uint32
@ -485,7 +489,20 @@ func (c *CPUState) Step() error {
case 0b1110011:
// ECALL/EBREAK
panic("todo")
if opcode == 0b00000000000000000000000001110011 {
// ECALL
err := c.w.Syscall()
if err != nil {
return err
}
} else if opcode == 0b00000000000100000000000001110011 {
// EBREAK
return ErrBreak{}
} else {
return ErrInvalidOpcode{}
}
default:
return ErrInvalidOpcode{}

4
eei.go
View File

@ -11,9 +11,7 @@ type EEI interface {
Write16(addr uint32, value uint16) error
Write32(addr, value uint32) error
Syscall()
Trap() (bool, error)
Syscall() error
MemFence(opcode uint32) error
}

View File

@ -108,14 +108,10 @@ func (ve *VirtualEEI) WriteAt(p []byte, off int64) (n int, err error) {
return len(p), nil
}
func (ve *VirtualEEI) Syscall() {
func (ve *VirtualEEI) Syscall() error {
panic("syscall")
}
func (ve *VirtualEEI) Trap() (bool, error) {
panic("trap")
}
func (ve *VirtualEEI) MemFence(opcode uint32) error {
// In the virtual EEI, a memory fence is a no-op.
// It matters for synchronizing multiple cores or for peripherals.