-
Notifications
You must be signed in to change notification settings - Fork 124
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Lean: Memory model #965
Lean: Memory model #965
Changes from 16 commits
e72db01
70464e1
4de2646
4f5df07
e2dc69d
7ed0b0b
d93d5d5
57926e2
a15e2ff
7058f9c
8b1fd04
573f159
8d6a2bf
68afab4
6f5be3d
646b325
9e28c27
7fa15aa
52ebdd7
f5ec79b
741ecdd
91935c5
4dc0827
7e1df36
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
import Std.Data.DHashMap | ||
import Std.Data.HashMap | ||
namespace Sail | ||
|
||
section Regs | ||
|
@@ -41,17 +42,30 @@ def trivialChoiceSource : ChoiceSource where | |
| .fin _ => 0 | ||
| .bitvector _ => 0 | ||
|
||
class Arch where | ||
va_size : Nat | ||
pa : Type | ||
arch_ak : Type | ||
translation : Type | ||
abort : Type | ||
barrier : Type | ||
cache_op : Type | ||
tlb_op : Type | ||
fault : Type | ||
sys_reg_id : Type | ||
|
||
/- The Units are placeholders for a future implementation of the state monad some Sail functions use. -/ | ||
inductive Error where | ||
| Exit | ||
| Unreachable | ||
| UninitializedMemory | ||
| Assertion (s : String) | ||
open Error | ||
|
||
structure SequentialState (RegisterType : Register → Type) (c : ChoiceSource) where | ||
regs : Std.DHashMap Register RegisterType | ||
choiceState : c.α | ||
mem : Unit | ||
mem : Std.HashMap Nat (BitVec 8) | ||
tags : Unit | ||
|
||
inductive RegisterRef (RegisterType : Register → Type) : Type → Type where | ||
|
@@ -113,6 +127,94 @@ def vectorUpdate (v : Vector α m) (n : Nat) (a : α) := v.set! n a | |
def assert (p : Bool) (s : String) : PreSailM RegisterType c Unit := | ||
if p then pure () else throw (Assertion s) | ||
|
||
section concurrency_interface | ||
|
||
inductive Access_variety where | ||
| AV_plain | ||
| AV_exclusive | ||
| AV_atomic_rmw | ||
export Access_variety (AV_plain AV_exclusive AV_atomic_rmw) | ||
|
||
inductive Access_strength where | ||
| AS_normal | ||
| AS_rel_or_acq | ||
| AS_acq_rcpc | ||
export Access_strength(AS_normal AS_rel_or_acq AS_acq_rcpc) | ||
|
||
structure Explicit_access_kind where | ||
variety : Access_variety | ||
strength : Access_strength | ||
|
||
inductive Access_kind (arch : Type) where | ||
| AK_explicit (_ : Explicit_access_kind) | ||
| AK_ifetch (_ : Unit) | ||
| AK_ttw (_ : Unit) | ||
| AK_arch (_ : arch) | ||
export Access_kind(AK_explicit AK_ifetch AK_ttw AK_arch) | ||
|
||
inductive Result (α : Type) (β : Type) where | ||
| Ok (_ : α) | ||
| Err (_ : β) | ||
export Result(Ok Err) | ||
|
||
structure Mem_read_request | ||
(n : Nat) (vasize : Nat) (pa : Type) (ts : Type) (arch_ak : Type) where | ||
access_kind : Access_kind arch_ak | ||
va : (Option (BitVec vasize)) | ||
pa : pa | ||
translation : ts | ||
size : Int | ||
tag : Bool | ||
|
||
structure Mem_write_request | ||
(n : Nat) (vasize : Nat) (pa : Type) (ts : Type) (arch_ak : Type) where | ||
access_kind : Access_kind arch_ak | ||
va : (Option (BitVec vasize)) | ||
pa : pa | ||
translation : ts | ||
size : Int | ||
value : (Option (BitVec (8 * n))) | ||
tag : (Option Bool) | ||
|
||
def write_byte (addr : Nat) (value : BitVec 8) : PreSailM RegisterType c PUnit := do | ||
modify fun s => { s with mem := s.mem.insert addr value } | ||
pure () | ||
|
||
def write_bytes (addr : Nat) (value : BitVec (8 * n)) : PreSailM RegisterType c Bool := do | ||
let list := List.ofFn (λ i : Fin n => (addr + i, value.extractLsb' (8 * i) 8)) | ||
List.forM list (λ (a, v) => write_byte a v) | ||
pure true | ||
|
||
def sail_mem_write [Arch] (req : Mem_write_request n vasize (BitVec pa_size) ts arch) : PreSailM RegisterType c (Result (Option Bool) Arch.abort) := do | ||
let addr := req.pa.toNat | ||
let b ← match req.value with | ||
| some v => write_bytes addr v | ||
| none => pure true | ||
pure (Ok (some b)) | ||
|
||
def read_byte (addr : Nat) : PreSailM RegisterType c (BitVec 8) := do | ||
let .some s := (← get).mem.get? addr | ||
| throw UninitializedMemory | ||
pure s | ||
|
||
def read_bytes (size : Nat) (addr : Nat) : PreSailM RegisterType c ((BitVec (8 * size)) × (Option Bool)) := | ||
match size with | ||
| 0 => pure (default, some true) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In theory, the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed |
||
| n + 1 => do | ||
let b ← read_byte addr | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think the do block should get an extra indentation here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
let (bytes, bool) ← read_bytes n (addr+1) | ||
have h : 8 + 8 * n = 8 * (n + 1) := by omega | ||
return (h ▸ b.append bytes, bool) | ||
|
||
def sail_mem_read [Arch] (req : Mem_read_request n vasize (BitVec pa_size) ts arch) : PreSailM RegisterType c (Result ((BitVec (8 * n)) × (Option Bool)) Arch.abort) := do | ||
let addr := req.pa.toNat | ||
let value ← read_bytes n addr | ||
pure (Ok value) | ||
|
||
def sail_barrier (_ : α) : PreSailM RegisterType c Unit := pure () | ||
|
||
end concurrency_interface | ||
|
||
end Regs | ||
|
||
namespace BitVec | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where does this
toNat
comes from?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the type of
req
in the argument fixes req.pa to be aBitVec pa_size
So that
toNat
isBitVec.toNat