cpu: implement ECALL/EBREAK
This commit is contained in:
parent
b5809d4689
commit
396cece705
19
cpu.go
19
cpu.go
@ -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
4
eei.go
@ -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
|
||||
}
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user