cpu: implement FENCE/FENCE.TSO/PAUSE as stub
This commit is contained in:
parent
2864b16817
commit
b5809d4689
19
cpu.go
19
cpu.go
@ -464,7 +464,24 @@ func (c *CPUState) Step() error {
|
|||||||
|
|
||||||
case 0b0001111:
|
case 0b0001111:
|
||||||
// FENCE/FENCE.TSO/PAUSE
|
// FENCE/FENCE.TSO/PAUSE
|
||||||
panic("todo")
|
funct3 := (opcode >> 12) & 0b111
|
||||||
|
if funct3 != 0b000 {
|
||||||
|
return ErrInvalidOpcode{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if opcode == 0b00000001000000000000000000001111 {
|
||||||
|
// Zihintpause PAUSE extension
|
||||||
|
// PAUSE is encoded as a FENCE instruction with pred=W, succ=0, fm=0, rd=x0, and rs1=x0.
|
||||||
|
// PAUSE is encoded as a hint within the FENCE opcode because some implementations are ex-
|
||||||
|
// pected to deliberately stall the PAUSE instruction until outstanding memory transactions have
|
||||||
|
// completed. Because the successor set is null, however, PAUSE does not mandate any particular
|
||||||
|
// memory ordering - hence, it truly is a HINT.
|
||||||
|
}
|
||||||
|
|
||||||
|
err := c.w.MemFence(opcode)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
case 0b1110011:
|
case 0b1110011:
|
||||||
// ECALL/EBREAK
|
// ECALL/EBREAK
|
||||||
|
2
eei.go
2
eei.go
@ -14,4 +14,6 @@ type EEI interface {
|
|||||||
Syscall()
|
Syscall()
|
||||||
|
|
||||||
Trap() (bool, error)
|
Trap() (bool, error)
|
||||||
|
|
||||||
|
MemFence(opcode uint32) error
|
||||||
}
|
}
|
||||||
|
@ -116,4 +116,10 @@ func (ve *VirtualEEI) Trap() (bool, error) {
|
|||||||
panic("trap")
|
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.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
var _ EEI = &VirtualEEI{} // interface assertion
|
var _ EEI = &VirtualEEI{} // interface assertion
|
||||||
|
Loading…
Reference in New Issue
Block a user