├── .clang-format ├── .clang-tidy ├── .dockerignore ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── bug-report.md │ ├── feature-request.md │ ├── technical-debt.md │ └── update-dependencies.md ├── pull_request_template.md └── workflows │ ├── build.yml │ └── commits.yml ├── .gitignore ├── .gitmodules ├── .typos.toml ├── AUTHORS ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── COPYING ├── Dockerfile ├── LICENSES.md ├── Makefile ├── README.md ├── doc └── Doxyfile ├── src ├── .gitignore ├── Makefile ├── access-log.h ├── back-merkle-tree.cpp ├── back-merkle-tree.h ├── base64.cpp ├── base64.h ├── bracket-note.h ├── cartesi-machine-stored-hash.lua ├── cartesi-machine.lua ├── cartesi │ ├── gdbstub.lua │ ├── proof.lua │ └── util.lua ├── clint-factory.cpp ├── clint-factory.h ├── clint.cpp ├── clint.h ├── clua-cartesi-jsonrpc.cpp ├── clua-cartesi.cpp ├── clua-i-virtual-machine.cpp ├── clua-i-virtual-machine.h ├── clua.cpp ├── clua.h ├── compiler-defines.h ├── complete-merkle-tree.cpp ├── complete-merkle-tree.h ├── device-state-access.h ├── dtb.cpp ├── dtb.h ├── fdt-builder.h ├── find-pma-entry.h ├── full-merkle-tree.cpp ├── full-merkle-tree.h ├── htif-defines.h ├── htif-factory.cpp ├── htif-factory.h ├── htif.cpp ├── htif.h ├── i-device-state-access.h ├── i-hasher.h ├── i-state-access.h ├── i-uarch-state-access.h ├── i-virtual-machine.h ├── interpret.cpp ├── interpret.h ├── is-pristine.h ├── json-util.cpp ├── json-util.h ├── jsonrpc-discover.h ├── jsonrpc-discover.json ├── jsonrpc-fork-result.h ├── jsonrpc-machine-c-api.cpp ├── jsonrpc-machine-c-api.h ├── jsonrpc-remote-machine.cpp ├── jsonrpc-version.h ├── jsonrpc-virtual-machine.cpp ├── jsonrpc-virtual-machine.h ├── keccak-256-hasher.h ├── machine-c-api-internal.h ├── machine-c-api.cpp ├── machine-c-api.h ├── machine-config.cpp ├── machine-config.h ├── machine-memory-range-descr.h ├── machine-merkle-tree.cpp ├── machine-merkle-tree.h ├── machine-reg.h ├── machine-runtime-config.h ├── machine-state.h ├── machine-statistics.h ├── machine.cpp ├── machine.h ├── merkle-tree-hash.cpp ├── merkle-tree-proof.h ├── meta.h ├── os-features.h ├── os.cpp ├── os.h ├── plic-factory.cpp ├── plic-factory.h ├── plic.cpp ├── plic.h ├── pma-constants.h ├── pma-defines.h ├── pma-driver.cpp ├── pma-driver.h ├── pma.cpp ├── pma.h ├── pristine-merkle-tree.cpp ├── pristine-merkle-tree.h ├── record-send-cmio-state-access.h ├── record-step-state-access.h ├── replay-send-cmio-state-access.h ├── replay-step-state-access-interop.cpp ├── replay-step-state-access-interop.h ├── replay-step-state-access.h ├── riscv-constants.h ├── rng-seed.h ├── rtc-defines.h ├── rtc.h ├── scope-exit.h ├── semantic-version.h ├── send-cmio-response.cpp ├── send-cmio-response.h ├── shadow-pmas-factory.cpp ├── shadow-pmas-factory.h ├── shadow-pmas.h ├── shadow-state-factory.cpp ├── shadow-state-factory.h ├── shadow-state.cpp ├── shadow-state.h ├── shadow-tlb-factory.cpp ├── shadow-tlb-factory.h ├── shadow-tlb.cpp ├── shadow-tlb.h ├── shadow-uarch-state-factory.cpp ├── shadow-uarch-state-factory.h ├── shadow-uarch-state.cpp ├── shadow-uarch-state.h ├── slog.cpp ├── slog.h ├── soft-float.h ├── state-access.h ├── strict-aliasing.h ├── translate-virtual-address.h ├── uarch-bridge.h ├── uarch-config.h ├── uarch-constants.h ├── uarch-defines.h ├── uarch-interpret.cpp ├── uarch-interpret.h ├── uarch-machine.cpp ├── uarch-machine.h ├── uarch-pristine-state-hash.cpp ├── uarch-pristine-state-hash.h ├── uarch-pristine.h ├── uarch-record-state-access.h ├── uarch-replay-state-access.h ├── uarch-reset-state.cpp ├── uarch-reset-state.h ├── uarch-solidity-compat.h ├── uarch-state-access.h ├── uarch-state.h ├── uarch-step.cpp ├── uarch-step.h ├── uint128.h ├── unique-c-ptr.h ├── virtio-console.cpp ├── virtio-console.h ├── virtio-device.cpp ├── virtio-device.h ├── virtio-factory.cpp ├── virtio-factory.h ├── virtio-net-carrier-slirp.cpp ├── virtio-net-carrier-slirp.h ├── virtio-net-carrier-tuntap.cpp ├── virtio-net-carrier-tuntap.h ├── virtio-net.cpp ├── virtio-net.h ├── virtio-p9fs.cpp ├── virtio-p9fs.h ├── virtio-serializer.h ├── virtual-machine.cpp └── virtual-machine.h ├── tests ├── Dockerfile ├── Makefile ├── dependencies ├── dependencies.sha256 ├── lua │ ├── cartesi-machine-tests.lua │ ├── cartesi │ │ ├── parallel.lua │ │ ├── tabular.lua │ │ └── tests │ │ │ ├── data.lua │ │ │ └── util.lua │ ├── cmio-test.lua │ ├── create-machines.lua │ ├── htif-cmio.lua │ ├── htif-console.lua │ ├── htif-yield.lua │ ├── log-with-mtime-transition.lua │ ├── machine-bind.lua │ ├── machine-test.lua │ ├── mcycle-overflow.lua │ ├── mtime-interrupt.lua │ ├── run-rv64i-arch-test.lua │ ├── test-jsonrpc-fork.lua │ └── uarch-riscv-tests.lua ├── machine │ ├── .gitignore │ ├── AUTHORS │ ├── CODE_OF_CONDUCT.md │ ├── CONTRIBUTING.md │ ├── LICENSE │ ├── Makefile │ ├── README.md │ └── src │ │ ├── Makefile │ │ ├── access.S │ │ ├── amo.S │ │ ├── bootstrap.S │ │ ├── bootstrap.ld │ │ ├── clint_ops.S │ │ ├── compressed.S │ │ ├── csr_counters.S │ │ ├── csr_semantics.S │ │ ├── dont_write_x0.S │ │ ├── ebreak.S │ │ ├── fbinary_d.S │ │ ├── fbinary_s.S │ │ ├── fclass.S │ │ ├── fcmp.S │ │ ├── fcvt.S │ │ ├── float_util.h │ │ ├── fternary_d.S │ │ ├── fternary_s.S │ │ ├── funary.S │ │ ├── htif_cmio.S │ │ ├── htif_console.S │ │ ├── htif_invalid_ops.S │ │ ├── htif_util.h │ │ ├── htif_yield.S │ │ ├── illegal_insn.S │ │ ├── interrupts.S │ │ ├── link.ld │ │ ├── lrsc_semantics.S │ │ ├── mcycle_overflow.S │ │ ├── mcycle_write.S │ │ ├── mtime_interrupt.S │ │ ├── pte_reserved_exception.S │ │ ├── sd_pma_overflow.S │ │ ├── shadow_ops.S │ │ ├── translate_vaddr.S │ │ ├── version_check.S │ │ └── xpie_exceptions.S ├── misc │ ├── .gitignore │ ├── Makefile │ ├── test-machine-c-api.cpp │ ├── test-merkle-tree-hash.cpp │ └── test-utils.h ├── scripts │ ├── collect-machine-tests-logs.sh │ ├── collect-uarch-test-logs.sh │ ├── run-lua-tests.sh │ ├── test-cmio.sh │ ├── test-jsonrpc-server.sh │ ├── test-save-and-load.sh │ └── test-yield-and-save.sh └── uarch │ ├── .gitignore │ ├── AUTHORS │ ├── CODE_OF_CONDUCT.md │ ├── CONTRIBUTING.md │ ├── LICENSE │ ├── Makefile │ ├── README.md │ ├── ebreak.S │ ├── ecall-putchar.S │ ├── ecall-unsupported.S │ ├── fence.S │ ├── link.ld │ ├── riscv_test.h │ └── rv64ui-uarch-catalog.json ├── third-party ├── llvm-flang-uint128 │ ├── LICENSE │ └── flang-common │ │ ├── leading-zero-bit-count.h │ │ └── uint128.h ├── nlohmann-json │ ├── LICENSE.MIT │ └── json.hpp └── tiny_sha3 │ ├── LICENSE │ ├── sha3.c │ └── sha3.h ├── tools ├── docker-entrypoint.sh ├── gdb │ └── gdbinit ├── gen-interpret-jump-table.lua ├── gnu │ └── stubs-lp64.h └── template │ ├── cartesi-machine-stored-hash.template │ ├── cartesi-machine-tests.template │ ├── cartesi-machine.template │ ├── control.template │ ├── machine-c-version.h.template │ ├── tests-control.template │ ├── tests-copyright.template │ ├── tests-data-control.template │ ├── tests-data-copyright.template │ └── uarch-riscv-tests.template └── uarch ├── .gitignore ├── Makefile ├── README.md ├── compute-uarch-pristine-hash.cpp ├── uarch-machine-state-access.h ├── uarch-printf.c ├── uarch-printf.h ├── uarch-ram-entry.S ├── uarch-ram.ld.in ├── uarch-run.cpp ├── uarch-runtime.cpp └── uarch-runtime.h /.clang-format: -------------------------------------------------------------------------------- 1 | Language: Cpp 2 | BasedOnStyle: LLVM 3 | AccessModifierOffset: -4 4 | AlignAfterOpenBracket: DontAlign 5 | AlignOperands: DontAlign 6 | AllowAllArgumentsOnNextLine: false 7 | AllowAllConstructorInitializersOnNextLine: false 8 | AllowAllParametersOfDeclarationOnNextLine: false 9 | AllowShortFunctionsOnASingleLine: Empty 10 | AlwaysBreakTemplateDeclarations: Yes 11 | BreakInheritanceList: AfterColon 12 | BreakBeforeTernaryOperators: false 13 | BreakConstructorInitializers: AfterColon 14 | ColumnLimit: 120 15 | ConstructorInitializerAllOnOneLineOrOnePerLine: true 16 | IndentCaseLabels: true 17 | IndentWidth: 4 18 | SpaceAfterCStyleCast: true 19 | Standard: c++20 20 | -------------------------------------------------------------------------------- /.clang-tidy: -------------------------------------------------------------------------------- 1 | Checks: >- 2 | boost*, 3 | -boost-use-ranges, 4 | bugprone*, 5 | -bugprone-easily-swappable-parameters, 6 | cert*, 7 | -cert-int09-c, 8 | clang-analyzer*, 9 | -clang-analyzer-optin.cplusplus.VirtualCall, 10 | cppcoreguidelines*, 11 | -cppcoreguidelines-avoid-magic-numbers, 12 | -cppcoreguidelines-owning-memory, 13 | -cppcoreguidelines-pro-bounds-array-to-pointer-decay, 14 | -cppcoreguidelines-pro-bounds-constant-array-index, 15 | -cppcoreguidelines-pro-bounds-pointer-arithmetic, 16 | -cppcoreguidelines-pro-type-vararg, 17 | -cppcoreguidelines-avoid-c-arrays, 18 | google*, 19 | -google-build-using-namespace, 20 | -google-objc-*, 21 | hicpp*, 22 | -hicpp-avoid-c-arrays, 23 | -hicpp-no-array-decay, 24 | -hicpp-signed-bitwise, 25 | -hicpp-vararg, 26 | misc*, 27 | -misc-no-recursion, 28 | -misc-non-private-member-variables-in-classes, 29 | -misc-use-anonymous-namespace, 30 | -misc-include-cleaner, 31 | modernize*, 32 | -modernize-use-nodiscard, 33 | -modernize-use-trailing-return-type, 34 | -modernize-avoid-c-arrays, 35 | -modernize-use-ranges, 36 | performance*, 37 | -performance-enum-size, 38 | portability*, 39 | readability*, 40 | -readability-function-cognitive-complexity, 41 | -readability-identifier-length, 42 | -readability-magic-numbers, 43 | -readability-enum-initial-value, 44 | WarningsAsErrors: >- 45 | boost*, 46 | bugprone*, 47 | cert*, 48 | clang-analyzer*, 49 | cppcoreguidelines*, 50 | google*, 51 | hicpp*, 52 | misc*, 53 | modernize*, 54 | performance*, 55 | portability*, 56 | readability*, 57 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | **/*.o 2 | **/*.a 3 | **/*.swp 4 | **/*.d 5 | **/*.pb.cc 6 | **/*.pb.h 7 | **/*.gcno 8 | **/*.so 9 | **/*.dtb 10 | **/*.bin 11 | !uarch/uarch-ram.bin 12 | **/*.md 13 | **/*.deb 14 | 15 | build 16 | third-party/downloads 17 | src/cartesi-jsonrpc-machine 18 | src/cartesi-merkle-tree-hash 19 | 20 | doc/html 21 | doc/api.md 22 | doc/html/ 23 | doc/xml/ 24 | 25 | .git 26 | .github 27 | .venv 28 | .vscode 29 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | third-party/** linguist-vendored 2 | tests/** linguist-vendored 3 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug Report 3 | about: Template for reporting bugs 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | | WARNING: Please, read carefully before submitting an issue | 11 | |------------------------------------------------------------| 12 | 13 | Do not use issues to seek technical support. 14 | If you need support read the [documentation](https://docs.cartesi.io/) first. 15 | If you still have unanswered questions or need further discussion, join the [Cartesi Discord server](https://discord.gg/cartesi) and use the `#cartesi-machine` channel. 16 | 17 | Before submitting a new issue, please make sure that: 18 | - You are sure the issue manifests itself on the latest release (i.e., in the main branch); 19 | - You have verified that a similar issue has not already been reported; 20 | - You have verified, with your best effort, that your code or use case is not itself at fault. 21 | 22 | ## Context 23 | 24 | What is the bug that you are experiencing? 25 | Why is this bug relevant? 26 | 27 | (Please try to be clear and concise.) 28 | 29 | ## Expected behavior 30 | 31 | What was expected? 32 | 33 | ## Actual behavior 34 | 35 | What happened instead? 36 | 37 | ## Steps to reproduce 38 | 39 | Please describe a minimal set of steps to reproduce the bug. 40 | Try to keep it as simple as possible, focusing exclusively on the bug. 41 | Your description should include the artifacts used and their versions. 42 | Provide the exact commands needed to reproduce the bug, if possible in the form of a script that can be run on other machines. 43 | 44 | ## Environment 45 | 46 | Please describe the environment where the bug happens. 47 | 48 | Include the following (when applicable and/or relevant): 49 | - Emulator version; 50 | - Host operating system (e.g. Ubuntu 22.04, MacOS 13, Cartesi Playground v0.6.0); 51 | - Host architecture (e.g. x86_64, arm64); 52 | - Docker version (e.g. Docker Desktop 4.19.0); 53 | - Compiler version (e.g. GCC 12.3, Clang 15.0.7). 54 | 55 | ## Possible solutions 56 | 57 | *This section is optional.* 58 | 59 | Is there any workaround for the issue? (This may help others experiencing the same issue.) 60 | 61 | Can you offer any hint on how to solve the issue? 62 | What parts of the code will be affected? 63 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature Request 3 | about: Template for requesting new features 4 | title: '' 5 | labels: feature 6 | assignees: '' 7 | 8 | --- 9 | 10 | | WARNING: Please, read carefully before submitting an issue | 11 | |------------------------------------------------------------| 12 | 13 | Do not use issues to seek technical support. 14 | If you need support read the [documentation](https://docs.cartesi.io/) first. 15 | If you still have unanswered questions or need further discussion, join the [Cartesi Discord server](https://discord.gg/cartesi) and use the `#cartesi-machine` channel. 16 | 17 | Before submitting a new issue, please make sure that: 18 | - You are sure the issue manifests itself on the latest release (i.e., in the main branch); 19 | - You have verified that a similar issue has not already been reported; 20 | - You have verified, with your best effort, that your code or use case is not itself at fault. 21 | 22 | ## Context 23 | 24 | What problem are you trying to solve? 25 | Why is this feature relevant? 26 | 27 | (Please try to be clear and concise.) 28 | 29 | ## Possible solutions 30 | 31 | *This section is optional.* 32 | 33 | What are the possible solutions? 34 | If there are multiple alternatives, what are the benefits and drawbacks of each one? 35 | 36 | ## Subtasks 37 | 38 | *This section is optional.* 39 | 40 | - [ ] If there is a solution, what are the subtasks for completing this issue? 41 | 42 | ## Definition of Done 43 | 44 | *This section is optional.* 45 | 46 | - [ ] If there is a solution, what are the final deliverables? 47 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/technical-debt.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Technical Debt 3 | about: Template for proposing solutions to technical debts 4 | title: '' 5 | labels: refactor 6 | assignees: '' 7 | 8 | --- 9 | 10 | | WARNING: Please, read carefully before submitting an issue | 11 | |------------------------------------------------------------| 12 | 13 | ## Context 14 | 15 | What problem are you trying to solve? 16 | Why is this problem relevant? 17 | How does this problem affect the feature roadmap? 18 | Is it a blocker to implement a new future? 19 | What parts of the architecture and code are affected? 20 | 21 | ## Possible solutions 22 | 23 | What are the possible solutions? 24 | If there are multiple alternatives, what are the benefits and drawbacks of each one? 25 | 26 | ## Subtasks 27 | 28 | *This section is optional.* 29 | 30 | - [ ] What are the subtasks for completing this issue? 31 | 32 | ## Definition of Done 33 | 34 | *This section is optional.* 35 | 36 | - [ ] What are the final deliverables? 37 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/update-dependencies.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Update Dependencies 3 | about: Template for updating dependencies 4 | title: '' 5 | labels: chore 6 | assignees: '' 7 | 8 | --- 9 | 10 | | WARNING: Please, read carefully before submitting an issue | 11 | |------------------------------------------------------------| 12 | 13 | ## Context 14 | 15 | Does the dependency have a bug fix? 16 | Does it provide additional features or optimizations? 17 | 18 | ## Subtasks 19 | 20 | - [ ] Verify that the new version is available on all supported platforms. 21 | - [ ] Update build scripts and Dockerfiles 22 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | | WARNING: Please, read carefully before submitting a pull request | 2 | |------------------------------------------------------------------| 3 | 4 | Although this software is open source and we welcome contributions, 5 | we believe these contributions should be preceded by an open discussion. 6 | Open discussions tend to result in better solutions to any given problem, 7 | and help maintain and improve the quality of the software. 8 | If you would like to see a bug fixed or a new feature implemented, 9 | please open an issue for the discussion rather than directly opening 10 | a pull request. 11 | 12 | If you would like to contribute please read [CONTRIBUTING.md](https://github.com/cartesi/machine-emulator/blob/main/CONTRIBUTING.md). 13 | 14 | When you finally create a pull request, please follow these guidelines: 15 | 16 | - Make sure the description clearly describes the problem, its solution, and references the associated issue; 17 | - Do not create large pull requests (involving many different changes) because these are difficult to review. Instead, break large changes into smaller ones and create independent pull requests for each one; 18 | - Use different pull requests for different issues. Each pull request should address a single issue; 19 | - When fixing a bug or adding a new feature, make sure to add tests that cover your changes. This will ensure the changes will continue to work in the future; 20 | - Verify that changes do not break the tests. You can check this with `make test`; 21 | - Follow the same coding style rules as the rest of the code base; 22 | - Pull requests for stylistic changes (or even simple typos or grammatical errors) may be rejected. Pull requests should always address worthy issues. 23 | -------------------------------------------------------------------------------- /.github/workflows/commits.yml: -------------------------------------------------------------------------------- 1 | # yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json 2 | name: Conventional Commits Check 3 | on: [push] 4 | jobs: 5 | commit_messages: 6 | runs-on: ubuntu-latest 7 | steps: 8 | - name: Install cocogitto tool 9 | run: | 10 | VERSION=5.6.0 11 | TAR=cocogitto-${VERSION}-x86_64-unknown-linux-musl.tar.gz 12 | curl --output-dir /tmp -OL https://github.com/cocogitto/cocogitto/releases/download/${VERSION}/${TAR} 13 | sudo tar -xzf /tmp/${TAR} -C /usr/local/bin 14 | 15 | - name: Checkout code 16 | uses: actions/checkout@v4 17 | with: 18 | fetch-depth: 0 19 | 20 | - name: Conventional commit check 21 | run: | 22 | # Assuming 'main' is the default base branch 23 | BASE_BRANCH=${{ github.base_ref || 'origin/main' }} 24 | cog check ${BASE_BRANCH}..HEAD 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.swp 3 | *.d 4 | *.clang-tidy 5 | *.deb 6 | *.a 7 | *.lib 8 | *.wasm 9 | 10 | build 11 | pkg 12 | third-party/downloads 13 | src/cartesi-jsonrpc-machine 14 | src/cartesi-merkle-tree-hash 15 | src/tests/test-machine-c-api 16 | src/tests/test-merkle-tree-hash 17 | 18 | doc/html 19 | doc/api.md 20 | doc/html/ 21 | doc/xml/ 22 | 23 | .clangd 24 | .venv 25 | .vscode 26 | .ycm_extra_conf.py 27 | 28 | *.tar.gz 29 | *.raw 30 | *.so 31 | *.dll 32 | *.exe 33 | *.dylib 34 | *.dtb 35 | .DS_Store 36 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "tests/riscv-tests"] 2 | path = third-party/riscv-tests 3 | url = ../riscv-tests.git 4 | [submodule "tests/riscv-arch-test"] 5 | path = third-party/riscv-arch-test 6 | url = ../riscv-arch-test.git 7 | -------------------------------------------------------------------------------- /.typos.toml: -------------------------------------------------------------------------------- 1 | [files] 2 | extend-exclude = ["third-party/*", "*.S"] 3 | 4 | [default.extend-words] 5 | fle = "fle" 6 | sie = "sie" 7 | stip = "stip" 8 | stap = "stap" 9 | wronly = "wronly" 10 | optin = "optin" 11 | sxl = "sxl" 12 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Alexander Mikhalevich 2 | Carlo Fragni 3 | Carsten Munk 4 | Colin Steil 5 | Danilo Tuler 6 | Diego Nehab 7 | Eduardo Barthel 8 | Enderson Maia 9 | Erick de Moura 10 | Fabiana Cecin 11 | Felipe Argento 12 | Gabriel de Quadros Ligneul 13 | Lourival Vieira Neto 14 | Marcelo Politzer 15 | Marcos Pernambuco Motta 16 | Marko Atanasievski 17 | Stephen Chen 18 | Victor Fusco 19 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Cartesi 2 | 3 | Thank you for your interest in Cartesi! We highly appreciate even the smallest of fixes or additions to our project. 4 | 5 | Make sure to review our [Contributing License Agreement](https://forms.gle/k3E9ZNkZY6Vy3mkK9), 6 | sign and send it to info@cartesi.io with the title of "CLA Signed" before taking part in the project. We are happy to automate 7 | this for you via DocuSign upon request in the Google Form as well. 8 | 9 | ## Basic Contributing Guidelines 10 | 11 | We use the same guidelines for contributing code to any of our repositories, any developers wanting to contribute to Cartesi 12 | must create pull requests. This process is described in the [GitHub documentation](https://help.github.com/en/articles/creating-a-pull-request). Each pull request should be started against the master branch 13 | in the respective Cartesi repository. After a pull request is submitted the Cartesi team will review the submission and 14 | give feedback via the comments section of the pull request. After the submission is reviewed and approved, it will be merged 15 | into the master branch of the source. 16 | 17 | Please note the below! We appreciate everyone following the guidelines. 18 | 19 | * No --force pushes or modifying the Git history in any way; 20 | * Use non-master branches, using a short meaningful description, with words separated by dash (e.g. 'fix-this-bug'); 21 | * All modifications must be made in a pull-request to solicit feedback from other contributors. 22 | 23 | ## Get in Touch 24 | 25 | When contributing in a deeper manner to this repository, please first discuss the change you wish to make via our 26 | [Discord channel here](https://discord.gg/cartesi), or contact us at info@cartesi.io email before working on the change. 27 | -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- 1 | *.ext2 2 | *.bin 3 | *.gcno 4 | *.gcov 5 | *.gcda 6 | *.profraw 7 | compile_flags.txt 8 | coverage* 9 | jsonrpc-discover.cpp 10 | machine-c-version.h 11 | interpret-jump-table.h 12 | -------------------------------------------------------------------------------- /src/base64.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef BASE64_H 18 | #define BASE64_H 19 | 20 | #include 21 | #include 22 | 23 | namespace cartesi { 24 | 25 | std::string encode_base64(const std::string_view &input); 26 | 27 | std::string decode_base64(const std::string_view &input); 28 | 29 | } // namespace cartesi 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /src/bracket-note.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef BRACKET_NOTE_H 18 | #define BRACKET_NOTE_H 19 | 20 | #include 21 | #include 22 | 23 | /// \file 24 | /// \brief Bracket annotation for access log 25 | 26 | namespace cartesi { 27 | 28 | /// \brief Bracket type 29 | enum class bracket_type { 30 | begin, ///< Start of scope 31 | end ///< End of scope 32 | }; 33 | 34 | /// \brief Bracket note 35 | struct bracket_note { 36 | bracket_type type{bracket_type::begin}; ///< Bracket type 37 | uint64_t where{0}; ///< Where it points to in the log 38 | std::string text; ///< Note text 39 | }; 40 | 41 | } // namespace cartesi 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/cartesi-machine-stored-hash.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua5.4 2 | 3 | -- Copyright Cartesi and individual authors (see AUTHORS) 4 | -- SPDX-License-Identifier: LGPL-3.0-or-later 5 | -- 6 | -- This program is free software: you can redistribute it and/or modify it under 7 | -- the terms of the GNU Lesser General Public License as published by the Free 8 | -- Software Foundation, either version 3 of the License, or (at your option) any 9 | -- later version. 10 | -- 11 | -- This program is distributed in the hope that it will be useful, but WITHOUT ANY 12 | -- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 13 | -- PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 14 | -- 15 | -- You should have received a copy of the GNU Lesser General Public License along 16 | -- with this program (see COPYING). If not, see . 17 | -- 18 | 19 | local util = require("cartesi.util") 20 | 21 | local f = assert( 22 | io.open(assert(arg[1], "missing machine name") .. "/hash", "rb"), 23 | string.format("unable to open machine '%s'", tostring(arg[1])) 24 | ) 25 | local h = assert(f:read("a"), "unable to read hash") 26 | f:close() 27 | print(util.hexhash(h)) 28 | -------------------------------------------------------------------------------- /src/cartesi/proof.lua: -------------------------------------------------------------------------------- 1 | local cartesi = require("cartesi") 2 | 3 | local _M = {} 4 | 5 | function _M.roll_hash_up_tree(proof, target_hash) 6 | local hash = target_hash 7 | for log2_size = proof.log2_target_size, proof.log2_root_size - 1 do 8 | local bit = (proof.target_address & (1 << log2_size)) ~= 0 9 | local first, second 10 | local i = proof.log2_root_size - log2_size 11 | if bit then 12 | first, second = proof.sibling_hashes[i], hash 13 | else 14 | first, second = hash, proof.sibling_hashes[i] 15 | end 16 | hash = cartesi.keccak(first, second) 17 | end 18 | return hash 19 | end 20 | 21 | function _M.slice_assert(root_hash, proof) 22 | assert(root_hash == proof.root_hash, "proof root_hash mismatch") 23 | assert(_M.roll_hash_up_tree(proof, proof.target_hash) == root_hash, "node not in tree") 24 | end 25 | 26 | function _M.word_slice_assert(root_hash, proof, word) 27 | assert(proof.log2_target_size == 3, "not a word proof") 28 | assert(root_hash == proof.root_hash, "proof root_hash mismatch") 29 | assert(cartesi.keccak(word) == proof.target_hash, "proof target_hash mismatch") 30 | assert(_M.roll_hash_up_tree(proof, proof.target_hash) == root_hash, "node not in tree") 31 | end 32 | 33 | function _M.splice_assert(root_hash, proof, new_target_hash, new_root_hash) 34 | _M.slice_assert(root_hash, proof) 35 | assert(_M.roll_hash_up_tree(proof, new_target_hash) == new_root_hash, "new root hash mismatch") 36 | end 37 | 38 | function _M.word_splice_assert(root_hash, proof, old_word, new_word, new_root_hash) 39 | _M.word_slice_assert(root_hash, proof, old_word) 40 | assert(_M.roll_hash_up_tree(proof, cartesi.keccak(new_word)) == new_root_hash, "new root hash mismatch") 41 | end 42 | 43 | return _M 44 | -------------------------------------------------------------------------------- /src/clint-factory.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #include 18 | 19 | #include "clint-factory.h" 20 | #include "clint.h" 21 | #include "machine.h" 22 | #include "pma-constants.h" 23 | #include "pma.h" 24 | 25 | namespace cartesi { 26 | 27 | /// \brief CLINT device peek callback. See ::pma_peek. 28 | static bool clint_peek(const pma_entry &pma, const machine & /*m*/, uint64_t page_offset, 29 | const unsigned char **page_data, unsigned char * /*scratch*/) { 30 | *page_data = nullptr; 31 | return (page_offset % PMA_PAGE_SIZE) == 0 && page_offset < pma.get_length(); 32 | } 33 | 34 | pma_entry make_clint_pma_entry(uint64_t start, uint64_t length) { 35 | const pma_entry::flags f{.R = true, .W = true, .X = false, .IR = false, .IW = false, .DID = PMA_ISTART_DID::CLINT}; 36 | return make_device_pma_entry("CLINT device", start, length, clint_peek, &clint_driver).set_flags(f); 37 | } 38 | 39 | } // namespace cartesi 40 | -------------------------------------------------------------------------------- /src/clint-factory.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef CLINT_FACTORY_H 18 | #define CLINT_FACTORY_H 19 | 20 | #include 21 | 22 | #include "pma.h" 23 | 24 | namespace cartesi { 25 | 26 | /// \brief Creates a PMA entry for the CLINT device 27 | /// \param start Start address for memory range. 28 | /// \param length Length of memory range. 29 | /// \returns Corresponding PMA entry 30 | pma_entry make_clint_pma_entry(uint64_t start, uint64_t length); 31 | 32 | } // namespace cartesi 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/clint.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef CLINT_H 18 | #define CLINT_H 19 | 20 | #include 21 | 22 | #include "pma-driver.h" 23 | 24 | /// \file 25 | /// \brief Clock interruptor device. 26 | 27 | namespace cartesi { 28 | 29 | /// \brief Global CLINT device driver instance 30 | extern const pma_driver clint_driver; 31 | 32 | /// \brief Mapping between CSRs and their relative addresses in CLINT memory 33 | enum class clint_csr { 34 | msip0 = UINT64_C(0), // Machine software interrupt for hart 0 35 | mtimecmp = UINT64_C(0x4000), 36 | mtime = UINT64_C(0xbff8) 37 | }; 38 | 39 | /// \brief Obtains the relative address of the msip0 CSR in HTIF memory. 40 | static constexpr auto clint_msip0_rel_addr = static_cast(clint_csr::msip0); 41 | 42 | /// \brief Obtains the relative address of the mtime CSR in HTIF memory. 43 | static constexpr auto clint_mtime_rel_addr = static_cast(clint_csr::mtime); 44 | 45 | /// \brief Obtains the relative address of the mtimecmp CSR in HTIF memory. 46 | constexpr auto clint_mtimecmp_rel_addr = static_cast(clint_csr::mtimecmp); 47 | 48 | } // namespace cartesi 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /src/compiler-defines.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef COMPILER_DEFINES_H 18 | #define COMPILER_DEFINES_H 19 | 20 | #ifndef CODE_COVERAGE 21 | #define FORCE_INLINE __attribute__((always_inline)) inline 22 | #else 23 | // Avoid using always_inline attribute when code coverage is enabled, 24 | // because it makes code coverage results harder to read 25 | #define FORCE_INLINE inline 26 | #endif 27 | 28 | #define NO_INLINE __attribute__((noinline)) 29 | 30 | #define NO_RETURN [[noreturn]] 31 | 32 | // These macros are used only in very hot code paths (such as TLB hit checks). 33 | // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 34 | #define likely(x) __builtin_expect((x), 1) 35 | // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 36 | #define unlikely(x) __builtin_expect((x), 0) 37 | //??E Although using PGO (Profile Guided Optimizations) makes use of these macros unneeded, 38 | // using them allows for more performance without the need to compile with PGO, 39 | // useful when doing benchmark of code changes. 40 | 41 | #define PACKED __attribute__((packed)) 42 | 43 | #if defined(__GNUC__) && !defined(__clang__) 44 | #define FORCE_OPTIMIZE_O3 __attribute__((optimize("-O3"))) 45 | #else 46 | #define FORCE_OPTIMIZE_O3 47 | #endif 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /src/dtb.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef DTB_H 18 | #define DTB_H 19 | 20 | /// \file 21 | /// \brief Device Tree Blob 22 | 23 | #include 24 | 25 | #include "machine-config.h" 26 | 27 | namespace cartesi { 28 | 29 | /// \brief Initializes flattened device tree from machine config on DTB 30 | /// \param c Machine configuration. 31 | /// \param dtb_start Pointer to start of DTB contiguous range in host memory 32 | /// \param dtb_length Maximum amount of DTB to use from start. 33 | void dtb_init(const machine_config &c, unsigned char *dtb_start, uint64_t dtb_length); 34 | 35 | } // namespace cartesi 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /src/find-pma-entry.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef FIND_PMA_ENTRY_H 18 | #define FIND_PMA_ENTRY_H 19 | 20 | #include "compiler-defines.h" 21 | #include 22 | 23 | namespace cartesi { 24 | 25 | /// \brief Returns PMAs entry where a word falls. 26 | /// \tparam T uint8_t, uint16_t, uint32_t, or uint64_t. 27 | /// \tparam STATE_ACCESS Class of machine state accessor object. 28 | /// \param a Machine state accessor object. 29 | /// \param paddr Target physical address of word. 30 | /// \returns PMA entry where word falls, or empty sentinel. 31 | template 32 | static FORCE_INLINE auto &find_pma_entry(STATE_ACCESS a, uint64_t paddr) { 33 | uint64_t index = 0; 34 | while (true) { 35 | auto &pma = a.read_pma_entry(index); 36 | const auto length = pma.get_length(); 37 | // The pmas array always contain a sentinel. 38 | // It is an entry with zero length. 39 | // If we hit it, return it 40 | if (unlikely(length == 0)) { 41 | return pma; 42 | } 43 | // Otherwise, if we found an entry where the access fits, return it 44 | // Note the "strange" order of arithmetic operations. 45 | // This is to ensure there is no overflow. 46 | // Since we know paddr >= start, there is no chance of overflow in the first subtraction. 47 | // Since length is at least 4096 (an entire page), there is no chance of overflow in the second subtraction. 48 | const auto start = pma.get_start(); 49 | if (paddr >= start && paddr - start <= length - sizeof(T)) { 50 | return pma; 51 | } 52 | ++index; 53 | } 54 | } 55 | 56 | } // namespace cartesi 57 | 58 | #endif // FIND_PMA_ENTRY_H 59 | -------------------------------------------------------------------------------- /src/htif-defines.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef HTIF_DEFINES_H 18 | #define HTIF_DEFINES_H 19 | // NOLINTBEGIN(cppcoreguidelines-macro-usage,cppcoreguidelines-macro-to-enum,modernize-macro-to-enum) 20 | #define HTIF_DEV_SHIFT_DEF 56 21 | #define HTIF_CMD_SHIFT_DEF 48 22 | #define HTIF_REASON_SHIFT_DEF 32 23 | #define HTIF_DATA_SHIFT_DEF 0 24 | 25 | #define HTIF_DEV_MASK_DEF 0xFF00000000000000 26 | #define HTIF_CMD_MASK_DEF 0x00FF000000000000 27 | #define HTIF_REASON_MASK_DEF 0x0000FFFF00000000 28 | #define HTIF_DATA_MASK_DEF 0x00000000FFFFFFFF 29 | 30 | #define HTIF_DEV_HALT_DEF 0 31 | #define HTIF_DEV_CONSOLE_DEF 1 32 | #define HTIF_DEV_YIELD_DEF 2 33 | 34 | #define HTIF_HALT_CMD_HALT_DEF 0 35 | #define HTIF_CONSOLE_CMD_GETCHAR_DEF 0 36 | #define HTIF_CONSOLE_CMD_PUTCHAR_DEF 1 37 | #define HTIF_YIELD_CMD_AUTOMATIC_DEF 0 38 | #define HTIF_YIELD_CMD_MANUAL_DEF 1 39 | 40 | /* request */ 41 | #define HTIF_YIELD_AUTOMATIC_REASON_PROGRESS_DEF 1 42 | #define HTIF_YIELD_AUTOMATIC_REASON_TX_OUTPUT_DEF 2 43 | #define HTIF_YIELD_AUTOMATIC_REASON_TX_REPORT_DEF 4 44 | 45 | #define HTIF_YIELD_MANUAL_REASON_RX_ACCEPTED_DEF 1 46 | #define HTIF_YIELD_MANUAL_REASON_RX_REJECTED_DEF 2 47 | #define HTIF_YIELD_MANUAL_REASON_TX_EXCEPTION_DEF 4 48 | 49 | /* reply */ 50 | #define HTIF_YIELD_REASON_ADVANCE_STATE_DEF 0 51 | #define HTIF_YIELD_REASON_INSPECT_STATE_DEF 1 52 | // NOLINTEND(cppcoreguidelines-macro-usage,cppcoreguidelines-macro-to-enum,modernize-macro-to-enum) 53 | 54 | #endif /* end of include guard: HTIF_DEFINES_H */ 55 | -------------------------------------------------------------------------------- /src/htif-factory.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #include 18 | 19 | #include "htif-factory.h" 20 | #include "htif.h" 21 | #include "machine-runtime-config.h" 22 | #include "machine.h" 23 | #include "pma-constants.h" 24 | #include "pma.h" 25 | 26 | namespace cartesi { 27 | 28 | /// \brief HTIF device peek callback. See ::pma_peek. 29 | static bool htif_peek(const pma_entry &pma, const machine & /*m*/, uint64_t page_offset, 30 | const unsigned char **page_data, unsigned char * /*scratch*/) { 31 | *page_data = nullptr; 32 | return (page_offset % PMA_PAGE_SIZE) == 0 && page_offset < pma.get_length(); 33 | } 34 | 35 | pma_entry make_htif_pma_entry(uint64_t start, uint64_t length) { 36 | const pma_entry::flags f{.R = true, .W = true, .X = false, .IR = false, .IW = false, .DID = PMA_ISTART_DID::HTIF}; 37 | return make_device_pma_entry("HTIF device", start, length, htif_peek, &htif_driver).set_flags(f); 38 | } 39 | 40 | } // namespace cartesi 41 | -------------------------------------------------------------------------------- /src/htif-factory.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef HTIF_FACTORY_H 18 | #define HTIF_FACTORY_H 19 | 20 | #include 21 | 22 | #include "machine-runtime-config.h" 23 | #include "pma.h" 24 | 25 | namespace cartesi { 26 | 27 | /// \brief Creates a PMA entry for the HTIF device 28 | pma_entry make_htif_pma_entry(uint64_t start, uint64_t length); 29 | 30 | } // namespace cartesi 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /src/interpret.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef INTERPRET_H 18 | #define INTERPRET_H 19 | 20 | #include 21 | 22 | /// \file 23 | /// \brief Interpreter implementation. 24 | 25 | namespace cartesi { 26 | 27 | /// \brief Instruction execution status code 28 | enum execute_status : uint64_t { 29 | success, // Instruction execution succeed, the interpreter should continue normally 30 | failure, // Instruction execution failed, the interpreter should continue normally 31 | success_and_flush_fetch, // Instruction execution succeed, the interpreter must flush fetch address translation 32 | // cache 33 | success_and_serve_interrupts, // Instruction execution succeed, the interpreter must serve pending interrupts 34 | // immediately 35 | success_and_yield, // Instruction execution succeed, the interpreter must stop and handle a yield externally 36 | success_and_halt, // Instruction execution succeed, the interpreter must stop because the machine cannot continue 37 | }; 38 | 39 | /// \brief Reasons for interpreter loop interruption 40 | enum class interpreter_break_reason { 41 | failed, ///< This value is not really returned by the interpreter loop, but it's reserved for C API 42 | halted, 43 | yielded_manually, 44 | yielded_automatically, 45 | yielded_softly, 46 | reached_target_mcycle 47 | }; 48 | 49 | /// \brief Tries to run the interpreter until mcycle hits a target 50 | /// \tparam STATE_ACCESS Class of machine state accessor object. 51 | /// \param a Machine state accessor object. 52 | /// \param mcycle_end Target value for mcycle. 53 | /// \returns Returns a reason code informing why the interpreter loop has been stopped. 54 | /// \details The interpret may stop early if the machine halts permanently or becomes temporarily idle (waiting for 55 | /// interrupts). 56 | template 57 | interpreter_break_reason interpret(STATE_ACCESS a, uint64_t mcycle_end); 58 | 59 | } // namespace cartesi 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /src/is-pristine.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef IS_PRISTINE_H 18 | #define IS_PRISTINE_H 19 | 20 | #include "compiler-defines.h" 21 | #include 22 | #include 23 | 24 | namespace cartesi { 25 | 26 | /// \brief This is an optimized function for checking if memory page is pristine. 27 | /// \param data Memory pointer 28 | /// \param length Memory length 29 | /// \details It's instead to be used in situations where length is equal or less than a page size. 30 | // NOLINTNEXTLINE(clang-diagnostic-unknown-attributes) 31 | static inline bool FORCE_OPTIMIZE_O3 is_pristine(const unsigned char *data, size_t length) { 32 | // This tight for loop has no branches, and is optimized to SIMD instructions in x86_64, 33 | // making it very fast to check if a given page is pristine. 34 | unsigned char bits = 0; 35 | for (size_t i = 0; i < length; ++i) { 36 | bits |= data[i]; 37 | } 38 | return bits == 0; 39 | } 40 | 41 | } // namespace cartesi 42 | 43 | #endif -------------------------------------------------------------------------------- /src/jsonrpc-discover.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef JSONRPC_DISCOVER_H 18 | #define JSONRPC_DISCOVER_H 19 | 20 | namespace cartesi { 21 | 22 | extern char const *const jsonrpc_discover_json; 23 | 24 | } // namespace cartesi 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/jsonrpc-fork-result.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef JSONRPC_FORK_RESULT_H 18 | #define JSONRPC_FORK_RESULT_H 19 | 20 | namespace cartesi { 21 | 22 | struct fork_result final { 23 | std::string address; 24 | uint32_t pid{}; 25 | }; 26 | 27 | } // namespace cartesi 28 | 29 | #endif // JSONRPC_FORK_RESULT_H 30 | -------------------------------------------------------------------------------- /src/jsonrpc-version.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef JSONRPC_VERSION_H 18 | #define JSONRPC_VERSION_H 19 | 20 | #include 21 | 22 | namespace cartesi { 23 | 24 | constexpr uint32_t JSONRPC_VERSION_MAJOR = 0; 25 | constexpr uint32_t JSONRPC_VERSION_MINOR = 5; 26 | constexpr uint32_t JSONRPC_VERSION_PATCH = 0; 27 | constexpr const char *JSONRPC_VERSION_PRE_RELEASE = ""; 28 | constexpr const char *JSONRPC_VERSION_BUILD = ""; 29 | 30 | } // namespace cartesi 31 | 32 | #endif // JSONRPC_VERSION_H 33 | -------------------------------------------------------------------------------- /src/keccak-256-hasher.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef KECCAK_256_HASHER_H 18 | #define KECCAK_256_HASHER_H 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include "i-hasher.h" 25 | 26 | extern "C" { 27 | #include "sha3.h" 28 | } 29 | 30 | namespace cartesi { 31 | 32 | struct keccak_instance final { 33 | union { 34 | uint8_t b[200]; 35 | uint64_t q[25]; 36 | } st; 37 | int pt; 38 | }; 39 | 40 | class keccak_256_hasher final : public i_hasher> { 41 | sha3_ctx_t m_ctx{}; 42 | 43 | friend i_hasher>; 44 | 45 | void do_begin() { 46 | sha3_init(&m_ctx, 32, 0x01); 47 | } 48 | 49 | void do_add_data(const unsigned char *data, size_t length) { 50 | sha3_update(&m_ctx, data, length); 51 | } 52 | 53 | void do_end(hash_type &hash) { 54 | sha3_final(hash.data(), &m_ctx); 55 | } 56 | 57 | public: 58 | /// \brief Default constructor 59 | keccak_256_hasher() = default; 60 | 61 | /// \brief Default destructor 62 | ~keccak_256_hasher() = default; 63 | 64 | /// \brief No copy constructor 65 | keccak_256_hasher(const keccak_256_hasher &) = delete; 66 | /// \brief No move constructor 67 | keccak_256_hasher(keccak_256_hasher &&) = delete; 68 | /// \brief No copy assignment 69 | keccak_256_hasher &operator=(const keccak_256_hasher &) = delete; 70 | /// \brief No move assignment 71 | keccak_256_hasher &operator=(keccak_256_hasher &&) = delete; 72 | }; 73 | 74 | } // namespace cartesi 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /src/machine-c-api-internal.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef CM_C_API_INTERNAL_H 18 | #define CM_C_API_INTERNAL_H 19 | 20 | #include 21 | 22 | #include "machine-c-api.h" 23 | 24 | /// \brief Helper function that returns error result from C api function 25 | CM_API cm_error cm_result_failure(); 26 | 27 | /// \brief Helper function that returns success result from C api function 28 | CM_API cm_error cm_result_success(); 29 | 30 | /// \brief Helper function that stores a string to a temporary thread local. 31 | CM_API const char *cm_set_temp_string(const std::string &s); 32 | 33 | #endif // CM_C_API_INTERNAL_H 34 | -------------------------------------------------------------------------------- /src/machine-memory-range-descr.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef MACHINE_MEMORY_RANGE_DESCR_H 18 | #define MACHINE_MEMORY_RANGE_DESCR_H 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | namespace cartesi { 25 | 26 | /// \brief Description of memory range used for introspection (i.e., get_memory_ranges()) 27 | struct machine_memory_range_descr { 28 | uint64_t start = 0; ///< Start of memory range 29 | uint64_t length = 0; ///< Length of memory range 30 | std::string description; ///< User-friendly description for memory range 31 | }; 32 | 33 | /// \brief List of memory range descriptions used for introspection (i.e., get_memory_ranges()) 34 | using machine_memory_range_descrs = std::vector; 35 | 36 | } // namespace cartesi 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/machine-runtime-config.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef MACHINE_RUNTIME_CONFIG_H 18 | #define MACHINE_RUNTIME_CONFIG_H 19 | 20 | #include 21 | 22 | /// \file 23 | /// \brief Runtime configuration for machines. 24 | 25 | namespace cartesi { 26 | 27 | /// \brief Concurrency runtime configuration 28 | struct concurrency_runtime_config { 29 | uint64_t update_merkle_tree{}; 30 | }; 31 | 32 | /// \brief HTIF runtime configuration 33 | struct htif_runtime_config { 34 | bool no_console_putchar; 35 | }; 36 | 37 | /// \brief Machine runtime configuration 38 | struct machine_runtime_config { 39 | concurrency_runtime_config concurrency{}; 40 | htif_runtime_config htif{}; 41 | bool skip_root_hash_check{}; 42 | bool skip_root_hash_store{}; 43 | bool skip_version_check{}; 44 | bool soft_yield{}; 45 | }; 46 | 47 | /// \brief CONCURRENCY constants 48 | enum CONCURRENCY_constants : uint64_t { 49 | THREADS_MAX = 256 ///< Maximum number of threads 50 | }; 51 | 52 | } // namespace cartesi 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/os-features.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef OS_FEATURES_H 18 | #define OS_FEATURES_H 19 | 20 | #if !defined(NO_TTY) 21 | #define HAVE_TTY 22 | #endif 23 | 24 | #if !defined(NO_THREADS) 25 | #define HAVE_THREADS 26 | #define THREAD_LOCAL thread_local 27 | #else 28 | #define THREAD_LOCAL 29 | #endif 30 | 31 | #if !defined(NO_TERMIOS) && !defined(_WIN32) && !defined(__wasi__) 32 | #define HAVE_TERMIOS 33 | #endif 34 | 35 | #if !defined(NO_IOCTL) && !defined(_WIN32) && !defined(__wasi__) 36 | #define HAVE_IOCTL 37 | #endif 38 | 39 | #if !defined(NO_MMAP) && !defined(_WIN32) && !defined(__wasi__) 40 | #define HAVE_MMAP 41 | #endif 42 | 43 | #if !defined(NO_MKDIR) 44 | #define HAVE_MKDIR 45 | #endif 46 | 47 | #if !defined(NO_TUNTAP) && defined(__linux__) 48 | #define HAVE_TUNTAP 49 | #endif 50 | 51 | #if !defined(NO_SLIRP) && !defined(__wasi__) 52 | #define HAVE_SLIRP 53 | #endif 54 | 55 | #if !defined(NO_SIGACTION) && !defined(__wasi__) && !defined(_WIN32) 56 | #define HAVE_SIGACTION 57 | #endif 58 | 59 | #if !defined(NO_SELECT) 60 | #define HAVE_SELECT 61 | #endif 62 | 63 | #if !defined(NO_POSIX_FILE) && !defined(__wasi__) 64 | #define HAVE_POSIX_FS 65 | #endif 66 | 67 | #if !defined(NO_USLEEP) && (defined(__unix__) || defined(__APPLE__)) 68 | #define HAVE_USLEEP 69 | #endif 70 | 71 | #if !defined(NO_FORK) && (defined(__linux__) || defined(__unix__) || defined(__APPLE__)) && !defined(__wasi__) 72 | #define HAVE_FORK 73 | #endif 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /src/plic-factory.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #include "plic-factory.h" 18 | 19 | #include 20 | 21 | #include "plic.h" 22 | #include "pma-constants.h" 23 | #include "pma.h" 24 | 25 | namespace cartesi { 26 | 27 | /// \brief PLIC device peek callback. See ::pma_peek. 28 | static bool plic_peek(const pma_entry &pma, const machine & /*m*/, uint64_t page_offset, 29 | const unsigned char **page_data, unsigned char * /*context*/) { 30 | // PLIC range can be represented as pristine because its state is already represented in shadow CSRs 31 | *page_data = nullptr; 32 | return (page_offset % PMA_PAGE_SIZE) == 0 && page_offset < pma.get_length(); 33 | } 34 | 35 | pma_entry make_plic_pma_entry(uint64_t start, uint64_t length) { 36 | const pma_entry::flags f{.R = true, .W = true, .X = false, .IR = false, .IW = false, .DID = PMA_ISTART_DID::PLIC}; 37 | return make_device_pma_entry("PLIC device", start, length, plic_peek, &plic_driver).set_flags(f); 38 | } 39 | 40 | } // namespace cartesi 41 | -------------------------------------------------------------------------------- /src/plic-factory.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef PLIC_FACTORY_H 18 | #define PLIC_FACTORY_H 19 | 20 | #include 21 | 22 | #include "pma.h" 23 | 24 | namespace cartesi { 25 | 26 | /// \brief Creates a PMA entry for the PLIC device 27 | /// \param start Start address for memory range. 28 | /// \param length Length of memory range. 29 | /// \returns Corresponding PMA entry 30 | pma_entry make_plic_pma_entry(uint64_t start, uint64_t length); 31 | 32 | } // namespace cartesi 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/pma-driver.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #include "pma-driver.h" 18 | 19 | #include 20 | 21 | #include "interpret.h" 22 | 23 | namespace cartesi { 24 | 25 | bool device_read_error(void * /*context*/, i_device_state_access * /*a*/, uint64_t /*offset*/, uint64_t * /*val*/, 26 | int /*log2_size*/) { 27 | return false; 28 | } 29 | 30 | execute_status device_write_error(void * /*context*/, i_device_state_access * /*a*/, uint64_t /*offset*/, 31 | uint64_t /*val*/, int /*log2_size*/) { 32 | return execute_status::failure; 33 | } 34 | 35 | } // namespace cartesi 36 | -------------------------------------------------------------------------------- /src/pristine-merkle-tree.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #include "pristine-merkle-tree.h" 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include "i-hasher.h" 26 | 27 | /// \file 28 | /// \brief Pristine Merkle tree implementation. 29 | 30 | namespace cartesi { 31 | 32 | pristine_merkle_tree::pristine_merkle_tree(int log2_root_size, int log2_word_size) : 33 | m_log2_root_size{log2_root_size}, 34 | m_log2_word_size{log2_word_size}, 35 | m_hashes(std::max(0, log2_root_size - log2_word_size + 1)) { 36 | if (log2_root_size < 0) { 37 | throw std::out_of_range{"log2_root_size is negative"}; 38 | } 39 | if (log2_word_size < 0) { 40 | throw std::out_of_range{"log2_word_size is negative"}; 41 | } 42 | if (log2_word_size > log2_root_size) { 43 | throw std::out_of_range{"log2_word_size is greater than log2_root_size"}; 44 | } 45 | std::vector word(1 << log2_word_size, 0); 46 | assert(word.size() == (UINT64_C(1) << log2_word_size)); 47 | hasher_type h; 48 | h.begin(); 49 | h.add_data(word.data(), word.size()); 50 | h.end(m_hashes[0]); 51 | for (unsigned i = 1; i < m_hashes.size(); ++i) { 52 | get_concat_hash(h, m_hashes[i - 1], m_hashes[i - 1], m_hashes[i]); 53 | } 54 | } 55 | 56 | const pristine_merkle_tree::hash_type &pristine_merkle_tree::get_hash(int log2_size) const { 57 | if (log2_size < m_log2_word_size || log2_size > m_log2_root_size) { 58 | throw std::out_of_range{"log2_size is out of range"}; 59 | } 60 | return m_hashes[log2_size - m_log2_word_size]; 61 | } 62 | 63 | } // namespace cartesi 64 | -------------------------------------------------------------------------------- /src/pristine-merkle-tree.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef PRISTINE_MERKLE_TREE_H 18 | #define PRISTINE_MERKLE_TREE_H 19 | 20 | #include 21 | #include 22 | 23 | #include "keccak-256-hasher.h" 24 | 25 | /// \file 26 | /// \brief Pristine Merkle tree interface. 27 | 28 | namespace cartesi { 29 | 30 | /// \brief Hashes of pristine subtrees for a range of sizes 31 | class pristine_merkle_tree { 32 | public: 33 | /// \brief Hasher class. 34 | using hasher_type = keccak_256_hasher; 35 | 36 | /// \brief Storage for a hash. 37 | using hash_type = hasher_type::hash_type; 38 | 39 | using address_type = uint64_t; 40 | 41 | /// \brief Constructor 42 | /// \param log2_root_size Log2 of root node 43 | /// \param log2_word_size Log2 of word 44 | pristine_merkle_tree(int log2_root_size, int log2_word_size); 45 | 46 | /// \brief Returns hash of pristine subtree 47 | /// \param log2_size Log2 of subtree size. Must be between 48 | /// log2_word_size (inclusive) and log2_root_size (inclusive) passed 49 | /// to constructor. 50 | const hash_type &get_hash(int log2_size) const; 51 | 52 | private: 53 | int m_log2_root_size; ///< Log2 of tree size 54 | int m_log2_word_size; ///< Log2 of word size 55 | std::vector m_hashes; ///< Vector with hashes 56 | }; 57 | 58 | } // namespace cartesi 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /src/replay-step-state-access-interop.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #include "replay-step-state-access-interop.h" 18 | #include "machine-merkle-tree.h" 19 | 20 | using namespace cartesi; 21 | 22 | static_assert(interop_log2_root_size == machine_merkle_tree::get_log2_root_size(), 23 | "interop_log2_root_size must match machine_merkle_tree::get_log2_root_size()"); 24 | static_assert(sizeof(cartesi::machine_merkle_tree::hash_type) == sizeof(std::remove_pointer_t), 25 | "hash_type size mismatch"); 26 | 27 | extern "C" void interop_merkle_tree_hash(const unsigned char *data, size_t size, interop_hash_type hash) { 28 | machine_merkle_tree::hasher_type hasher{}; 29 | get_merkle_tree_hash(hasher, data, size, machine_merkle_tree::get_word_size(), 30 | // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 31 | *reinterpret_cast(hash)); 32 | } 33 | 34 | extern "C" void interop_concat_hash(interop_const_hash_type left, interop_const_hash_type right, 35 | interop_hash_type result) { 36 | machine_merkle_tree::hasher_type hasher{}; 37 | // NOLINTBEGIN(cppcoreguidelines-pro-type-reinterpret-cast) 38 | get_concat_hash(hasher, *reinterpret_cast(left), 39 | *reinterpret_cast(right), 40 | *reinterpret_cast(result)); 41 | // NOLINTEND(cppcoreguidelines-pro-type-reinterpret-cast) 42 | } 43 | -------------------------------------------------------------------------------- /src/replay-step-state-access-interop.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef REPLAY_STEP_STATE_ACCESS_INTEROP_H 18 | #define REPLAY_STEP_STATE_ACCESS_INTEROP_H 19 | 20 | #include "compiler-defines.h" 21 | #include 22 | #include 23 | #include 24 | 25 | const static uint64_t interop_log2_root_size = 64; 26 | constexpr size_t interop_machine_hash_byte_size = 32; 27 | 28 | using interop_hash_type = unsigned char (*)[interop_machine_hash_byte_size]; 29 | using interop_const_hash_type = const unsigned char (*)[interop_machine_hash_byte_size]; 30 | 31 | NO_RETURN inline void interop_throw_runtime_error(const char *msg) { 32 | throw std::runtime_error(msg); 33 | } 34 | 35 | extern "C" void interop_merkle_tree_hash(const unsigned char *data, size_t size, interop_hash_type hash); 36 | 37 | extern "C" void interop_concat_hash(interop_const_hash_type left, interop_const_hash_type right, 38 | interop_hash_type result); 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /src/rtc-defines.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef RTC_DEFINES_H 18 | #define RTC_DEFINES_H 19 | // NOLINTBEGIN(cppcoreguidelines-macro-usage,cppcoreguidelines-macro-to-enum,modernize-macro-to-enum) 20 | 21 | /// \brief Number of cycles between RTC ticks 22 | /// Changing this value affects the machine state hash 23 | /// Higher values decrease the performance of the interactive machine emulator 24 | /// Using base 2 values optimizes division and multiplications in the interpreter loop 25 | #define RTC_FREQ_DIV_DEF 8192 26 | 27 | /// \brief Arbitrary CPU clock frequency. 28 | /// We have to make sure the clock frequency is divisible by RTC_FREQ_DIV_DEF and 10^6 29 | #define RTC_CLOCK_FREQ_DEF 128000000 ///< 128 MHz frequency 30 | // NOLINTEND(cppcoreguidelines-macro-usage,cppcoreguidelines-macro-to-enum,modernize-macro-to-enum) 31 | #endif /* end of include guard: RTC_DEFINES_H */ 32 | -------------------------------------------------------------------------------- /src/rtc.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef RTC_H 18 | #define RTC_H 19 | 20 | #include 21 | 22 | #include "rtc-defines.h" 23 | 24 | /// \file 25 | /// \brief Real Time Clock 26 | 27 | namespace cartesi { 28 | 29 | /// \brief RTC constants 30 | enum RTC_constants : uint64_t { 31 | RTC_FREQ_DIV = RTC_FREQ_DIV_DEF, ///< Clock divisor is set stone in whitepaper 32 | RTC_CLOCK_FREQ = RTC_CLOCK_FREQ_DEF, ///< Clock frequency 33 | RTC_CYCLES_PER_US = RTC_CLOCK_FREQ / 1000000, ///< Clock cycles per microsecond 34 | }; 35 | 36 | /// \brief Converts from cycle count to time count 37 | /// \param cycle Cycle count 38 | /// \returns Time count 39 | static inline uint64_t rtc_cycle_to_time(uint64_t cycle) { 40 | return cycle / RTC_FREQ_DIV; 41 | } 42 | 43 | /// \brief Converts from time count to cycle count 44 | /// \param time Time count 45 | /// \returns Cycle count 46 | static inline uint64_t rtc_time_to_cycle(uint64_t time) { 47 | return time * RTC_FREQ_DIV; 48 | } 49 | 50 | /// \brief Returns whether the cycle is a RTC tick 51 | /// \param cycle Cycle count 52 | static inline bool rtc_is_tick(uint64_t cycle) { 53 | return (cycle % RTC_FREQ_DIV) == 0; 54 | } 55 | 56 | } // namespace cartesi 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /src/semantic-version.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef SEMANTIC_VERSION_H 18 | #define SEMANTIC_VERSION_H 19 | 20 | #include 21 | #include 22 | 23 | namespace cartesi { 24 | 25 | struct semantic_version { 26 | uint32_t major{}; 27 | uint32_t minor{}; 28 | uint32_t patch{}; 29 | std::string pre_release; 30 | std::string build; 31 | }; 32 | 33 | } // namespace cartesi 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/send-cmio-response.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef SEND_CMIO_RESPONSE_H 18 | #define SEND_CMIO_RESPONSE_H 19 | 20 | #include 21 | 22 | namespace cartesi { 23 | 24 | /// \brief Sends cmio response 25 | /// \tparam STATE_ACCESS State accessor type 26 | /// \param a State accessor 27 | /// \param reason Reason for sending the response 28 | /// \param data Response data 29 | /// \param length Response data length 30 | template 31 | void send_cmio_response(STATE_ACCESS a, uint16_t reason, const unsigned char *data, uint32_t dataLength); 32 | 33 | class state_access; 34 | class record_state_access; 35 | class replay_state_access; 36 | 37 | // Declaration of explicit instantiation in module send_cmio_response.cpp 38 | extern template void send_cmio_response(state_access a, uint16_t reason, const unsigned char *data, 39 | uint32_t dataLength); 40 | 41 | // Declaration of explicit instantiation in module uarch-reset-state.cpp 42 | extern template void send_cmio_response(record_state_access a, uint16_t reason, const unsigned char *data, 43 | uint32_t dataLength); 44 | 45 | // Declaration of explicit instantiation in module uarch-reset-state.cpp 46 | extern template void send_cmio_response(replay_state_access a, uint16_t reason, const unsigned char *data, 47 | uint32_t dataLength); 48 | 49 | } // namespace cartesi 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /src/shadow-pmas-factory.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #include "shadow-pmas-factory.h" 18 | 19 | #include 20 | #include 21 | 22 | #include "machine.h" 23 | #include "pma-constants.h" 24 | #include "pma.h" 25 | #include "shadow-pmas.h" 26 | 27 | namespace cartesi { 28 | 29 | pma_entry make_shadow_pmas_pma_entry(uint64_t start, uint64_t length) { 30 | const pma_entry::flags f{.R = true, 31 | .W = false, 32 | .X = false, 33 | .IR = false, 34 | .IW = false, 35 | .DID = PMA_ISTART_DID::shadow_pmas}; 36 | return make_callocd_memory_pma_entry("shadow PMAs", start, length).set_flags(f); 37 | } 38 | 39 | } // namespace cartesi 40 | -------------------------------------------------------------------------------- /src/shadow-pmas-factory.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef SHADOW_PMAS_FACTORY_H 18 | #define SHADOW_PMAS_FACTORY_H 19 | 20 | #include 21 | 22 | /// \file 23 | /// \brief Shadow device. 24 | 25 | #include "pma.h" 26 | #include "shadow-pmas.h" 27 | 28 | namespace cartesi { 29 | 30 | pma_entry make_shadow_pmas_pma_entry(uint64_t start, uint64_t length); 31 | 32 | template 33 | void populate_shadow_pmas_state(const PMAS &pmas, shadow_pmas_state *shadow) { 34 | static_assert(PMA_SHADOW_PMAS_LENGTH >= sizeof(shadow_pmas_state), "shadow PMAs length is too small"); 35 | unsigned index = 0; 36 | for (const auto &pma : pmas) { 37 | shadow->pmas[index].istart = pma.get_istart(); 38 | shadow->pmas[index].ilength = pma.get_ilength(); 39 | ++index; 40 | } 41 | } 42 | 43 | } // namespace cartesi 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /src/shadow-pmas.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef SHADOW_PMAS_H 18 | #define SHADOW_PMAS_H 19 | 20 | #include 21 | #include 22 | 23 | #include "compiler-defines.h" 24 | #include "pma-constants.h" 25 | #include "pma-driver.h" 26 | 27 | /// \file 28 | /// \brief Shadow device. 29 | 30 | namespace cartesi { 31 | 32 | /// \brief Shadow memory layout 33 | 34 | struct PACKED shadow_pma_entry { 35 | uint64_t istart; 36 | uint64_t ilength; 37 | }; 38 | 39 | struct PACKED shadow_pmas_state { 40 | shadow_pma_entry pmas[PMA_MAX]; 41 | }; 42 | 43 | /// \brief Obtains the relative address of a PMA entry in shadow memory. 44 | /// \param p Index of desired shadow PMA entry, in 0..31. 45 | /// \returns The address. 46 | static inline uint64_t shadow_pmas_get_pma_rel_addr(uint64_t p) { 47 | assert(p < (int) PMA_MAX); 48 | return p * sizeof(shadow_pma_entry); 49 | } 50 | 51 | /// \brief Obtains the absolute address of a PMA entry in shadow memory. 52 | static inline uint64_t shadow_pmas_get_pma_abs_addr(uint64_t p) { 53 | return PMA_SHADOW_PMAS_START + shadow_pmas_get_pma_rel_addr(p); 54 | } 55 | 56 | } // namespace cartesi 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /src/shadow-state-factory.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef SHADOW_STATE_FACTORY_H 18 | #define SHADOW_STATE_FACTORY_H 19 | 20 | #include 21 | 22 | /// \file 23 | /// \brief Shadow device. 24 | 25 | #include "pma.h" 26 | 27 | namespace cartesi { 28 | 29 | /// \brief Creates a PMA entry for the shadow device 30 | /// \param start Start address for memory range. 31 | /// \param length Length of memory range. 32 | /// \returns Corresponding PMA entry 33 | pma_entry make_shadow_state_pma_entry(uint64_t start, uint64_t length); 34 | 35 | } // namespace cartesi 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /src/shadow-state.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #include "shadow-state.h" 18 | #include "pma-driver.h" 19 | 20 | namespace cartesi { 21 | 22 | const pma_driver shadow_state_driver = {.name = "SHADOW STATE", .read = device_read_error, .write = device_write_error}; 23 | 24 | } // namespace cartesi 25 | -------------------------------------------------------------------------------- /src/shadow-state.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef SHADOW_STATE_H 18 | #define SHADOW_STATE_H 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include "compiler-defines.h" 25 | #include "pma-driver.h" 26 | #include "riscv-constants.h" 27 | 28 | /// \file 29 | /// \brief Shadow device. 30 | 31 | namespace cartesi { 32 | 33 | /// \brief Shadow memory layout 34 | struct PACKED shadow_state { 35 | uint64_t x[X_REG_COUNT]; ///< Register file. 36 | uint64_t f[F_REG_COUNT]; ///< Floating-point register file. 37 | uint64_t pc; 38 | uint64_t fcsr; 39 | uint64_t mvendorid; 40 | uint64_t marchid; 41 | uint64_t mimpid; 42 | uint64_t mcycle; 43 | uint64_t icycleinstret; 44 | uint64_t mstatus; 45 | uint64_t mtvec; 46 | uint64_t mscratch; 47 | uint64_t mepc; 48 | uint64_t mcause; 49 | uint64_t mtval; 50 | uint64_t misa; 51 | uint64_t mie; 52 | uint64_t mip; 53 | uint64_t medeleg; 54 | uint64_t mideleg; 55 | uint64_t mcounteren; 56 | uint64_t menvcfg; 57 | uint64_t stvec; 58 | uint64_t sscratch; 59 | uint64_t sepc; 60 | uint64_t scause; 61 | uint64_t stval; 62 | uint64_t satp; 63 | uint64_t scounteren; 64 | uint64_t senvcfg; 65 | uint64_t ilrsc; 66 | uint64_t iprv; 67 | uint64_t iflags_X; 68 | uint64_t iflags_Y; 69 | uint64_t iflags_H; 70 | uint64_t iunrep; 71 | uint64_t clint_mtimecmp; 72 | uint64_t plic_girqpend; 73 | uint64_t plic_girqsrvd; 74 | uint64_t htif_tohost; 75 | uint64_t htif_fromhost; 76 | uint64_t htif_ihalt; 77 | uint64_t htif_iconsole; 78 | uint64_t htif_iyield; 79 | }; 80 | 81 | /// \brief Global instance of the processor shadow device driver. 82 | extern const pma_driver shadow_state_driver; 83 | 84 | } // namespace cartesi 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /src/shadow-tlb-factory.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef SHADOW_TLB_FACTORY_H 18 | #define SHADOW_TLB_FACTORY_H 19 | 20 | /// \file 21 | /// \brief TLB device factory. 22 | 23 | #include 24 | 25 | #include "pma.h" 26 | 27 | namespace cartesi { 28 | 29 | /// \brief Creates a PMA entry for the TLB device 30 | /// \param start Start address for memory range. 31 | /// \param length Length of memory range. 32 | /// \returns Corresponding PMA entry 33 | pma_entry make_shadow_tlb_pma_entry(uint64_t start, uint64_t length); 34 | 35 | } // namespace cartesi 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /src/shadow-tlb.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #include "shadow-tlb.h" 18 | 19 | #include "pma-driver.h" 20 | 21 | namespace cartesi { 22 | 23 | const pma_driver shadow_tlb_driver = {.name = "SHADOW TLB", .read = device_read_error, .write = device_write_error}; 24 | 25 | } // namespace cartesi 26 | -------------------------------------------------------------------------------- /src/shadow-uarch-state-factory.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #include "shadow-uarch-state-factory.h" 18 | 19 | #include "pma-constants.h" 20 | #include "pma.h" 21 | #include "riscv-constants.h" 22 | #include "shadow-uarch-state.h" 23 | #include 24 | #include 25 | 26 | #include "machine.h" 27 | 28 | namespace cartesi { 29 | 30 | /// \brief Shadow uarch state device peek callback. See ::pma_peek. 31 | static bool shadow_uarch_state_peek(const pma_entry & /*pma*/, const machine &m, uint64_t page_offset, 32 | const unsigned char **page_data, unsigned char *scratch) { 33 | static_assert(sizeof(shadow_uarch_state) <= PMA_PAGE_SIZE); 34 | 35 | // There is only one page: 0 36 | if (page_offset != 0) { 37 | *page_data = nullptr; 38 | return false; 39 | } 40 | // Clear page 41 | memset(scratch, 0, PMA_PAGE_SIZE); 42 | 43 | // The page will reflect the shadow uarch state structure 44 | // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 45 | auto *s = reinterpret_cast(scratch); 46 | 47 | s->halt_flag = m.read_reg(machine_reg::uarch_halt_flag); 48 | s->cycle = m.read_reg(machine_reg::uarch_cycle); 49 | s->pc = m.read_reg(machine_reg::uarch_pc); 50 | for (int i = 0; i < UARCH_X_REG_COUNT; ++i) { 51 | s->x[i] = m.read_reg(machine_reg_enum(machine_reg::uarch_x0, i)); 52 | } 53 | *page_data = scratch; 54 | return true; 55 | } 56 | 57 | pma_entry make_shadow_uarch_state_pma_entry(uint64_t start, uint64_t length) { 58 | const pma_entry::flags f{.R = false, 59 | .W = false, 60 | .X = false, 61 | .IR = false, 62 | .IW = false, 63 | .DID = PMA_ISTART_DID::shadow_uarch}; 64 | return make_device_pma_entry("shadow uarch state device", start, length, shadow_uarch_state_peek, 65 | &shadow_uarch_state_driver) 66 | .set_flags(f); 67 | } 68 | 69 | } // namespace cartesi 70 | -------------------------------------------------------------------------------- /src/shadow-uarch-state-factory.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef SHADOW_UARCH_STATE_FACTORY_H 18 | #define SHADOW_UARCH_STATE_FACTORY_H 19 | 20 | #include 21 | 22 | /// \file 23 | /// \brief Shadow uarch state device. 24 | 25 | #include "pma.h" 26 | 27 | namespace cartesi { 28 | 29 | /// \brief Creates a PMA entry for the shadow uarch state device 30 | /// \param start Start address for memory range. 31 | /// \param length Length of memory range. 32 | /// \returns Corresponding PMA entry 33 | pma_entry make_shadow_uarch_state_pma_entry(uint64_t start, uint64_t length); 34 | 35 | } // namespace cartesi 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /src/shadow-uarch-state.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #include "shadow-uarch-state.h" 18 | #include "pma-driver.h" 19 | 20 | namespace cartesi { 21 | 22 | const pma_driver shadow_uarch_state_driver = {.name = "SHADOW UARCH", 23 | .read = device_read_error, 24 | .write = device_write_error}; 25 | 26 | } // namespace cartesi 27 | -------------------------------------------------------------------------------- /src/shadow-uarch-state.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef SHADOW_UARCH_STATE_H 18 | #define SHADOW_UARCH_STATE_H 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include "compiler-defines.h" 25 | #include "pma-driver.h" 26 | #include "riscv-constants.h" 27 | 28 | /// \file 29 | /// \brief Shadow uarch state device. 30 | 31 | namespace cartesi { 32 | 33 | /// \brief Shadow uarch memory layout 34 | struct PACKED shadow_uarch_state { 35 | uint64_t halt_flag; 36 | uint64_t cycle; 37 | uint64_t pc; 38 | uint64_t x[UARCH_X_REG_COUNT]; 39 | }; 40 | 41 | /// \brief Global instance of theprocessor shadow uarch state device driver. 42 | extern const pma_driver shadow_uarch_state_driver; 43 | 44 | } // namespace cartesi 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /src/slog.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #include "slog.h" 18 | 19 | #include 20 | 21 | namespace slog { 22 | 23 | severity_level log_level(level_operation operation, severity_level new_level) { 24 | static severity_level level = severity_level::trace; 25 | if (operation == level_operation::set) { 26 | auto old_level = level; 27 | level = new_level; 28 | return old_level; 29 | } 30 | return level; 31 | } 32 | 33 | const char *to_string(severity_level level) { 34 | switch (level) { 35 | case severity_level::trace: 36 | return "trace"; 37 | case severity_level::debug: 38 | return "debug"; 39 | case severity_level::info: 40 | return "info"; 41 | case severity_level::warning: 42 | return "warning"; 43 | case severity_level::error: 44 | return "error"; 45 | case severity_level::fatal: 46 | return "fatal"; 47 | default: 48 | return "unknown"; 49 | } 50 | } 51 | 52 | severity_level from_string(const char *name) { 53 | if (strcmp(name, "trace") == 0) { 54 | return severity_level::trace; 55 | } 56 | if (strcmp(name, "debug") == 0) { 57 | return severity_level::debug; 58 | } 59 | if (strcmp(name, "info") == 0) { 60 | return severity_level::info; 61 | } 62 | if (strcmp(name, "warning") == 0) { 63 | return severity_level::warning; 64 | } 65 | if (strcmp(name, "error") == 0) { 66 | return severity_level::error; 67 | } 68 | if (strcmp(name, "fatal") == 0) { 69 | return severity_level::fatal; 70 | } 71 | throw std::domain_error{"unknown log severity level"}; 72 | } 73 | 74 | } // namespace slog 75 | -------------------------------------------------------------------------------- /src/uarch-config.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef UARCH_CONFIG_H 18 | #define UARCH_CONFIG_H 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include "riscv-constants.h" 25 | 26 | namespace cartesi { 27 | 28 | /// \brief RAM state configuration for the microarchitecture 29 | struct uarch_ram_config final { 30 | std::string image_filename; ///< RAM image file name 31 | }; 32 | 33 | /// \brief Microarchitecture processor configuration 34 | struct uarch_processor_config final { 35 | std::array x{}; ///< Value of general-purpose registers 36 | uint64_t pc{UARCH_PC_INIT}; ///< Value of pc 37 | uint64_t cycle{UARCH_CYCLE_INIT}; ///< Value of ucycle counter 38 | bool halt_flag{}; 39 | }; 40 | 41 | /// \brief Microarchitecture configuration 42 | struct uarch_config final { 43 | uarch_processor_config processor{}; ///< processor configuration 44 | uarch_ram_config ram{}; ///< RAM configuration 45 | }; 46 | 47 | } // namespace cartesi 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /src/uarch-defines.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef UARCH_DEFINES_H 18 | #define UARCH_DEFINES_H 19 | 20 | #include "pma-defines.h" 21 | // NOLINTBEGIN(cppcoreguidelines-macro-usage,cppcoreguidelines-macro-to-enum,modernize-macro-to-enum) 22 | /// \brief Start address of the entire uarch memory range: shadow and ram 23 | #define UARCH_STATE_START_ADDRESS_DEF PMA_SHADOW_UARCH_STATE_START_DEF 24 | 25 | /// \brief Log2 size of the entire uarch memory range: shadow and ram 26 | #define UARCH_STATE_LOG2_SIZE_DEF 22 27 | 28 | // microarchitecture ecall function codes 29 | #define UARCH_ECALL_FN_HALT_DEF 1 // halt uarch 30 | #define UARCH_ECALL_FN_PUTCHAR_DEF 2 // putchar 31 | 32 | // NOLINTEND(cppcoreguidelines-macro-usage,cppcoreguidelines-macro-to-enum,modernize-macro-to-enum) 33 | #endif /* end of include guard: UARCH_DEFINES_H */ 34 | -------------------------------------------------------------------------------- /src/uarch-interpret.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #include "uarch-interpret.h" 18 | 19 | #include 20 | 21 | #include "uarch-state-access.h" 22 | #include "uarch-step.h" 23 | 24 | namespace cartesi { 25 | 26 | // Declaration of explicit instantiation in module uarch-step.cpp 27 | extern template UArchStepStatus uarch_step(uarch_state_access &a); 28 | 29 | uarch_interpreter_break_reason uarch_interpret(uarch_state_access &a, uint64_t cycle_end) { 30 | uint64_t cycle = a.read_cycle(); 31 | if (cycle_end < cycle) { 32 | throw std::invalid_argument{"uarch_cycle is past"}; 33 | } 34 | while (cycle < cycle_end) { 35 | const UArchStepStatus status = uarch_step(a); 36 | switch (status) { 37 | case UArchStepStatus::Success: 38 | cycle += 1; 39 | break; 40 | case UArchStepStatus::UArchHalted: 41 | return uarch_interpreter_break_reason::uarch_halted; 42 | // LCOV_EXCL_START 43 | case UArchStepStatus::CycleOverflow: 44 | // Prior condition ensures that this case is unreachable. but linter may complain about missing it 45 | return uarch_interpreter_break_reason::reached_target_cycle; 46 | // LCOV_EXCL_STOP 47 | } 48 | } 49 | return uarch_interpreter_break_reason::reached_target_cycle; 50 | } 51 | 52 | } // namespace cartesi 53 | -------------------------------------------------------------------------------- /src/uarch-interpret.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef UARCH_INTERPRET_H 18 | #define UARCH_INTERPRET_H 19 | 20 | #include 21 | 22 | #include "uarch-state-access.h" 23 | 24 | namespace cartesi { 25 | 26 | enum class uarch_interpreter_break_reason : int { reached_target_cycle, uarch_halted }; 27 | 28 | // Run the microarchitecture interpreter until cycle hits a target or a fixed point is reached 29 | uarch_interpreter_break_reason uarch_interpret(uarch_state_access &a, uint64_t uarch_cycle_end); 30 | 31 | } // namespace cartesi 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/uarch-pristine-state-hash.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #include "uarch-pristine-state-hash.h" 18 | 19 | #include 20 | 21 | #include "machine-merkle-tree.h" 22 | #include "uarch-pristine.h" 23 | 24 | namespace cartesi { 25 | 26 | static machine_merkle_tree::hash_type make_uarch_pristine_state_hash() noexcept { 27 | machine_merkle_tree::hash_type h; 28 | for (std::size_t i = 0; i < h.size(); ++i) { 29 | h[i] = uarch_pristine_hash[i]; 30 | } 31 | return h; 32 | } 33 | 34 | const machine_merkle_tree::hash_type &get_uarch_pristine_state_hash() { 35 | static const machine_merkle_tree::hash_type uarch_pristine_state_hash = make_uarch_pristine_state_hash(); 36 | return uarch_pristine_state_hash; 37 | } 38 | 39 | } // namespace cartesi 40 | -------------------------------------------------------------------------------- /src/uarch-pristine-state-hash.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef UARCH_STATE_HASH_H 18 | #define UARCH_STATE_HASH_H 19 | 20 | #include "machine-merkle-tree.h" 21 | 22 | namespace cartesi { 23 | 24 | /// \brief Gets the hash of the pristine uarch state. 25 | /// \details This hash is computed at compile time by the program compute-uarch-pristine-hash.cpp 26 | const machine_merkle_tree::hash_type &get_uarch_pristine_state_hash(); 27 | 28 | } // namespace cartesi 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/uarch-pristine.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef UARCH_PRISTINE_H 18 | #define UARCH_PRISTINE_H 19 | 20 | /// \brief Embedded pristine uarch ram image. This symbol is created by "xxd" 21 | extern "C" const unsigned char uarch_pristine_ram[]; 22 | 23 | /// \brief Length of the embedded pristine uarch ram image. This symbol is created by "xxd" 24 | extern "C" const unsigned int uarch_pristine_ram_len; 25 | 26 | /// \brief Embedded pristine uarch ram image. This symbol is created by "compute-uarch-pristine-hash" 27 | extern "C" const unsigned char uarch_pristine_hash[]; 28 | 29 | /// \brief Length of the embedded pristine uarch ram image. This symbol is created by "compute-uarch-pristine-hash" 30 | extern "C" const unsigned int uarch_pristine_hash_len; 31 | 32 | #endif // UARCH_PRISTINE_H 33 | -------------------------------------------------------------------------------- /src/uarch-reset-state.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | /// \file 18 | /// \brief This file is be converted to Solidity by the machine-solidity-step. 19 | 20 | // NOLINTBEGIN(google-readability-casting,misc-const-correctness,modernize-use-auto,hicpp-use-auto) 21 | 22 | #include "uarch-reset-state.h" 23 | #include "uarch-record-state-access.h" 24 | #include "uarch-replay-state-access.h" 25 | #include "uarch-solidity-compat.h" 26 | #include "uarch-state-access.h" 27 | 28 | namespace cartesi { 29 | 30 | template 31 | void uarch_reset_state(UarchState &a) { 32 | resetState(a); 33 | } 34 | 35 | // Explicit instantiation for uarch_state_access 36 | template void uarch_reset_state(uarch_state_access &a); 37 | 38 | // Explicit instantiation for uarch_record_state_access 39 | template void uarch_reset_state(uarch_record_state_access &a); 40 | 41 | // Explicit instantiation for uarch_replay_state_access 42 | template void uarch_reset_state(uarch_replay_state_access &a); 43 | 44 | } // namespace cartesi 45 | // NOLINTEND(google-readability-casting,misc-const-correctness,modernize-use-auto,hicpp-use-auto) 46 | -------------------------------------------------------------------------------- /src/uarch-reset-state.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef UARCH_RESET_STATE_H 18 | #define UARCH_RESET_STATE_H 19 | 20 | namespace cartesi { 21 | 22 | /// \brief Reset uarch to pristine state 23 | /// \tparam STATE_ACCESS state accessor type 24 | /// \param a state accessor instance 25 | template 26 | void uarch_reset_state(STATE_ACCESS &a); 27 | 28 | class uarch_state_access; 29 | class uarch_record_state_access; 30 | class uarch_replay_state_access; 31 | 32 | // Declaration of explicit instantiation in module uarch-reset-state.cpp 33 | extern template void uarch_reset_state(uarch_state_access &a); 34 | 35 | // Declaration of explicit instantiation in module uarch-reset-state.cpp 36 | extern template void uarch_reset_state(uarch_state_access &a); 37 | 38 | // Declaration of explicit instantiation in module uarch-reset-state.cpp 39 | extern template void uarch_reset_state(uarch_record_state_access &a); 40 | 41 | // Declaration of explicit instantiation in module uarch-reset-state.cpp 42 | extern template void uarch_reset_state(uarch_replay_state_access &a); 43 | 44 | } // namespace cartesi 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /src/uarch-state.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef UARCH_STATE_H 18 | #define UARCH_STATE_H 19 | 20 | /// \file 21 | /// \brief Cartesi microarchitecture machine state structure definition. 22 | 23 | #include 24 | #include 25 | 26 | #include "pma.h" 27 | #include "riscv-constants.h" 28 | 29 | namespace cartesi { 30 | 31 | struct uarch_state { 32 | uarch_state() = default; 33 | ~uarch_state() = default; 34 | 35 | /// \brief No copy or move constructor or assignment 36 | uarch_state(const uarch_state &other) = delete; 37 | uarch_state(uarch_state &&other) = delete; 38 | uarch_state &operator=(const uarch_state &other) = delete; 39 | uarch_state &operator=(uarch_state &&other) = delete; 40 | 41 | uint64_t pc{}; ///< Program counter. 42 | std::array x{}; ///< Register file. 43 | uint64_t cycle{}; ///< Cycles counter 44 | bool halt_flag{}; 45 | pma_entry shadow_state; ///< Shadow uarch state 46 | pma_entry ram; ///< Memory range for micro RAM 47 | pma_entry empty_pma; ///< Empty range fallback 48 | }; 49 | 50 | } // namespace cartesi 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /src/uarch-step.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef UARCH_STEP_H 18 | #define UARCH_STEP_H 19 | 20 | namespace cartesi { 21 | 22 | /// \brief Microarchitecture step execution status code 23 | enum class UArchStepStatus : int { 24 | Success, // one micro instruction was executed successfully 25 | CycleOverflow, // already at fixed point: uarch cycle has reached its maximum value 26 | UArchHalted // already at fixed point: microarchitecture is halted 27 | }; 28 | 29 | /// \brief Advances the microarchitecture by one micro cycle 30 | /// \tparam Microarchitecture state accessor class 31 | /// \returns Returns a status code indicating whether and how the microarchitecure was advanced 32 | /// \details The microarchitecture will not advance if it is at a fixed point 33 | template 34 | UArchStepStatus uarch_step(STATE_ACCESS &a); 35 | 36 | } // namespace cartesi 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/uint128.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef UINT128_H 18 | #define UINT128_H 19 | 20 | #include 21 | 22 | using uint128_t = Fortran::common::uint128_t; 23 | using int128_t = Fortran::common::int128_t; 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /src/virtio-factory.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #include "virtio-factory.h" 18 | 19 | #include 20 | #include 21 | 22 | #include "pma-constants.h" 23 | #include "pma-driver.h" 24 | #include "pma.h" 25 | 26 | namespace cartesi { 27 | 28 | pma_entry make_virtio_pma_entry(uint64_t start, uint64_t length, const std::string &description, 29 | const pma_driver *driver, void *context) { 30 | const pma_entry::flags f{.R = true, .W = true, .X = false, .IR = false, .IW = false, .DID = PMA_ISTART_DID::VIRTIO}; 31 | // VirtIO devices are not verifiable yet, 32 | // therefore peek will always fail and cause an runtime error when updating the Merkle tree. 33 | return make_device_pma_entry(description, start, length, pma_peek_error, driver, context).set_flags(f); 34 | } 35 | 36 | } // namespace cartesi 37 | -------------------------------------------------------------------------------- /src/virtio-factory.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef VIRTIO_FACTORY_H 18 | #define VIRTIO_FACTORY_H 19 | 20 | #include 21 | #include 22 | 23 | #include "pma-driver.h" 24 | #include "pma.h" 25 | 26 | namespace cartesi { 27 | 28 | /// \brief Creates a PMA entry for a VirtIO device 29 | /// \param start Start address for memory range. 30 | /// \param length Length of memory range. 31 | /// \returns Corresponding PMA entry 32 | pma_entry make_virtio_pma_entry(uint64_t start, uint64_t length, const std::string &description, 33 | const pma_driver *driver, void *context); 34 | 35 | } // namespace cartesi 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /src/virtio-net-carrier-tuntap.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef VIRTIO_NET_CARRIER_TUNTAP_H 18 | #define VIRTIO_NET_CARRIER_TUNTAP_H 19 | 20 | #include "os-features.h" 21 | 22 | #ifdef HAVE_TUNTAP 23 | 24 | #include 25 | #include 26 | 27 | #include "i-device-state-access.h" 28 | #include "os.h" 29 | #include "virtio-device.h" 30 | #include "virtio-net.h" 31 | 32 | namespace cartesi { 33 | 34 | class virtio_net_carrier_tuntap final : public virtio_net_carrier { 35 | int m_tapfd = -1; 36 | 37 | public: 38 | explicit virtio_net_carrier_tuntap(const std::string &tap_name); 39 | ~virtio_net_carrier_tuntap() override; 40 | virtio_net_carrier_tuntap(const virtio_net_carrier_tuntap &other) = delete; 41 | virtio_net_carrier_tuntap(virtio_net_carrier_tuntap &&other) = delete; 42 | virtio_net_carrier_tuntap &operator=(const virtio_net_carrier_tuntap &other) = delete; 43 | virtio_net_carrier_tuntap &operator=(virtio_net_carrier_tuntap &&other) = delete; 44 | 45 | void reset() override; 46 | 47 | void do_prepare_select(select_fd_sets *fds, uint64_t *timeout_us) override; 48 | bool do_poll_selected(int select_ret, select_fd_sets *fds) override; 49 | 50 | bool write_packet_to_host(i_device_state_access *a, virtq &vq, uint16_t desc_idx, uint32_t read_avail_len, 51 | uint32_t *pread_len) override; 52 | bool read_packet_from_host(i_device_state_access *a, virtq &vq, uint16_t desc_idx, uint32_t write_avail_len, 53 | uint32_t *pwritten_len) override; 54 | }; 55 | 56 | } // namespace cartesi 57 | 58 | #endif // HAVE_TUNTAP 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /tests/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG TAG=devel 2 | FROM cartesi/machine-emulator:builder AS tests-builder 3 | ARG DEBUG=no 4 | ARG COVERAGE=no 5 | ARG SANITIZE=no 6 | 7 | RUN make -j$(nproc) build-tests-machine debug=$DEBUG coverage=$COVERAGE sanitize=$SANITIZE 8 | RUN make -j$(nproc) build-tests-misc build-tests-uarch build-tests-images debug=$DEBUG coverage=$COVERAGE sanitize=$SANITIZE 9 | 10 | #################################################################################################### 11 | FROM tests-builder AS tests-debian-packager 12 | 13 | RUN make tests-debian-package DESTDIR=$PWD/dpkg/tests-install && \ 14 | make tests-data-debian-package DESTDIR=$PWD/dpkg/tests-data-install 15 | 16 | #################################################################################################### 17 | FROM cartesi/machine-emulator:$TAG 18 | 19 | ENV CARTESI_IMAGES_PATH=/usr/share/cartesi-machine/tests/data/images 20 | ENV CARTESI_TESTS_PATH=/usr/share/cartesi-machine/tests/data/machine 21 | ENV CARTESI_TESTS_UARCH_PATH=/usr/share/cartesi-machine/tests/data/uarch 22 | ENV CARTESI_CMIO_PATH=/tmp/cartesi-machine/tests/data/cmio 23 | 24 | USER root 25 | 26 | COPY --from=tests-debian-packager /usr/src/emulator/machine-emulator-tests*.deb . 27 | RUN <. 15 | -- 16 | 17 | -- module to convert array tables into key-value tables 18 | local M = {} 19 | 20 | -- convert a table with indexed rows into a table with named rows. e.g. 21 | -- {"foo", 999} -> {name = "foo", cycles = 999} with keys described by md 22 | local function expand_row(metadata, row) 23 | local expanded_row = {} 24 | for key, val in ipairs(metadata) do 25 | expanded_row[val] = row[key] 26 | end 27 | return expanded_row 28 | end 29 | 30 | -- apply `expand_row` for each row of `t`. e.g. 31 | -- {{ "foo", 999 }} -> {{name = "foo", cycles = 999}} with keys described by md 32 | M.expand = function(metadata, t) 33 | local expanded_t = {} 34 | for _, row in ipairs(t) do 35 | expanded_t[#expanded_t + 1] = expand_row(metadata, row) 36 | end 37 | return expanded_t 38 | end 39 | 40 | return M 41 | -------------------------------------------------------------------------------- /tests/lua/htif-cmio.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua5.4 2 | 3 | -- Copyright Cartesi and individual authors (see AUTHORS) 4 | -- SPDX-License-Identifier: LGPL-3.0-or-later 5 | -- 6 | -- This program is free software: you can redistribute it and/or modify it under 7 | -- the terms of the GNU Lesser General Public License as published by the Free 8 | -- Software Foundation, either version 3 of the License, or (at your option) any 9 | -- later version. 10 | -- 11 | -- This program is distributed in the hope that it will be useful, but WITHOUT ANY 12 | -- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 13 | -- PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 14 | -- 15 | -- You should have received a copy of the GNU Lesser General Public License along 16 | -- with this program (see COPYING). If not, see . 17 | -- 18 | 19 | local cartesi = require("cartesi") 20 | local test_util = require("cartesi.tests.util") 21 | 22 | local config_base = { 23 | ram = { 24 | -- This test will fetch the cmio buffers from the PMA entries; check 25 | -- that `rx_buffer` is filled with a byte pattern; 26 | -- then write a byte pattern into `tx_buffer` to be checked inside. 27 | image_filename = test_util.tests_path .. "htif_cmio.bin", 28 | length = 0x4000000, 29 | }, 30 | } 31 | 32 | local function stderr(...) 33 | io.stderr:write(string.format(...)) 34 | end 35 | 36 | local final_mcycle = 1835101 37 | local exit_payload = 0 38 | 39 | local function test(config) 40 | local pattern = "\xef\xcd\xab\x89\x67\x45\x23\x01" 41 | local machine = cartesi.machine(config) 42 | 43 | -- fill input with `pattern` 44 | local rx_length = 1 << cartesi.PMA_CMIO_RX_BUFFER_LOG2_SIZE 45 | machine:write_memory(cartesi.PMA_CMIO_RX_BUFFER_START, string.rep(pattern, rx_length / 8), rx_length) 46 | 47 | machine:run(math.maxinteger) 48 | 49 | -- check that buffers got filled in with `pattern` 50 | local tx_length = 1 << cartesi.PMA_CMIO_TX_BUFFER_LOG2_SIZE 51 | assert(string.rep(pattern, tx_length / 8) == machine:read_memory(cartesi.PMA_CMIO_TX_BUFFER_START, tx_length)) 52 | 53 | assert(machine:read_reg("iflags_H") ~= 0) 54 | 55 | local mcycle = machine:read_reg("mcycle") 56 | assert(mcycle == final_mcycle, "[mcycle] expected:" .. final_mcycle .. " got: " .. mcycle) 57 | 58 | local exit = machine:read_reg("htif_tohost_data") >> 1 59 | assert(exit == exit_payload, "[exit] expected: " .. exit_payload .. " got: " .. exit) 60 | 61 | stderr(" passed\n") 62 | end 63 | 64 | stderr("testing cmio\n") 65 | test(config_base) 66 | -------------------------------------------------------------------------------- /tests/lua/htif-console.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua5.4 2 | 3 | -- Copyright Cartesi and individual authors (see AUTHORS) 4 | -- SPDX-License-Identifier: LGPL-3.0-or-later 5 | -- 6 | -- This program is free software: you can redistribute it and/or modify it under 7 | -- the terms of the GNU Lesser General Public License as published by the Free 8 | -- Software Foundation, either version 3 of the License, or (at your option) any 9 | -- later version. 10 | -- 11 | -- This program is distributed in the hope that it will be useful, but WITHOUT ANY 12 | -- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 13 | -- PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 14 | -- 15 | -- You should have received a copy of the GNU Lesser General Public License along 16 | -- with this program (see COPYING). If not, see . 17 | -- 18 | 19 | local cartesi = require("cartesi") 20 | local test_util = require("cartesi.tests.util") 21 | 22 | local config_base = { 23 | processor = { 24 | iunrep = 1, 25 | }, 26 | ram = { 27 | image_filename = test_util.tests_path .. "htif_console.bin", 28 | length = 0x4000000, 29 | }, 30 | } 31 | 32 | local function stderr(...) 33 | io.stderr:write(string.format(...)) 34 | end 35 | 36 | local expected_final_mcycle = 2137 37 | local expected_exit_payload = 42 38 | 39 | local function test(config, console_getchar_enable) 40 | stderr(" testing console_getchar:%s\n", console_getchar_enable and "on" or "off") 41 | config.htif = { 42 | console_getchar = console_getchar_enable, 43 | } 44 | local machine = cartesi.machine(config) 45 | machine:run(math.maxinteger) 46 | 47 | -- should be halted 48 | assert(machine:read_reg("iflags_H") ~= 0, "expected iflags_H set") 49 | 50 | -- with the expected payload 51 | local exit_payload = machine:read_reg("htif_tohost_data") >> 1 52 | assert( 53 | exit_payload == expected_exit_payload, 54 | string.format("exit payload: expected %u, got %u\n", expected_exit_payload, exit_payload) 55 | ) 56 | 57 | -- at the expected mcycle 58 | local final_mcycle = machine:read_reg("mcycle") 59 | assert( 60 | final_mcycle == expected_final_mcycle, 61 | string.format("mcycle: expected, %u got %u", expected_final_mcycle, final_mcycle) 62 | ) 63 | 64 | stderr(" passed\n") 65 | end 66 | 67 | for _, getchar in ipairs({ true, false }) do 68 | test(config_base, getchar) 69 | end 70 | -------------------------------------------------------------------------------- /tests/lua/log-with-mtime-transition.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua5.4 2 | 3 | local cartesi = require("cartesi") 4 | 5 | local config = { 6 | processor = { 7 | mcycle = 99, 8 | }, 9 | ram = { 10 | length = 1 << 12, 11 | }, 12 | } 13 | local machine = cartesi.machine(config) 14 | 15 | local old_hash = machine:get_root_hash() 16 | local access_log = machine:log_step_uarch() 17 | local new_hash = machine:get_root_hash() 18 | cartesi.machine:verify_step_uarch(old_hash, access_log, new_hash, {}) 19 | print("ok") 20 | -------------------------------------------------------------------------------- /tests/lua/mtime-interrupt.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua5.4 2 | 3 | -- Copyright Cartesi and individual authors (see AUTHORS) 4 | -- SPDX-License-Identifier: LGPL-3.0-or-later 5 | -- 6 | -- This program is free software: you can redistribute it and/or modify it under 7 | -- the terms of the GNU Lesser General Public License as published by the Free 8 | -- Software Foundation, either version 3 of the License, or (at your option) any 9 | -- later version. 10 | -- 11 | -- This program is distributed in the hope that it will be useful, but WITHOUT ANY 12 | -- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 13 | -- PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 14 | -- 15 | -- You should have received a copy of the GNU Lesser General Public License along 16 | -- with this program (see COPYING). If not, see . 17 | -- 18 | 19 | local cartesi = require("cartesi") 20 | local test_util = require("cartesi.tests.util") 21 | 22 | local function build_machine() 23 | local machine_config = { 24 | ram = { 25 | image_filename = test_util.tests_path .. "mtime_interrupt.bin", 26 | length = 32 << 20, 27 | }, 28 | } 29 | return cartesi.machine(machine_config) 30 | end 31 | 32 | local function do_test(description, f) 33 | io.write(" " .. description .. "...") 34 | local machine = build_machine() 35 | f(machine) 36 | print(" passed") 37 | end 38 | 39 | local RTC_FREQ_DIV = 8192 40 | local EXPECTED_MCYCLE = RTC_FREQ_DIV * 2 + 20 41 | 42 | local function check_state(machine) 43 | assert(machine:read_reg("iflags_H") ~= 0, "machine did not halt") 44 | assert(machine:read_reg("htif_tohost_data") >> 1 == 0, "invalid return code") 45 | assert(machine:read_reg("mcycle") == EXPECTED_MCYCLE, "invalid mcycle") 46 | end 47 | 48 | print("testing mtime interrupt") 49 | 50 | do_test("machine:run should interrupt for mtime", function(machine) 51 | for _ = 1, EXPECTED_MCYCLE do 52 | machine:run(-1) 53 | if machine:read_reg("iflags_H") ~= 0 then 54 | break 55 | end 56 | end 57 | check_state(machine) 58 | end) 59 | 60 | --[[ 61 | do_test("machine:log_step_uarch should interrupt for mtime", function(machine) 62 | for _ = 1, EXPECTED_MCYCLE do 63 | machine:log_step_uarch() 64 | if machine:read_reg("iflags_H") ~= 0 then 65 | break 66 | end 67 | end 68 | check_state(machine) 69 | end) 70 | ]] 71 | 72 | print("passed") 73 | -------------------------------------------------------------------------------- /tests/lua/run-rv64i-arch-test.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua5.4 2 | 3 | -- Copyright Cartesi and individual authors (see AUTHORS) 4 | -- SPDX-License-Identifier: LGPL-3.0-or-later 5 | -- 6 | -- This program is free software: you can redistribute it and/or modify it under 7 | -- the terms of the GNU Lesser General Public License as published by the Free 8 | -- Software Foundation, either version 3 of the License, or (at your option) any 9 | -- later version. 10 | -- 11 | -- This program is distributed in the hope that it will be useful, but WITHOUT ANY 12 | -- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 13 | -- PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 14 | -- 15 | -- You should have received a copy of the GNU Lesser General Public License along 16 | -- with this program (see COPYING). If not, see . 17 | -- 18 | 19 | local cartesi = require("cartesi") 20 | 21 | if #arg ~= 2 then 22 | io.stderr:write(string.format( 23 | [=[ 24 | Usage: 25 | 26 | %s 27 | 28 | where: 29 | 30 | name of file containing the image of microemulator RAM. 31 | 32 | 33 | name of file to write test signature results 34 | ]=], 35 | arg[0] 36 | )) 37 | os.exit(1) 38 | end 39 | 40 | local uarch_ram_image_filename = arg[1] 41 | local output_signature_file = arg[2] 42 | local uarch_ram_start = cartesi.UARCH_RAM_START_ADDRESS 43 | 44 | local config = { 45 | uarch = { 46 | ram = { 47 | image_filename = uarch_ram_image_filename, 48 | }, 49 | }, 50 | processor = {}, 51 | ram = { length = 0x1000 }, 52 | } 53 | 54 | local machine = assert(cartesi.machine(config)) 55 | 56 | -- run microarchitecture 57 | machine:run_uarch() 58 | 59 | -- extract test result signature from microarchitecture RAM 60 | local mem = machine:read_memory(uarch_ram_start, cartesi.UARCH_RAM_LENGTH) 61 | local _, e1 = string.find(mem, "BEGIN_CTSI_SIGNATURE____") 62 | local s2, _ = string.find(mem, "END_CTSI_SIGNATURE______") 63 | local sig = string.sub(mem, e1 + 1, s2 - 1) 64 | 65 | -- write signature to file, in the format expected by the arch test script 66 | local fd = assert(io.open(output_signature_file, "w")) 67 | for i = 1, #sig, 4 do 68 | local w = string.reverse(string.sub(sig, i, i + 3)) 69 | for j = 1, 4, 1 do 70 | local b = string.byte(string.sub(w, j)) 71 | fd:write(string.format("%02x", b)) 72 | end 73 | fd:write("\n") 74 | end 75 | 76 | -- pad fill output file 77 | if (#sig % 16) ~= 0 then 78 | fd:write("00000000\n00000000\n") 79 | end 80 | 81 | fd:close() 82 | -------------------------------------------------------------------------------- /tests/machine/.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | .DS_Store 3 | .vscode 4 | 5 | -------------------------------------------------------------------------------- /tests/machine/AUTHORS: -------------------------------------------------------------------------------- 1 | Alexander Mikhalevich 2 | Colin Steil 3 | Danilo Tuler 4 | Diego Nehab 5 | Eduardo Barthel 6 | Felipe Argento 7 | Gabriel de Quadros Ligneul 8 | Marcelo Politzer 9 | Marcos Pernambuco Motta 10 | Victor Fusco 11 | -------------------------------------------------------------------------------- /tests/machine/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Cartesi 2 | 3 | Thank you for your interest in Cartesi! We highly appreciate even the smallest of fixes or additions to our project. 4 | 5 | Make sure to review our [Contributing License Agreement](https://forms.gle/k3E9ZNkZY6Vy3mkK9), 6 | sign and send it to info@cartesi.io with the title of "CLA Signed" before taking part in the project. We are happy to automate 7 | this for you via DocuSign upon request in the Google Form as well. 8 | 9 | ## Basic Contributing Guidelines 10 | 11 | We use the same guidelines for contributing code to any of our repositories, any developers wanting to contribute to Cartesi must create pull requests. This process is described in the [GitHub documentation](https://help.github.com/en/articles/creating-a-pull-request). Each pull request should be started against the master branch in the respective Cartesi repository. After a pull request is submitted the Cartesi team will review the submission and give feedback via the comments section of the pull request. After the submission is reviewed and approved, it will be merged into the master branch of the source. 12 | 13 | Please note the below! We appreciate everyone following the guidelines. 14 | 15 | * No --force pushes or modifying the Git history in any way; 16 | * Use non-master branches, using a short meaningful description, with words separated by dash (e.g. 'fix-this-bug'); 17 | * All modifications must be made in a pull-request to solicit feedback from other contributors. 18 | 19 | ## Get in Touch 20 | 21 | When contributing in a deeper manner to this repository, please first discuss the change you wish to make via our 22 | [Discord channel here](https://discord.gg/cartesi), or contact us at info@cartesi.io email before working on the change. 23 | -------------------------------------------------------------------------------- /tests/machine/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright Cartesi and individual authors (see AUTHORS) 2 | # SPDX-License-Identifier: Apache-2.0 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | PREFIX = /opt/cartesi 18 | INSTALLDIR = $(PREFIX)/tests 19 | 20 | SRCDIR := $(abspath src) 21 | BUILDDIR ?= $(abspath build) 22 | SRCCLEAN := $(addsuffix .clean,$(SRCDIR)) 23 | 24 | RISCV_PREFIX = riscv64-unknown-elf- 25 | RVCC = $(RISCV_PREFIX)gcc 26 | RVCXX = $(RISCV_PREFIX)g++ 27 | RVCOPY = $(RISCV_PREFIX)objcopy 28 | RVDUMP = $(RISCV_PREFIX)objdump 29 | 30 | all: $(SRCDIR) 31 | 32 | clean: $(SRCCLEAN) 33 | 34 | depclean: clean 35 | rm -rf $(BUILDDIR) 36 | $(MAKE) -C $@ clean 37 | 38 | distclean: clean 39 | rm -rf $(BUILDDIR) 40 | 41 | $(SRCCLEAN): %.clean: 42 | $(MAKE) -C $* clean 43 | 44 | $(BUILDDIR): 45 | mkdir -p $(BUILDDIR) 46 | 47 | $(SRCDIR): $(BUILDDIR) 48 | $(MAKE) -C $@ RISCV_PREFIX=$(RISCV_PREFIX) $(TARGET) 49 | 50 | install: 51 | mkdir -p $(INSTALLDIR) 52 | cp -a $(BUILDDIR)/*.bin $(BUILDDIR)/*.dump $(BUILDDIR)/*.elf $(INSTALLDIR) 53 | 54 | 55 | .PHONY: all clean distclean $(SRCDIR) $(SRCCLEAN) $(DEPCLEAN) 56 | -------------------------------------------------------------------------------- /tests/machine/README.md: -------------------------------------------------------------------------------- 1 | # Cartesi Machine Tests 2 | 3 | The Cartesi Machine Tests is a repository containing RISC-V testing code. 4 | 5 | ## Getting Started 6 | 7 | ### Requirements 8 | 9 | - RISCV64 C/C++ Compiler with support for C++20 (tested with GCC >= 8+). 10 | - GNU Make >= 3.81 11 | 12 | ### Build 13 | 14 | ```bash 15 | $ make toolchain-env 16 | [toolchain-env]$ make uarch 17 | [toolchain-env]$ make 18 | [toolchain-env]$ exit 19 | $ make INSTALLDIR=/my/path install 20 | $ make INSTALLDIR=/my/path uarch-install 21 | ``` 22 | 23 | Cleaning: 24 | 25 | ```bash 26 | [toolchain-env]$ make depclean 27 | [toolchain-env]$ make clean 28 | ``` 29 | 30 | ## Usage 31 | 32 | TODO 33 | 34 | ## Contributing 35 | 36 | Thank you for your interest in Cartesi! Head over to our [Contributing Guidelines](CONTRIBUTING.md) for instructions on how to sign our Contributors Agreement and get started with Cartesi! 37 | 38 | Please note we have a [Code of Conduct](CODE_OF_CONDUCT.md), please follow it in all your interactions with the project. 39 | 40 | ## Authors 41 | 42 | * *Diego Nehab* 43 | * *Victor Fusco* 44 | 45 | ## License 46 | 47 | The machine-tests repository and all contributions are licensed under 48 | [APACHE 2.0](https://www.apache.org/licenses/LICENSE-2.0). Please review our [LICENSE](LICENSE) file. 49 | -------------------------------------------------------------------------------- /tests/machine/src/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright Cartesi and individual authors (see AUTHORS) 2 | # SPDX-License-Identifier: Apache-2.0 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | BUILDDIR ?= $(abspath ../build) 18 | RISCV_TESTS_DIR ?= $(abspath ../../../third-party/riscv-tests) 19 | 20 | RISCV_PREFIX = riscv64-unknown-elf- 21 | CC = $(RISCV_PREFIX)gcc 22 | CXX = $(RISCV_PREFIX)g++ 23 | OBJCOPY = $(RISCV_PREFIX)objcopy 24 | OBJDUMP = $(RISCV_PREFIX)objdump 25 | 26 | INCS=\ 27 | -I$(BUILD_DIR)/include \ 28 | -I$(RISCV_TESTS_DIR)/env/p \ 29 | -I$(RISCV_TESTS_DIR)/env \ 30 | -I$(RISCV_TESTS_DIR)/isa/macros/scalar \ 31 | -I$(abspath ../../../src) 32 | 33 | CFLAGS=-g -march=rv64g -mabi=lp64d -static -mcmodel=medany -fvisibility=hidden -ffreestanding -nostdlib -nostartfiles $(INCS) 34 | CXXFLAGS=-fno-exceptions $(CFLAGS) 35 | 36 | SRCS := $(wildcard *.S) 37 | TMPS := $(SRCS:.S=.elf) 38 | BINS := $(TMPS:%.elf=$(BUILDDIR)/%.bin) 39 | DUMPS := $(TMPS:%.elf=$(BUILDDIR)/%.dump) 40 | 41 | .DEFAULT_GOAL := all 42 | 43 | $(BUILDDIR)/%.bin: $(BUILDDIR)/%.elf 44 | $(OBJCOPY) -S -O binary $< $@ 45 | 46 | $(BUILDDIR)/%.dump: $(BUILDDIR)/%.elf 47 | $(OBJDUMP) -d $< > $@ 48 | 49 | $(BUILDDIR): 50 | mkdir -p $(BUILDDIR) 51 | 52 | # assembly 53 | $(BUILDDIR)/%.elf: %.S | $(BUILDDIR) 54 | $(CC) $(CFLAGS) -Tlink.ld -o $@ $< 55 | 56 | $(BUILDDIR)/bootstrap.elf: bootstrap.S $(BUILDDIR) 57 | $(CC) $(CFLAGS) -Tbootstrap.ld -o $@ $< 58 | 59 | .PRECIOUS: $(BUILDDIR)/%.elf 60 | .PHONY: all clean copy uarch uarch-clean uarch-install 61 | all: $(BINS) $(DUMPS) 62 | 63 | uarch: 64 | make -C uarch 65 | 66 | uarch-install: 67 | make -C uarch install INSTALLDIR=$(INSTALLDIR) 68 | 69 | uarch-clean: 70 | make -C uarch clean 71 | 72 | clean: 73 | $(RM) -r $(BUILDDIR)/*.elf $(BUILDDIR)/*.bin $(BUILDDIR)/*.dump 74 | -------------------------------------------------------------------------------- /tests/machine/src/amo.S: -------------------------------------------------------------------------------- 1 | /* Copyright Cartesi and individual authors (see AUTHORS) 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | /* 19 | Tests to improve code coverage of AMO instructions. 20 | */ 21 | 22 | #include "riscv_test.h" 23 | #include "test_macros.h" 24 | 25 | RVTEST_RV64M 26 | RVTEST_CODE_BEGIN 27 | # amominu.w 28 | TEST_CASE(1, a4, 0xfffffffffffff800, \ 29 | li a0, 0xfffffffffffff800; \ 30 | li a1, 0xffffffff80000000; \ 31 | la a3, amo_operand; \ 32 | sw a0, 0(a3); \ 33 | amominu.w a4, a1, 0(a3); \ 34 | ) 35 | TEST_CASE(2, a5, 0xffffffff80000000, lw a5, 0(a3)) 36 | 37 | # amominu.d 38 | TEST_CASE(3, a4, 0xfffffffffffff800, \ 39 | li a0, 0xfffffffffffff800; \ 40 | li a1, 0xffffffff80000000; \ 41 | la a3, amo_operand; \ 42 | sd a0, 0(a3); \ 43 | amominu.d a4, a1, 0(a3); \ 44 | ) 45 | TEST_CASE(4, a5, 0xffffffff80000000, ld a5, 0(a3)) 46 | 47 | # amomaxu.w 48 | TEST_CASE(5, a4, 0xfffffffffffff800, \ 49 | li a0, 0xfffffffffffff800; \ 50 | li a1, 0xffffffff80000000; \ 51 | la a3, amo_operand; \ 52 | sw a0, 0(a3); \ 53 | amomaxu.w a4, a1, 0(a3); \ 54 | ) 55 | TEST_CASE(6, a5, 0xfffffffffffff800, lw a5, 0(a3)) 56 | 57 | # amomaxu.d 58 | TEST_CASE(7, a4, 0xfffffffffffff800, \ 59 | li a0, 0xfffffffffffff800; \ 60 | li a1, 0xffffffff80000000; \ 61 | la a3, amo_operand; \ 62 | sd a0, 0(a3); \ 63 | amomaxu.d a4, a1, 0(a3); \ 64 | ) 65 | TEST_CASE(8, a5, 0xfffffffffffff800, ld a5, 0(a3)) 66 | 67 | # amomax.w 68 | TEST_CASE(9, a4, 0xfffffffffffff800, \ 69 | li a0, 0xfffffffffffff800; \ 70 | li a1, 0xffffffff80000000; \ 71 | la a3, amo_operand; \ 72 | sw a0, 0(a3); \ 73 | amomax.w a4, a1, 0(a3); \ 74 | ) 75 | TEST_CASE(10, a5, 0xfffffffffffff800, lw a5, 0(a3)) 76 | 77 | # amomax.d 78 | TEST_CASE(11, a4, 0xfffffffffffff800, \ 79 | li a0, 0xfffffffffffff800; \ 80 | li a1, 0xffffffff80000000; \ 81 | la a3, amo_operand; \ 82 | sd a0, 0(a3); \ 83 | amomax.d a4, a1, 0(a3); \ 84 | ) 85 | TEST_CASE(12, a5, 0xfffffffffffff800, ld a5, 0(a3)) 86 | 87 | TEST_PASSFAIL 88 | 89 | RVTEST_CODE_END 90 | 91 | .data 92 | RVTEST_DATA_BEGIN 93 | 94 | TEST_DATA 95 | 96 | RVTEST_DATA_END 97 | 98 | .bss 99 | .align 3 100 | amo_operand: 101 | .dword 0 102 | -------------------------------------------------------------------------------- /tests/machine/src/bootstrap.S: -------------------------------------------------------------------------------- 1 | /* Copyright Cartesi and individual authors (see AUTHORS) 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #include 19 | 20 | .section .text.init; 21 | .align 2; 22 | .global _start; 23 | _start: 24 | 25 | li t0, PMA_RAM_START_DEF; // converted to 2 instructions addiw and slli 26 | csrr a0, mhartid; 27 | jr t0; 28 | -------------------------------------------------------------------------------- /tests/machine/src/bootstrap.ld: -------------------------------------------------------------------------------- 1 | /* Copyright Cartesi and individual authors (see AUTHORS) 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | OUTPUT_ARCH( "riscv" ) 19 | ENTRY(_start) 20 | 21 | SECTIONS 22 | { 23 | . = 0x1000; 24 | .text.init : { *(.text.init) } 25 | . = ALIGN(0x1000); 26 | .text : { *(.text) } 27 | . = ALIGN(0x1000); 28 | .data : { *(.data) } 29 | .bss : { *(.bss) } 30 | _end = .; 31 | } 32 | -------------------------------------------------------------------------------- /tests/machine/src/ebreak.S: -------------------------------------------------------------------------------- 1 | /* Copyright Cartesi and individual authors (see AUTHORS) 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #include 19 | 20 | // Uses HTIF to exit the emulator with exit code in an immediate 21 | #define exit_imm(imm) \ 22 | li gp, imm; \ 23 | j exit; 24 | 25 | // Section with code 26 | .section .text.init 27 | .align 2; 28 | .global _start; 29 | _start: 30 | // Set the exception handler to trap 31 | // This is just in case an exception happens 32 | la t0, trap; 33 | csrw mtvec, t0; 34 | do_break: 35 | ebreak 36 | j fail 37 | 38 | // catch exception and exit 39 | trap: 40 | li t1, 0x3 // MCAUSE_BREAKPOINT 41 | csrr t0, mcause 42 | bne t0, t1, fail 43 | la t1, do_break 44 | csrr t0, mtval 45 | // software breakpoint exceptions write PC to xtval 46 | bne t0, t1, fail 47 | j exit 48 | 49 | fail: 50 | exit_imm(1); 51 | 52 | // Exits via HTIF using gp content as the exit code 53 | exit: 54 | // HTIF exits with dev = cmd = 0 and a payload with lsb set. 55 | // the exit code is taken from payload >> 2 56 | slli gp, gp, 16; 57 | srli gp, gp, 15; 58 | ori gp, gp, 1; 59 | 1: 60 | li t0, PMA_HTIF_START_DEF 61 | sd gp, 0(t0); 62 | j 1b; // Should not be necessary 63 | 64 | -------------------------------------------------------------------------------- /tests/machine/src/htif_console.S: -------------------------------------------------------------------------------- 1 | /* Copyright Cartesi and individual authors (see AUTHORS) 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "htif_util.h" 18 | 19 | // This program Exercises HTIF console getchar and putchar. 20 | 21 | // @a0 - getchar() 22 | // @a1 - enabled:0, disabled:-1 23 | #define check_console_getchar(x) \ 24 | li t0, x; \ 25 | or t0, t0, a1; \ 26 | bne t0, a0, ack_failed; 27 | 28 | // Section with code 29 | .section .text.init 30 | .align 2; 31 | .global _start; 32 | _start: 33 | // Set the exception handler to trap 34 | // This is just in case an exception happens 35 | la t0, trap; 36 | csrw mtvec, t0; 37 | 38 | jal is_console_getchar_enabled; 39 | add a1, a0, -1; 40 | 41 | call wait_0x400; /* wait for IO to start working */ 42 | 43 | // Test console getchar 44 | htif_console_getchar(); 45 | check_console_getchar('C'); 46 | 47 | htif_console_getchar(); 48 | check_console_getchar('T'); 49 | 50 | htif_console_getchar(); 51 | check_console_getchar('S'); 52 | 53 | htif_console_getchar(); 54 | check_console_getchar('I'); 55 | 56 | // Test console putchar 57 | htif_console_putchar('C'); 58 | htif_console_putchar('T'); 59 | htif_console_putchar('S'); 60 | htif_console_putchar('I'); 61 | 62 | htif_exit(42); 63 | 64 | 65 | wait_0x400: 66 | li a0, 0x400; 67 | wait: 68 | addi a0, a0, -1; 69 | bne zero, a0, wait; 70 | ret 71 | 72 | is_console_getchar_enabled: 73 | li t0, PMA_HTIF_START_DEF; \ 74 | ld t0, O_ICONSOLE (t0); \ 75 | srli t0, t0, HTIF_CONSOLE_CMD_GETCHAR_DEF; \ 76 | andi a0, t0, 1; 77 | ret 78 | 79 | // If HTIF device command is not acked, exit with 2 80 | ack_failed: 81 | htif_exit(2); 82 | 83 | // catch exception and exit 84 | trap: 85 | htif_exit(1); 86 | -------------------------------------------------------------------------------- /tests/machine/src/htif_util.h: -------------------------------------------------------------------------------- 1 | #ifndef HTIF_UTIL_H 2 | #define HTIF_UTIL_H 3 | #include 4 | #include 5 | 6 | /* from: https://www.cartesi.io/en/docs/machine/target/architecture/ 7 | * 1. start by writing 0 to fromhost 8 | * 2. write the request to tohost (from a0) 9 | * 3. read the response from fromhost (into a0) 10 | * 11 | * with the following memory layout: 12 | * +------+----------+ 13 | * | 0x00 | tohost | 14 | * | 0x08 | fromhost | 15 | * | 0x10 | ihalt | 16 | * | 0x18 | iconsole | 17 | * | 0x20 | iyield | 18 | * +------+----------+ 19 | * 20 | * htif register offsets: */ 21 | #define O_TOHOST 0x00 22 | #define O_FROMHOST 0x08 23 | #define O_IHALT 0x10 24 | #define O_ICONSOLE 0x18 25 | #define O_IYIELD 0x20 26 | 27 | // Construct a HTIF constant value from `dev`, `cmd` and `data` that can be used 28 | // in conjunction with htif_call. 29 | #define htif_const(dev, cmd, data) \ 30 | (((dev) << 56UL) | (((cmd) & 0xff) << 48UL) | (((data) & 0xffffffffffUL))) 31 | 32 | // Construct a htif_const `data` constant from `reason` and `data` fields. 33 | #define htif_yield_const(reason, data) \ 34 | ((((reason) & 0xffffUL) << 32UL) | (((data) & 0xffffffffUL))) 35 | 36 | // Issue a HTIF call with `ireg` as the input, place the output in `oreg`. 37 | // NOTE: `base` will be used as scratch register 38 | #define htif_call(base, ireg, oreg) \ 39 | li base, PMA_HTIF_START_DEF; \ 40 | sd zero, O_FROMHOST (base); \ 41 | sd ireg, O_TOHOST (base); \ 42 | ld oreg, O_FROMHOST (base) 43 | 44 | // Issue a HTIF yield call with `cmd`, `reason` and `data` as a constants. 45 | // Result in a0 46 | #define htif_yield(cmd, reason, data) \ 47 | li t1, htif_const(HTIF_DEV_YIELD_DEF, cmd, htif_yield_const(reason, data)); \ 48 | htif_call(t0, t1, a0) 49 | 50 | // Issue a HTIF exit call with `retval` as a constant. 51 | #define htif_exit(retval) \ 52 | li t1, htif_const(HTIF_DEV_HALT_DEF, HTIF_HALT_CMD_HALT_DEF, ((retval) << 1) | 0x01); \ 53 | htif_call(t0, t1, a0) 54 | 55 | // Issue a HTIF putchar with `data` as a constant. 56 | #define htif_console_putchar(data) \ 57 | li t1, htif_const(HTIF_DEV_CONSOLE_DEF, HTIF_CONSOLE_CMD_PUTCHAR_DEF, data); \ 58 | htif_call(t0, t1, a0) 59 | 60 | // Issue a HTIF getchar 61 | // Result in a0 62 | #define htif_console_getchar() \ 63 | li t1, htif_const(HTIF_DEV_CONSOLE_DEF, HTIF_CONSOLE_CMD_GETCHAR_DEF, 0); \ 64 | htif_call(t0, t1, a0); \ 65 | andi a0, a0, 0xFF; \ 66 | addi a0, a0, -1 67 | 68 | #endif /* HTIF_UTIL_H */ 69 | -------------------------------------------------------------------------------- /tests/machine/src/link.ld: -------------------------------------------------------------------------------- 1 | OUTPUT_ARCH( "riscv" ) 2 | ENTRY(_start) 3 | 4 | SECTIONS 5 | { 6 | .tohost 0x40008000 (NOLOAD): { *(.tohost) } 7 | . = 0x80000000; 8 | .text.init : { *(.text.init) } 9 | . = ALIGN(0x1000); 10 | .text : { *(.text) } 11 | . = ALIGN(0x1000); 12 | .data : { *(.data) } 13 | .bss : { *(.bss) } 14 | _end = .; 15 | } 16 | 17 | -------------------------------------------------------------------------------- /tests/machine/src/lrsc_semantics.S: -------------------------------------------------------------------------------- 1 | /* Copyright Cartesi and individual authors (see AUTHORS) 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #include 19 | 20 | #define exit_imm(imm) \ 21 | li gp, imm; \ 22 | j exit; 23 | 24 | // Section with code 25 | .section .text.init 26 | .align 2; 27 | .global _start; 28 | _start: 29 | // Set the trap handler 30 | la t0, fail; 31 | csrw mtvec, t0; 32 | 33 | la a0, foo; // load address of foo into a0 34 | la a1, boo; // load address of foo into a0 35 | li a2, 0xc0ffee; // save dummy value for testing purposes 36 | 37 | // Test valid LR/SC 38 | lr.d t0, (a0); // load and reserve a0 39 | sc.d t1, a2, (a0); // store a2 into a0 40 | bnez t0, fail; // t0 should be 0, that is, the initial value of 'foo' 41 | bnez t1, fail; // t1 should be 1, that is, SC success 42 | ld t0, (a0); // loads 'foo' value into t0 43 | bne t0, a2, fail; // t0 should be equal to a2 44 | 45 | // Attempt to reuse old LR 46 | sc.d t1, a0, (a0); // attempt to store a0 into a0 (it should fail) 47 | beqz t1, fail; // t1 should be 1, that is, SC failure 48 | ld t0, (a0); // loads 'foo' value into t0 49 | bne t0, a2, fail; // t0 should be equal to a2 50 | 51 | // Test SC reservation clear 52 | lr.d t0, (a0); 53 | sc.d zero, zero, (a1); // invalid SC just to clear reservation 54 | sc.d t0, a0, (a0); // attempt to store a0 into a0 (it should fail) 55 | ld t0, (a0); // loads 'foo' value into t0 56 | bne t0, a2, fail; // t0 should be equal to a2 57 | 58 | exit_imm(0); 59 | 60 | fail: 61 | exit_imm(1); 62 | 63 | // Exits via HTIF using gp content as the exit code 64 | exit: 65 | // HTIF exits with dev = cmd = 0 and a payload with lsb set. 66 | // the exit code is taken from payload >> 2 67 | slli gp, gp, 16; 68 | srli gp, gp, 15; 69 | ori gp, gp, 1; 70 | 1: 71 | li t0, PMA_HTIF_START_DEF 72 | sd gp, 0(t0); 73 | j 1b; // Should not be necessary 74 | 75 | .data 76 | .align 3; foo: .dword 0 77 | .align 3; boo: .dword 0 -------------------------------------------------------------------------------- /tests/machine/src/mcycle_overflow.S: -------------------------------------------------------------------------------- 1 | /* Copyright Cartesi and individual authors (see AUTHORS) 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #include 19 | 20 | // Uses HTIF to exit the emulator with exit code in an immediate 21 | #define exit_imm(imm) \ 22 | li gp, imm; \ 23 | j exit; 24 | 25 | // Section with code 26 | .section .text.init 27 | .align 2; 28 | .global _start; 29 | _start: 30 | // Set the exception handler to trap 31 | // This is just in case an exception happens 32 | la t0, trap; 33 | csrw mtvec, t0; 34 | 35 | // Run a few WFI instructions to catch a possible integer overflow in 36 | // cartesi-machine's mcycle 37 | wfi 38 | wfi 39 | wfi 40 | wfi 41 | wfi 42 | wfi 43 | wfi 44 | wfi 45 | wfi 46 | wfi 47 | exit_imm(0); 48 | 49 | // catch exception and exit 50 | trap: 51 | exit_imm(1); 52 | 53 | // Exits via HTIF using gp content as the exit code 54 | exit: 55 | // HTIF exits with dev = cmd = 0 and a payload with lsb set. 56 | // the exit code is taken from payload >> 2 57 | slli gp, gp, 16; 58 | srli gp, gp, 15; 59 | ori gp, gp, 1; 60 | 1: 61 | li t0, PMA_HTIF_START_DEF 62 | sd gp, 0(t0); 63 | j 1b; // Should not be necessary 64 | 65 | -------------------------------------------------------------------------------- /tests/machine/src/mcycle_write.S: -------------------------------------------------------------------------------- 1 | /* Copyright Cartesi and individual authors (see AUTHORS) 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #include 19 | 20 | #define exit_imm(imm) \ 21 | li gp, imm; \ 22 | j exit; 23 | 24 | // Section with code 25 | .section .text.init 26 | .align 2; 27 | .global _start; 28 | _start: 29 | // Set mcycle trap handler 30 | la t0, mcycle_trap; 31 | csrw mtvec, t0; 32 | 33 | // Test writing to mcycle SC 34 | li a0, 0; 35 | li t0, 0xffffffffffffffff; 36 | // Attempt to clear mcycle, this will raise an exception because mcycle is not writeable in the emulator 37 | csrrc a0, mcycle, t0; 38 | exit_imm(1); 39 | 40 | mcycle_trap: 41 | bnez a0, fail; // a0 should be 0 (as it was) 42 | exit_imm(0); 43 | 44 | fail: 45 | exit_imm(1); 46 | 47 | // Exits via HTIF using gp content as the exit code 48 | exit: 49 | // HTIF exits with dev = cmd = 0 and a payload with lsb set. 50 | // the exit code is taken from payload >> 2 51 | slli gp, gp, 16; 52 | srli gp, gp, 15; 53 | ori gp, gp, 1; 54 | 1: 55 | li t0, PMA_HTIF_START_DEF 56 | sd gp, 0(t0); 57 | j 1b; // Should not be necessary 58 | -------------------------------------------------------------------------------- /tests/machine/src/mtime_interrupt.S: -------------------------------------------------------------------------------- 1 | /* Copyright Cartesi and individual authors (see AUTHORS) 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | // This test case sets up a mtimer interrupt for MTIME=10 and then waits in a 19 | // WFI loop for this interrupt to happen. When the interrupt occurs, the test 20 | // checks whether the cause CSR is set properly. 21 | 22 | #include 23 | 24 | // Uses HTIF to exit the emulator with exit code in an immediate 25 | #define exit_imm(imm) \ 26 | li gp, imm; \ 27 | j exit; 28 | 29 | // MTIMECMP is a CLINT register that is mapped to RAM 30 | #define MTIMECMP_ADDR (PMA_CLINT_START_DEF + 0x4000) 31 | 32 | #define MTIE_MASK (1<<7) 33 | #define MIE_MASK (1<<3) 34 | 35 | #define MCAUSE_INT_BIT 63 36 | #define MCAUSE_MTIP_CODE 7 37 | #define MCAUSE_MTIP ((1<> 2 89 | slli gp, gp, 16; 90 | srli gp, gp, 15; 91 | ori gp, gp, 1; 92 | 1: 93 | li t0, PMA_HTIF_START_DEF 94 | sd gp, 0(t0); 95 | j 1b; // Should not be necessary 96 | -------------------------------------------------------------------------------- /tests/machine/src/pte_reserved_exception.S: -------------------------------------------------------------------------------- 1 | /* Copyright Cartesi and individual authors (see AUTHORS) 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #include 19 | 20 | #define MSTATUS_MPP 0x1800 21 | #define CAUSE_USER_ECALL 0x8 22 | #define CAUSE_INSTRUCTION_PAGE_FAULT 0xc 23 | #define PTE_FLAGS 0x3f // V | R | W | X | G | U 24 | #define PTE_RESERVED 4 // right shift to the PTE reserved field 25 | #define SATP_SV39 0x8000000000000000 26 | 27 | // Uses HTIF to exit the emulator with exit code in an immediate 28 | #define exit_imm(imm) \ 29 | li gp, imm; \ 30 | j exit; 31 | 32 | .section .text.init 33 | .align 2; 34 | .global _start; 35 | _start: 36 | 37 | // Set the exception handler to trap 38 | // This is just in case an exception happens 39 | la t0, trap; 40 | csrw mtvec, t0; 41 | 42 | // Set up a page table entry that maps 0x0... to 0x8... 43 | la t0, page_table 44 | srl t0, t0, 12 45 | li t1, SATP_SV39 46 | or t0, t0, t1 47 | csrw satp, t0 48 | 49 | // Set user mode 50 | csrr t1, mstatus 51 | li t0, ~MSTATUS_MPP 52 | and t1, t0, t1 53 | csrw mstatus, t1 54 | 55 | la t0, (user - 0x80000000) 56 | csrw mepc, t0 57 | 58 | mret 59 | 60 | user: 61 | ecall 62 | 63 | // catch exception and exit 64 | trap: 65 | csrr t0, mcause 66 | // page fault because reserved PTE bit is set 67 | li t1, CAUSE_INSTRUCTION_PAGE_FAULT 68 | beq t0, t1, success 69 | exit_imm(1); 70 | 71 | success: 72 | exit_imm(0); 73 | 74 | // Exits via HTIF using gp content as the exit code 75 | exit: 76 | // HTIF exits with dev = cmd = 0 and a payload with lsb set. 77 | // the exit code is taken from payload >> 2 78 | slli gp, gp, 16; 79 | srli gp, gp, 15; 80 | ori gp, gp, 1; 81 | 1: 82 | li t0, PMA_HTIF_START_DEF 83 | sd gp, 0(t0); 84 | j 1b; // Should not be necessary 85 | 86 | .data 87 | .align 12 88 | .skip 176 89 | page_table: 90 | .word ((0x80000000 >> 2) | PTE_FLAGS) 91 | .word (0x80000000 >> PTE_RESERVED) 92 | -------------------------------------------------------------------------------- /tests/machine/src/sd_pma_overflow.S: -------------------------------------------------------------------------------- 1 | /* Copyright Cartesi and individual authors (see AUTHORS) 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #include 19 | 20 | // Uses HTIF to exit the emulator with exit code in an immediate 21 | #define exit_imm(imm) \ 22 | li gp, imm; \ 23 | j exit; 24 | 25 | // Section with code 26 | .section .text.init 27 | .align 2; 28 | .global _start; 29 | _start: 30 | // Set the exception handler to trap 31 | // This is just in case an exception happens 32 | la t0, trap; 33 | csrw mtvec, t0; 34 | 35 | // Test SD PMA address overflow 36 | // sp starts at zero 37 | // this should trigger and exception 38 | addi sp,sp,-16; 39 | sd s0,8(sp); 40 | 41 | // fallback if exception was not triggered 42 | exit_imm(1); 43 | 44 | // catch exception and exit 45 | trap: 46 | exit_imm(0); 47 | 48 | // Exits via HTIF using gp content as the exit code 49 | exit: 50 | // HTIF exits with dev = cmd = 0 and a payload with lsb set. 51 | // the exit code is taken from payload >> 2 52 | slli gp, gp, 16; 53 | srli gp, gp, 15; 54 | ori gp, gp, 1; 55 | 1: 56 | li t0, PMA_HTIF_START_DEF 57 | sd gp, 0(t0); 58 | j 1b; // Should not be necessary 59 | -------------------------------------------------------------------------------- /tests/machine/src/version_check.S: -------------------------------------------------------------------------------- 1 | /* Copyright Cartesi and individual authors (see AUTHORS) 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #include 19 | 20 | // Uses HTIF to exit the emulator with exit code in an immediate 21 | #define exit_imm(imm) \ 22 | li gp, imm; \ 23 | j exit; 24 | 25 | #define CARTESI_MVENDORID 0x6361727465736920 26 | #define CARTESI_MARCHID_MIN 0x10 // Minimum marchid 27 | #define CARTESI_MIMPID_MIN 0x1 // Minimum mimpid 28 | 29 | // Section with code 30 | .section .text.init 31 | .align 2; 32 | .global _start; 33 | _start: 34 | // Set the exception handler to trap 35 | // This is just in case an exception happens 36 | la t0, trap; 37 | csrw mtvec, t0; 38 | 39 | li t0, CARTESI_MVENDORID; 40 | csrr t1, mvendorid; 41 | bne t0, t1, error; 42 | 43 | li t0, CARTESI_MARCHID_MIN; 44 | csrr t1, marchid; 45 | bgt t0, t1, error; 46 | 47 | li t0, CARTESI_MIMPID_MIN; 48 | csrr t1, mimpid; 49 | bgt t0, t1, error; 50 | 51 | // Exit with success 52 | exit_imm(0); 53 | 54 | // on error halt with 1 55 | error: 56 | exit_imm(1); 57 | 58 | // catch exception and exit with 2 59 | trap: 60 | exit_imm(2); 61 | 62 | // Exits via HTIF using gp content as the exit code 63 | exit: 64 | // HTIF exits with dev = cmd = 0 and a payload with lsb set. 65 | // the exit code is taken from payload >> 2 66 | slli gp, gp, 16; 67 | srli gp, gp, 15; 68 | ori gp, gp, 1; 69 | 1: 70 | li t0, PMA_HTIF_START_DEF 71 | sd gp, 0(t0); 72 | j 1b; // Should not be necessary 73 | -------------------------------------------------------------------------------- /tests/misc/.gitignore: -------------------------------------------------------------------------------- 1 | test-machine-c-api 2 | test-merkle-tree-hash 3 | compile_flags.txt 4 | -------------------------------------------------------------------------------- /tests/scripts/collect-machine-tests-logs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright Cartesi and individual authors (see AUTHORS) 4 | # SPDX-License-Identifier: LGPL-3.0-or-later 5 | # 6 | # This program is free software: you can redistribute it and/or modify it under 7 | # the terms of the GNU Lesser General Public License as published by the Free 8 | # Software Foundation, either version 3 of the License, or (at your option) any 9 | # later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, but WITHOUT ANY 12 | # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 13 | # PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License along 16 | # with this program (see COPYING). If not, see . 17 | # 18 | 19 | if [ "$#" -ne 2 ]; then 20 | echo $0 " " 21 | exit 1; 22 | fi 23 | 24 | set -e 25 | 26 | test_path=$1 27 | shift 28 | output_path=$1 29 | shift 30 | 31 | task() { 32 | local f=$1 33 | local b=${output_path}/$(basename $f .bin).json 34 | echo running $f 35 | ./cartesi-machine.lua --no-root-backing --ram-image=$f --memory-size=128 --json-steps=$b --batch 36 | echo compressing $b 37 | brotli -j $b 38 | } 39 | 40 | # Default for unknown OS 41 | max_jobs=1 42 | if [[ "$OSTYPE" == "linux-gnu"* ]]; then 43 | max_jobs=$(nproc) 44 | elif [[ "$OSTYPE" == "darwin"* ]]; then 45 | max_jobs=$(sysctl -n hw.ncpu) 46 | fi 47 | 48 | jobs=0; 49 | for f in ${test_path}/rv64*.bin ${test_path}/sd_pma_overflow.bin; do 50 | ((jobs++)) 51 | task "$f" & 52 | # Wait if the number of jobs reaches max_jobs 53 | if ((jobs >= max_jobs)); then 54 | echo waiting 55 | wait -n # Waits for a single job to finish 56 | ((jobs--)) 57 | fi 58 | done 59 | 60 | wait 61 | -------------------------------------------------------------------------------- /tests/scripts/collect-uarch-test-logs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright Cartesi and individual authors (see AUTHORS) 4 | # SPDX-License-Identifier: LGPL-3.0-or-later 5 | # 6 | # This program is free software: you can redistribute it and/or modify it under 7 | # the terms of the GNU Lesser General Public License as published by the Free 8 | # Software Foundation, either version 3 of the License, or (at your option) any 9 | # later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, but WITHOUT ANY 12 | # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 13 | # PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License along 16 | # with this program (see COPYING). If not, see . 17 | # 18 | set -e 19 | mkdir -m 755 -p /tmp/uarch-riscv-tests-json-logs 20 | uarch-riscv-tests --output-dir=/tmp/uarch-riscv-tests-json-logs --create-reset-uarch-log --create-send-cmio-response-log --jobs=$(nproc) json-step-logs 21 | tar -czf uarch-riscv-tests-json-logs.tar.gz -C /tmp uarch-riscv-tests-json-logs 22 | -------------------------------------------------------------------------------- /tests/scripts/run-lua-tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright Cartesi and individual authors (see AUTHORS) 4 | # SPDX-License-Identifier: LGPL-3.0-or-later 5 | # 6 | # This program is free software: you can redistribute it and/or modify it under 7 | # the terms of the GNU Lesser General Public License as published by the Free 8 | # Software Foundation, either version 3 of the License, or (at your option) any 9 | # later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, but WITHOUT ANY 12 | # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 13 | # PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License along 16 | # with this program (see COPYING). If not, see . 17 | # 18 | 19 | set -e 20 | 21 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 22 | 23 | LUA=${1:-lua5.4} 24 | 25 | TEST_LIST=(htif-console.lua htif-cmio.lua htif-yield.lua log-with-mtime-transition.lua machine-bind.lua machine-test.lua mcycle-overflow.lua mtime-interrupt.lua) 26 | 27 | for x in ${TEST_LIST[@]}; do 28 | echo "Running $x" 29 | echo -n 'CTSICTSI' | (bash -c "${LUA} $SCRIPT_DIR/../lua/$x local") || exit 1; 30 | done 31 | -------------------------------------------------------------------------------- /tests/scripts/test-cmio.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright Cartesi and individual authors (see AUTHORS) 4 | # SPDX-License-Identifier: LGPL-3.0-or-later 5 | # 6 | # This program is free software: you can redistribute it and/or modify it under 7 | # the terms of the GNU Lesser General Public License as published by the Free 8 | # Software Foundation, either version 3 of the License, or (at your option) any 9 | # later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, but WITHOUT ANY 12 | # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 13 | # PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License along 16 | # with this program (see COPYING). If not, see . 17 | # 18 | 19 | set -e 20 | 21 | script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 22 | remote_cartesi_machine=$1 23 | cartesi_machine=$2 24 | lua=$3 25 | test_path=${CARTESI_TESTS_PATH} 26 | cmio_path=${CARTESI_CMIO_PATH} 27 | 28 | server_address=127.0.0.1:6010 29 | 30 | tests=( 31 | "$lua $script_dir/../lua/cmio-test.lua jsonrpc --remote-address=$server_address" 32 | ) 33 | 34 | is_server_running () { 35 | echo $cartesi_machine --remote-address=$server_address --remote-health-check 36 | eval $cartesi_machine --remote-address=$server_address --remote-health-check 37 | } 38 | 39 | wait_for_server () { 40 | for i in $(seq 1 10); do 41 | if is_server_running 42 | then 43 | return 0 44 | fi 45 | sleep 1 46 | done 47 | echo "server didn't start" >&2 48 | exit 1 49 | } 50 | 51 | wait_for_shutdown () { 52 | sleep 1 53 | pid=$1 54 | if ps -g $pid > /dev/null; then 55 | kill -- -$pid 56 | echo >&2 57 | echo "FAILED: servers still running after tests" >&2 58 | echo >&2 59 | exit 1 60 | fi 61 | } 62 | 63 | for test_cmd in "${tests[@]}" 64 | do 65 | echo $remote_cartesi_machine --server-address=$server_address 66 | $remote_cartesi_machine --server-address=$server_address & 67 | server_pid=$! 68 | wait_for_server 69 | eval $test_cmd 70 | retcode=$? 71 | wait_for_shutdown $server_pid 72 | if [[ $retcode != 0 ]] 73 | then 74 | exit $retcode 75 | fi 76 | done 77 | 78 | eval "$lua $script_dir/../lua/cmio-test.lua local" 79 | -------------------------------------------------------------------------------- /tests/scripts/test-jsonrpc-server.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright Cartesi and individual authors (see AUTHORS) 4 | # SPDX-License-Identifier: LGPL-3.0-or-later 5 | # 6 | # This program is free software: you can redistribute it and/or modify it under 7 | # the terms of the GNU Lesser General Public License as published by the Free 8 | # Software Foundation, either version 3 of the License, or (at your option) any 9 | # later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, but WITHOUT ANY 12 | # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 13 | # PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public License along 16 | # with this program (see COPYING). If not, see . 17 | # 18 | 19 | set -e 20 | 21 | script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 22 | remote_cartesi_machine=$1 23 | cartesi_machine=$2 24 | cartesi_machine_tests=$3 25 | lua=$4 26 | test_path=${CARTESI_TESTS_PATH} 27 | 28 | server_address=127.0.0.1:6001 29 | 30 | tests=( 31 | "$cartesi_machine_tests --remote-address=$server_address --test-path=\"$test_path\" --test='.*' run" 32 | "$lua $script_dir/../lua/machine-bind.lua jsonrpc --remote-address=$server_address" 33 | "$lua $script_dir/../lua/machine-test.lua jsonrpc --remote-address=$server_address" 34 | "$lua $script_dir/../lua/test-jsonrpc-fork.lua --remote-address=$server_address" 35 | ) 36 | 37 | is_server_running () { 38 | echo $cartesi_machine --remote-address=$server_address --remote-health-check 39 | eval $cartesi_machine --remote-address=$server_address --remote-health-check 40 | } 41 | 42 | wait_for_server () { 43 | for i in $(seq 1 10) 44 | do 45 | if is_server_running 46 | then 47 | return 0 48 | fi 49 | sleep 1 50 | done 51 | echo "server didn't start" >&2 52 | exit 1 53 | } 54 | 55 | wait_for_shutdown () { 56 | pid=$1 57 | sleep 1 58 | if ps -g $pid > /dev/null 59 | then 60 | kill -- -$pid 61 | echo >&2 62 | echo "FAILED: servers still running after tests" >&2 63 | echo >&2 64 | exit 1 65 | fi 66 | } 67 | 68 | for test_cmd in "${tests[@]}" 69 | do 70 | echo $remote_cartesi_machine --server-address=$server_address 71 | $remote_cartesi_machine --server-address=$server_address & 72 | server_pid=$! 73 | wait_for_server 74 | eval $test_cmd 75 | retcode=$? 76 | wait_for_shutdown $server_pid 77 | if [[ $retcode != 0 ]] 78 | then 79 | exit $retcode 80 | fi 81 | done 82 | -------------------------------------------------------------------------------- /tests/scripts/test-save-and-load.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | cartesi_machine=${1:-cartesi-machine} 6 | 7 | mkdir -m 755 -p /tmp/snapshots 8 | bash -c "$cartesi_machine --max-mcycle=0 --store=/tmp/snapshots/save_and_load_test" 9 | bash -c "$cartesi_machine --load=/tmp/snapshots/save_and_load_test" 10 | rm -rf /tmp/snapshots 11 | -------------------------------------------------------------------------------- /tests/scripts/test-yield-and-save.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | cartesi_machine=${1:-cartesi-machine} 6 | snapshot_dir="/tmp/snapshots/yield_and_save_test" 7 | 8 | mkdir -m 755 -p /tmp/snapshots 9 | bash -c "$cartesi_machine --store=$snapshot_dir ioctl-echo-loop --reports=2 --verbose=1" 10 | if [ ! -d "$snapshot_dir" ] || [ ! "$(ls -A $snapshot_dir)" ]; then 11 | echo "yield_and_save_test machine was not saved. Test failed!" 12 | exit 1 13 | fi 14 | rm -rf /tmp/snapshots 15 | -------------------------------------------------------------------------------- /tests/uarch/.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | third_party_build/ 3 | 4 | -------------------------------------------------------------------------------- /tests/uarch/AUTHORS: -------------------------------------------------------------------------------- 1 | Alexander Mikhalevich 2 | Colin Steil 3 | Danilo Tuler 4 | Diego Nehab 5 | Eduardo Barthel 6 | Felipe Argento 7 | Gabriel de Quadros Ligneul 8 | Marcelo Politzer 9 | Marcos Pernambuco Motta 10 | Victor Fusco 11 | -------------------------------------------------------------------------------- /tests/uarch/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Cartesi 2 | 3 | Thank you for your interest in Cartesi! We highly appreciate even the smallest of fixes or additions to our project. 4 | 5 | Make sure to review our [Contributing License Agreement](https://forms.gle/k3E9ZNkZY6Vy3mkK9), 6 | sign and send it to info@cartesi.io with the title of "CLA Signed" before taking part in the project. We are happy to automate 7 | this for you via DocuSign upon request in the Google Form as well. 8 | 9 | ## Basic Contributing Guidelines 10 | 11 | We use the same guidelines for contributing code to any of our repositories, any developers wanting to contribute to Cartesi must create pull requests. This process is described in the [GitHub documentation](https://help.github.com/en/articles/creating-a-pull-request). Each pull request should be started against the master branch in the respective Cartesi repository. After a pull request is submitted the Cartesi team will review the submission and give feedback via the comments section of the pull request. After the submission is reviewed and approved, it will be merged into the master branch of the source. 12 | 13 | Please note the below! We appreciate everyone following the guidelines. 14 | 15 | * No --force pushes or modifying the Git history in any way; 16 | * Use non-master branches, using a short meaningful description, with words separated by dash (e.g. 'fix-this-bug'); 17 | * All modifications must be made in a pull-request to solicit feedback from other contributors. 18 | 19 | ## Get in Touch 20 | 21 | When contributing in a deeper manner to this repository, please first discuss the change you wish to make via our 22 | [Discord channel here](https://discord.gg/cartesi), or contact us at info@cartesi.io email before working on the change. 23 | -------------------------------------------------------------------------------- /tests/uarch/README.md: -------------------------------------------------------------------------------- 1 | # uarch 2 | 3 | Build tests for the Cartesi Machine microarchitecture 4 | -------------------------------------------------------------------------------- /tests/uarch/ebreak.S: -------------------------------------------------------------------------------- 1 | /* Copyright Cartesi and individual authors (see AUTHORS) 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #include "riscv_test.h" 19 | #include "test_macros.h" 20 | 21 | RVTEST_RV64U 22 | RVTEST_CODE_BEGIN 23 | 24 | nop 25 | ebreak 26 | 27 | RVTEST_FAIL // unsupported instruction can't reach this point 28 | 29 | RVTEST_CODE_END 30 | 31 | .data 32 | RVTEST_DATA_BEGIN 33 | TEST_DATA 34 | RVTEST_DATA_END 35 | -------------------------------------------------------------------------------- /tests/uarch/ecall-putchar.S: -------------------------------------------------------------------------------- 1 | /* Copyright Cartesi and individual authors (see AUTHORS) 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #include "riscv_test.h" 19 | #include "test_macros.h" 20 | 21 | RVTEST_RV64U 22 | RVTEST_CODE_BEGIN 23 | 24 | li a7, UARCH_ECALL_FN_PUTCHAR_DEF 25 | li a6, 'X' // char to print 26 | ecall 27 | 28 | RVTEST_PASS 29 | 30 | RVTEST_CODE_END 31 | 32 | .data 33 | RVTEST_DATA_BEGIN 34 | TEST_DATA 35 | RVTEST_DATA_END 36 | -------------------------------------------------------------------------------- /tests/uarch/ecall-unsupported.S: -------------------------------------------------------------------------------- 1 | /* Copyright Cartesi and individual authors (see AUTHORS) 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #include "riscv_test.h" 19 | #include "test_macros.h" 20 | 21 | RVTEST_RV64U 22 | RVTEST_CODE_BEGIN 23 | 24 | li a7, 0 // unsupported ecall function 25 | ecall 26 | 27 | RVTEST_FAIL // it should fail previously so it can't reach this point 28 | 29 | RVTEST_CODE_END 30 | 31 | .data 32 | RVTEST_DATA_BEGIN 33 | TEST_DATA 34 | RVTEST_DATA_END 35 | -------------------------------------------------------------------------------- /tests/uarch/fence.S: -------------------------------------------------------------------------------- 1 | /* Copyright Cartesi and individual authors (see AUTHORS) 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #include "riscv_test.h" 19 | #include "test_macros.h" 20 | 21 | RVTEST_RV64U 22 | RVTEST_CODE_BEGIN 23 | 24 | fence 25 | 26 | RVTEST_PASS 27 | 28 | RVTEST_CODE_END 29 | 30 | .data 31 | RVTEST_DATA_BEGIN 32 | TEST_DATA 33 | RVTEST_DATA_END 34 | -------------------------------------------------------------------------------- /tests/uarch/link.ld: -------------------------------------------------------------------------------- 1 | OUTPUT_ARCH( "riscv" ) 2 | ENTRY(_start) 3 | 4 | SECTIONS 5 | { 6 | . = 0x70000000; 7 | .text.init : { *(.text.init) } 8 | . = ALIGN(0x1000); 9 | .text : { *(.text) } 10 | . = ALIGN(0x1000); 11 | .data : { *(.data) } 12 | .bss : { *(.bss) } 13 | _end = .; 14 | } 15 | 16 | -------------------------------------------------------------------------------- /tests/uarch/riscv_test.h: -------------------------------------------------------------------------------- 1 | /* Copyright Cartesi and individual authors (see AUTHORS) 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _UARCH_ENV_FOR_RISCV_TESTS_H 18 | #define _UARCH_ENV_FOR_RISCV_TESTS_H 19 | 20 | #include 21 | 22 | #define RVTEST_RV64U \ 23 | .macro init; \ 24 | .endm 25 | 26 | #define RVTEST_CODE_BEGIN \ 27 | .section .text.init; \ 28 | .globl _start; \ 29 | _start: \ 30 | 31 | 32 | #define RVTEST_HALT \ 33 | li a7, UARCH_ECALL_FN_HALT_DEF; \ 34 | ecall; \ 35 | 36 | //----------------------------------------------------------------------- 37 | // End Macro 38 | //----------------------------------------------------------------------- 39 | 40 | #define TESTNUM gp 41 | #define TEST_SUCCEEDED 0xbe1e7aaa 42 | #define TEST_FAILED 0xdeadbeef 43 | 44 | #define RVTEST_CODE_END \ 45 | li ra, TEST_SUCCEEDED; \ 46 | RVTEST_HALT 47 | 48 | //----------------------------------------------------------------------- 49 | // Pass/Fail Macro 50 | //----------------------------------------------------------------------- 51 | 52 | #define RVTEST_PASS \ 53 | li ra, TEST_SUCCEEDED; \ 54 | li TESTNUM, 1; \ 55 | 56 | #define RVTEST_FAIL \ 57 | li ra, TEST_FAILED; \ 58 | RVTEST_HALT 59 | 60 | //----------------------------------------------------------------------- 61 | // Data Section Macro 62 | //----------------------------------------------------------------------- 63 | 64 | #define EXTRA_DATA \ 65 | ; 66 | 67 | #define RVTEST_DATA_BEGIN \ 68 | ; 69 | 70 | #define RVTEST_DATA_END \ 71 | ; 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /tests/uarch/rv64ui-uarch-catalog.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "path": "rv64ui-uarch-simple.bin", "cycle": 12}, 3 | { "path": "rv64ui-uarch-add.bin", "cycle": 441}, 4 | { "path": "rv64ui-uarch-addi.bin", "cycle": 216}, 5 | { "path": "rv64ui-uarch-addiw.bin", "cycle": 213}, 6 | { "path": "rv64ui-uarch-addw.bin", "cycle": 436}, 7 | { "path": "rv64ui-uarch-and.bin", "cycle": 516}, 8 | { "path": "rv64ui-uarch-andi.bin", "cycle": 187}, 9 | { "path": "rv64ui-uarch-auipc.bin", "cycle": 30}, 10 | { "path": "rv64ui-uarch-beq.bin", "cycle": 262}, 11 | { "path": "rv64ui-uarch-bge.bin", "cycle": 280}, 12 | { "path": "rv64ui-uarch-bgeu.bin", "cycle": 370}, 13 | { "path": "rv64ui-uarch-blt.bin", "cycle": 262}, 14 | { "path": "rv64ui-uarch-bltu.bin", "cycle": 348}, 15 | { "path": "rv64ui-uarch-bne.bin", "cycle": 262}, 16 | { "path": "rv64ui-uarch-jal.bin", "cycle": 26}, 17 | { "path": "rv64ui-uarch-jalr.bin", "cycle": 86}, 18 | { "path": "rv64ui-uarch-lb.bin", "cycle": 224}, 19 | { "path": "rv64ui-uarch-lbu.bin", "cycle": 224}, 20 | { "path": "rv64ui-uarch-lh.bin", "cycle": 240}, 21 | { "path": "rv64ui-uarch-lhu.bin", "cycle": 249}, 22 | { "path": "rv64ui-uarch-lw.bin", "cycle": 254}, 23 | { "path": "rv64ui-uarch-lwu.bin", "cycle": 288}, 24 | { "path": "rv64ui-uarch-ld.bin", "cycle": 406}, 25 | { "path": "rv64ui-uarch-lui.bin", "cycle": 36}, 26 | { "path": "rv64ui-uarch-or.bin", "cycle": 549}, 27 | { "path": "rv64ui-uarch-ori.bin", "cycle": 180}, 28 | { "path": "rv64ui-uarch-sb.bin", "cycle": 425}, 29 | { "path": "rv64ui-uarch-sh.bin", "cycle": 478}, 30 | { "path": "rv64ui-uarch-sw.bin", "cycle": 485}, 31 | { "path": "rv64ui-uarch-sd.bin", "cycle": 597}, 32 | { "path": "rv64ui-uarch-sll.bin", "cycle": 511}, 33 | { "path": "rv64ui-uarch-slli.bin", "cycle": 241}, 34 | { "path": "rv64ui-uarch-slliw.bin", "cycle": 248}, 35 | { "path": "rv64ui-uarch-sllw.bin", "cycle": 511}, 36 | { "path": "rv64ui-uarch-slt.bin", "cycle": 430}, 37 | { "path": "rv64ui-uarch-slti.bin", "cycle": 208}, 38 | { "path": "rv64ui-uarch-sltiu.bin", "cycle": 208}, 39 | { "path": "rv64ui-uarch-sltu.bin", "cycle": 447}, 40 | { "path": "rv64ui-uarch-sra.bin", "cycle": 483}, 41 | { "path": "rv64ui-uarch-srai.bin", "cycle": 229}, 42 | { "path": "rv64ui-uarch-sraiw.bin", "cycle": 275}, 43 | { "path": "rv64ui-uarch-sraw.bin", "cycle": 523}, 44 | { "path": "rv64ui-uarch-srl.bin", "cycle": 525}, 45 | { "path": "rv64ui-uarch-srli.bin", "cycle": 250}, 46 | { "path": "rv64ui-uarch-srliw.bin", "cycle": 257}, 47 | { "path": "rv64ui-uarch-srlw.bin", "cycle": 517}, 48 | { "path": "rv64ui-uarch-sub.bin", "cycle": 432}, 49 | { "path": "rv64ui-uarch-subw.bin", "cycle": 428}, 50 | { "path": "rv64ui-uarch-xor.bin", "cycle": 544}, 51 | { "path": "rv64ui-uarch-xori.bin", "cycle": 178}, 52 | { "path": "rv64ui-uarch-fence.bin", "cycle": 13}, 53 | { "path": "rv64ui-uarch-ecall-putchar.bin", "cycle": 15} 54 | ] -------------------------------------------------------------------------------- /third-party/nlohmann-json/LICENSE.MIT: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2013-2022 Niels Lohmann 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /third-party/tiny_sha3/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Markku-Juhani O. Saarinen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /third-party/tiny_sha3/sha3.h: -------------------------------------------------------------------------------- 1 | // sha3.h 2 | // 19-Nov-11 Markku-Juhani O. Saarinen 3 | 4 | #ifndef SHA3_H 5 | #define SHA3_H 6 | 7 | #include 8 | #include 9 | 10 | // state context 11 | typedef struct { 12 | union { // state: 13 | uint8_t b[200]; // 8-bit bytes 14 | uint64_t q[25]; // 64-bit words 15 | } st; 16 | int pt, rsiz, mdlen, dsuffix; // these don't overflow 17 | } sha3_ctx_t; 18 | 19 | // Compression function. 20 | void sha3_keccakf(uint64_t st[25]); 21 | 22 | // OpenSSL - like interfece 23 | int sha3_init(sha3_ctx_t *c, int mdlen, int dsuffix); // mdlen = hash output in bytes 24 | int sha3_update(sha3_ctx_t *c, const void *data, size_t len); 25 | int sha3_final(void *md, sha3_ctx_t *c); // digest goes to md 26 | 27 | // compute a sha3 hash (md) of given byte length from "in" 28 | void *sha3(const void *in, size_t inlen, void *md, int mdlen); 29 | 30 | // SHAKE128 and SHAKE256 extensible-output functions 31 | #define shake128_init(c) sha3_init(c, 16, 0x06) 32 | #define shake256_init(c) sha3_init(c, 32, 0x06) 33 | #define shake_update sha3_update 34 | 35 | void shake_xof(sha3_ctx_t *c); 36 | void shake_out(sha3_ctx_t *c, void *out, size_t len); 37 | 38 | #endif 39 | 40 | -------------------------------------------------------------------------------- /tools/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright Cartesi and individual authors (see AUTHORS) 4 | # SPDX-License-Identifier: Apache-2.0 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | if [ -z "$GID" -o -z "$UID" -o -z "$USER" -o -z "$GROUP" ]; then 20 | echo Running as $(whoami) 21 | exec "$@" 22 | else 23 | if [ ! $(getent group $GID) ]; then 24 | if [ $(getent group $GROUP) ]; then 25 | echo Group name $GROUP already exists 26 | GROUP=container-group-$GID 27 | fi 28 | groupadd -g $GID $GROUP 29 | else 30 | echo The id $GID of group $GROUP already exists 31 | fi 32 | if [ ! $(getent passwd $UID) ]; then 33 | if [ $(getent passwd $USER) ]; then 34 | echo User name $USER already exists. 35 | USER=container-user-$UID 36 | fi 37 | useradd -u $UID -g $GID -G $GROUP $USER 38 | else 39 | echo The id $UID of user $USER already exists 40 | fi 41 | USERNAME=$(id -nu $UID) 42 | export HOME=/home/$USERNAME 43 | mkdir -p $HOME 44 | chown $UID:$GID $HOME 45 | 46 | # Workaround for issue with su-exec tty ownership 47 | # Should be removed once ticket https://github.com/ncopa/su-exec/issues/33 48 | # is resolved, or alternative solution with reusing file descriptors is found 49 | # Test if stdin is associated with a terminal 50 | if [ -t 0 ]; then 51 | chown $UID:$GID $(/usr/bin/tty) 52 | fi 53 | 54 | echo Running as $USERNAME and group $(id -ng $UID) 55 | exec /usr/local/bin/su-exec $USERNAME "$@" 56 | fi 57 | -------------------------------------------------------------------------------- /tools/gdb/gdbinit: -------------------------------------------------------------------------------- 1 | # retrieve machine cycles 2 | define cycles 3 | monitor cycles 4 | end 5 | 6 | # step a fixed number of machine cycles 7 | define stepc 8 | if $argc == 0 9 | monitor stepc 1 10 | end 11 | if $argc == 1 12 | monitor stepc $arg0 13 | end 14 | c 15 | monitor stepc_clear 16 | cycles 17 | end 18 | 19 | # step until until the machine reaches a cycle 20 | define stepu 21 | monitor stepu $arg0 22 | c 23 | monitor stepc_clear 24 | cycles 25 | end 26 | 27 | # print machine CSRs 28 | define csr 29 | monitor csr $arg0 30 | end 31 | 32 | # print machine hash 33 | define hash 34 | monitor hash 35 | end 36 | 37 | # store machine state 38 | define store 39 | monitor store $arg0 40 | end 41 | 42 | # execute arbitrary lua code 43 | define lua 44 | monitor lua $arg0 45 | end 46 | 47 | # toggle a hardware breakpoint at PC 48 | define breakpc 49 | monitor breakpc $arg0 50 | end 51 | 52 | # dump registers (example on how to execute arbitrary Lua code) 53 | define dump_regs 54 | lua "print('mcycle:', machine:read_mcycle()) return 'read the machine mcycle value in the machine terminal'" 55 | end 56 | 57 | # shortcuts 58 | alias sc=stepc 59 | alias su=stepu 60 | alias bpc=breakpc 61 | -------------------------------------------------------------------------------- /tools/gnu/stubs-lp64.h: -------------------------------------------------------------------------------- 1 | /* This file is automatically generated. 2 | It defines a symbol `__stub_FUNCTION' for each function 3 | in the C library which is a stub, meaning it will fail 4 | every time called, usually setting errno to ENOSYS. */ 5 | 6 | #ifdef _LIBC 7 | #error Applications may not define the macro _LIBC 8 | #endif 9 | 10 | #define __stub___compat_bdflush 11 | #define __stub___compat_create_module 12 | #define __stub___compat_get_kernel_syms 13 | #define __stub___compat_query_module 14 | #define __stub___compat_uselib 15 | #define __stub_chflags 16 | #define __stub_fchflags 17 | #define __stub_feclearexcept 18 | #define __stub_fedisableexcept 19 | #define __stub_feenableexcept 20 | #define __stub_fegetenv 21 | #define __stub_fegetexcept 22 | #define __stub_fegetexceptflag 23 | #define __stub_fegetmode 24 | #define __stub_fegetround 25 | #define __stub_feholdexcept 26 | #define __stub_feraiseexcept 27 | #define __stub_fesetenv 28 | #define __stub_fesetexcept 29 | #define __stub_fesetexceptflag 30 | #define __stub_fesetmode 31 | #define __stub_fesetround 32 | #define __stub_fetestexcept 33 | #define __stub_feupdateenv 34 | #define __stub_gtty 35 | #define __stub_revoke 36 | #define __stub_setlogin 37 | #define __stub_sigreturn 38 | #define __stub_stty -------------------------------------------------------------------------------- /tools/template/cartesi-machine-stored-hash.template: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | export LUA_PATH_5_4="ARG_LUA_PATH;${LUA_PATH_5_4:-;}" 3 | export LUA_CPATH_5_4="ARG_LUA_CPATH;${LUA_CPATH_5_4:-;}" 4 | lua5.4 "ARG_LUA_RUNTIME_PATH/cartesi-machine-stored-hash.lua" "$@" 5 | -------------------------------------------------------------------------------- /tools/template/cartesi-machine-tests.template: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | export LUA_PATH_5_4="ARG_LUA_PATH;${LUA_PATH_5_4:-;}" 3 | export LUA_CPATH_5_4="ARG_LUA_CPATH;${LUA_CPATH_5_4:-;}" 4 | export CARTESI_TESTS_PATH="${CARTESI_TESTS_PATH:-ARG_TESTS_PATH}" 5 | lua5.4 "ARG_LUA_RUNTIME_PATH/cartesi-machine-tests.lua" "$@" 6 | -------------------------------------------------------------------------------- /tools/template/cartesi-machine.template: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | export LUA_PATH_5_4="ARG_LUA_PATH;${LUA_PATH_5_4:-;}" 3 | export LUA_CPATH_5_4="ARG_LUA_CPATH;${LUA_CPATH_5_4:-;}" 4 | export CARTESI_IMAGES_PATH="${CARTESI_IMAGES_PATH:-ARG_IMAGES_PATH}" 5 | lua5.4 "ARG_LUA_RUNTIME_PATH/cartesi-machine.lua" "$@" 6 | -------------------------------------------------------------------------------- /tools/template/control.template: -------------------------------------------------------------------------------- 1 | Package: cartesi-machine-emulator 2 | Source: cartesi-machine-emulator 3 | Version: ARG_VERSION 4 | Homepage: https://github.com/cartesi/machine-emulator 5 | Architecture: ARG_ARCH 6 | Maintainer: Cartesi Machine Reference Unit 7 | Provides: cartesi-machine-emulator 8 | Depends: lua5.4, libslirp0 9 | Section: devel 10 | Priority: optional 11 | Multi-Arch: foreign 12 | Description: Cartesi Machine emulator for RISC-V Linux systems 13 | -------------------------------------------------------------------------------- /tools/template/machine-c-version.h.template: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef CM_MACHINE_C_VERSION_H // NOLINTBEGIN 18 | #define CM_MACHINE_C_VERSION_H 19 | 20 | #define CM_MARCHID EMULATOR_MARCHID 21 | 22 | #define CM_VERSION_MAJOR EMULATOR_VERSION_MAJOR 23 | #define CM_VERSION_MINOR EMULATOR_VERSION_MINOR 24 | #define CM_VERSION_PATCH EMULATOR_VERSION_PATCH 25 | #define CM_VERSION_LABEL "EMULATOR_VERSION_LABEL" 26 | 27 | #define _CM_STR_HELPER(x) #x 28 | #define _CM_STR(x) _CM_STR_HELPER(x) 29 | #define CM_VERSION \ 30 | _CM_STR(CM_VERSION_MAJOR) "." _CM_STR(CM_VERSION_MINOR) "." _CM_STR(CM_VERSION_PATCH) CM_VERSION_LABEL 31 | #define CM_VERSION_MAJMIN _CM_STR(CM_VERSION_MAJOR) "." _CM_STR(CM_VERSION_MINOR) 32 | 33 | #define CM_MIMPID (CM_VERSION_MAJOR * 1000 + CM_VERSION_MINOR) 34 | 35 | #endif // NOLINTEND 36 | -------------------------------------------------------------------------------- /tools/template/tests-control.template: -------------------------------------------------------------------------------- 1 | Package: cartesi-machine-tests 2 | Source: cartesi-machine-tests 3 | Version: ARG_VERSION 4 | Homepage: https://github.com/cartesi/machine-emulator 5 | Architecture: ARG_ARCH 6 | Maintainer: Cartesi Machine Reference Unit 7 | Provides: cartesi-machine-tests 8 | Depends: cartesi-machine-emulator (>= ARG_VERSION) 9 | Section: devel 10 | Priority: optional 11 | Multi-Arch: foreign 12 | Description: Cartesi Machine emulator tests 13 | -------------------------------------------------------------------------------- /tools/template/tests-copyright.template: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: cartesi-machine-tests 3 | Source: https://github.com/cartesi/machine-emulator 4 | 5 | Files: * 6 | Copyright: Cartesi and individual authors (see AUTHORS) 7 | License: LGPL-3.0+ 8 | 9 | License: LGPL-3.0+ 10 | This package is free software; you can redistribute it and/or 11 | modify it under the terms of the GNU Lesser General Public License as 12 | published by the Free Software Foundation; either version 3 of the 13 | License, or (at your option) any later version. 14 | . 15 | This package is distributed in the hope that it will be useful, 16 | but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | Lesser General Public License for more details. 19 | . 20 | You should have received a copy of the GNU Lesser General Public 21 | License along with this package; if not, write to the Free Software 22 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 23 | . 24 | On Debian systems, the complete text of the GNU Lesser General 25 | Public License can be found in '/usr/share/common-licenses/LGPL-3'. 26 | 27 | -------------------------------------------------------------------------------- /tools/template/tests-data-control.template: -------------------------------------------------------------------------------- 1 | Package: cartesi-machine-tests-data 2 | Source: cartesi-machine-tests-data 3 | Version: ARG_VERSION 4 | Homepage: https://github.com/cartesi/machine-emulator 5 | Architecture: all 6 | Maintainer: Cartesi Machine Reference Unit 7 | Provides: cartesi-machine-tests-data 8 | Depends: cartesi-machine-emulator (>= ARG_VERSION), procps 9 | Section: devel 10 | Priority: optional 11 | Multi-Arch: foreign 12 | Description: Cartesi Machine emulator tests data 13 | -------------------------------------------------------------------------------- /tools/template/uarch-riscv-tests.template: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | export LUA_PATH_5_4="ARG_LUA_PATH;${LUA_PATH_5_4:-;}" 3 | export LUA_CPATH_5_4="ARG_LUA_CPATH;${LUA_CPATH_5_4:-;}" 4 | export CARTESI_TESTS_UARCH_PATH="${CARTESI_TESTS_UARCH_PATH:-ARG_TESTS_UARCH_PATH}" 5 | lua5.4 "ARG_LUA_RUNTIME_PATH/uarch-riscv-tests.lua" "$@" 6 | -------------------------------------------------------------------------------- /uarch/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.tmp 3 | *.ld 4 | *.elf 5 | *.bin 6 | .DS_Store 7 | .vscode 8 | uarch-pristine-hash.c 9 | uarch-pristine-ram.c 10 | compute-uarch-pristine-hash 11 | *.insn.txt 12 | *.objdump -------------------------------------------------------------------------------- /uarch/README.md: -------------------------------------------------------------------------------- 1 | # Cartesi Machine Microarchitecture Build Directory 2 | 3 | This directory contains scripts and instructions to compile the Cartesi Machine emulator to microarchitecture code 4 | 5 | -------------------------------------------------------------------------------- /uarch/uarch-ram-entry.S: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #include 18 | #include 19 | 20 | .section .text.init; 21 | .align 3; 22 | .global _start; 23 | _start: 24 | // Initialize stack 25 | li sp, PMA_UARCH_RAM_START_DEF 26 | li t0, PMA_UARCH_RAM_LENGTH_DEF 27 | add sp, sp, t0 // stack pointer at the end of RAM 28 | call interpret_next_mcycle_with_uarch 29 | 30 | 31 | -------------------------------------------------------------------------------- /uarch/uarch-ram.ld.in: -------------------------------------------------------------------------------- 1 | OUTPUT_ARCH( "riscv" ) 2 | ENTRY(_start) 3 | 4 | #include "pma-defines.h" 5 | 6 | SECTIONS 7 | { 8 | . = PMA_UARCH_RAM_START_DEF; 9 | .text.init : { *(.text.init) } 10 | .text : { *(.text) } 11 | .rodata : { *(.rodata) } 12 | .sdata : { *(.sdata) } 13 | .bss : { *(.bss) } 14 | .tdata : { *(.tdata) } 15 | 16 | _end = .; 17 | } 18 | -------------------------------------------------------------------------------- /uarch/uarch-run.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #include "uarch-runtime.h" // must be included first, because of assert 18 | 19 | #include "compiler-defines.h" 20 | #include "interpret.h" 21 | #include "uarch-constants.h" 22 | #include "uarch-machine-state-access.h" 23 | 24 | #include 25 | 26 | using namespace cartesi; 27 | 28 | static void set_uarch_halt_flag() { 29 | // NOLINTNEXTLINE(hicpp-no-assembler) 30 | asm volatile("mv a7, %0\n" 31 | "ecall\n" 32 | : // no output 33 | : "r"(cartesi::uarch_ecall_functions::UARCH_ECALL_FN_HALT) 34 | : "a7" // modified registers 35 | ); 36 | } 37 | 38 | namespace cartesi { 39 | 40 | // Declaration of explicit instantiation in module interpret.cpp when compiled with microarchitecture 41 | extern template interpreter_break_reason interpret(uarch_machine_state_access a, uint64_t mcycle_end); 42 | 43 | } // namespace cartesi 44 | 45 | /// \brief Advances one mcycle by executing the "big machine interpreter" compiled to the microarchitecture 46 | /// \return This function never returns 47 | extern "C" NO_RETURN void interpret_next_mcycle_with_uarch() { 48 | // Let the state accessor be on static memory storage to speed up uarch initialization 49 | static std::array, PMA_MAX> pmas; 50 | uarch_machine_state_access a(pmas); 51 | const uint64_t mcycle_end = a.read_mcycle() + 1; 52 | interpret(a, mcycle_end); 53 | // Finished executing a whole mcycle: halt the microarchitecture 54 | set_uarch_halt_flag(); 55 | // The micro interpreter will never execute this line because the micro machine is halted 56 | __builtin_trap(); 57 | } 58 | -------------------------------------------------------------------------------- /uarch/uarch-runtime.h: -------------------------------------------------------------------------------- 1 | // Copyright Cartesi and individual authors (see AUTHORS) 2 | // SPDX-License-Identifier: LGPL-3.0-or-later 3 | // 4 | // This program is free software: you can redistribute it and/or modify it under 5 | // the terms of the GNU Lesser General Public License as published by the Free 6 | // Software Foundation, either version 3 of the License, or (at your option) any 7 | // later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY 10 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | // PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License along 14 | // with this program (see COPYING). If not, see . 15 | // 16 | 17 | #ifndef UARCH_RUNTIME_H 18 | #define UARCH_RUNTIME_H 19 | 20 | #include "uarch-printf.h" 21 | #include "compiler-defines.h" 22 | 23 | #include 24 | #include 25 | 26 | // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 27 | #define fprintf(a, ...) printf(__VA_ARGS__) 28 | 29 | // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 30 | #define assert(a) \ 31 | if (!(a)) { \ 32 | printf("Assertion failed\n"); \ 33 | abort(); \ 34 | } 35 | 36 | extern "C" NO_RETURN void abort(); 37 | 38 | namespace cartesi { 39 | 40 | void os_open_tty(); 41 | void os_close_tty(); 42 | bool os_poll_tty(uint64_t /*timeout_us*/); 43 | int os_getchar(); 44 | void os_putchar(uint8_t ch); 45 | 46 | } // namespace cartesi 47 | 48 | #endif 49 | --------------------------------------------------------------------------------