-
Notifications
You must be signed in to change notification settings - Fork 142
Draft PR for lean riscv emulator #1326
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
base: sail2
Are you sure you want to change the base?
Changes from 17 commits
14d2eaa
159ec84
f6f7a10
07a9255
053d96f
01c7d9c
801d563
c1a6dd2
ce235a9
4731737
7dec8d0
7a2a2f7
fbc0c31
4c35c76
a260bf3
d0d30a0
201341f
cdc5536
7b57157
7a02b9d
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 |
|---|---|---|
| @@ -0,0 +1,95 @@ | ||
| -- This module serves as the root of the `LeanRiscv` library. | ||
| -- Import modules here that should be built as part of the library. | ||
| import ELFSage | ||
| import LeanRV64D | ||
| import LeanRV64D.Sail.Sail | ||
|
|
||
| def readElf32 (elfFilepath : System.FilePath) : IO (Except String ELF32File) := do | ||
| let bytes <- IO.FS.readBinFile elfFilepath | ||
| match mkRawELFFile? bytes with | ||
| | .error warning => do | ||
| pure (.error warning) | ||
| | .ok (.elf32 elf) => do | ||
| -- IO.println s!"{repr elf}" | ||
| pure (.ok elf) | ||
| | .ok (.elf64 _elf) => do | ||
| pure (.error "64 bit ELF file not supported") | ||
|
|
||
| inductive MachineBits where | ||
| | B32 | ||
| | B64 | ||
|
|
||
| def DEFAULT_RSTVEC := 0x00001000 | ||
|
|
||
| def initializeMemory (_size: MachineBits) (elf : ELF32File) : Std.HashMap Nat (BitVec 8) := | ||
| -- From: sail-riscv/c_emulator/riscv_sim.cpp | ||
| -- | ||
| -- let RST_VEC_SIZE : UInt32 := 8 | ||
| -- let is_32bit_model := match size with | ||
| -- | .B32 => true | ||
| -- | .B64 => false | ||
| -- let entry : UInt64 := sorry | ||
| -- -- Little endian | ||
| -- let reset_vec : List UInt32 := [ | ||
| -- 0x297, -- auipc t0,0x0 | ||
| -- (0x28593 : UInt32) + (RST_VEC_SIZE * (4 : UInt32) <<< 20), -- addi a1, t0, &dtb | ||
| -- 0xf1402573, -- csrr a0, mhartid | ||
| -- if is_32bit_model then 0x0182a283 -- lw t0,24(t0) | ||
| -- else 0x0182b283, -- ld t0,24(t0) | ||
| -- 0x28067, -- jr t0 | ||
| -- 0, | ||
| -- UInt64.toUInt32 (entry &&& 0xffffffff), | ||
| -- UInt64.toUInt32 (entry >>> 32) | ||
| -- ] | ||
| -- let rv_rom_base := DEFAULT_RSTVEC | ||
|
|
||
| let update_mem_segment mem first_addr body := | ||
| let addrs := Array.range' first_addr (Array.size body) | ||
| Array.foldl (λ mem (addr, byte) => | ||
| if mem.contains addr then | ||
| panic s!"Address {addr} is already written to!" | ||
| else | ||
| mem.insert addr byte.toBitVec | ||
| ) mem (Array.zip addrs body) | ||
|
|
||
| -- Handle interpreted_segments | ||
| let mem'' := List.foldl (λ mem (_header, inst) => | ||
| -- TODO(JP): Is this address correct? | ||
| update_mem_segment mem inst.segment_base inst.segment_body.data | ||
| ) default elf.interpreted_segments | ||
| -- Handle interpreted_sections | ||
| let mem' := mem'' | ||
| -- let mem' := List.foldl (λ mem (_header, inst) => | ||
| -- -- TODO(JP): Is this address correct? | ||
| -- update_mem_segment mem inst.section_offset inst.section_body.data | ||
| -- ) mem'' elf.interpreted_sections | ||
| -- Handle bits_and_bobs | ||
| let mem := List.foldl (λ mem (addr, data) => | ||
| update_mem_segment mem addr data.data | ||
| ) mem' elf.bits_and_bobs | ||
|
|
||
| mem | ||
|
|
||
| def initializeRegisters : Std.ExtDHashMap Register RegisterType := | ||
| -- TODO: initialize register properly | ||
| Std.ExtDHashMap.emptyWithCapacity | ||
|
|
||
| def my_main (_ : PUnit) := | ||
| open LeanRV64D.Functions in | ||
| open Sail in | ||
| do | ||
| -- monadLift (IO.print "TEST") | ||
| -- let _ <- pure (unsafeIO (IO.print "TEST")) | ||
| dbg_trace "In my_main!" | ||
| -- print_effect | ||
| sail_main () | ||
|
|
||
|
|
||
| def runElf32 (elf : ELF32File) : IO UInt32 := | ||
| open Sail in | ||
| open LeanRV64D.Functions in | ||
| let mem := initializeMemory MachineBits.B32 elf | ||
| let regs := initializeRegisters | ||
| let initialState := ⟨regs, (), mem, default, default, default⟩ | ||
| main_of_sail_main initialState (sail_model_init >=> my_main) | ||
| -- main_of_sail_main initialState my_main |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| def hello := "world" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| import LeanRiscv | ||
|
|
||
| def main (args : List String) : IO UInt32 := do | ||
|
Collaborator
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. The other error you're getting is because the Sail output already includes a
Collaborator
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. The issue is that the risc-v model has its own main function that we don't want to use here. I changed my executable model branch to not compile the |
||
| if args.length != 2 then do | ||
| IO.println "usage: run-riscv-lean <elf_file>" | ||
|
|
||
| pure 255 | ||
| else do | ||
| -- Parse input elf file. | ||
| let elfE <- readElf32 args[1]! | ||
| match elfE with | ||
| | Except.error err => do | ||
| IO.println "Failed to parse elf file:" | ||
| IO.println err | ||
|
|
||
| pure 255 | ||
|
|
||
| | Except.ok elf => do | ||
| -- Run program | ||
| runElf32 elf | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| # lean-riscv |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| {"version": "1.1.0", | ||
| "packagesDir": ".lake/packages", | ||
| "packages": | ||
| [{"url": "https://github.com/opencompl/sail-riscv-lean.git", | ||
| "type": "git", | ||
| "subDir": null, | ||
| "scope": "", | ||
| "rev": "5b601c9012c093087e1584f7a2dc3972838f1b54", | ||
| "name": "Lean_RV64D", | ||
| "manifestFile": "lake-manifest.json", | ||
| "inputRev": "5b601c9012c093087e1584f7a2dc3972838f1b54", | ||
| "inherited": false, | ||
| "configFile": "lakefile.toml"}, | ||
| {"url": "https://github.com/jn80842/ELFSage.git", | ||
| "type": "git", | ||
| "subDir": null, | ||
| "scope": "", | ||
| "rev": "3cbf753d3596f9c361f877950fb079de701c0144", | ||
| "name": "ELFSage", | ||
| "manifestFile": "lake-manifest.json", | ||
| "inputRev": "3cbf753d3596f9c361f877950fb079de701c0144", | ||
| "inherited": false, | ||
| "configFile": "lakefile.lean"}, | ||
| {"url": "https://github.com/leanprover/lean4-cli.git", | ||
| "type": "git", | ||
| "subDir": null, | ||
| "scope": "", | ||
| "rev": "427778edba8deb053372e5d9de22dc5426b6d175", | ||
| "name": "Cli", | ||
| "manifestFile": "lake-manifest.json", | ||
| "inputRev": "main", | ||
| "inherited": true, | ||
| "configFile": "lakefile.toml"}], | ||
| "name": "«lean-riscv»", | ||
| "lakeDir": ".lake"} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| name = "lean-riscv" | ||
| version = "0.1.0" | ||
| defaultTargets = ["run-riscv-lean"] | ||
|
|
||
| [[lean_lib]] | ||
| name = "LeanRiscv" | ||
|
|
||
| [[lean_exe]] | ||
| name = "run-riscv-lean" | ||
| root = "Main" | ||
|
|
||
| [[require]] | ||
| name = "ELFSage" | ||
| git = "https://github.com/jn80842/ELFSage.git" | ||
| rev = "3cbf753d3596f9c361f877950fb079de701c0144" | ||
|
|
||
| [[require]] | ||
| name = "Lean_RV64D" | ||
| git = "https://github.com/opencompl/sail-riscv-lean.git" | ||
| rev = "5b601c9012c093087e1584f7a2dc3972838f1b54" | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| leanprover/lean4:nightly-2025-05-26 |
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.
@Alasdair @tperami this would not be needed with the new concurrency interface right? Do you know if it's going to be used in the RISC-V model soon?