├── .github ├── ISSUE_TEMPLATE │ ├── bug-report.md │ ├── feature-request.md │ ├── technical-debt.md │ └── update-dependencies.md ├── pull_request_template.md └── workflows │ └── build.yml ├── .gitignore ├── .gitmodules ├── AUTHORS ├── CHANGELOG.md ├── 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_console.S ├── htif_invalid_ops.S ├── htif_rollup.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 ├── uarch ├── .gitignore ├── Makefile ├── README.md ├── fence.S ├── link.ld ├── riscv_test.h └── rv64ui-uarch-catalog.json ├── version_check.S └── xpie_exceptions.S /.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](../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; 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/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | on: [push] 3 | env: 4 | TOOLCHAIN_DOCKER_REPOSITORY: ${{ github.repository_owner }}/toolchain 5 | TOOLCHAIN_TAG: 0.16.0 6 | jobs: 7 | build: 8 | runs-on: ubuntu-22.04 9 | steps: 10 | - uses: actions/checkout@v3 11 | with: 12 | submodules: recursive 13 | token: ${{ secrets.CI_TOKEN }} 14 | 15 | - name: Login to GitHub Container Registry 16 | uses: docker/login-action@v2 17 | with: 18 | registry: ghcr.io 19 | username: ${{ github.actor }} 20 | password: ${{ secrets.GITHUB_TOKEN }} 21 | 22 | - name: Login to Docker Hub 23 | uses: docker/login-action@v2 24 | with: 25 | username: ${{ secrets.DOCKER_USERNAME }} 26 | password: ${{ secrets.DOCKER_PASSWORD }} 27 | 28 | - name: Build dependencies 29 | run: make toolchain-exec CONTAINER_COMMAND="/usr/bin/make dep -j$(nproc)" 30 | 31 | - name: Build 32 | run: | 33 | make toolchain-exec CONTAINER_COMMAND="/usr/bin/make -j$(nproc)" 34 | make toolchain-exec CONTAINER_COMMAND="/usr/bin/make uarch -j$(nproc)" 35 | 36 | - name: Install 37 | run: | 38 | make install 39 | make uarch-install 40 | 41 | - name: TAR 42 | run: tar -czf machine-tests-`git describe --tags --exact-match`.tar.gz -C /opt/cartesi/tests . 43 | if: startsWith(github.ref, 'refs/tags/v') 44 | 45 | - uses: softprops/action-gh-release@v1 46 | if: startsWith(github.ref, 'refs/tags/v') 47 | with: 48 | prerelease: true 49 | files: machine-tests-*.tar.gz 50 | env: 51 | GITHUB_TOKEN: ${{ secrets.CI_TOKEN }} 52 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | .DS_Store 3 | .vscode 4 | 5 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "third-party/riscv-tests"] 2 | path = third-party/riscv-tests 3 | url = ../riscv-tests.git 4 | [submodule "lib/machine-emulator-defines"] 5 | path = lib/machine-emulator-defines 6 | url = ../machine-emulator-defines.git 7 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | ## [Unreleased] 8 | 9 | ## [0.30.0] - 2023-12-06 10 | ### Changed 11 | - Updated toolchain to v0.16.0 12 | 13 | ## [0.29.0] - 2023-08-12 14 | ### Added 15 | - Added pull request templates 16 | 17 | ### Changed 18 | - Updated license/copyright notice in all source code 19 | - Updated toolchain to v0.15.0 20 | - Updated machine-emulator-defines 21 | 22 | ## [0.28.0] - 2023-05-02 23 | ### Changed 24 | - Bump marchid to 0xf 25 | 26 | ## [0.27.0] - 2023-04-27 27 | ### Added 28 | - Added rv64ui-uarch-catalog.json 29 | - Added rv64ui uarch fence test 30 | 31 | ### Changed 32 | - Improved rv64ui test build 33 | 34 | ## [0.26.0] - 2023-04-18 35 | ### Added 36 | - Added separated build for uarch/rv64ui tests 37 | 38 | ### Changed 39 | - Updated toolchain image to v0.14.0 40 | - Updated machine-emulator-defines 41 | 42 | ## [0.25.0] - 2023-02-16 43 | ### Added 44 | - Added a big set of floating-point tests 45 | - Added virtual address translation tests 46 | - Added illegal instruction tests 47 | - Added new tests for HTIF and CLINT devices 48 | - Added interrupts tests 49 | - Added support for debugging tests with GDB 50 | 51 | ### Changed 52 | - Bump marchid to 0xe 53 | 54 | ## [0.24.0] - 2023-02-10 55 | ### Added 56 | - Added RISC-V compressed instructions tests 57 | 58 | ### Changed 59 | - Updated toolchain version to v0.13.0 60 | 61 | ## [0.23.0] - 2022-11-17 62 | ### Added 63 | - Added RISC-V floating-point tests 64 | 65 | ### Changed 66 | - Changed PMA board address to the new range in microarchitecture 67 | - Updated toolchain version to v0.12.0 68 | 69 | ## [0.22.0] - 2022-10-19 70 | ### Changed 71 | - Bump marchid to 0xd 72 | 73 | ## [0.21.0] - 2022-10-03 74 | ### Added 75 | - Added PTE reserved exception test 76 | - Added xtval value test 77 | 78 | ## [0.20.0] - 2022-09-14 79 | ### Added 80 | - Added CSR semantics test 81 | - Added CSR counters test 82 | - Added LR/SC test 83 | - Added mcycle write test 84 | 85 | ### Changed 86 | - Updated RISC-V tests. 87 | 88 | ## [0.19.0] - 2022-06-30 89 | ### Changed 90 | - Updated toolchain version to v0.11.0 91 | - Bump marchid to 0xc 92 | 93 | ## [0.18.0] - 2022-06-24 94 | ### Changed 95 | - Updated toolchain version to v0.10.0 96 | 97 | ## [0.17.0] - 2022-06-10 98 | ### Changed 99 | - Bump marchid to 0xb 100 | 101 | ## [0.16.0] - 2022-05-12 102 | ### Changed 103 | - Bump marchid to 0xa 104 | - Correct a bug on the HTIF test 105 | - Split yield and console into separate files 106 | 107 | ## [0.15.0] - 2022-04-20 108 | ### Changed 109 | - Updated toolchain version to v0.9.0 110 | 111 | ## [0.14.0] - 2022-03-24 112 | ### Added 113 | - Added rollup exception test 114 | 115 | ### Changed 116 | - Updated toolchain version to v0.8.0 117 | 118 | ## [0.13.0] - 2021-12-17 119 | ### Changed 120 | - Updated toolchain version to v0.7.0 121 | - Adjust yield test to generate both types: manual and automatic 122 | - Add rollup test 123 | 124 | ## [Previous Versions] 125 | - [0.12.0] 126 | - [0.11.0] 127 | - [0.10.0] 128 | - [0.9.0] 129 | - [0.8.0] 130 | - [0.7.0] 131 | - [0.6.0] 132 | - [0.5.0] 133 | - [0.4.0] 134 | - [0.3.0] 135 | - [0.2.0] 136 | - [0.1.0] 137 | 138 | [Unreleased]: https://github.com/cartesi/machine-tests/compare/v0.30.0...HEAD 139 | [0.30.0]: https://github.com/cartesi/machine-tests/releases/tag/v0.30.0 140 | [0.29.0]: https://github.com/cartesi/machine-tests/releases/tag/v0.29.0 141 | [0.28.0]: https://github.com/cartesi/machine-tests/releases/tag/v0.28.0 142 | [0.27.0]: https://github.com/cartesi/machine-tests/releases/tag/v0.27.0 143 | [0.26.0]: https://github.com/cartesi/machine-tests/releases/tag/v0.26.0 144 | [0.25.0]: https://github.com/cartesi/machine-tests/releases/tag/v0.25.0 145 | [0.24.0]: https://github.com/cartesi/machine-tests/releases/tag/v0.24.0 146 | [0.23.0]: https://github.com/cartesi/machine-tests/releases/tag/v0.23.0 147 | [0.22.0]: https://github.com/cartesi/machine-tests/releases/tag/v0.22.0 148 | [0.21.0]: https://github.com/cartesi/machine-tests/releases/tag/v0.21.0 149 | [0.20.0]: https://github.com/cartesi/machine-tests/releases/tag/v0.20.0 150 | [0.19.0]: https://github.com/cartesi/machine-tests/releases/tag/v0.19.0 151 | [0.18.0]: https://github.com/cartesi/machine-tests/releases/tag/v0.18.0 152 | [0.17.0]: https://github.com/cartesi/machine-tests/releases/tag/v0.17.0 153 | [0.16.0]: https://github.com/cartesi/machine-tests/releases/tag/v0.16.0 154 | [0.15.0]: https://github.com/cartesi/machine-tests/releases/tag/v0.15.0 155 | [0.14.0]: https://github.com/cartesi/machine-tests/releases/tag/v0.14.0 156 | [0.13.0]: https://github.com/cartesi/machine-tests/releases/tag/v0.13.0 157 | [0.12.0]: https://github.com/cartesi/machine-tests/releases/tag/v0.12.0 158 | [0.11.0]: https://github.com/cartesi/machine-tests/releases/tag/v0.11.0 159 | [0.10.0]: https://github.com/cartesi/machine-tests/releases/tag/v0.10.0 160 | [0.9.0]: https://github.com/cartesi/machine-tests/releases/tag/v0.9.0 161 | [0.8.0]: https://github.com/cartesi/machine-tests/releases/tag/v0.8.0 162 | [0.7.0]: https://github.com/cartesi/machine-tests/releases/tag/v0.7.0 163 | [0.6.0]: https://github.com/cartesi/machine-tests/releases/tag/v0.6.0 164 | [0.5.0]: https://github.com/cartesi/machine-tests/releases/tag/v0.5.0 165 | [0.4.0]: https://github.com/cartesi/machine-tests/releases/tag/v0.4.0 166 | [0.3.0]: https://github.com/cartesi/machine-tests/releases/tag/v0.3.0 167 | [0.2.0]: https://github.com/cartesi/machine-tests/releases/tag/v0.2.0 168 | [0.1.0]: https://github.com/cartesi/machine-tests/releases/tag/v0.1.0 169 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at info@cartesi.io. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /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/Pt2NrnS), or contact us at info@cartesi.io email before working on the change. 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /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 | UNAME:=$(shell uname) 18 | 19 | PREFIX = /opt/cartesi 20 | INSTALLDIR = $(PREFIX)/tests 21 | 22 | DEPDIR := third-party 23 | SRCDIR := $(abspath src) 24 | BUILDDIR = $(abspath build) 25 | DOWNLOADDIR := $(DEPDIR)/downloads 26 | SRCCLEAN := $(addsuffix .clean,$(SRCDIR)) 27 | DEPDIRS := $(addprefix $(DEPDIR)/,riscv-tests) 28 | DEPCLEAN := $(addsuffix .clean,$(DEPDIRS)) 29 | 30 | TOOLCHAIN_DOCKER_REPOSITORY ?= cartesi/toolchain 31 | TOOLCHAIN_TAG ?= 0.16.0 32 | 33 | RISCV_PREFIX = riscv64-cartesi-linux-gnu- 34 | RVCC = $(RISCV_PREFIX)gcc 35 | RVCXX = $(RISCV_PREFIX)g++ 36 | RVCOPY = $(RISCV_PREFIX)objcopy 37 | RVDUMP = $(RISCV_PREFIX)objdump 38 | 39 | all: $(SRCDIR) 40 | 41 | clean: $(SRCCLEAN) uarch-clean 42 | 43 | depclean: $(DEPCLEAN) clean 44 | rm -rf $(BUILDDIR) 45 | $(MAKE) -C $@ clean 46 | 47 | distclean: clean 48 | rm -rf $(BUILDDIR) $(DOWNLOADDIR) $(DEPDIRS) 49 | 50 | $(BUILDDIR): 51 | mkdir -p $(BUILDDIR) 52 | 53 | lib/machine-emulator-defines/pma-defines.h: 54 | git submodule update --init --recursive lib/machine-emulator-defines 55 | 56 | $(DEPDIR)/riscv-tests: 57 | cd $@ && ./configure 58 | $(MAKE) -C $@ RISCV_PREFIX=$(RISCV_PREFIX) 59 | $(MAKE) copy-riscv-tests 60 | 61 | submodules: 62 | git submodule update --init --recursive third-party/riscv-tests 63 | 64 | downloads: submodules 65 | 66 | dep: $(BUILDDIR) $(DEPDIRS) 67 | 68 | $(SRCDIR): 69 | $(MAKE) -C $@ RISCV_PREFIX=$(RISCV_PREFIX) $(TARGET) 70 | 71 | uarch: 72 | $(MAKE) -C $(SRCDIR) RISCV_PREFIX=$(RISCV_PREFIX) $(TARGET) uarch 73 | 74 | uarch-install: 75 | $(MAKE) -C $(SRCDIR) INSTALLDIR=$(INSTALLDIR) $@ 76 | 77 | $(SRCCLEAN) $(DEPCLEAN): %.clean: 78 | $(MAKE) -C $* clean 79 | 80 | copy-riscv-tests: $(BUILDDIR) 81 | cp -a $(DEPDIR)/riscv-tests/isa/*.bin $(DEPDIR)/riscv-tests/isa/*.dump $(BUILDDIR) 82 | cd $(DEPDIR)/riscv-tests/isa && find . -maxdepth 1 -type f ! -name "*.*" -exec cp -a {} $(BUILDDIR)/{}.elf \; 83 | 84 | install: copy-riscv-tests 85 | mkdir -p $(INSTALLDIR) 86 | cp -a $(BUILDDIR)/*.bin $(BUILDDIR)/*.dump $(BUILDDIR)/*.elf $(INSTALLDIR) 87 | 88 | uarch-clean: 89 | $(MAKE) -C $(SRCDIR) $@ 90 | 91 | toolchain-env: 92 | @docker run --hostname toolchain-env -it --rm \ 93 | -e USER=$$(id -u -n) \ 94 | -e GROUP=$$(id -g -n) \ 95 | -e UID=$$(id -u) \ 96 | -e GID=$$(id -g) \ 97 | -v `pwd`:/opt/cartesi/machine-tests \ 98 | -w /opt/cartesi/machine-tests \ 99 | $(TOOLCHAIN_DOCKER_REPOSITORY):$(TOOLCHAIN_TAG) 100 | 101 | toolchain-exec: 102 | docker run --hostname toolchain-env --rm \ 103 | -e USER=$$(id -u -n) \ 104 | -e GROUP=$$(id -g -n) \ 105 | -e UID=$$(id -u) \ 106 | -e GID=$$(id -g) \ 107 | -v `pwd`:/opt/cartesi/machine-tests \ 108 | -w /opt/cartesi/machine-tests \ 109 | $(TOOLCHAIN_DOCKER_REPOSITORY):$(TOOLCHAIN_TAG) $(CONTAINER_COMMAND) 110 | 111 | .PHONY: all clean distclean downloads $(SRCDIR) $(DEPDIRS) $(SRCCLEAN) $(DEPCLEAN) uarch-install uarch-clean 112 | -------------------------------------------------------------------------------- /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++17 (tested with GCC >= 8+). 10 | - GNU Make >= 3.81 11 | - Docker image `cartesi/toolchain` 12 | 13 | ### Build 14 | 15 | ```bash 16 | $ make downloads 17 | $ make toolchain-env 18 | [toolchain-env]$ make dep 19 | [toolchain-env]$ make uarch 20 | [toolchain-env]$ make 21 | [toolchain-env]$ exit 22 | $ make INSTALLDIR=/my/path install 23 | $ make INSTALLDIR=/my/path uarch-install 24 | ``` 25 | 26 | Cleaning: 27 | 28 | ```bash 29 | [toolchain-env]$ make depclean 30 | [toolchain-env]$ make clean 31 | ``` 32 | 33 | ## Usage 34 | 35 | TODO 36 | 37 | ## Contributing 38 | 39 | 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! 40 | 41 | Please note we have a [Code of Conduct](CODE_OF_CONDUCT.md), please follow it in all your interactions with the project. 42 | 43 | ## Authors 44 | 45 | * *Diego Nehab* 46 | * *Victor Fusco* 47 | 48 | ## License 49 | 50 | The machine-tests repository and all contributions are licensed under 51 | [APACHE 2.0](https://www.apache.org/licenses/LICENSE-2.0). Please review our [LICENSE](LICENSE) file. 52 | -------------------------------------------------------------------------------- /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 | BUILD_DIR ?= $(abspath ../build) 18 | RISCV_TESTS_DIR ?= $(abspath ../third-party/riscv-tests) 19 | 20 | RISCV_PREFIX = riscv64-cartesi-linux-gnu- 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 ../lib/machine-emulator-defines) 32 | 33 | CFLAGS=-g -march=rv64g -mabi=lp64d -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles $(INCS) 34 | CXXFLAGS=-fno-exceptions $(CFLAGS) 35 | 36 | SRCS := $(wildcard *.S) 37 | TMPS := $(SRCS:.S=.elf) 38 | BINS := $(TMPS:%.elf=$(BUILD_DIR)/%.bin) 39 | DUMPS := $(TMPS:%.elf=$(BUILD_DIR)/%.dump) 40 | 41 | .DEFAULT_GOAL := all 42 | 43 | $(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf 44 | $(OBJCOPY) -S -O binary $< $@ 45 | 46 | $(BUILD_DIR)/%.dump: $(BUILD_DIR)/%.elf 47 | $(OBJDUMP) -d $< > $@ 48 | 49 | $(BUILD_DIR): 50 | mkdir -p $(BUILD_DIR) 51 | 52 | # assembly 53 | $(BUILD_DIR)/%.elf: %.S | $(BUILD_DIR) 54 | $(CC) $(CFLAGS) -Tlink.ld -o $@ $< 55 | 56 | $(BUILD_DIR)/bootstrap.elf: bootstrap.S $(BUILD_DIR) 57 | $(CC) $(CFLAGS) -Tbootstrap.ld -o $@ $< 58 | 59 | .PRECIOUS: $(BUILD_DIR)/%.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 $(BUILD_DIR)/*.elf $(BUILD_DIR)/*.bin $(BUILD_DIR)/*.dump 74 | -------------------------------------------------------------------------------- /src/access.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 | #define MSTATUS_FS_MASK (3<<13) 25 | 26 | #define MCAUSE_INSN_ADDRESS_MISALIGNED 0x0 ///< Instruction address misaligned 27 | #define MCAUSE_INSN_ACCESS_FAULT 0x1 ///< Instruction access fault 28 | #define MCAUSE_ILLEGAL_INSN 0x2 ///< Illegal instruction 29 | #define MCAUSE_BREAKPOINT 0x3 ///< Breakpoint 30 | #define MCAUSE_LOAD_ADDRESS_MISALIGNED 0x4 ///< Load address misaligned 31 | #define MCAUSE_LOAD_ACCESS_FAULT 0x5 ///< Load access fault 32 | #define MCAUSE_STORE_AMO_ADDRESS_MISALIGNED 0x6 ///< Store/AMO address misaligned 33 | #define MCAUSE_STORE_AMO_ACCESS_FAULT 0x7 ///< Store/AMO access fault 34 | #define MCAUSE_ECALL_BASE 0x8 ///< Environment call (+0: from U-mode, +1: from S-mode, +3: from M-mode) 35 | #define MCAUSE_SUPERVISOR_ECALL 0x9 ///< Environment call from S-mode 36 | #define MCAUSE_MACHINE_ECALL 0xb ///< Environment call from M-mode 37 | #define MCAUSE_FETCH_PAGE_FAULT 0xc ///< Instruction page fault 38 | #define MCAUSE_LOAD_PAGE_FAULT 0xd ///< Load page fault 39 | #define MCAUSE_STORE_AMO_PAGE_FAULT 0xf ///< Store/AMO page fault 40 | 41 | #define HTIF_IHALT_ADDR 0x40008010 42 | #define HTIF_INVALID_ADDR 0x40008100 43 | #define MEM_FLASH_DRIVE_ADDR 0x80000000000000 44 | 45 | // Section with code 46 | .section .text.init 47 | .align 2; 48 | .global _start; 49 | _start: 50 | // Set a trap that will ignore the failing instruction and resume to next instruction 51 | la t0, skip_instruction_trap 52 | csrw mtvec, t0 53 | li a5, 0xc00fd00d 54 | 55 | // Enable FS state 56 | li t0, MSTATUS_FS_MASK; 57 | csrs mstatus, t0; 58 | 59 | // Writes in the shadow area should raise store access fault exception 60 | li gp, 0 61 | sd zero, (zero) 62 | li t0, MCAUSE_STORE_AMO_ACCESS_FAULT 63 | bne gp, t0, exit 64 | 65 | // Attempt to store a float in the shadow should raise store access fault exception 66 | li gp, 0 67 | fsd f0, (zero) 68 | li t0, MCAUSE_STORE_AMO_ACCESS_FAULT 69 | bne gp, t0, exit 70 | 71 | // Attempts to read invalid addresses in HTIF should raise load access fault exception 72 | mv a0, a5 73 | li a1, HTIF_INVALID_ADDR 74 | li gp, 0 75 | ld a0, (a1) 76 | bne a0, a5, fail 77 | li t0, MCAUSE_LOAD_ACCESS_FAULT 78 | bne gp, t0, exit 79 | 80 | // HTIF ihalt should be readable but not writable, 81 | // therefore writes to it should raise an store access fault exception 82 | mv a0, a5 83 | li a3, HTIF_IHALT_ADDR 84 | li gp, 0 85 | amoswap.d a0, zero, (a3) 86 | bne a0, a5, fail 87 | li t0, MCAUSE_STORE_AMO_ACCESS_FAULT 88 | bne gp, t0, exit 89 | 90 | // Attempt to read an invalid CSR should raise an illegal instruction exception 91 | li gp, 0 92 | csrr a0, 0x800 93 | li t0, MCAUSE_ILLEGAL_INSN 94 | bne gp, t0, exit 95 | 96 | // Attempt to set a bit in an invalid CSR should raise an illegal instruction exception 97 | li gp, 0 98 | csrrci a0, 0x800, 1 99 | li t0, MCAUSE_ILLEGAL_INSN 100 | bne gp, t0, exit 101 | 102 | // Attempt to set a bit in an non-writable CSR should raise an illegal instruction exception 103 | li gp, 0 104 | csrrci a0, mvendorid, 1 105 | li t0, MCAUSE_ILLEGAL_INSN 106 | bne gp, t0, exit 107 | 108 | // Memory flash drivers are not executable, 109 | // executing instructions on it should raise an instruction access fault 110 | la t0, jalr_trap 111 | csrw mtvec, t0 112 | li t0, MEM_FLASH_DRIVE_ADDR 113 | jalr t0 114 | 115 | exit_imm(254) 116 | 117 | jalr_trap: 118 | csrr gp, mcause 119 | li t0, MCAUSE_INSN_ACCESS_FAULT 120 | bne gp, t0, exit 121 | exit_imm(0) 122 | 123 | fail: 124 | exit_imm(255) 125 | 126 | skip_instruction_trap: 127 | csrr t0, mepc 128 | addi t0, t0, 4 129 | csrw mepc, t0 130 | csrr gp, mcause 131 | mret 132 | exit_imm(1) 133 | 134 | // Exits via HTIF using gp content as the exit code 135 | exit: 136 | // HTIF exits with dev = cmd = 0 and a payload with lsb set. 137 | // the exit code is taken from payload >> 2 138 | slli gp, gp, 16; 139 | srli gp, gp, 15; 140 | ori gp, gp, 1; 141 | 1: 142 | li t0, PMA_HTIF_START_DEF 143 | sd gp, 0(t0); 144 | j 1b; // Should not be necessary 145 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /src/clint_ops.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 programs exercise load/writes in the CLINT device. 19 | 20 | #include 21 | 22 | // Uses HTIF to exit the emulator with exit code in an immediate 23 | #define exit_imm(imm) \ 24 | li gp, imm; \ 25 | j exit; 26 | 27 | #define expect_trap(cause, code...) \ 28 | li a0, cause; \ 29 | li a1, 1; \ 30 | code \ 31 | bnez a1, fail; 32 | 33 | #define MCAUSE_STORE_AMO_ACCESS_FAULT 0x7 34 | #define MCAUSE_LOAD_ACCESS_FAULT 0x5 35 | 36 | #define O_MSIP 0 37 | #define O_MTIMECMP 0x4000 38 | #define O_MTIME 0xbff8 39 | 40 | #define MIP_MSIP_MASK (1 << 3) 41 | 42 | // Section with code 43 | .section .text.init 44 | .align 2; 45 | .global _start; 46 | _start: 47 | // Set the exception handler to trap 48 | la t0, fail; 49 | csrw mtvec, t0; 50 | 51 | // Load CLINT.MTIME, it should equal to zero at the very start 52 | li t0, PMA_CLINT_START_DEF + O_MTIME; 53 | ld t1, 0(t0); 54 | bnez t1, fail; 55 | 56 | // Store and load CLINT.MSIP 57 | li t0, PMA_CLINT_START_DEF + O_MSIP; 58 | li t1, 0xffffffffff; 59 | sw t1, 0(t0); 60 | lw t2, 0(t0); // note that this won't raise an interrupts, because mip should be 0 61 | li t3, 1; 62 | bne t2, t3, fail; // make sure only the less significant bit is set 63 | csrr t2, mip; 64 | li t3, MIP_MSIP_MASK; 65 | bne t2, t3, fail; // make sure mie.MSIP is set 66 | 67 | // Store and load CLINT.MTIMECMP 68 | li t0, PMA_CLINT_START_DEF + O_MTIMECMP; 69 | li t1, 0xffffffffffffffff; 70 | sd t1, 0(t0); 71 | ld t2, 0(t0); 72 | bne t1, t2, fail; 73 | 74 | // Set the exception handler to skip instructions 75 | la t0, skip_insn_trap; 76 | csrw mtvec, t0; 77 | 78 | // Attempt to load a non 4-bytes value from CLINT.MSIP 79 | expect_trap(MCAUSE_LOAD_ACCESS_FAULT, 80 | li t0, PMA_CLINT_START_DEF + O_MSIP; 81 | ld t1, 0(t0); 82 | ) 83 | 84 | // Attempt to load a non 8-bytes value from CLINT.MTIMECMP 85 | expect_trap(MCAUSE_LOAD_ACCESS_FAULT, 86 | li t0, PMA_CLINT_START_DEF + O_MTIMECMP; 87 | lw t1, 0(t0); 88 | ) 89 | 90 | // Attempt to load a non 8-bytes value from CLINT.MTIME 91 | expect_trap(MCAUSE_LOAD_ACCESS_FAULT, 92 | li t0, PMA_CLINT_START_DEF + O_MTIME; 93 | lw t1, 0(t0); 94 | ) 95 | 96 | // Attempt to load from an invalid CLINT offset 97 | expect_trap(MCAUSE_LOAD_ACCESS_FAULT, 98 | li t0, PMA_CLINT_START_DEF + 1; 99 | lb t1, 0(t0); 100 | ) 101 | 102 | // Attempt to store a non 4-bytes value in CLINT.MSIP 103 | expect_trap(MCAUSE_STORE_AMO_ACCESS_FAULT, 104 | li t0, PMA_CLINT_START_DEF + O_MSIP; 105 | sd zero, 0(t0); 106 | ) 107 | 108 | // Attempt to store a non 8-bytes value in CLINT.MTIMECMP 109 | expect_trap(MCAUSE_STORE_AMO_ACCESS_FAULT, 110 | li t0, PMA_CLINT_START_DEF + O_MTIMECMP; 111 | sw zero, 0(t0); 112 | ) 113 | 114 | // Attempt to write to CLINT.MTIME 115 | expect_trap(MCAUSE_STORE_AMO_ACCESS_FAULT, 116 | li t0, PMA_CLINT_START_DEF + O_MTIME; 117 | sd zero, 0(t0); 118 | ) 119 | 120 | // Attempt to store in an invalid CLINT offset 121 | expect_trap(MCAUSE_STORE_AMO_ACCESS_FAULT, 122 | li t0, PMA_CLINT_START_DEF + 1; 123 | sb zero, 0(t0); 124 | ) 125 | 126 | exit_imm(0); 127 | 128 | skip_insn_trap: 129 | csrr gp, mcause; 130 | bne gp, a0, exit; 131 | csrr t5, mepc; 132 | addi t5, t5, 4; 133 | csrw mepc, t5; 134 | addi a1, a1, -1; 135 | mret; 136 | 137 | fail: 138 | exit_imm(1); 139 | 140 | // Exits via HTIF using gp content as the exit code 141 | exit: 142 | slli gp, gp, 16; 143 | srli gp, gp, 15; 144 | ori gp, gp, 1; 145 | 1: 146 | li t0, PMA_HTIF_START_DEF 147 | sd gp, 0(t0); 148 | j 1b; 149 | -------------------------------------------------------------------------------- /src/compressed.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 MSTATUS_FS_MASK (3<<13) 26 | #define MCAUSE_ILLEGAL_INSN 0x2 27 | #define MCAUSE_BREAKPOINT 0x3 28 | #define MCAUSE_LOAD_ACCESS_FAULT 0x5 29 | #define MCAUSE_STORE_AMO_ACCESS_FAULT 0x7 30 | #define C_NOP 0x0001 31 | 32 | #define C_INSN(code...) \ 33 | .option push; .option rvc; \ 34 | code; \ 35 | c.nop; \ 36 | .option pop; 37 | 38 | #define TEST_RAWC_HINT(insn) \ 39 | li x8, -1; \ 40 | .half (C_NOP); \ 41 | .half (insn); \ 42 | li t5, -1; \ 43 | bne t5, x8, fail; \ 44 | xor t5, t5, t5; \ 45 | bne t5, x0, fail; 46 | 47 | #define TEST_RAWC_ILLEGAL_INSN(insn)\ 48 | li a0, MCAUSE_ILLEGAL_INSN; \ 49 | li t5, 0; \ 50 | .half (insn); \ 51 | .half (C_NOP); \ 52 | li t0, 1; \ 53 | bne t5, t0, fail; 54 | 55 | #define TEST_C_TRAP_INSN(cause, code...)\ 56 | li a0, cause; \ 57 | li t5, 0; \ 58 | .option push; .option rvc; \ 59 | code; \ 60 | c.nop; \ 61 | .option pop; \ 62 | li t0, 1; \ 63 | bne t5, t0, fail; 64 | 65 | #define SHIFT_C_OPCODE 0 66 | #define SHIFT_C_Q0_RD 2 67 | #define SHIFT_C_Q1_RD 7 68 | #define SHIFT_C_Q2_RD 7 69 | #define SHIFT_C_Q1_IMM 5 70 | #define SHIFT_C_Q2_IMM 2 71 | #define SHIFT_C_Q2_RS2 2 72 | #define SHIFT_C_FUNCT3 13 73 | #define SHIFT_C_FUNCT4 12 74 | 75 | // Section with code 76 | .section .text.init 77 | .align 2; 78 | .global _start; 79 | _start: 80 | // Set the exception handler to trap 81 | la t0, fail; 82 | csrw mtvec, t0; 83 | 84 | // Enable FS state 85 | li t3, MSTATUS_FS_MASK; 86 | csrs mstatus, t3; 87 | 88 | test_float_insns: 89 | la s0, my_float0; 90 | ld a0, 0(s0); 91 | 92 | // C.FLD should load float from 0(s0) into fs0 correctly 93 | la s0, my_float0; 94 | C_INSN(c.fld fs0, 0(s0)) 95 | fmv.x.d a0, fs0; 96 | ld t1, 0(s0); 97 | bne a0, t1, fail; 98 | 99 | // C.FLD should load float from 0(sp) into fs0 correctly 100 | la sp, my_float0; 101 | C_INSN(c.fldsp fs0, 0(sp)) 102 | fmv.x.d a0, fs0; 103 | ld t1, 0(sp); 104 | bne a0, t1, fail; 105 | 106 | // C.FSD should store float from fs0 into 0(s1) correctly 107 | la s1, my_float1; 108 | C_INSN(c.fsd fs0, 0(s1)) 109 | ld t1, 0(s1); 110 | bne a0, t1, fail; 111 | sd zero, 0(s1); // undo the memory change 112 | 113 | // C.FSDSP should store float from fs0 into 0(sp) correctly 114 | la sp, my_float1; 115 | C_INSN(c.fsdsp fs0, 0(sp)) 116 | ld t1, 0(sp); 117 | bne a0, t1, fail; 118 | sd zero, 0(sp); // undo the memory change 119 | 120 | test_hint_insns: 121 | // Quadrant 1 122 | TEST_RAWC_HINT((0b000 << SHIFT_C_FUNCT3) | (0 << SHIFT_C_Q1_RD) | (1 << SHIFT_C_Q1_IMM) | (1 << SHIFT_C_OPCODE)) // C.NOP with imm!=0 123 | TEST_RAWC_HINT((0b000 << SHIFT_C_FUNCT3) | (8 << SHIFT_C_Q1_RD) | (0 << SHIFT_C_Q1_IMM) | (1 << SHIFT_C_OPCODE)) // C.ADDI with imm=0 124 | TEST_RAWC_HINT((0b010 << SHIFT_C_FUNCT3) | (0 << SHIFT_C_Q1_RD) | (1 << SHIFT_C_Q1_IMM) | (1 << SHIFT_C_OPCODE)) // C.LI with rd=0 125 | TEST_RAWC_HINT((0b011 << SHIFT_C_FUNCT3) | (0 << SHIFT_C_Q1_RD) | (1 << SHIFT_C_Q1_IMM) | (1 << SHIFT_C_OPCODE)) // C.LUI with rd=0 126 | TEST_RAWC_HINT((0b100 << SHIFT_C_FUNCT3) | (0b00001 << SHIFT_C_Q1_RD) | (1 << SHIFT_C_OPCODE)) // C.SRLI64 127 | TEST_RAWC_HINT((0b100 << SHIFT_C_FUNCT3) | (0b01001 << SHIFT_C_Q1_RD) | (1 << SHIFT_C_OPCODE)) // C.SRAI64 128 | 129 | // Quadrant 2 130 | TEST_RAWC_HINT((0b1000 << SHIFT_C_FUNCT4) | (0 << SHIFT_C_Q2_RD) | (8 << SHIFT_C_Q2_RS2) | (2 << SHIFT_C_OPCODE)) // C.MV with rd=0 131 | TEST_RAWC_HINT((0b1001 << SHIFT_C_FUNCT4) | (0 << SHIFT_C_Q2_RD) | (8 << SHIFT_C_Q2_RS2) | (2 << SHIFT_C_OPCODE)) // C.ADD with rd=0 132 | TEST_RAWC_HINT((0b000 << SHIFT_C_FUNCT3) | (0 << SHIFT_C_Q2_RD) | (1 << SHIFT_C_Q2_IMM) | (2 << SHIFT_C_OPCODE)) // C.SLLI with rd=0 133 | TEST_RAWC_HINT((0b000 << SHIFT_C_FUNCT3) | (8 << SHIFT_C_Q2_RD) | (2 << SHIFT_C_OPCODE)) // C.SLLI64 134 | 135 | test_illegal_insns: 136 | // Set a trap that will ignore the failing illegal instructions and resume to next instruction 137 | la t0, skip_insn_trap; 138 | csrw mtvec, t0; 139 | 140 | // Invalid instruction (no bit set) 141 | TEST_RAWC_ILLEGAL_INSN(0x0) 142 | 143 | // Reserved ranges 144 | TEST_RAWC_ILLEGAL_INSN((0b100 << SHIFT_C_FUNCT3) | (0 << SHIFT_C_OPCODE)) 145 | TEST_RAWC_ILLEGAL_INSN((0b100 << SHIFT_C_FUNCT3) | (0b111 << 10) | (0b10 << 5) | (1 << SHIFT_C_OPCODE)) 146 | TEST_RAWC_ILLEGAL_INSN((0b100 << SHIFT_C_FUNCT3) | (0b111 << 10) | (0b11 << 5) | (1 << SHIFT_C_OPCODE)) 147 | 148 | // Quadrant 0 149 | TEST_RAWC_ILLEGAL_INSN((0 << SHIFT_C_FUNCT3) | (1 << SHIFT_C_Q0_RD) | (0 << SHIFT_C_OPCODE)) // C.ADDI4SPN with imm=0 150 | 151 | // Quadrant 1 152 | TEST_RAWC_ILLEGAL_INSN((0b001 << SHIFT_C_FUNCT3) | (0 << SHIFT_C_Q1_RD) | (1 << SHIFT_C_OPCODE)) // C.ADDIW with rd=0 153 | TEST_RAWC_ILLEGAL_INSN((0b011 << SHIFT_C_FUNCT3) | (2 << SHIFT_C_Q1_RD) | (1 << SHIFT_C_OPCODE)) // C.ADDI16SP with imm=0 154 | TEST_RAWC_ILLEGAL_INSN((0b011 << SHIFT_C_FUNCT3) | (1 << SHIFT_C_Q1_RD) | (1 << SHIFT_C_OPCODE)) // C.LUI with imm=0 155 | 156 | // Quadrant 2 157 | TEST_RAWC_ILLEGAL_INSN((0b010 << SHIFT_C_FUNCT3) | (2 << SHIFT_C_OPCODE)) // C.LWSP with rd=0 158 | TEST_RAWC_ILLEGAL_INSN((0b011 << SHIFT_C_FUNCT3) | (2 << SHIFT_C_OPCODE)) // C.LDSP with rd=0 159 | TEST_RAWC_ILLEGAL_INSN((0b100 << SHIFT_C_FUNCT3) | (2 << SHIFT_C_OPCODE)) // C.JR with rs1=0 160 | 161 | // Invalid memory access 162 | li s0, 0x9000000000000; 163 | li sp, 0x9000000000000; 164 | TEST_C_TRAP_INSN(MCAUSE_LOAD_ACCESS_FAULT, c.lw s0, 0(s0)) 165 | TEST_C_TRAP_INSN(MCAUSE_LOAD_ACCESS_FAULT, c.ld s0, 0(s0)) 166 | TEST_C_TRAP_INSN(MCAUSE_LOAD_ACCESS_FAULT, c.fld fs0, 0(s0)) 167 | TEST_C_TRAP_INSN(MCAUSE_LOAD_ACCESS_FAULT, c.fldsp fs0, 0(sp)) 168 | TEST_C_TRAP_INSN(MCAUSE_STORE_AMO_ACCESS_FAULT, c.sw s0, 0(s0)) 169 | TEST_C_TRAP_INSN(MCAUSE_STORE_AMO_ACCESS_FAULT, c.sd s0, 0(s0)) 170 | TEST_C_TRAP_INSN(MCAUSE_STORE_AMO_ACCESS_FAULT, c.fsd fs0, 0(s0)) 171 | TEST_C_TRAP_INSN(MCAUSE_STORE_AMO_ACCESS_FAULT, c.fsdsp fs0, 0(sp)) 172 | 173 | // Disable FS state 174 | li t3, MSTATUS_FS_MASK; 175 | csrc mstatus, t3; 176 | 177 | // Float instructions while float state is disabled 178 | TEST_C_TRAP_INSN(MCAUSE_ILLEGAL_INSN, c.fld fs0, 0(s0)) 179 | TEST_C_TRAP_INSN(MCAUSE_ILLEGAL_INSN, c.fldsp fs0, 0(sp)) 180 | TEST_C_TRAP_INSN(MCAUSE_ILLEGAL_INSN, c.fsd fs0, 0(s0)) 181 | TEST_C_TRAP_INSN(MCAUSE_ILLEGAL_INSN, c.fsdsp fs0, 0(sp)) 182 | 183 | 184 | // Breakpoint 185 | TEST_C_TRAP_INSN(MCAUSE_BREAKPOINT, c.ebreak) 186 | 187 | success: 188 | exit_imm(0) 189 | 190 | fail: 191 | exit_imm(1); 192 | 193 | skip_insn_trap: 194 | // Expected an illegal instruction exception 195 | csrr gp, mcause; 196 | bne gp, a0, exit; 197 | 198 | // Increment illegal instruction counter 199 | addi t5, t5, 1; 200 | 201 | // Resume to next instruction 202 | csrr t6, mepc; 203 | addi t6, t6, 4; 204 | csrw mepc, t6; 205 | mret; 206 | 207 | exit_imm(1); 208 | 209 | // Exits via HTIF using gp content as the exit code 210 | exit: 211 | // HTIF exits with dev = cmd = 0 and a payload with lsb set. 212 | // the exit code is taken from payload >> 2 213 | slli gp, gp, 16; 214 | srli gp, gp, 15; 215 | ori gp, gp, 1; 216 | 1: 217 | li t0, PMA_HTIF_START_DEF 218 | sd gp, 0(t0); 219 | j 1b; // Should not be necessary 220 | 221 | .data; 222 | .align 3; 223 | my_float0: .dword 0x3f3240fef40a55d0; // 0.00027853226132753834 224 | my_float1: .dword 0x0; // 0.0 225 | -------------------------------------------------------------------------------- /src/csr_counters.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 tests all hardware counters in different privilege modes 19 | 20 | #include 21 | 22 | #define exit_imm(imm) \ 23 | li gp, imm; \ 24 | j exit; 25 | 26 | #define check_minstret(n) \ 27 | csrr t0, minstret; \ 28 | li t1, n; \ 29 | bne t0, t1, fail; 30 | 31 | #define set_minstret(n) \ 32 | csrwi minstret, n; 33 | 34 | #define MSTATUS_MPP_MASK 0x1800 35 | #define MSTATUS_SPP_MASK 0x100 36 | #define MSTATUS_MPP_S 0x800 37 | #define MCAUSE_INSN_ADDRESS_MISALIGNED 0 38 | #define MCAUSE_ILLEGAL_INSN 2 39 | #define MCAUSE_BREAKPOINT 3 40 | #define MCAUSE_USER_ECALL 8 41 | #define MCAUSE_MACHINE_ECALL 11 42 | 43 | #define CSR_WRITE_AND_READ_0(csrname) \ 44 | li t0, 1; \ 45 | csrw csrname, t0; \ 46 | csrr t0, csrname; \ 47 | bne t0, zero, fail; 48 | 49 | #define CSR_READ_FAIL_EXPECTED(csrname) \ 50 | li t6, 0; \ 51 | csrr t0, csrname; \ 52 | beq t6, zero, fail; 53 | 54 | // Section with code 55 | .section .text.init 56 | .align 2; 57 | .global _start; 58 | _start: 59 | // Set the fail exception handler to trap 60 | la t0, fail; 61 | csrw mtvec, t0; 62 | 63 | // Illegal instruction counter 64 | li t6, 0; 65 | 66 | // Expect time read to be valid 67 | li t0, 0; 68 | rdtime t0; 69 | 70 | // Expect cycle greater than 0 71 | li t0, 0; 72 | rdcycle t0; 73 | beq t0, zero, fail; 74 | 75 | // Expect instret to be greater than 0 76 | li t0, 0; 77 | rdinstret t0; 78 | beq t0, zero, fail; 79 | 80 | // Expect mcountinhibit to read 0 81 | li t0, 1; 82 | csrr t0, mcountinhibit; 83 | bne t0, zero, fail; 84 | 85 | // Expect all hpmcounters to always read 0 even after writing to it 86 | CSR_WRITE_AND_READ_0(mhpmcounter3) 87 | CSR_WRITE_AND_READ_0(mhpmcounter4) 88 | CSR_WRITE_AND_READ_0(mhpmcounter5) 89 | CSR_WRITE_AND_READ_0(mhpmcounter6) 90 | CSR_WRITE_AND_READ_0(mhpmcounter7) 91 | CSR_WRITE_AND_READ_0(mhpmcounter8) 92 | CSR_WRITE_AND_READ_0(mhpmcounter9) 93 | CSR_WRITE_AND_READ_0(mhpmcounter10) 94 | CSR_WRITE_AND_READ_0(mhpmcounter11) 95 | CSR_WRITE_AND_READ_0(mhpmcounter12) 96 | CSR_WRITE_AND_READ_0(mhpmcounter13) 97 | CSR_WRITE_AND_READ_0(mhpmcounter14) 98 | CSR_WRITE_AND_READ_0(mhpmcounter15) 99 | CSR_WRITE_AND_READ_0(mhpmcounter16) 100 | CSR_WRITE_AND_READ_0(mhpmcounter17) 101 | CSR_WRITE_AND_READ_0(mhpmcounter18) 102 | CSR_WRITE_AND_READ_0(mhpmcounter19) 103 | CSR_WRITE_AND_READ_0(mhpmcounter20) 104 | CSR_WRITE_AND_READ_0(mhpmcounter21) 105 | CSR_WRITE_AND_READ_0(mhpmcounter22) 106 | CSR_WRITE_AND_READ_0(mhpmcounter23) 107 | CSR_WRITE_AND_READ_0(mhpmcounter24) 108 | CSR_WRITE_AND_READ_0(mhpmcounter25) 109 | CSR_WRITE_AND_READ_0(mhpmcounter26) 110 | CSR_WRITE_AND_READ_0(mhpmcounter27) 111 | CSR_WRITE_AND_READ_0(mhpmcounter28) 112 | CSR_WRITE_AND_READ_0(mhpmcounter29) 113 | CSR_WRITE_AND_READ_0(mhpmcounter30) 114 | CSR_WRITE_AND_READ_0(mhpmcounter31) 115 | 116 | // Expect all hpmevents to always read 0 117 | CSR_WRITE_AND_READ_0(mhpmevent3) 118 | CSR_WRITE_AND_READ_0(mhpmevent4) 119 | CSR_WRITE_AND_READ_0(mhpmevent5) 120 | CSR_WRITE_AND_READ_0(mhpmevent6) 121 | CSR_WRITE_AND_READ_0(mhpmevent7) 122 | CSR_WRITE_AND_READ_0(mhpmevent8) 123 | CSR_WRITE_AND_READ_0(mhpmevent9) 124 | CSR_WRITE_AND_READ_0(mhpmevent10) 125 | CSR_WRITE_AND_READ_0(mhpmevent11) 126 | CSR_WRITE_AND_READ_0(mhpmevent12) 127 | CSR_WRITE_AND_READ_0(mhpmevent13) 128 | CSR_WRITE_AND_READ_0(mhpmevent14) 129 | CSR_WRITE_AND_READ_0(mhpmevent15) 130 | CSR_WRITE_AND_READ_0(mhpmevent16) 131 | CSR_WRITE_AND_READ_0(mhpmevent17) 132 | CSR_WRITE_AND_READ_0(mhpmevent18) 133 | CSR_WRITE_AND_READ_0(mhpmevent19) 134 | CSR_WRITE_AND_READ_0(mhpmevent20) 135 | CSR_WRITE_AND_READ_0(mhpmevent21) 136 | CSR_WRITE_AND_READ_0(mhpmevent22) 137 | CSR_WRITE_AND_READ_0(mhpmevent23) 138 | CSR_WRITE_AND_READ_0(mhpmevent24) 139 | CSR_WRITE_AND_READ_0(mhpmevent25) 140 | CSR_WRITE_AND_READ_0(mhpmevent26) 141 | CSR_WRITE_AND_READ_0(mhpmevent27) 142 | CSR_WRITE_AND_READ_0(mhpmevent28) 143 | CSR_WRITE_AND_READ_0(mhpmevent29) 144 | CSR_WRITE_AND_READ_0(mhpmevent30) 145 | CSR_WRITE_AND_READ_0(mhpmevent31) 146 | 147 | // Set a trap that will ignore the failing instruction and resume to next instruction 148 | la t0, skip_insn_trap; 149 | csrw mtvec, t0; 150 | 151 | // No instructions between instret read and write, it should stay 0 152 | set_minstret(0); 153 | check_minstret(0); 154 | 155 | // One instruction must, increment instret by 1 156 | set_minstret(0); 157 | nop; // increment 1 instruction 158 | check_minstret(1); 159 | 160 | // EBREAK 161 | set_minstret(0); 162 | ebreak; // exception raised, increment only 4 trap instructions 163 | check_minstret(4); 164 | 165 | // ECALL 166 | set_minstret(0); 167 | ecall; // exception raised, increment only 4 trap instructions 168 | check_minstret(4); 169 | 170 | // LR/SC for invalid addresses 171 | set_minstret(0); 172 | li t0, 0xffffffffffffffff; // increment 1 instruction 173 | lr.w t0, (t0); // exception raised, increment only 4 trap instructions 174 | li t0, 0xffffffffffffffff; // increment 1 instruction 175 | sc.w t0, t0, (t0); // exception raised increment only 4 trap instructions 176 | check_minstret(10); 177 | 178 | // LW/SW for invalid addresses 179 | set_minstret(0); 180 | li t0, 0xffffffffffffffff; // increment 1 instruction 181 | lw t0, (t0); // exception raised, increment only 4 trap instructions 182 | li t0, 0xffffffffffffffff; // increment 1 instruction 183 | sw t0, 0(t0); // exception raised, increment only 4 trap instructions 184 | check_minstret(10); 185 | 186 | // Set a trap that will ignore the failing illegal instructions and resume to next instruction 187 | la t0, skip_illegal_insn_trap; 188 | csrw mtvec, t0; 189 | 190 | // Allow reading time/cycle/instret in S-mode 191 | li t0, 7 192 | csrw mcounteren, t0 193 | csrr t1, mcounteren 194 | bne t1, t0, fail 195 | 196 | // Allow delegation user ECALL in S-mode 197 | li t0, (1 << MCAUSE_USER_ECALL) 198 | csrw medeleg, t0 199 | li t1, 0 200 | csrr t1, medeleg 201 | bne t1, t0, fail 202 | 203 | // Enter supervisor mode 204 | la t0, in_supervisor 205 | csrw mepc, t0 206 | li t0, MSTATUS_MPP_MASK 207 | csrc mstatus, t0 208 | li t0, MSTATUS_MPP_S 209 | csrs mstatus, t0 210 | mret 211 | exit_imm(1); 212 | 213 | in_supervisor: 214 | // Expect cycle greater than 0 215 | li t0, 0 216 | rdcycle t0 217 | beq t0, zero, fail 218 | 219 | // Expect instret to be greater than 0 220 | li t0, 0 221 | rdinstret t0 222 | beq t0, zero, fail 223 | 224 | // Expect time read to be valid 225 | li t6, 0 226 | rdtime t0 227 | bne t6, zero, fail 228 | 229 | // Expect all hpmcounters reads to fail in supervisor mode 230 | CSR_READ_FAIL_EXPECTED(hpmcounter3) 231 | CSR_READ_FAIL_EXPECTED(hpmcounter4) 232 | CSR_READ_FAIL_EXPECTED(hpmcounter5) 233 | CSR_READ_FAIL_EXPECTED(hpmcounter6) 234 | CSR_READ_FAIL_EXPECTED(hpmcounter7) 235 | CSR_READ_FAIL_EXPECTED(hpmcounter8) 236 | CSR_READ_FAIL_EXPECTED(hpmcounter9) 237 | CSR_READ_FAIL_EXPECTED(hpmcounter10) 238 | CSR_READ_FAIL_EXPECTED(hpmcounter11) 239 | CSR_READ_FAIL_EXPECTED(hpmcounter12) 240 | CSR_READ_FAIL_EXPECTED(hpmcounter13) 241 | CSR_READ_FAIL_EXPECTED(hpmcounter14) 242 | CSR_READ_FAIL_EXPECTED(hpmcounter15) 243 | CSR_READ_FAIL_EXPECTED(hpmcounter16) 244 | CSR_READ_FAIL_EXPECTED(hpmcounter17) 245 | CSR_READ_FAIL_EXPECTED(hpmcounter18) 246 | CSR_READ_FAIL_EXPECTED(hpmcounter19) 247 | CSR_READ_FAIL_EXPECTED(hpmcounter20) 248 | CSR_READ_FAIL_EXPECTED(hpmcounter21) 249 | CSR_READ_FAIL_EXPECTED(hpmcounter22) 250 | CSR_READ_FAIL_EXPECTED(hpmcounter23) 251 | CSR_READ_FAIL_EXPECTED(hpmcounter24) 252 | CSR_READ_FAIL_EXPECTED(hpmcounter25) 253 | CSR_READ_FAIL_EXPECTED(hpmcounter26) 254 | CSR_READ_FAIL_EXPECTED(hpmcounter27) 255 | CSR_READ_FAIL_EXPECTED(hpmcounter28) 256 | CSR_READ_FAIL_EXPECTED(hpmcounter29) 257 | CSR_READ_FAIL_EXPECTED(hpmcounter30) 258 | CSR_READ_FAIL_EXPECTED(hpmcounter31) 259 | 260 | // Allow U-mode to read access to cycle 261 | li t0, 1 262 | csrw scounteren, t0 263 | csrr t1, scounteren 264 | bne t1, t0, fail 265 | 266 | // Set a trap handler for user mode 267 | la t0, ecall_trap 268 | csrw stvec, t0 269 | 270 | // Enter user mode 271 | la t0, in_user1 272 | csrw sepc, t0 273 | li t0, MSTATUS_SPP_MASK 274 | csrc sstatus, t0 275 | sret 276 | exit_imm(1); 277 | 278 | in_user1: 279 | // We should be able to read cycle 280 | li t0, 0 281 | csrr t0, cycle 282 | beq t0, zero, fail 283 | 284 | // We should not be able to read instret 285 | li t0, 0 286 | li t6, 0 287 | rdinstret t0 288 | bne t0, zero, fail 289 | beq t6, zero, fail 290 | 291 | // We should not be able to read time 292 | li t0, 0 293 | li t6, 0 294 | rdtime t0 295 | bne t0, zero, fail 296 | beq t6, zero, fail 297 | 298 | ecall 299 | exit_imm(1); 300 | 301 | ecall_trap: 302 | // We should be coming from a U-mode ECALL back to S-mode 303 | li t1, MCAUSE_USER_ECALL 304 | csrr t0, scause 305 | bne t0, t1, fail 306 | 307 | // ECALL should tval should be 0 308 | csrr t0, stval 309 | bne t0, zero, fail 310 | 311 | // Disallow reading cycle in U-mode 312 | li t0, 0 313 | csrw scounteren, t0 314 | csrr t1, scounteren 315 | bne t0, t1, fail 316 | 317 | // Enter user mode again 318 | la t0, in_user2 319 | csrw sepc, t0 320 | li t0, MSTATUS_SPP_MASK 321 | csrc sstatus, t0 322 | sret 323 | exit_imm(1); 324 | 325 | in_user2: 326 | // We should not be able to read cycle 327 | li t0, 0 328 | li t6, 0 329 | rdcycle t0 330 | bne t0, zero, fail 331 | beq t6, zero, fail 332 | 333 | exit_imm(0); 334 | 335 | skip_illegal_insn_trap: 336 | csrr gp, mcause 337 | li t4, MCAUSE_ILLEGAL_INSN 338 | bne gp, t4, exit 339 | csrr t4, mepc 340 | addi t4, t4, 4 341 | csrw mepc, t4 342 | addi t6, t6, 1 343 | mret 344 | exit_imm(1) 345 | 346 | skip_insn_trap: 347 | csrr t6, mepc 348 | addi t6, t6, 4 349 | csrw mepc, t6 350 | mret 351 | exit_imm(1) 352 | 353 | fail: 354 | exit_imm(1) 355 | 356 | // Exits via HTIF using gp content as the exit code 357 | exit: 358 | // HTIF exits with dev = cmd = 0 and a payload with lsb set. 359 | // the exit code is taken from payload >> 2 360 | slli gp, gp, 16; 361 | srli gp, gp, 15; 362 | ori gp, gp, 1; 363 | 1: 364 | li t0, PMA_HTIF_START_DEF 365 | sd gp, 0(t0); 366 | j 1b; // Should not be necessary 367 | -------------------------------------------------------------------------------- /src/csr_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 | // This test case tests many CSR semantics in different privilege modes 19 | 20 | #include 21 | 22 | // Uses HTIF to exit the emulator with exit code in an immediate 23 | #define exit_imm(imm) \ 24 | li gp, imm; \ 25 | j exit; 26 | 27 | #define MSTATUS_MPP_MASK 0x1800 28 | #define MSTATUS_MPRV_MASK (1<<17) 29 | #define MSTATUS_SPP_MASK 0x100 30 | #define MSTATUS_FS_MASK (3<<13) 31 | #define MSTATUS_TVM_MASK (1<<20) 32 | #define MSTATUS_TW_MASK (1<<21) 33 | #define MSTATUS_MPP_U 0x0 34 | #define MSTATUS_MPP_S 0x800 35 | #define MSTATUS_MPP_HS 0x1000 36 | #define MSTATUS_MPP_M 0x1800 37 | #define MCAUSE_SUPERVISOR_ECALL 9 38 | #define MCAUSE_ILLEGAL_INSN 0x2 39 | 40 | #define menvcfg 0x30a 41 | #define senvcfg 0x10a 42 | 43 | // Section with code 44 | .section .text.init 45 | .align 2; 46 | .global _start; 47 | _start: 48 | // Set the exception handler to trap 49 | // This is just in case an exception happens 50 | la t0, fail_trap 51 | csrw mtvec, t0 52 | 53 | // Set MPRV, we will check later if its cleared after MRET 54 | li t0, MSTATUS_MPRV_MASK 55 | csrs mstatus, t0 56 | 57 | // Check if HS-mode is supported (currently it's not) 58 | li t0, MSTATUS_MPP_MASK 59 | csrc mstatus, t0 // set MPP to U-mode 60 | li t1, MSTATUS_MPP_HS 61 | csrs mstatus, t1 // attempt to set MPP to HS-mode 62 | csrr t2, mstatus 63 | and t2, t2, t0 // read MPP 64 | bne t2, zero, fail // MPP should be in U-mode 65 | 66 | // Check if S-mode is supported 67 | li t0, MSTATUS_MPP_MASK 68 | csrc mstatus, t0 // set MPP to U-mode 69 | li t1, MSTATUS_MPP_S 70 | csrs mstatus, t1 // attempt to set MPP to S-mode 71 | csrr t2, mstatus 72 | and t2, t2, t0 // read MPP 73 | bne t2, t1, fail // MPP should be in S-mode 74 | 75 | // Check if M-mode is supported 76 | li t0, MSTATUS_MPP_MASK 77 | csrc mstatus, t0 // set MPP to U-mode 78 | li t1, MSTATUS_MPP_M 79 | csrs mstatus, t1 // attempt to set MPP to S-mode 80 | csrr t2, mstatus 81 | and t2, t2, t0 // read MPP 82 | bne t2, t1, fail // MPP should be in M-mode 83 | 84 | // Writing invalid modes to satp doesn't change it 85 | csrr t0, satp 86 | li t1, (2 << 60) // mode 2 is reserved and invalid 87 | csrw satp, t1 88 | csrr t1, satp 89 | bne t0, t1, fail 90 | 91 | // We should be able to read/write mtval 92 | li t0, 0xff 93 | csrw mtval, t0 94 | csrr t1, mtval 95 | bne t1, t0, fail 96 | 97 | // We should be able to read/write mcause 98 | li t0, 0xff 99 | csrw mcause, t0 100 | csrr t1, mcause 101 | bne t1, t0, fail 102 | 103 | // We should be able to read/write menvcfg 104 | li t0, 0xff 105 | csrw menvcfg, t0 106 | csrr t1, menvcfg 107 | li t0, 1 108 | bne t1, t0, fail 109 | 110 | // Enter supervisor mode. 111 | la t0, in_supervisor1 112 | csrw mepc, t0 113 | li t0, MSTATUS_MPP_MASK 114 | csrc mstatus, t0 115 | li t1, MSTATUS_MPP_S 116 | csrs mstatus, t1 117 | mret 118 | exit_imm(1) 119 | 120 | in_supervisor1: 121 | // We should be able to read/write scause 122 | li t0, 1337 123 | csrw scause, t0 124 | csrr t1, scause 125 | bne t0, t1, fail 126 | 127 | // We should be able to read/write stval 128 | li t0, 1337 129 | csrw stval, t0 130 | csrr t1, stval 131 | bne t0, t1, fail 132 | 133 | // We should be able to read/write senvcfg 134 | li t0, 0xff 135 | csrw senvcfg, t0 136 | csrr t1, senvcfg 137 | li t0, 1 138 | bne t1, t0, fail 139 | 140 | // We should be able to read/write satp 141 | li t0, 1 142 | csrw satp, t0 143 | csrr t1, satp 144 | li t0, 1 145 | bne t1, t0, fail 146 | 147 | // WFI should work when TW is 0 148 | li t5, 0 149 | wfi 150 | bne t5, zero, fail 151 | 152 | ecall 153 | exit_imm(1) 154 | 155 | in_machine_again: 156 | // MPRV should have been cleared by last MRET 157 | csrr t1, mstatus 158 | li t0, MSTATUS_MPRV_MASK 159 | and t1, t1, t0 160 | bne t1, zero, fail 161 | 162 | // Enable TVM (trap virtual memory) bit 163 | li t0, MSTATUS_TVM_MASK 164 | csrrs t0, mstatus, t0 165 | 166 | // Enable TW (timeout wait) bit 167 | li t0, MSTATUS_TW_MASK 168 | csrrs t0, mstatus, t0 169 | 170 | // Set a trap that will ignore the failing instruction and resume to next instruction 171 | la t0, skip_illegal_insn_trap 172 | csrw mtvec, t0 173 | 174 | // We should not be able to read/write fflags because FS state is disabled 175 | li t5, 0 176 | csrr t0, fflags 177 | beq t5, zero, fail 178 | li t5, 0 179 | csrw fflags, 0 180 | beq t5, zero, fail 181 | 182 | // We should not be able to read/write frm because FS state is disabled 183 | li t5, 0 184 | csrr t0, frm 185 | beq t5, zero, fail 186 | li t5, 0 187 | csrw frm, 0 188 | beq t5, zero, fail 189 | 190 | // We should not be able to read/write fcsr because FS state is disabled 191 | li t5, 0 192 | csrr t0, fcsr 193 | beq t5, zero, fail 194 | li t5, 0 195 | csrw fcsr, 0 196 | beq t5, zero, fail 197 | 198 | // We should not be able to read/write invalid CSRs 199 | li t5, 0 200 | csrr t0, 0x800 201 | beq t5, zero, fail 202 | li t5, 0 203 | csrw 0x800, 0 204 | beq t5, zero, fail 205 | 206 | // Enable FS state 207 | li t0, MSTATUS_FS_MASK 208 | csrs mstatus, t0 209 | 210 | // We should not be able to execute float instructions with float rounding mode disabled 211 | csrwi frm, 7 212 | li t5, 0 213 | fadd.d f0, f0, f0 214 | fmadd.d f0, f0, f0, f0 215 | fsqrt.d f0, f0 216 | fcvt.s.d f0, f0 217 | fcvt.l.d t0, f0 218 | fcvt.d.l f0, t0 219 | li t0, 6 220 | bne t5, t0, fail 221 | 222 | // Enter supervisor mode again 223 | la t0, in_supervisor2 224 | csrw mepc, t0 225 | li t0, MSTATUS_MPP_MASK 226 | csrc mstatus, t0 227 | li t1, MSTATUS_MPP_S 228 | csrs mstatus, t1 229 | mret 230 | exit_imm(1) 231 | 232 | in_supervisor2: 233 | // We should not be able to write a M-mode CSR 234 | li t5, 0 235 | csrw minstret, 0 236 | beq t5, zero, fail 237 | li t5, 0 238 | csrrwi t0, minstret, 0 239 | beq t5, zero, fail 240 | 241 | // We should not be able to read stap when TVM is 1 242 | li t5, 0 243 | csrr t0, satp 244 | beq t5, zero, fail 245 | 246 | // We should not be able to write stap when TVM is 1 247 | li t0, 0 248 | li t5, 0 249 | csrw satp, t0 250 | beq t5, zero, fail 251 | 252 | // SFENCE should fail when TVM is 1 253 | li t5, 0 254 | sfence.vma 255 | beq t5, zero, fail 256 | 257 | // WFI should fail when TW is 1 258 | li t5, 0 259 | wfi 260 | beq t5, zero, fail 261 | 262 | // MRET should fail while in S-mode 263 | li t5, 0 264 | mret 265 | beq t5, zero, fail 266 | 267 | // Enter U-mode 268 | la t0, in_user 269 | csrw sepc, t0 270 | li t0, MSTATUS_SPP_MASK 271 | csrc sstatus, t0 272 | sret 273 | exit_imm(1) 274 | 275 | in_user: 276 | // SFENCE should fail in U-mode 277 | li t5, 0 278 | sfence.vma 279 | beq t5, zero, fail 280 | 281 | // SRET should fail in U-mode 282 | li t5, 0 283 | sret 284 | beq t5, zero, fail 285 | 286 | // WFI should fail in U-mode 287 | li t5, 0 288 | wfi 289 | beq t5, zero, fail 290 | 291 | exit_imm(0) 292 | 293 | // catch exception and exit 294 | fail_trap: 295 | csrr t0, mcause 296 | li t1, MCAUSE_SUPERVISOR_ECALL 297 | beq t0, t1, in_machine_again 298 | exit_imm(1) 299 | 300 | skip_illegal_insn_trap: 301 | csrr gp, mcause 302 | li t4, MCAUSE_ILLEGAL_INSN 303 | bne gp, t4, exit 304 | csrr t4, mepc 305 | addi t4, t4, 4 306 | csrw mepc, t4 307 | addi t5, t5, 1 308 | mret 309 | exit_imm(1) 310 | 311 | // on fail halt with 1 312 | fail: 313 | exit_imm(1) 314 | 315 | // Exits via HTIF using gp content as the exit code 316 | exit: 317 | // HTIF exits with dev = cmd = 0 and a payload with lsb set. 318 | // the exit code is taken from payload >> 2 319 | slli gp, gp, 16; 320 | srli gp, gp, 15; 321 | ori gp, gp, 1; 322 | 1: 323 | li t0, PMA_HTIF_START_DEF 324 | sd gp, 0(t0); 325 | j 1b; // Should not be necessary 326 | -------------------------------------------------------------------------------- /src/dont_write_x0.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_FS_MASK (3<<13) 21 | 22 | // Uses HTIF to exit the emulator with exit code in an immediate 23 | #define exit_imm(imm) \ 24 | li gp, imm; \ 25 | j exit; 26 | 27 | // Section with code 28 | .section .text.init 29 | .align 2; 30 | .global _start; 31 | _start: 32 | // Set the exception handler to trap 33 | // This is just in case an exception happens 34 | la t0, fail; 35 | csrw mtvec, t0; 36 | 37 | // Enable FS state 38 | li t3, MSTATUS_FS_MASK; 39 | csrs mstatus, t3; 40 | 41 | // Load float f0 and f1 42 | li t3, 0xff800000 // -inf 43 | fmv.w.x f0, t3; 44 | li t3, 0xfff0000000000000 // -inf 45 | fmv.d.x f1, t3; 46 | 47 | execute_LR: 48 | la t1, foo; 49 | lr.w x0, (t0); 50 | bnez x0, fail; 51 | 52 | execute_SC: 53 | sc.w x0, t0, (t1); 54 | bnez x0, fail; 55 | 56 | execute_AMO: 57 | amoadd.w x0, t0, (t1); 58 | bnez x0, fail; 59 | 60 | execute_csr_RW: 61 | csrrw x0, sscratch, x0; 62 | bnez x0, fail; 63 | 64 | execute_csr_SC: 65 | csrrs x0, sscratch, t1; 66 | bnez x0, fail; 67 | 68 | execute_csr_SCI: 69 | csrrsi x0, sscratch, 4; 70 | bnez x0, fail; 71 | 72 | execute_arithmetic: 73 | add x0, t0, t1; 74 | bnez x0, fail; 75 | 76 | execute_arithmetic_imm: 77 | addi x0, x0, 9; 78 | bnez x0, fail; 79 | 80 | execute_L: 81 | lb x0, (t1) 82 | bnez x0, fail; 83 | 84 | execute_LUI: 85 | lui x0, 0x00001; 86 | bnez x0, fail; 87 | 88 | execute_AUIPC: 89 | auipc x0, 0x00001; 90 | bnez x0, fail; 91 | 92 | execute_JAL: 93 | jal x0, jal_test; 94 | jal_test: 95 | bnez x0, fail; 96 | 97 | execute_JALR: 98 | la t2, jalr_test; 99 | jalr x0, t2, 0; 100 | jalr_test: 101 | bnez x0, fail; 102 | 103 | execute_FMV_X_W: 104 | fmv.x.w x0, f0; 105 | bnez x0, fail; 106 | 107 | execute_FMV_X_D: 108 | fmv.x.d x0, f1; 109 | bnez x0, fail; 110 | 111 | execute_FCVT_W_S: 112 | fcvt.w.s x0, f0; 113 | bnez x0, fail; 114 | 115 | execute_FCVT_L_D: 116 | fcvt.l.d x0, f1; 117 | bnez x0, fail; 118 | 119 | execute_FCLASS_S: 120 | fclass.s x0, f0; 121 | bnez x0, fail; 122 | 123 | execute_FCLASS_D: 124 | fclass.d x0, f1; 125 | bnez x0, fail; 126 | 127 | execute_FEQ_S: 128 | feq.s x0, f0, f0; 129 | bnez x0, fail; 130 | 131 | execute_FEQ_D: 132 | feq.d x0, f1, f1; 133 | bnez x0, fail; 134 | 135 | success: 136 | exit_imm(0); 137 | 138 | // catch exception and exit 139 | fail: 140 | exit_imm(1); 141 | 142 | // Exits via HTIF using gp content as the exit code 143 | exit: 144 | // HTIF exits with dev = cmd = 0 and a payload with lsb set. 145 | // the exit code is taken from payload >> 2 146 | slli gp, gp, 16; 147 | srli gp, gp, 15; 148 | ori gp, gp, 1; 149 | 1: 150 | li t0, PMA_HTIF_START_DEF 151 | sd gp, 0(t0); 152 | j 1b; // Should not be necessary 153 | 154 | .data 155 | foo: .word 0; 156 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /src/fclass.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 | #include "float_util.h" 21 | 22 | RVTEST_RV64UF 23 | RVTEST_CODE_BEGIN 24 | 25 | TEST_FCLASS_S(1, 8, 0x80000000); 26 | TEST_FCLASS_S(2, 4, 0x807fffff); 27 | TEST_FCLASS_S(3, 2, 0xbf800000); 28 | TEST_FCLASS_S(4, 1, 0xff800000); 29 | TEST_FCLASS_S(5, 2, 0xff7fffff); 30 | TEST_FCLASS_S(6, 4, 0x80000001); 31 | TEST_FCLASS_S(7, 256, 0xff800001); 32 | TEST_FCLASS_S(8, 512, 0xffc00000); 33 | TEST_FCLASS_S(9, 16, 0x00); 34 | TEST_FCLASS_S(10, 32, 0x7fffff); 35 | TEST_FCLASS_S(11, 64, 0x3f800000); 36 | TEST_FCLASS_S(12, 128, 0x7f800000); 37 | TEST_FCLASS_S(13, 64, 0x7f7fffff); 38 | TEST_FCLASS_S(14, 32, 0x01); 39 | TEST_FCLASS_S(15, 256, 0x7f800001); 40 | TEST_FCLASS_S(16, 512, 0x7fc00000); 41 | TEST_FCLASS_S(17, 64, 0x800000); 42 | TEST_FCLASS_S(18, 2, 0x80800000); 43 | TEST_FCLASS_S(19, 64, 0x40066666); 44 | TEST_FCLASS_S(20, 2, 0xc0066666); 45 | TEST_FCLASS_S(21, 64, 0x3f000000); 46 | TEST_FCLASS_S(22, 2, 0xbf000000); 47 | TEST_FCLASS_S(23, 64, 0x4e000000); 48 | TEST_FCLASS_S(24, 64, 0x5f000000); 49 | TEST_FCLASS_S(25, 2, 0xcfffd7ff); 50 | TEST_FCLASS_D(26, 8, 0x8000000000000000); 51 | TEST_FCLASS_D(27, 4, 0x800fffffffffffff); 52 | TEST_FCLASS_D(28, 2, 0xbff0000000000000); 53 | TEST_FCLASS_D(29, 1, 0xfff0000000000000); 54 | TEST_FCLASS_D(30, 2, 0xffefffffffffffff); 55 | TEST_FCLASS_D(31, 4, 0x8000000000000001); 56 | TEST_FCLASS_D(32, 256, 0xfff0000000000001); 57 | TEST_FCLASS_D(33, 512, 0xfff8000000000000); 58 | TEST_FCLASS_D(34, 16, 0x00); 59 | TEST_FCLASS_D(35, 32, 0xfffffffffffff); 60 | TEST_FCLASS_D(36, 64, 0x3ff0000000000000); 61 | TEST_FCLASS_D(37, 128, 0x7ff0000000000000); 62 | TEST_FCLASS_D(38, 64, 0x7fefffffffffffff); 63 | TEST_FCLASS_D(39, 32, 0x01); 64 | TEST_FCLASS_D(40, 256, 0x7ff0000000000001); 65 | TEST_FCLASS_D(41, 512, 0x7ff8000000000000); 66 | TEST_FCLASS_D(42, 64, 0x10000000000000); 67 | TEST_FCLASS_D(43, 2, 0x8010000000000000); 68 | TEST_FCLASS_D(44, 64, 0x4000cccccccccccd); 69 | TEST_FCLASS_D(45, 2, 0xc000cccccccccccd); 70 | TEST_FCLASS_D(46, 64, 0x3fe0000000000000); 71 | TEST_FCLASS_D(47, 2, 0xbfe0000000000000); 72 | TEST_FCLASS_D(48, 64, 0x4fc0000000000000); 73 | TEST_FCLASS_D(49, 64, 0x5fe0000000000000); 74 | TEST_FCLASS_D(50, 64, 0x3f3240fef40a55d0); 75 | 76 | TEST_PASSFAIL 77 | 78 | RVTEST_CODE_END 79 | 80 | .data 81 | RVTEST_DATA_BEGIN 82 | 83 | TEST_DATA 84 | 85 | RVTEST_DATA_END 86 | 87 | -------------------------------------------------------------------------------- /src/float_util.h: -------------------------------------------------------------------------------- 1 | #ifndef FLOAT_UTIL_H 2 | #define FLOAT_UTIL_H 3 | 4 | #define TEST_FP_OP1_RM_S( testnum, inst, flags, result, val1, rm) \ 5 | test_ ## testnum: \ 6 | li TESTNUM, testnum; \ 7 | la a0, test_ ## testnum ## _data ;\ 8 | flw f0, 0(a0); \ 9 | lw a3, 4(a0); \ 10 | inst f3, f0, rm; \ 11 | fmv.x.s a0, f3; \ 12 | fsflags a1, x0; \ 13 | li a2, flags; \ 14 | bne a0, a3, fail; \ 15 | bne a1, a2, fail; \ 16 | .pushsection .data; \ 17 | .align 2; \ 18 | test_ ## testnum ## _data: \ 19 | .float val1; \ 20 | .float result; \ 21 | .popsection 22 | 23 | #define TEST_FP_OP1_RM_D( testnum, inst, flags, result, val1, rm) \ 24 | test_ ## testnum: \ 25 | li TESTNUM, testnum; \ 26 | la a0, test_ ## testnum ## _data ;\ 27 | fld f0, 0(a0); \ 28 | ld a3, 8(a0); \ 29 | inst f3, f0, rm; \ 30 | fmv.x.d a0, f3; \ 31 | fsflags a1, x0; \ 32 | li a2, flags; \ 33 | bne a0, a3, fail; \ 34 | bne a1, a2, fail; \ 35 | .pushsection .data; \ 36 | .align 3; \ 37 | test_ ## testnum ## _data: \ 38 | .double val1; \ 39 | .double result; \ 40 | .popsection 41 | 42 | #define TEST_FP_OP2_RM_S( testnum, inst, flags, result, val1, val2, rm) \ 43 | test_ ## testnum: \ 44 | li TESTNUM, testnum; \ 45 | la a0, test_ ## testnum ## _data ;\ 46 | flw f0, 0(a0); \ 47 | flw f1, 4(a0); \ 48 | lw a3, 8(a0); \ 49 | inst f3, f0, f1, rm; \ 50 | fmv.x.s a0, f3; \ 51 | fsflags a1, x0; \ 52 | li a2, flags; \ 53 | bne a0, a3, fail; \ 54 | bne a1, a2, fail; \ 55 | .pushsection .data; \ 56 | .align 2; \ 57 | test_ ## testnum ## _data: \ 58 | .float val1; \ 59 | .float val2; \ 60 | .float result; \ 61 | .popsection 62 | 63 | #define TEST_FP_OP2_RM_D( testnum, inst, flags, result, val1, val2, rm) \ 64 | test_ ## testnum: \ 65 | li TESTNUM, testnum; \ 66 | la a0, test_ ## testnum ## _data ;\ 67 | fld f0, 0(a0); \ 68 | fld f1, 8(a0); \ 69 | ld a3, 16(a0); \ 70 | inst f3, f0, f1, rm; \ 71 | fmv.x.d a0, f3; \ 72 | fsflags a1, x0; \ 73 | li a2, flags; \ 74 | bne a0, a3, fail; \ 75 | bne a1, a2, fail; \ 76 | .pushsection .data; \ 77 | .align 3; \ 78 | test_ ## testnum ## _data: \ 79 | .double val1; \ 80 | .double val2; \ 81 | .double result; \ 82 | .popsection 83 | 84 | #define TEST_FP_OP3_RM_S( testnum, inst, flags, result, val1, val2, val3, rm) \ 85 | test_ ## testnum: \ 86 | li TESTNUM, testnum; \ 87 | la a0, test_ ## testnum ## _data ;\ 88 | flw f0, 0(a0); \ 89 | flw f1, 4(a0); \ 90 | flw f2, 8(a0); \ 91 | lw a3, 12(a0); \ 92 | inst f3, f0, f1, f2, rm; \ 93 | fmv.x.s a0, f3; \ 94 | fsflags a1, x0; \ 95 | li a2, flags; \ 96 | bne a0, a3, fail; \ 97 | bne a1, a2, fail; \ 98 | .pushsection .data; \ 99 | .align 2; \ 100 | test_ ## testnum ## _data: \ 101 | .float val1; \ 102 | .float val2; \ 103 | .float val3; \ 104 | .float result; \ 105 | .popsection 106 | 107 | #define TEST_FP_OP3_RM_D( testnum, inst, flags, result, val1, val2, val3, rm) \ 108 | test_ ## testnum: \ 109 | li TESTNUM, testnum; \ 110 | la a0, test_ ## testnum ## _data ;\ 111 | fld f0, 0(a0); \ 112 | fld f1, 8(a0); \ 113 | fld f2, 16(a0); \ 114 | ld a3, 24(a0); \ 115 | inst f3, f0, f1, f2, rm; \ 116 | fmv.x.d a0, f3; \ 117 | fsflags a1, x0; \ 118 | li a2, flags; \ 119 | bne a0, a3, fail; \ 120 | bne a1, a2, fail; \ 121 | .pushsection .data; \ 122 | .align 3; \ 123 | test_ ## testnum ## _data: \ 124 | .double val1; \ 125 | .double val2; \ 126 | .double val3; \ 127 | .double result; \ 128 | .popsection 129 | 130 | #define TEST_INT_FP_OP_RM_S( testnum, inst, flags, result, val1, rm) \ 131 | test_ ## testnum: \ 132 | li TESTNUM, testnum; \ 133 | la a0, test_ ## testnum ## _data ;\ 134 | lw a3, 0(a0); \ 135 | li a0, val1; \ 136 | inst f0, a0, rm; \ 137 | fmv.x.s a0, f0; \ 138 | fsflags a1, x0; \ 139 | li a2, flags; \ 140 | bne a0, a3, fail; \ 141 | bne a1, a2, fail; \ 142 | .pushsection .data; \ 143 | .align 2; \ 144 | test_ ## testnum ## _data: \ 145 | .float result; \ 146 | .popsection 147 | 148 | #define TEST_INT_FP_OP_RM_D( testnum, inst, flags, result, val1, rm) \ 149 | test_ ## testnum: \ 150 | li TESTNUM, testnum; \ 151 | la a0, test_ ## testnum ## _data ;\ 152 | ld a3, 0(a0); \ 153 | li a0, val1; \ 154 | inst f0, a0, rm; \ 155 | fmv.x.d a0, f0; \ 156 | fsflags a1, x0; \ 157 | li a2, flags; \ 158 | bne a0, a3, fail; \ 159 | bne a1, a2, fail; \ 160 | .pushsection .data; \ 161 | .align 3; \ 162 | test_ ## testnum ## _data: \ 163 | .double result; \ 164 | .popsection 165 | 166 | #define TEST_INT_FP_OP_NORM_D( testnum, inst, flags, result, val1) \ 167 | test_ ## testnum: \ 168 | li TESTNUM, testnum; \ 169 | la a0, test_ ## testnum ## _data ;\ 170 | ld a3, 0(a0); \ 171 | li a0, val1; \ 172 | inst f0, a0; \ 173 | fmv.x.d a0, f0; \ 174 | fsflags a1, x0; \ 175 | li a2, flags; \ 176 | bne a0, a3, fail; \ 177 | bne a1, a2, fail; \ 178 | .pushsection .data; \ 179 | .align 3; \ 180 | test_ ## testnum ## _data: \ 181 | .double result; \ 182 | .popsection 183 | 184 | #define TEST_FP_INT_OP_WORD_RM_S(testnum, inst, flags, result, val1, rm) \ 185 | test_ ## testnum: \ 186 | li TESTNUM, testnum; \ 187 | la a0, test_ ## testnum ## _data ;\ 188 | lw a3, 0(a0); \ 189 | flw f0, 4(a0); \ 190 | inst a0, f0, rm; \ 191 | fsflags a1, x0; \ 192 | li a2, flags; \ 193 | bne a0, a3, fail; \ 194 | bne a1, a2, fail; \ 195 | .pushsection .data; \ 196 | .align 2; \ 197 | test_ ## testnum ## _data: \ 198 | .word result; \ 199 | .float val1; \ 200 | .popsection 201 | 202 | #define TEST_FP_INT_OP_WORD_RM_D(testnum, inst, flags, result, val1, rm) \ 203 | test_ ## testnum: \ 204 | li TESTNUM, testnum; \ 205 | la a0, test_ ## testnum ## _data ;\ 206 | fld f0, 0(a0); \ 207 | lw a3, 8(a0); \ 208 | inst a0, f0, rm; \ 209 | fsflags a1, x0; \ 210 | li a2, flags; \ 211 | bne a0, a3, fail; \ 212 | bne a1, a2, fail; \ 213 | .pushsection .data; \ 214 | .align 3; \ 215 | test_ ## testnum ## _data: \ 216 | .double val1; \ 217 | .word result; \ 218 | .popsection 219 | 220 | #define TEST_FP_INT_OP_DWORD_RM_S(testnum, inst, flags, result, val1, rm) \ 221 | test_ ## testnum: \ 222 | li TESTNUM, testnum; \ 223 | la a0, test_ ## testnum ## _data ;\ 224 | ld a3, 0(a0); \ 225 | flw f0, 8(a0); \ 226 | inst a0, f0, rm; \ 227 | fsflags a1, x0; \ 228 | li a2, flags; \ 229 | bne a0, a3, fail; \ 230 | bne a1, a2, fail; \ 231 | .pushsection .data; \ 232 | .align 3; \ 233 | test_ ## testnum ## _data: \ 234 | .dword result; \ 235 | .float val1; \ 236 | .popsection 237 | 238 | #define TEST_FP_INT_OP_DWORD_RM_D(testnum, inst, flags, result, val1, rm) \ 239 | test_ ## testnum: \ 240 | li TESTNUM, testnum; \ 241 | la a0, test_ ## testnum ## _data ;\ 242 | ld a3, 0(a0); \ 243 | fld f0, 8(a0); \ 244 | inst a0, f0, rm; \ 245 | fsflags a1, x0; \ 246 | li a2, flags; \ 247 | bne a0, a3, fail; \ 248 | bne a1, a2, fail; \ 249 | .pushsection .data; \ 250 | .align 3; \ 251 | test_ ## testnum ## _data: \ 252 | .dword result; \ 253 | .double val1; \ 254 | .popsection 255 | 256 | #define TEST_FCVT_D_S_RM( testnum, flags, result, val1 ) \ 257 | test_ ## testnum: \ 258 | li TESTNUM, testnum; \ 259 | la a0, test_ ## testnum ## _data ;\ 260 | ld a3, 0(a0); \ 261 | flw f0, 8(a0); \ 262 | fcvt.d.s f3, f0; \ 263 | fmv.x.d a0, f3; \ 264 | fsflags a1, x0; \ 265 | li a2, flags; \ 266 | bne a0, a3, fail; \ 267 | bne a1, a2, fail; \ 268 | .pushsection .data; \ 269 | .align 3; \ 270 | test_ ## testnum ## _data: \ 271 | .double result; \ 272 | .float val1; \ 273 | .popsection 274 | 275 | #define TEST_FCVT_S_D_RM( testnum, flags, result, val1, rm) \ 276 | test_ ## testnum: \ 277 | li TESTNUM, testnum; \ 278 | la a0, test_ ## testnum ## _data ;\ 279 | fld f0, 0(a0); \ 280 | lw a3, 8(a0); \ 281 | fcvt.s.d f3, f0; \ 282 | fmv.x.s a0, f3; \ 283 | fsflags a1, x0; \ 284 | li a2, flags; \ 285 | bne a0, a3, fail; \ 286 | bne a1, a2, fail; \ 287 | .pushsection .data; \ 288 | .align 3; \ 289 | test_ ## testnum ## _data: \ 290 | .double val1; \ 291 | .float result; \ 292 | .popsection 293 | 294 | #endif 295 | -------------------------------------------------------------------------------- /src/funary.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 | #include "float_util.h" 21 | 22 | RVTEST_RV64UF 23 | RVTEST_CODE_BEGIN 24 | 25 | TEST_FP_OP1_RM_S(1, fsqrt.s, 0x00, 0f:80000000, 0f:80000000, rne); 26 | TEST_FP_OP1_RM_S(2, fsqrt.s, 0x10, 0f:7fc00000, 0f:807fffff, rne); 27 | TEST_FP_OP1_RM_S(3, fsqrt.s, 0x10, 0f:7fc00000, 0f:bf800000, rne); 28 | TEST_FP_OP1_RM_S(4, fsqrt.s, 0x10, 0f:7fc00000, 0f:ff800000, rne); 29 | TEST_FP_OP1_RM_S(5, fsqrt.s, 0x10, 0f:7fc00000, 0f:ff7fffff, rne); 30 | TEST_FP_OP1_RM_S(6, fsqrt.s, 0x10, 0f:7fc00000, 0f:80000001, rne); 31 | TEST_FP_OP1_RM_S(7, fsqrt.s, 0x10, 0f:7fc00000, 0f:ff800001, rne); 32 | TEST_FP_OP1_RM_S(8, fsqrt.s, 0x00, 0f:7fc00000, 0f:ffc00000, rne); 33 | TEST_FP_OP1_RM_S(9, fsqrt.s, 0x00, 0f:00000000, 0f:00000000, rne); 34 | TEST_FP_OP1_RM_S(10, fsqrt.s, 0x01, 0f:1fffffff, 0f:007fffff, rne); 35 | TEST_FP_OP1_RM_S(11, fsqrt.s, 0x00, 0f:3f800000, 0f:3f800000, rne); 36 | TEST_FP_OP1_RM_S(12, fsqrt.s, 0x00, 0f:7f800000, 0f:7f800000, rne); 37 | TEST_FP_OP1_RM_S(13, fsqrt.s, 0x01, 0f:5f7fffff, 0f:7f7fffff, rne); 38 | TEST_FP_OP1_RM_S(14, fsqrt.s, 0x01, 0f:1a3504f3, 0f:00000001, rne); 39 | TEST_FP_OP1_RM_S(15, fsqrt.s, 0x10, 0f:7fc00000, 0f:7f800001, rne); 40 | TEST_FP_OP1_RM_S(16, fsqrt.s, 0x00, 0f:7fc00000, 0f:7fc00000, rne); 41 | TEST_FP_OP1_RM_S(17, fsqrt.s, 0x00, 0f:20000000, 0f:00800000, rne); 42 | TEST_FP_OP1_RM_S(18, fsqrt.s, 0x10, 0f:7fc00000, 0f:80800000, rne); 43 | TEST_FP_OP1_RM_S(19, fsqrt.s, 0x01, 0f:3fb97d58, 0f:40066666, rne); 44 | TEST_FP_OP1_RM_S(20, fsqrt.s, 0x10, 0f:7fc00000, 0f:c0066666, rne); 45 | TEST_FP_OP1_RM_S(21, fsqrt.s, 0x01, 0f:3f3504f3, 0f:3f000000, rne); 46 | TEST_FP_OP1_RM_S(22, fsqrt.s, 0x10, 0f:7fc00000, 0f:bf000000, rne); 47 | TEST_FP_OP1_RM_S(23, fsqrt.s, 0x01, 0f:46b504f3, 0f:4e000000, rne); 48 | TEST_FP_OP1_RM_S(24, fsqrt.s, 0x01, 0f:4f3504f3, 0f:5f000000, rne); 49 | TEST_FP_OP1_RM_S(25, fsqrt.s, 0x10, 0f:7fc00000, 0f:cfffd7ff, rne); 50 | TEST_FP_OP1_RM_S(26, fsqrt.s, 0x00, 0f:80000000, 0f:80000000, rtz); 51 | TEST_FP_OP1_RM_S(27, fsqrt.s, 0x10, 0f:7fc00000, 0f:807fffff, rtz); 52 | TEST_FP_OP1_RM_S(28, fsqrt.s, 0x10, 0f:7fc00000, 0f:bf800000, rtz); 53 | TEST_FP_OP1_RM_S(29, fsqrt.s, 0x10, 0f:7fc00000, 0f:ff800000, rtz); 54 | TEST_FP_OP1_RM_S(30, fsqrt.s, 0x10, 0f:7fc00000, 0f:ff7fffff, rtz); 55 | TEST_FP_OP1_RM_S(31, fsqrt.s, 0x10, 0f:7fc00000, 0f:80000001, rtz); 56 | TEST_FP_OP1_RM_S(32, fsqrt.s, 0x10, 0f:7fc00000, 0f:ff800001, rtz); 57 | TEST_FP_OP1_RM_S(33, fsqrt.s, 0x00, 0f:7fc00000, 0f:ffc00000, rtz); 58 | TEST_FP_OP1_RM_S(34, fsqrt.s, 0x00, 0f:00000000, 0f:00000000, rtz); 59 | TEST_FP_OP1_RM_S(35, fsqrt.s, 0x01, 0f:1ffffffe, 0f:007fffff, rtz); 60 | TEST_FP_OP1_RM_S(36, fsqrt.s, 0x00, 0f:3f800000, 0f:3f800000, rtz); 61 | TEST_FP_OP1_RM_S(37, fsqrt.s, 0x00, 0f:7f800000, 0f:7f800000, rtz); 62 | TEST_FP_OP1_RM_S(38, fsqrt.s, 0x01, 0f:5f7fffff, 0f:7f7fffff, rtz); 63 | TEST_FP_OP1_RM_S(39, fsqrt.s, 0x01, 0f:1a3504f3, 0f:00000001, rtz); 64 | TEST_FP_OP1_RM_S(40, fsqrt.s, 0x10, 0f:7fc00000, 0f:7f800001, rtz); 65 | TEST_FP_OP1_RM_S(41, fsqrt.s, 0x00, 0f:7fc00000, 0f:7fc00000, rtz); 66 | TEST_FP_OP1_RM_S(42, fsqrt.s, 0x00, 0f:20000000, 0f:00800000, rtz); 67 | TEST_FP_OP1_RM_S(43, fsqrt.s, 0x10, 0f:7fc00000, 0f:80800000, rtz); 68 | TEST_FP_OP1_RM_S(44, fsqrt.s, 0x01, 0f:3fb97d57, 0f:40066666, rtz); 69 | TEST_FP_OP1_RM_S(45, fsqrt.s, 0x10, 0f:7fc00000, 0f:c0066666, rtz); 70 | TEST_FP_OP1_RM_S(46, fsqrt.s, 0x01, 0f:3f3504f3, 0f:3f000000, rtz); 71 | TEST_FP_OP1_RM_S(47, fsqrt.s, 0x10, 0f:7fc00000, 0f:bf000000, rtz); 72 | TEST_FP_OP1_RM_S(48, fsqrt.s, 0x01, 0f:46b504f3, 0f:4e000000, rtz); 73 | TEST_FP_OP1_RM_S(49, fsqrt.s, 0x01, 0f:4f3504f3, 0f:5f000000, rtz); 74 | TEST_FP_OP1_RM_S(50, fsqrt.s, 0x10, 0f:7fc00000, 0f:cfffd7ff, rtz); 75 | TEST_FP_OP1_RM_S(51, fsqrt.s, 0x00, 0f:80000000, 0f:80000000, rdn); 76 | TEST_FP_OP1_RM_S(52, fsqrt.s, 0x10, 0f:7fc00000, 0f:807fffff, rdn); 77 | TEST_FP_OP1_RM_S(53, fsqrt.s, 0x10, 0f:7fc00000, 0f:bf800000, rdn); 78 | TEST_FP_OP1_RM_S(54, fsqrt.s, 0x10, 0f:7fc00000, 0f:ff800000, rdn); 79 | TEST_FP_OP1_RM_S(55, fsqrt.s, 0x10, 0f:7fc00000, 0f:ff7fffff, rdn); 80 | TEST_FP_OP1_RM_S(56, fsqrt.s, 0x10, 0f:7fc00000, 0f:80000001, rdn); 81 | TEST_FP_OP1_RM_S(57, fsqrt.s, 0x10, 0f:7fc00000, 0f:ff800001, rdn); 82 | TEST_FP_OP1_RM_S(58, fsqrt.s, 0x00, 0f:7fc00000, 0f:ffc00000, rdn); 83 | TEST_FP_OP1_RM_S(59, fsqrt.s, 0x00, 0f:00000000, 0f:00000000, rdn); 84 | TEST_FP_OP1_RM_S(60, fsqrt.s, 0x01, 0f:1ffffffe, 0f:007fffff, rdn); 85 | TEST_FP_OP1_RM_S(61, fsqrt.s, 0x00, 0f:3f800000, 0f:3f800000, rdn); 86 | TEST_FP_OP1_RM_S(62, fsqrt.s, 0x00, 0f:7f800000, 0f:7f800000, rdn); 87 | TEST_FP_OP1_RM_S(63, fsqrt.s, 0x01, 0f:5f7fffff, 0f:7f7fffff, rdn); 88 | TEST_FP_OP1_RM_S(64, fsqrt.s, 0x01, 0f:1a3504f3, 0f:00000001, rdn); 89 | TEST_FP_OP1_RM_S(65, fsqrt.s, 0x10, 0f:7fc00000, 0f:7f800001, rdn); 90 | TEST_FP_OP1_RM_S(66, fsqrt.s, 0x00, 0f:7fc00000, 0f:7fc00000, rdn); 91 | TEST_FP_OP1_RM_S(67, fsqrt.s, 0x00, 0f:20000000, 0f:00800000, rdn); 92 | TEST_FP_OP1_RM_S(68, fsqrt.s, 0x10, 0f:7fc00000, 0f:80800000, rdn); 93 | TEST_FP_OP1_RM_S(69, fsqrt.s, 0x01, 0f:3fb97d57, 0f:40066666, rdn); 94 | TEST_FP_OP1_RM_S(70, fsqrt.s, 0x10, 0f:7fc00000, 0f:c0066666, rdn); 95 | TEST_FP_OP1_RM_S(71, fsqrt.s, 0x01, 0f:3f3504f3, 0f:3f000000, rdn); 96 | TEST_FP_OP1_RM_S(72, fsqrt.s, 0x10, 0f:7fc00000, 0f:bf000000, rdn); 97 | TEST_FP_OP1_RM_S(73, fsqrt.s, 0x01, 0f:46b504f3, 0f:4e000000, rdn); 98 | TEST_FP_OP1_RM_S(74, fsqrt.s, 0x01, 0f:4f3504f3, 0f:5f000000, rdn); 99 | TEST_FP_OP1_RM_S(75, fsqrt.s, 0x10, 0f:7fc00000, 0f:cfffd7ff, rdn); 100 | TEST_FP_OP1_RM_S(76, fsqrt.s, 0x00, 0f:80000000, 0f:80000000, rup); 101 | TEST_FP_OP1_RM_S(77, fsqrt.s, 0x10, 0f:7fc00000, 0f:807fffff, rup); 102 | TEST_FP_OP1_RM_S(78, fsqrt.s, 0x10, 0f:7fc00000, 0f:bf800000, rup); 103 | TEST_FP_OP1_RM_S(79, fsqrt.s, 0x10, 0f:7fc00000, 0f:ff800000, rup); 104 | TEST_FP_OP1_RM_S(80, fsqrt.s, 0x10, 0f:7fc00000, 0f:ff7fffff, rup); 105 | TEST_FP_OP1_RM_S(81, fsqrt.s, 0x10, 0f:7fc00000, 0f:80000001, rup); 106 | TEST_FP_OP1_RM_S(82, fsqrt.s, 0x10, 0f:7fc00000, 0f:ff800001, rup); 107 | TEST_FP_OP1_RM_S(83, fsqrt.s, 0x00, 0f:7fc00000, 0f:ffc00000, rup); 108 | TEST_FP_OP1_RM_S(84, fsqrt.s, 0x00, 0f:00000000, 0f:00000000, rup); 109 | TEST_FP_OP1_RM_S(85, fsqrt.s, 0x01, 0f:1fffffff, 0f:007fffff, rup); 110 | TEST_FP_OP1_RM_S(86, fsqrt.s, 0x00, 0f:3f800000, 0f:3f800000, rup); 111 | TEST_FP_OP1_RM_S(87, fsqrt.s, 0x00, 0f:7f800000, 0f:7f800000, rup); 112 | TEST_FP_OP1_RM_S(88, fsqrt.s, 0x01, 0f:5f800000, 0f:7f7fffff, rup); 113 | TEST_FP_OP1_RM_S(89, fsqrt.s, 0x01, 0f:1a3504f4, 0f:00000001, rup); 114 | TEST_FP_OP1_RM_S(90, fsqrt.s, 0x10, 0f:7fc00000, 0f:7f800001, rup); 115 | TEST_FP_OP1_RM_S(91, fsqrt.s, 0x00, 0f:7fc00000, 0f:7fc00000, rup); 116 | TEST_FP_OP1_RM_S(92, fsqrt.s, 0x00, 0f:20000000, 0f:00800000, rup); 117 | TEST_FP_OP1_RM_S(93, fsqrt.s, 0x10, 0f:7fc00000, 0f:80800000, rup); 118 | TEST_FP_OP1_RM_S(94, fsqrt.s, 0x01, 0f:3fb97d58, 0f:40066666, rup); 119 | TEST_FP_OP1_RM_S(95, fsqrt.s, 0x10, 0f:7fc00000, 0f:c0066666, rup); 120 | TEST_FP_OP1_RM_S(96, fsqrt.s, 0x01, 0f:3f3504f4, 0f:3f000000, rup); 121 | TEST_FP_OP1_RM_S(97, fsqrt.s, 0x10, 0f:7fc00000, 0f:bf000000, rup); 122 | TEST_FP_OP1_RM_S(98, fsqrt.s, 0x01, 0f:46b504f4, 0f:4e000000, rup); 123 | TEST_FP_OP1_RM_S(99, fsqrt.s, 0x01, 0f:4f3504f4, 0f:5f000000, rup); 124 | TEST_FP_OP1_RM_S(100, fsqrt.s, 0x10, 0f:7fc00000, 0f:cfffd7ff, rup); 125 | TEST_FP_OP1_RM_S(101, fsqrt.s, 0x00, 0f:80000000, 0f:80000000, rmm); 126 | TEST_FP_OP1_RM_S(102, fsqrt.s, 0x10, 0f:7fc00000, 0f:807fffff, rmm); 127 | TEST_FP_OP1_RM_S(103, fsqrt.s, 0x10, 0f:7fc00000, 0f:bf800000, rmm); 128 | TEST_FP_OP1_RM_S(104, fsqrt.s, 0x10, 0f:7fc00000, 0f:ff800000, rmm); 129 | TEST_FP_OP1_RM_S(105, fsqrt.s, 0x10, 0f:7fc00000, 0f:ff7fffff, rmm); 130 | TEST_FP_OP1_RM_S(106, fsqrt.s, 0x10, 0f:7fc00000, 0f:80000001, rmm); 131 | TEST_FP_OP1_RM_S(107, fsqrt.s, 0x10, 0f:7fc00000, 0f:ff800001, rmm); 132 | TEST_FP_OP1_RM_S(108, fsqrt.s, 0x00, 0f:7fc00000, 0f:ffc00000, rmm); 133 | TEST_FP_OP1_RM_S(109, fsqrt.s, 0x00, 0f:00000000, 0f:00000000, rmm); 134 | TEST_FP_OP1_RM_S(110, fsqrt.s, 0x01, 0f:1fffffff, 0f:007fffff, rmm); 135 | TEST_FP_OP1_RM_S(111, fsqrt.s, 0x00, 0f:3f800000, 0f:3f800000, rmm); 136 | TEST_FP_OP1_RM_S(112, fsqrt.s, 0x00, 0f:7f800000, 0f:7f800000, rmm); 137 | TEST_FP_OP1_RM_S(113, fsqrt.s, 0x01, 0f:5f7fffff, 0f:7f7fffff, rmm); 138 | TEST_FP_OP1_RM_S(114, fsqrt.s, 0x01, 0f:1a3504f3, 0f:00000001, rmm); 139 | TEST_FP_OP1_RM_S(115, fsqrt.s, 0x10, 0f:7fc00000, 0f:7f800001, rmm); 140 | TEST_FP_OP1_RM_S(116, fsqrt.s, 0x00, 0f:7fc00000, 0f:7fc00000, rmm); 141 | TEST_FP_OP1_RM_S(117, fsqrt.s, 0x00, 0f:20000000, 0f:00800000, rmm); 142 | TEST_FP_OP1_RM_S(118, fsqrt.s, 0x10, 0f:7fc00000, 0f:80800000, rmm); 143 | TEST_FP_OP1_RM_S(119, fsqrt.s, 0x01, 0f:3fb97d58, 0f:40066666, rmm); 144 | TEST_FP_OP1_RM_S(120, fsqrt.s, 0x10, 0f:7fc00000, 0f:c0066666, rmm); 145 | TEST_FP_OP1_RM_S(121, fsqrt.s, 0x01, 0f:3f3504f3, 0f:3f000000, rmm); 146 | TEST_FP_OP1_RM_S(122, fsqrt.s, 0x10, 0f:7fc00000, 0f:bf000000, rmm); 147 | TEST_FP_OP1_RM_S(123, fsqrt.s, 0x01, 0f:46b504f3, 0f:4e000000, rmm); 148 | TEST_FP_OP1_RM_S(124, fsqrt.s, 0x01, 0f:4f3504f3, 0f:5f000000, rmm); 149 | TEST_FP_OP1_RM_S(125, fsqrt.s, 0x10, 0f:7fc00000, 0f:cfffd7ff, rmm); 150 | TEST_FP_OP1_RM_D(126, fsqrt.d, 0x00, 0f:8000000000000000, 0f:8000000000000000, rne); 151 | TEST_FP_OP1_RM_D(127, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:800fffffffffffff, rne); 152 | TEST_FP_OP1_RM_D(128, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:bff0000000000000, rne); 153 | TEST_FP_OP1_RM_D(129, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:fff0000000000000, rne); 154 | TEST_FP_OP1_RM_D(130, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:ffefffffffffffff, rne); 155 | TEST_FP_OP1_RM_D(131, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:8000000000000001, rne); 156 | TEST_FP_OP1_RM_D(132, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:fff0000000000001, rne); 157 | TEST_FP_OP1_RM_D(133, fsqrt.d, 0x00, 0f:7ff8000000000000, 0f:fff8000000000000, rne); 158 | TEST_FP_OP1_RM_D(134, fsqrt.d, 0x00, 0f:0000000000000000, 0f:0000000000000000, rne); 159 | TEST_FP_OP1_RM_D(135, fsqrt.d, 0x01, 0f:1fffffffffffffff, 0f:000fffffffffffff, rne); 160 | TEST_FP_OP1_RM_D(136, fsqrt.d, 0x00, 0f:3ff0000000000000, 0f:3ff0000000000000, rne); 161 | TEST_FP_OP1_RM_D(137, fsqrt.d, 0x00, 0f:7ff0000000000000, 0f:7ff0000000000000, rne); 162 | TEST_FP_OP1_RM_D(138, fsqrt.d, 0x01, 0f:5fefffffffffffff, 0f:7fefffffffffffff, rne); 163 | TEST_FP_OP1_RM_D(139, fsqrt.d, 0x00, 0f:1e60000000000000, 0f:0000000000000001, rne); 164 | TEST_FP_OP1_RM_D(140, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:7ff0000000000001, rne); 165 | TEST_FP_OP1_RM_D(141, fsqrt.d, 0x00, 0f:7ff8000000000000, 0f:7ff8000000000000, rne); 166 | TEST_FP_OP1_RM_D(142, fsqrt.d, 0x00, 0f:2000000000000000, 0f:0010000000000000, rne); 167 | TEST_FP_OP1_RM_D(143, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:8010000000000000, rne); 168 | TEST_FP_OP1_RM_D(144, fsqrt.d, 0x01, 0f:3ff72faafc7e3cd7, 0f:4000cccccccccccd, rne); 169 | TEST_FP_OP1_RM_D(145, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:c000cccccccccccd, rne); 170 | TEST_FP_OP1_RM_D(146, fsqrt.d, 0x01, 0f:3fe6a09e667f3bcd, 0f:3fe0000000000000, rne); 171 | TEST_FP_OP1_RM_D(147, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:bfe0000000000000, rne); 172 | TEST_FP_OP1_RM_D(148, fsqrt.d, 0x01, 0f:47d6a09e667f3bcd, 0f:4fc0000000000000, rne); 173 | TEST_FP_OP1_RM_D(149, fsqrt.d, 0x01, 0f:4fe6a09e667f3bcd, 0f:5fe0000000000000, rne); 174 | TEST_FP_OP1_RM_D(150, fsqrt.d, 0x01, 0f:3f9116ff033cb0d0, 0f:3f3240fef40a55d0, rne); 175 | TEST_FP_OP1_RM_D(151, fsqrt.d, 0x00, 0f:8000000000000000, 0f:8000000000000000, rtz); 176 | TEST_FP_OP1_RM_D(152, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:800fffffffffffff, rtz); 177 | TEST_FP_OP1_RM_D(153, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:bff0000000000000, rtz); 178 | TEST_FP_OP1_RM_D(154, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:fff0000000000000, rtz); 179 | TEST_FP_OP1_RM_D(155, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:ffefffffffffffff, rtz); 180 | TEST_FP_OP1_RM_D(156, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:8000000000000001, rtz); 181 | TEST_FP_OP1_RM_D(157, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:fff0000000000001, rtz); 182 | TEST_FP_OP1_RM_D(158, fsqrt.d, 0x00, 0f:7ff8000000000000, 0f:fff8000000000000, rtz); 183 | TEST_FP_OP1_RM_D(159, fsqrt.d, 0x00, 0f:0000000000000000, 0f:0000000000000000, rtz); 184 | TEST_FP_OP1_RM_D(160, fsqrt.d, 0x01, 0f:1ffffffffffffffe, 0f:000fffffffffffff, rtz); 185 | TEST_FP_OP1_RM_D(161, fsqrt.d, 0x00, 0f:3ff0000000000000, 0f:3ff0000000000000, rtz); 186 | TEST_FP_OP1_RM_D(162, fsqrt.d, 0x00, 0f:7ff0000000000000, 0f:7ff0000000000000, rtz); 187 | TEST_FP_OP1_RM_D(163, fsqrt.d, 0x01, 0f:5fefffffffffffff, 0f:7fefffffffffffff, rtz); 188 | TEST_FP_OP1_RM_D(164, fsqrt.d, 0x00, 0f:1e60000000000000, 0f:0000000000000001, rtz); 189 | TEST_FP_OP1_RM_D(165, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:7ff0000000000001, rtz); 190 | TEST_FP_OP1_RM_D(166, fsqrt.d, 0x00, 0f:7ff8000000000000, 0f:7ff8000000000000, rtz); 191 | TEST_FP_OP1_RM_D(167, fsqrt.d, 0x00, 0f:2000000000000000, 0f:0010000000000000, rtz); 192 | TEST_FP_OP1_RM_D(168, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:8010000000000000, rtz); 193 | TEST_FP_OP1_RM_D(169, fsqrt.d, 0x01, 0f:3ff72faafc7e3cd6, 0f:4000cccccccccccd, rtz); 194 | TEST_FP_OP1_RM_D(170, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:c000cccccccccccd, rtz); 195 | TEST_FP_OP1_RM_D(171, fsqrt.d, 0x01, 0f:3fe6a09e667f3bcc, 0f:3fe0000000000000, rtz); 196 | TEST_FP_OP1_RM_D(172, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:bfe0000000000000, rtz); 197 | TEST_FP_OP1_RM_D(173, fsqrt.d, 0x01, 0f:47d6a09e667f3bcc, 0f:4fc0000000000000, rtz); 198 | TEST_FP_OP1_RM_D(174, fsqrt.d, 0x01, 0f:4fe6a09e667f3bcc, 0f:5fe0000000000000, rtz); 199 | TEST_FP_OP1_RM_D(175, fsqrt.d, 0x01, 0f:3f9116ff033cb0d0, 0f:3f3240fef40a55d0, rtz); 200 | TEST_FP_OP1_RM_D(176, fsqrt.d, 0x00, 0f:8000000000000000, 0f:8000000000000000, rdn); 201 | TEST_FP_OP1_RM_D(177, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:800fffffffffffff, rdn); 202 | TEST_FP_OP1_RM_D(178, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:bff0000000000000, rdn); 203 | TEST_FP_OP1_RM_D(179, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:fff0000000000000, rdn); 204 | TEST_FP_OP1_RM_D(180, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:ffefffffffffffff, rdn); 205 | TEST_FP_OP1_RM_D(181, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:8000000000000001, rdn); 206 | TEST_FP_OP1_RM_D(182, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:fff0000000000001, rdn); 207 | TEST_FP_OP1_RM_D(183, fsqrt.d, 0x00, 0f:7ff8000000000000, 0f:fff8000000000000, rdn); 208 | TEST_FP_OP1_RM_D(184, fsqrt.d, 0x00, 0f:0000000000000000, 0f:0000000000000000, rdn); 209 | TEST_FP_OP1_RM_D(185, fsqrt.d, 0x01, 0f:1ffffffffffffffe, 0f:000fffffffffffff, rdn); 210 | TEST_FP_OP1_RM_D(186, fsqrt.d, 0x00, 0f:3ff0000000000000, 0f:3ff0000000000000, rdn); 211 | TEST_FP_OP1_RM_D(187, fsqrt.d, 0x00, 0f:7ff0000000000000, 0f:7ff0000000000000, rdn); 212 | TEST_FP_OP1_RM_D(188, fsqrt.d, 0x01, 0f:5fefffffffffffff, 0f:7fefffffffffffff, rdn); 213 | TEST_FP_OP1_RM_D(189, fsqrt.d, 0x00, 0f:1e60000000000000, 0f:0000000000000001, rdn); 214 | TEST_FP_OP1_RM_D(190, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:7ff0000000000001, rdn); 215 | TEST_FP_OP1_RM_D(191, fsqrt.d, 0x00, 0f:7ff8000000000000, 0f:7ff8000000000000, rdn); 216 | TEST_FP_OP1_RM_D(192, fsqrt.d, 0x00, 0f:2000000000000000, 0f:0010000000000000, rdn); 217 | TEST_FP_OP1_RM_D(193, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:8010000000000000, rdn); 218 | TEST_FP_OP1_RM_D(194, fsqrt.d, 0x01, 0f:3ff72faafc7e3cd6, 0f:4000cccccccccccd, rdn); 219 | TEST_FP_OP1_RM_D(195, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:c000cccccccccccd, rdn); 220 | TEST_FP_OP1_RM_D(196, fsqrt.d, 0x01, 0f:3fe6a09e667f3bcc, 0f:3fe0000000000000, rdn); 221 | TEST_FP_OP1_RM_D(197, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:bfe0000000000000, rdn); 222 | TEST_FP_OP1_RM_D(198, fsqrt.d, 0x01, 0f:47d6a09e667f3bcc, 0f:4fc0000000000000, rdn); 223 | TEST_FP_OP1_RM_D(199, fsqrt.d, 0x01, 0f:4fe6a09e667f3bcc, 0f:5fe0000000000000, rdn); 224 | TEST_FP_OP1_RM_D(200, fsqrt.d, 0x01, 0f:3f9116ff033cb0d0, 0f:3f3240fef40a55d0, rdn); 225 | TEST_FP_OP1_RM_D(201, fsqrt.d, 0x00, 0f:8000000000000000, 0f:8000000000000000, rup); 226 | TEST_FP_OP1_RM_D(202, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:800fffffffffffff, rup); 227 | TEST_FP_OP1_RM_D(203, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:bff0000000000000, rup); 228 | TEST_FP_OP1_RM_D(204, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:fff0000000000000, rup); 229 | TEST_FP_OP1_RM_D(205, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:ffefffffffffffff, rup); 230 | TEST_FP_OP1_RM_D(206, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:8000000000000001, rup); 231 | TEST_FP_OP1_RM_D(207, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:fff0000000000001, rup); 232 | TEST_FP_OP1_RM_D(208, fsqrt.d, 0x00, 0f:7ff8000000000000, 0f:fff8000000000000, rup); 233 | TEST_FP_OP1_RM_D(209, fsqrt.d, 0x00, 0f:0000000000000000, 0f:0000000000000000, rup); 234 | TEST_FP_OP1_RM_D(210, fsqrt.d, 0x01, 0f:1fffffffffffffff, 0f:000fffffffffffff, rup); 235 | TEST_FP_OP1_RM_D(211, fsqrt.d, 0x00, 0f:3ff0000000000000, 0f:3ff0000000000000, rup); 236 | TEST_FP_OP1_RM_D(212, fsqrt.d, 0x00, 0f:7ff0000000000000, 0f:7ff0000000000000, rup); 237 | TEST_FP_OP1_RM_D(213, fsqrt.d, 0x01, 0f:5ff0000000000000, 0f:7fefffffffffffff, rup); 238 | TEST_FP_OP1_RM_D(214, fsqrt.d, 0x00, 0f:1e60000000000000, 0f:0000000000000001, rup); 239 | TEST_FP_OP1_RM_D(215, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:7ff0000000000001, rup); 240 | TEST_FP_OP1_RM_D(216, fsqrt.d, 0x00, 0f:7ff8000000000000, 0f:7ff8000000000000, rup); 241 | TEST_FP_OP1_RM_D(217, fsqrt.d, 0x00, 0f:2000000000000000, 0f:0010000000000000, rup); 242 | TEST_FP_OP1_RM_D(218, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:8010000000000000, rup); 243 | TEST_FP_OP1_RM_D(219, fsqrt.d, 0x01, 0f:3ff72faafc7e3cd7, 0f:4000cccccccccccd, rup); 244 | TEST_FP_OP1_RM_D(220, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:c000cccccccccccd, rup); 245 | TEST_FP_OP1_RM_D(221, fsqrt.d, 0x01, 0f:3fe6a09e667f3bcd, 0f:3fe0000000000000, rup); 246 | TEST_FP_OP1_RM_D(222, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:bfe0000000000000, rup); 247 | TEST_FP_OP1_RM_D(223, fsqrt.d, 0x01, 0f:47d6a09e667f3bcd, 0f:4fc0000000000000, rup); 248 | TEST_FP_OP1_RM_D(224, fsqrt.d, 0x01, 0f:4fe6a09e667f3bcd, 0f:5fe0000000000000, rup); 249 | TEST_FP_OP1_RM_D(225, fsqrt.d, 0x01, 0f:3f9116ff033cb0d1, 0f:3f3240fef40a55d0, rup); 250 | TEST_FP_OP1_RM_D(226, fsqrt.d, 0x00, 0f:8000000000000000, 0f:8000000000000000, rmm); 251 | TEST_FP_OP1_RM_D(227, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:800fffffffffffff, rmm); 252 | TEST_FP_OP1_RM_D(228, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:bff0000000000000, rmm); 253 | TEST_FP_OP1_RM_D(229, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:fff0000000000000, rmm); 254 | TEST_FP_OP1_RM_D(230, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:ffefffffffffffff, rmm); 255 | TEST_FP_OP1_RM_D(231, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:8000000000000001, rmm); 256 | TEST_FP_OP1_RM_D(232, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:fff0000000000001, rmm); 257 | TEST_FP_OP1_RM_D(233, fsqrt.d, 0x00, 0f:7ff8000000000000, 0f:fff8000000000000, rmm); 258 | TEST_FP_OP1_RM_D(234, fsqrt.d, 0x00, 0f:0000000000000000, 0f:0000000000000000, rmm); 259 | TEST_FP_OP1_RM_D(235, fsqrt.d, 0x01, 0f:1fffffffffffffff, 0f:000fffffffffffff, rmm); 260 | TEST_FP_OP1_RM_D(236, fsqrt.d, 0x00, 0f:3ff0000000000000, 0f:3ff0000000000000, rmm); 261 | TEST_FP_OP1_RM_D(237, fsqrt.d, 0x00, 0f:7ff0000000000000, 0f:7ff0000000000000, rmm); 262 | TEST_FP_OP1_RM_D(238, fsqrt.d, 0x01, 0f:5fefffffffffffff, 0f:7fefffffffffffff, rmm); 263 | TEST_FP_OP1_RM_D(239, fsqrt.d, 0x00, 0f:1e60000000000000, 0f:0000000000000001, rmm); 264 | TEST_FP_OP1_RM_D(240, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:7ff0000000000001, rmm); 265 | TEST_FP_OP1_RM_D(241, fsqrt.d, 0x00, 0f:7ff8000000000000, 0f:7ff8000000000000, rmm); 266 | TEST_FP_OP1_RM_D(242, fsqrt.d, 0x00, 0f:2000000000000000, 0f:0010000000000000, rmm); 267 | TEST_FP_OP1_RM_D(243, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:8010000000000000, rmm); 268 | TEST_FP_OP1_RM_D(244, fsqrt.d, 0x01, 0f:3ff72faafc7e3cd7, 0f:4000cccccccccccd, rmm); 269 | TEST_FP_OP1_RM_D(245, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:c000cccccccccccd, rmm); 270 | TEST_FP_OP1_RM_D(246, fsqrt.d, 0x01, 0f:3fe6a09e667f3bcd, 0f:3fe0000000000000, rmm); 271 | TEST_FP_OP1_RM_D(247, fsqrt.d, 0x10, 0f:7ff8000000000000, 0f:bfe0000000000000, rmm); 272 | TEST_FP_OP1_RM_D(248, fsqrt.d, 0x01, 0f:47d6a09e667f3bcd, 0f:4fc0000000000000, rmm); 273 | TEST_FP_OP1_RM_D(249, fsqrt.d, 0x01, 0f:4fe6a09e667f3bcd, 0f:5fe0000000000000, rmm); 274 | TEST_FP_OP1_RM_D(250, fsqrt.d, 0x01, 0f:3f9116ff033cb0d0, 0f:3f3240fef40a55d0, rmm); 275 | 276 | TEST_PASSFAIL 277 | 278 | RVTEST_CODE_END 279 | 280 | .data 281 | RVTEST_DATA_BEGIN 282 | 283 | TEST_DATA 284 | 285 | RVTEST_DATA_END 286 | 287 | -------------------------------------------------------------------------------- /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_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 | -------------------------------------------------------------------------------- /src/htif_invalid_ops.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 programs exercise invalid load/writes in the HTIF device. 19 | 20 | #include "htif_util.h" 21 | 22 | // Uses HTIF to exit the emulator with exit code in an immediate 23 | #define exit_imm(imm) \ 24 | li gp, imm; \ 25 | j exit; 26 | 27 | #define expect_trap(cause, code...) \ 28 | li a0, cause; \ 29 | li a1, 1; \ 30 | code \ 31 | bnez a1, fail; 32 | 33 | #define MCAUSE_STORE_AMO_ACCESS_FAULT 0x7 34 | #define MCAUSE_LOAD_ACCESS_FAULT 0x5 35 | 36 | // Section with code 37 | .section .text.init 38 | .align 2; 39 | .global _start; 40 | _start: 41 | // Set the exception handler to trap 42 | la t0, fail; 43 | csrw mtvec, t0; 44 | 45 | // Unknown HTIF devices are silently ignored 46 | li t0, PMA_HTIF_START_DEF; 47 | li t1, htif_const(0xff, 0, 0); 48 | sd zero, O_FROMHOST(t0); 49 | sd t1, O_TOHOST(t0); 50 | ld t2, O_FROMHOST(t0); 51 | bnez t2, fail; 52 | 53 | // HTIF halt with invalid commands is silently ignored 54 | li t0, PMA_HTIF_START_DEF; 55 | li t1, htif_const(HTIF_DEVICE_HALT_DEF, 0xff, 3); 56 | sd zero, O_FROMHOST(t0); 57 | sd t1, O_TOHOST(t0); 58 | ld t2, O_FROMHOST(t0); 59 | bnez t2, fail; 60 | 61 | // HTIF halt with exit least-signed bit unset is silently ignored 62 | li t0, PMA_HTIF_START_DEF; 63 | li t1, htif_const(HTIF_DEVICE_HALT_DEF, HTIF_HALT_HALT_DEF, 2); 64 | sd zero, O_FROMHOST(t0); 65 | sd t1, O_TOHOST(t0); 66 | ld t2, O_FROMHOST(t0); 67 | bnez t2, fail; 68 | 69 | // Set the exception handler to skip instructions 70 | la t0, skip_insn_trap; 71 | csrw mtvec, t0; 72 | 73 | // Attempt to load a non 8-bytes value from HTIF 74 | expect_trap(MCAUSE_LOAD_ACCESS_FAULT, 75 | li t0, PMA_HTIF_START_DEF; 76 | lw t1, O_TOHOST(t0); 77 | ) 78 | 79 | // Attempt to load from a misaligned HTIF offset 80 | expect_trap(MCAUSE_LOAD_ACCESS_FAULT, 81 | li t0, PMA_HTIF_START_DEF; 82 | lb t1, 1(t0); 83 | ) 84 | 85 | // Attempt to load from an invalid HTIF offset 86 | expect_trap(MCAUSE_LOAD_ACCESS_FAULT, 87 | li t0, PMA_HTIF_START_DEF; 88 | ld t1, (O_IYIELD+8)(t0); 89 | ) 90 | 91 | // Attempt to store a non 8-bytes value in HTIF 92 | expect_trap(MCAUSE_STORE_AMO_ACCESS_FAULT, 93 | li t0, PMA_HTIF_START_DEF; 94 | li t1, 3; 95 | sw t1, O_TOHOST(t0); 96 | ) 97 | 98 | // Attempt to store in a misaligned HTIF offset 99 | expect_trap(MCAUSE_STORE_AMO_ACCESS_FAULT, 100 | li t0, PMA_HTIF_START_DEF; 101 | li t1, 3; 102 | sb t1, 1(t0); 103 | ) 104 | 105 | // Attempt to store in an invalid HTIF offset 106 | expect_trap(MCAUSE_STORE_AMO_ACCESS_FAULT, 107 | li t0, PMA_HTIF_START_DEF; 108 | li t1, 3; 109 | sd t1, (O_IYIELD+8)(t0); 110 | ) 111 | 112 | exit_imm(0); 113 | 114 | skip_insn_trap: 115 | csrr gp, mcause; 116 | bne gp, a0, exit; 117 | csrr t5, mepc; 118 | addi t5, t5, 4; 119 | csrw mepc, t5; 120 | addi a1, a1, -1; 121 | mret; 122 | 123 | fail: 124 | exit_imm(1); 125 | 126 | // Exits via HTIF using gp content as the exit code 127 | exit: 128 | slli gp, gp, 16; 129 | srli gp, gp, 15; 130 | ori gp, gp, 1; 131 | 1: 132 | li t0, PMA_HTIF_START_DEF 133 | sd gp, 0(t0); 134 | j 1b; 135 | -------------------------------------------------------------------------------- /src/htif_rollup.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 test will fetch the rollup buffers from the PMA entries; check that 20 | // `rx_buffer` and `input_metadata` are filled with a byte patern; then write a 21 | // byte pattern into `tx_buffer`, `voucher_hashes` and `notice_hashes`. 22 | 23 | /** from: https://www.cartesi.io/en/docs/machine/target/architecture/ 24 | * 25 | * last entry has length == 0 26 | * 27 | * with the following memory layout: 28 | * +------+--------+--------+------+----+----+---+---+---+---+----+---+ 29 | * | | | 63-12 | 11-8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 30 | * | 0x00 | start | start | DID | IW | IR | X | W | R | E | IO | M | 31 | * +------+--------+--------+------+----+----+---+---+---+---+----+---+ 32 | * | | | 63-11 | 11-0 | 33 | * | 0x08 | length | length | reserved [=0] | 34 | * +------+--------+--------+-----------------------------------------+ 35 | */ 36 | #define O_START 0x00 37 | #define O_LENGTH 0x08 38 | 39 | #define PMA_START_DID_CONST(did) ((did) << 8) 40 | #define PMA_START_DID_MASK 0x0000000000000f00 41 | #define PMA_START_START_MASK 0xfffffffffffff000 42 | 43 | .global _start 44 | .align 2; 45 | _start: 46 | li a2, 0x0123456789abcdef; 47 | li a0, PMA_START_DID_CONST(PMA_ROLLUP_RX_BUFFER_DID_DEF); 48 | jal ra, find_pma_by_did; 49 | jal ra, check_pma_with_a2; 50 | 51 | li a2, 0x0123456789abcdef; 52 | li a0, PMA_START_DID_CONST(PMA_ROLLUP_INPUT_METADATA_DID_DEF); 53 | jal ra, find_pma_by_did; 54 | jal ra, check_pma_with_a2; 55 | 56 | li a2, 0x0123456789abcdef; 57 | li a0, PMA_START_DID_CONST(PMA_ROLLUP_TX_BUFFER_DID_DEF); 58 | jal ra, find_pma_by_did; 59 | jal ra, fill_pma_with_a2; 60 | 61 | li a2, 0x0123456789abcdef; 62 | li a0, PMA_START_DID_CONST(PMA_ROLLUP_VOUCHER_HASHES_DID_DEF); 63 | jal ra, find_pma_by_did; 64 | jal ra, fill_pma_with_a2; 65 | 66 | li a2, 0x0123456789abcdef; 67 | li a0, PMA_START_DID_CONST(PMA_ROLLUP_NOTICE_HASHES_DID_DEF); 68 | jal ra, find_pma_by_did; 69 | jal ra, fill_pma_with_a2; 70 | 71 | htif_exit(0); 72 | 73 | 74 | /* Find the PMA entry by DID or exit(1) 75 | * 76 | * a0: a pma_did_const(x) 77 | * ret: pointer to pma entry */ 78 | find_pma_by_did: 79 | li t0, PMA_SHADOW_PMAS_START_DEF; 80 | li t2, PMA_START_DID_MASK; 81 | /* is the pma array empty? */ 82 | ld t1, O_LENGTH (t0); 83 | beq t1, zero, not_found; 84 | 85 | l0: ld t1, O_START (t0); 86 | and t1, t1, t2; 87 | beq t1, a0, found; 88 | 89 | addi t0, t0, 0x10; 90 | ld t1, O_LENGTH (t0); 91 | bne t1, zero, l0; 92 | /* fallthrough */ 93 | not_found: 94 | htif_exit(1); 95 | found: 96 | mv a0, t0; 97 | jr ra; 98 | 99 | 100 | /* a0 -> pma entry pointer */ 101 | fill_pma_with_a2: 102 | ld a1, O_LENGTH(a0); 103 | ld a0, O_START (a0); 104 | li t0, PMA_START_START_MASK; 105 | and a0, a0, t0; 106 | j memset64; // tail call 107 | 108 | 109 | /* a0 -> start 110 | * a1 -> length 111 | * a2 -> value */ 112 | memset64: 113 | add a1, a0, a1; // a1 = start + length 114 | bge a0, a1, l2; 115 | l1: 116 | sd a2, 0 (a0); 117 | addi a0, a0, 0x08; 118 | blt a0, a1, l1; 119 | l2: jr ra; 120 | 121 | 122 | /* a0 -> pma entry pointer */ 123 | check_pma_with_a2: 124 | ld a1, O_LENGTH(a0); 125 | ld a0, O_START (a0); 126 | li t0, PMA_START_START_MASK; 127 | and a0, a0, t0; 128 | j memcheck64; 129 | 130 | 131 | /* a0 -> start 132 | * a1 -> length 133 | * a2 -> value */ 134 | memcheck64: 135 | add a1, a0, a1; // a1 = start + length 136 | bge a0, a1, l4; 137 | l3: 138 | ld a3, 0 (a0); 139 | bne a3, a2, fail; 140 | addi a0, a0, 0x08; 141 | blt a0, a1, l3; 142 | l4: jr ra; 143 | fail: 144 | htif_exit(1); 145 | -------------------------------------------------------------------------------- /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 scrach 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_DEVICE_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_DEVICE_HALT_DEF, HTIF_HALT_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_DEVICE_CONSOLE_DEF, HTIF_CONSOLE_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_DEVICE_CONSOLE_DEF, HTIF_CONSOLE_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 | -------------------------------------------------------------------------------- /src/htif_yield.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 different permutations of HTIF yield: 20 | // manual x automatic, the different 'reasons', and incrementing data values. 21 | 22 | // Uses HTIF to exit the emulator with exit code in an immediate. 23 | // HTIF halt device exits with dev = cmd = 0 and a payload with lsb set. 24 | // So the data payload uses bits 1-47 25 | #define exit_imm(imm) \ 26 | li gp, imm; \ 27 | j exit; 28 | 29 | // Check HTIF fromhost address for yield command ack 30 | #define check_htif_ack(dev, cmd, data) \ 31 | li t0, PMA_HTIF_START_DEF; \ 32 | ld t3, O_IYIELD (t0); \ 33 | srli t3, t3, cmd; \ 34 | andi t3, t3, 1; \ 35 | addi t3, t3, -1; \ 36 | not t3, t3; /* t3 is all 0 if cmd is disabled, all 1 if enabled */ \ 37 | li t0, dev; \ 38 | slli t1, t0, HTIF_DEV_SHIFT_DEF; \ 39 | li t0, cmd; \ 40 | slli t0, t0, HTIF_CMD_SHIFT_DEF; \ 41 | li t2, HTIF_CMD_MASK_DEF; \ 42 | and t0, t0, t2; \ 43 | or t1, t1, t0; \ 44 | li t0, data; \ 45 | li t2, HTIF_DATA_MASK_DEF; \ 46 | and t0, t0, t2; \ 47 | or t1, t1, t0; \ 48 | and t1, t1, t3; /* if cmd is disabled, expect 0 ack */ \ 49 | li t0, PMA_HTIF_START_DEF; \ 50 | ld t2, O_FROMHOST (t0); \ 51 | bne t1, t2, ack_failed; 52 | 53 | // Section with code 54 | .section .text.init 55 | .align 2; 56 | .global _start; 57 | _start: 58 | // Set the exception handler to trap 59 | // This is just in case an exception happens 60 | la t0, trap; 61 | csrw mtvec, t0; 62 | 63 | // Test yield, manual 64 | htif_yield(HTIF_YIELD_MANUAL_DEF, HTIF_YIELD_REASON_PROGRESS_DEF, 10) 65 | check_htif_ack(HTIF_DEVICE_YIELD_DEF, HTIF_YIELD_MANUAL_DEF, 0); 66 | htif_yield(HTIF_YIELD_MANUAL_DEF, HTIF_YIELD_REASON_PROGRESS_DEF, 11) 67 | check_htif_ack(HTIF_DEVICE_YIELD_DEF, HTIF_YIELD_MANUAL_DEF, 0); 68 | htif_yield(HTIF_YIELD_MANUAL_DEF, HTIF_YIELD_REASON_PROGRESS_DEF, 12) 69 | check_htif_ack(HTIF_DEVICE_YIELD_DEF, HTIF_YIELD_MANUAL_DEF, 0); 70 | 71 | htif_yield(HTIF_YIELD_MANUAL_DEF, HTIF_YIELD_REASON_RX_ACCEPTED_DEF, 13) 72 | check_htif_ack(HTIF_DEVICE_YIELD_DEF, HTIF_YIELD_MANUAL_DEF, 0); 73 | htif_yield(HTIF_YIELD_MANUAL_DEF, HTIF_YIELD_REASON_RX_REJECTED_DEF, 14) 74 | check_htif_ack(HTIF_DEVICE_YIELD_DEF, HTIF_YIELD_MANUAL_DEF, 0); 75 | 76 | htif_yield(HTIF_YIELD_MANUAL_DEF, HTIF_YIELD_REASON_TX_VOUCHER_DEF, 15) 77 | check_htif_ack(HTIF_DEVICE_YIELD_DEF, HTIF_YIELD_MANUAL_DEF, 0); 78 | 79 | htif_yield(HTIF_YIELD_MANUAL_DEF, HTIF_YIELD_REASON_TX_NOTICE_DEF, 16) 80 | check_htif_ack(HTIF_DEVICE_YIELD_DEF, HTIF_YIELD_MANUAL_DEF, 0); 81 | 82 | htif_yield(HTIF_YIELD_MANUAL_DEF, HTIF_YIELD_REASON_TX_REPORT_DEF, 17) 83 | check_htif_ack(HTIF_DEVICE_YIELD_DEF, HTIF_YIELD_MANUAL_DEF, 0); 84 | 85 | htif_yield(HTIF_YIELD_MANUAL_DEF, HTIF_YIELD_REASON_TX_EXCEPTION_DEF, 18) 86 | check_htif_ack(HTIF_DEVICE_YIELD_DEF, HTIF_YIELD_MANUAL_DEF, 0); 87 | 88 | // Test yield, auto 89 | htif_yield(HTIF_YIELD_AUTOMATIC_DEF, HTIF_YIELD_REASON_PROGRESS_DEF, 20) 90 | check_htif_ack(HTIF_DEVICE_YIELD_DEF, HTIF_YIELD_AUTOMATIC_DEF, 0); 91 | htif_yield(HTIF_YIELD_AUTOMATIC_DEF, HTIF_YIELD_REASON_PROGRESS_DEF, 21) 92 | check_htif_ack(HTIF_DEVICE_YIELD_DEF, HTIF_YIELD_AUTOMATIC_DEF, 0); 93 | htif_yield(HTIF_YIELD_AUTOMATIC_DEF, HTIF_YIELD_REASON_PROGRESS_DEF, 22) 94 | check_htif_ack(HTIF_DEVICE_YIELD_DEF, HTIF_YIELD_AUTOMATIC_DEF, 0); 95 | 96 | htif_yield(HTIF_YIELD_AUTOMATIC_DEF, HTIF_YIELD_REASON_RX_ACCEPTED_DEF, 23) 97 | check_htif_ack(HTIF_DEVICE_YIELD_DEF, HTIF_YIELD_AUTOMATIC_DEF, 0); 98 | htif_yield(HTIF_YIELD_AUTOMATIC_DEF, HTIF_YIELD_REASON_RX_REJECTED_DEF, 24) 99 | check_htif_ack(HTIF_DEVICE_YIELD_DEF, HTIF_YIELD_AUTOMATIC_DEF, 0); 100 | 101 | htif_yield(HTIF_YIELD_AUTOMATIC_DEF, HTIF_YIELD_REASON_TX_VOUCHER_DEF, 25) 102 | check_htif_ack(HTIF_DEVICE_YIELD_DEF, HTIF_YIELD_AUTOMATIC_DEF, 0); 103 | 104 | htif_yield(HTIF_YIELD_AUTOMATIC_DEF, HTIF_YIELD_REASON_TX_NOTICE_DEF, 26) 105 | check_htif_ack(HTIF_DEVICE_YIELD_DEF, HTIF_YIELD_AUTOMATIC_DEF, 0); 106 | 107 | htif_yield(HTIF_YIELD_AUTOMATIC_DEF, HTIF_YIELD_REASON_TX_REPORT_DEF, 27) 108 | check_htif_ack(HTIF_DEVICE_YIELD_DEF, HTIF_YIELD_AUTOMATIC_DEF, 0); 109 | 110 | // Test if invalid yields commands is not acked, they are silently ignored 111 | htif_yield(0xff, HTIF_YIELD_REASON_PROGRESS_DEF, 1) 112 | bnez a0, trap 113 | 114 | // halt with payload 42 115 | exit_imm(42); 116 | 117 | // If HTIF device command is not acked, exit with 2 118 | ack_failed: 119 | exit_imm(2); 120 | 121 | // catch exception and exit 122 | trap: 123 | exit_imm(1); 124 | 125 | // Exits via HTIF using gp content as the exit code 126 | exit: 127 | slli gp, gp, 16; 128 | srli gp, gp, 15; 129 | ori gp, gp, 1; 130 | 1: 131 | li t0, PMA_HTIF_START_DEF; 132 | sd x0, O_FROMHOST (t0); 133 | sd gp, O_TOHOST (t0); 134 | j 1b; // unreachable 135 | -------------------------------------------------------------------------------- /src/illegal_insn.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 | 26 | #define MSTATUS_FS_MASK (3<<13) 27 | 28 | #define MCAUSE_ILLEGAL_INSN 0x2 29 | 30 | #define TEST_ILLEGAL_INSN(insn) \ 31 | li t5, 0; \ 32 | .word (insn); \ 33 | li t0, 1; \ 34 | bne t5, t0, fail; 35 | 36 | #define SHIFT_OPCODE 0 37 | #define SHIFT_FUNCT7 25 38 | #define SHIFT_FUNCT3 12 39 | #define SHIFT_FUNCT2 25 40 | #define SHIFT_RM 12 41 | #define SHIFT_RS3 27 42 | #define SHIFT_RS2 20 43 | #define SHIFT_RD 7 44 | 45 | // Section with code 46 | .section .text.init 47 | .align 2; 48 | .global _start; 49 | _start: 50 | // Set a trap that will ignore the failing illegal instructions and resume to next instruction 51 | la t0, skip_illegal_insn_trap; 52 | csrw mtvec, t0; 53 | 54 | // Invalid instruction (no bit set) 55 | TEST_ILLEGAL_INSN(0x0) 56 | 57 | // Invalid instruction (all bits set) 58 | TEST_ILLEGAL_INSN(0xffffffff) 59 | 60 | // SLLI/SRLI/SRAI with invalid funct7 61 | TEST_ILLEGAL_INSN((0b0010011 << SHIFT_OPCODE) | (0b001 << SHIFT_FUNCT3) | (0b0000010 << SHIFT_FUNCT7)) 62 | TEST_ILLEGAL_INSN((0b0010011 << SHIFT_OPCODE) | (0b101 << SHIFT_FUNCT3) | (0b0000010 << SHIFT_FUNCT7)) 63 | 64 | // ADD/MUL/SUB/SLL/MULH/SLT/MULHSU/SLTU/MULHU/XOR/DIV/SRL/DIVU/SRA/OR/REM/AND/REMU with invalid funct7 65 | TEST_ILLEGAL_INSN((0b0110011 << SHIFT_OPCODE) | (0b000 << SHIFT_FUNCT3) | (0b0000010 << SHIFT_FUNCT7)) 66 | TEST_ILLEGAL_INSN((0b0110011 << SHIFT_OPCODE) | (0b001 << SHIFT_FUNCT3) | (0b0000010 << SHIFT_FUNCT7)) 67 | TEST_ILLEGAL_INSN((0b0110011 << SHIFT_OPCODE) | (0b010 << SHIFT_FUNCT3) | (0b0000010 << SHIFT_FUNCT7)) 68 | TEST_ILLEGAL_INSN((0b0110011 << SHIFT_OPCODE) | (0b011 << SHIFT_FUNCT3) | (0b0000010 << SHIFT_FUNCT7)) 69 | TEST_ILLEGAL_INSN((0b0110011 << SHIFT_OPCODE) | (0b100 << SHIFT_FUNCT3) | (0b0000010 << SHIFT_FUNCT7)) 70 | TEST_ILLEGAL_INSN((0b0110011 << SHIFT_OPCODE) | (0b101 << SHIFT_FUNCT3) | (0b0000010 << SHIFT_FUNCT7)) 71 | TEST_ILLEGAL_INSN((0b0110011 << SHIFT_OPCODE) | (0b110 << SHIFT_FUNCT3) | (0b0000010 << SHIFT_FUNCT7)) 72 | TEST_ILLEGAL_INSN((0b0110011 << SHIFT_OPCODE) | (0b111 << SHIFT_FUNCT3) | (0b0000010 << SHIFT_FUNCT7)) 73 | 74 | // SLLIW/SRLIW/SRAIW with invalid funct7 75 | TEST_ILLEGAL_INSN((0b0011011 << SHIFT_OPCODE) | (0b001 << SHIFT_FUNCT3) | (0b0000010 << SHIFT_FUNCT7)) 76 | TEST_ILLEGAL_INSN((0b0011011 << SHIFT_OPCODE) | (0b101 << SHIFT_FUNCT3) | (0b0000010 << SHIFT_FUNCT7)) 77 | 78 | // ADDW/SUBW/SLLW/SRLW/SRAW/MULW/DIVW/DIVUW/REMW/REMUW with invalid funct7 79 | TEST_ILLEGAL_INSN((0b0111011 << SHIFT_OPCODE) | (0b000 << SHIFT_FUNCT3) | (0b0000010 << SHIFT_FUNCT7)) 80 | TEST_ILLEGAL_INSN((0b0111011 << SHIFT_OPCODE) | (0b001 << SHIFT_FUNCT3) | (0b0000010 << SHIFT_FUNCT7)) 81 | TEST_ILLEGAL_INSN((0b0111011 << SHIFT_OPCODE) | (0b100 << SHIFT_FUNCT3) | (0b0000010 << SHIFT_FUNCT7)) 82 | TEST_ILLEGAL_INSN((0b0111011 << SHIFT_OPCODE) | (0b101 << SHIFT_FUNCT3) | (0b0000010 << SHIFT_FUNCT7)) 83 | TEST_ILLEGAL_INSN((0b0111011 << SHIFT_OPCODE) | (0b110 << SHIFT_FUNCT3) | (0b0000010 << SHIFT_FUNCT7)) 84 | TEST_ILLEGAL_INSN((0b0111011 << SHIFT_OPCODE) | (0b111 << SHIFT_FUNCT3) | (0b0000010 << SHIFT_FUNCT7)) 85 | 86 | // LR.W/LR.D with rs2 != 0 87 | TEST_ILLEGAL_INSN((0b0101111 << SHIFT_OPCODE) | (0b010 << SHIFT_FUNCT3) | (0b00010 << SHIFT_RS3) | (0b00001 << SHIFT_RS2)) 88 | TEST_ILLEGAL_INSN((0b0101111 << SHIFT_OPCODE) | (0b011 << SHIFT_FUNCT3) | (0b00010 << SHIFT_RS3) | (0b00001 << SHIFT_RS2)) 89 | 90 | // LR/AMO with invalid funct7 91 | TEST_ILLEGAL_INSN((0b0101111 << SHIFT_OPCODE) | (0b010 << SHIFT_FUNCT3) | (0b11111 << SHIFT_RS3)) 92 | TEST_ILLEGAL_INSN((0b0101111 << SHIFT_OPCODE) | (0b011 << SHIFT_FUNCT3) | (0b11111 << SHIFT_RS3)) 93 | 94 | // SFENCE.VMA with rd != 0 or funct7 != 0 95 | TEST_ILLEGAL_INSN((0b1110011 << SHIFT_OPCODE) | (0b000 << SHIFT_FUNCT3) | (0b0000001 << SHIFT_FUNCT7)) 96 | TEST_ILLEGAL_INSN((0b1110011 << SHIFT_OPCODE) | (0b000 << SHIFT_FUNCT3) | (0b00001 << SHIFT_RD)) 97 | 98 | // Privileged instruction with invalid funct7 99 | TEST_ILLEGAL_INSN((0b1110011 << SHIFT_OPCODE) | (0b000 << SHIFT_FUNCT3) | (0b1111111 << SHIFT_FUNCT7)) 100 | 101 | // Enable float state 102 | li t0, MSTATUS_FS_MASK 103 | csrs mstatus, t0 104 | 105 | // Invalid funct7 for float instruction 106 | TEST_ILLEGAL_INSN((0b1010011 << SHIFT_OPCODE) | (0b1111111 << SHIFT_FUNCT7)) 107 | 108 | // Invalid funct3 for float instruction 109 | TEST_ILLEGAL_INSN((0b1010011 << SHIFT_OPCODE) | (0b0010000 << SHIFT_FUNCT7) | (0b111 << SHIFT_FUNCT3)) 110 | TEST_ILLEGAL_INSN((0b1010011 << SHIFT_OPCODE) | (0b0010100 << SHIFT_FUNCT7) | (0b111 << SHIFT_FUNCT3)) 111 | TEST_ILLEGAL_INSN((0b1010011 << SHIFT_OPCODE) | (0b1010000 << SHIFT_FUNCT7) | (0b111 << SHIFT_FUNCT3)) 112 | TEST_ILLEGAL_INSN((0b1010011 << SHIFT_OPCODE) | (0b0010001 << SHIFT_FUNCT7) | (0b111 << SHIFT_FUNCT3)) 113 | TEST_ILLEGAL_INSN((0b1010011 << SHIFT_OPCODE) | (0b0010101 << SHIFT_FUNCT7) | (0b111 << SHIFT_FUNCT3)) 114 | TEST_ILLEGAL_INSN((0b1010011 << SHIFT_OPCODE) | (0b1010001 << SHIFT_FUNCT7) | (0b111 << SHIFT_FUNCT3)) 115 | TEST_ILLEGAL_INSN((0b1010011 << SHIFT_OPCODE) | (0b1110000 << SHIFT_FUNCT7) | (0b111 << SHIFT_FUNCT3)) 116 | TEST_ILLEGAL_INSN((0b1010011 << SHIFT_OPCODE) | (0b1110001 << SHIFT_FUNCT7) | (0b111 << SHIFT_FUNCT3)) 117 | 118 | // Invalid rs2 for float instruction 119 | TEST_ILLEGAL_INSN((0b1010011 << SHIFT_OPCODE) | (0b1110000 << SHIFT_FUNCT7) | (0b11111 << SHIFT_RS2)) 120 | TEST_ILLEGAL_INSN((0b1010011 << SHIFT_OPCODE) | (0b1111000 << SHIFT_FUNCT7) | (0b11111 << SHIFT_RS2)) 121 | TEST_ILLEGAL_INSN((0b1010011 << SHIFT_OPCODE) | (0b1110001 << SHIFT_FUNCT7) | (0b11111 << SHIFT_RS2)) 122 | TEST_ILLEGAL_INSN((0b1010011 << SHIFT_OPCODE) | (0b1111001 << SHIFT_FUNCT7) | (0b11111 << SHIFT_RS2)) 123 | TEST_ILLEGAL_INSN((0b1010011 << SHIFT_OPCODE) | (0b0101100 << SHIFT_FUNCT7) | (0b11111 << SHIFT_RS2)) 124 | TEST_ILLEGAL_INSN((0b1010011 << SHIFT_OPCODE) | (0b1100000 << SHIFT_FUNCT7) | (0b11111 << SHIFT_RS2)) 125 | TEST_ILLEGAL_INSN((0b1010011 << SHIFT_OPCODE) | (0b1101000 << SHIFT_FUNCT7) | (0b11111 << SHIFT_RS2)) 126 | TEST_ILLEGAL_INSN((0b1010011 << SHIFT_OPCODE) | (0b0101101 << SHIFT_FUNCT7) | (0b11111 << SHIFT_RS2)) 127 | TEST_ILLEGAL_INSN((0b1010011 << SHIFT_OPCODE) | (0b0100000 << SHIFT_FUNCT7) | (0b11111 << SHIFT_RS2)) 128 | TEST_ILLEGAL_INSN((0b1010011 << SHIFT_OPCODE) | (0b0100001 << SHIFT_FUNCT7) | (0b11111 << SHIFT_RS2)) 129 | TEST_ILLEGAL_INSN((0b1010011 << SHIFT_OPCODE) | (0b1100001 << SHIFT_FUNCT7) | (0b11111 << SHIFT_RS2)) 130 | TEST_ILLEGAL_INSN((0b1010011 << SHIFT_OPCODE) | (0b1101001 << SHIFT_FUNCT7) | (0b11111 << SHIFT_RS2)) 131 | 132 | // FADD.S with invalid rounding mode 133 | TEST_ILLEGAL_INSN((0b1010011 << SHIFT_OPCODE) | (0b101 << SHIFT_RM)) 134 | 135 | // FMV with rm != 0 136 | TEST_ILLEGAL_INSN((0b1010011 << SHIFT_OPCODE) | (0b1110000 << SHIFT_FUNCT7) | (0b111 << SHIFT_RM)) 137 | TEST_ILLEGAL_INSN((0b1010011 << SHIFT_OPCODE) | (0b1111000 << SHIFT_FUNCT7) | (0b111 << SHIFT_RM)) 138 | TEST_ILLEGAL_INSN((0b1010011 << SHIFT_OPCODE) | (0b1110001 << SHIFT_FUNCT7) | (0b111 << SHIFT_RM)) 139 | TEST_ILLEGAL_INSN((0b1010011 << SHIFT_OPCODE) | (0b1111001 << SHIFT_FUNCT7) | (0b111 << SHIFT_RM)) 140 | 141 | // FMADD/FMSUB/FNMSUB/FNMADD with invalid funct2 142 | TEST_ILLEGAL_INSN((0b1000011 << SHIFT_OPCODE) | (0b11 << SHIFT_FUNCT2)) 143 | TEST_ILLEGAL_INSN((0b1000111 << SHIFT_OPCODE) | (0b11 << SHIFT_FUNCT2)) 144 | TEST_ILLEGAL_INSN((0b1001011 << SHIFT_OPCODE) | (0b11 << SHIFT_FUNCT2)) 145 | TEST_ILLEGAL_INSN((0b1001111 << SHIFT_OPCODE) | (0b11 << SHIFT_FUNCT2)) 146 | 147 | // Privileged instructions with rd != 0 148 | TEST_ILLEGAL_INSN((0b1110011 << SHIFT_OPCODE) | (0b0000000 << SHIFT_FUNCT7) | (0b00001 << SHIFT_RD)) 149 | TEST_ILLEGAL_INSN((0b1110011 << SHIFT_OPCODE) | (0b0001000 << SHIFT_FUNCT7) | (0b00001 << SHIFT_RD)) 150 | TEST_ILLEGAL_INSN((0b1110011 << SHIFT_OPCODE) | (0b0011000 << SHIFT_FUNCT7) | (0b00001 << SHIFT_RD)) 151 | TEST_ILLEGAL_INSN((0b1110011 << SHIFT_OPCODE) | (0b0001100 << SHIFT_FUNCT7) | (0b00001 << SHIFT_RD)) 152 | TEST_ILLEGAL_INSN((0b1110011 << SHIFT_OPCODE) | (0b0001001 << SHIFT_FUNCT7) | (0b00001 << SHIFT_RD)) 153 | TEST_ILLEGAL_INSN((0b1110011 << SHIFT_OPCODE) | (0b0001011 << SHIFT_FUNCT7) | (0b00001 << SHIFT_RD)) 154 | TEST_ILLEGAL_INSN((0b1110011 << SHIFT_OPCODE) | (0b0010001 << SHIFT_FUNCT7) | (0b00001 << SHIFT_RD)) 155 | TEST_ILLEGAL_INSN((0b1110011 << SHIFT_OPCODE) | (0b0110001 << SHIFT_FUNCT7) | (0b00001 << SHIFT_RD)) 156 | TEST_ILLEGAL_INSN((0b1110011 << SHIFT_OPCODE) | (0b0010011 << SHIFT_FUNCT7) | (0b00001 << SHIFT_RD)) 157 | TEST_ILLEGAL_INSN((0b1110011 << SHIFT_OPCODE) | (0b0110011 << SHIFT_FUNCT7) | (0b00001 << SHIFT_RD)) 158 | 159 | // Hypervisor instructions with rd != 0 160 | TEST_ILLEGAL_INSN((0b1110011 << SHIFT_OPCODE) | (0b100 << SHIFT_FUNCT3) | (0b0110001 << SHIFT_FUNCT7) | (0b00001 << SHIFT_RD)) 161 | TEST_ILLEGAL_INSN((0b1110011 << SHIFT_OPCODE) | (0b100 << SHIFT_FUNCT3) | (0b0110011 << SHIFT_FUNCT7) | (0b00001 << SHIFT_RD)) 162 | TEST_ILLEGAL_INSN((0b1110011 << SHIFT_OPCODE) | (0b100 << SHIFT_FUNCT3) | (0b0110101 << SHIFT_FUNCT7) | (0b00001 << SHIFT_RD)) 163 | TEST_ILLEGAL_INSN((0b1110011 << SHIFT_OPCODE) | (0b100 << SHIFT_FUNCT3) | (0b0110111 << SHIFT_FUNCT7) | (0b00001 << SHIFT_RD)) 164 | 165 | // Hypervisor instructions with invalid rs2 166 | TEST_ILLEGAL_INSN((0b1110011 << SHIFT_OPCODE) | (0b100 << SHIFT_FUNCT3) | (0b0110000 << SHIFT_FUNCT7) | (0b11111 << SHIFT_RS2)) 167 | TEST_ILLEGAL_INSN((0b1110011 << SHIFT_OPCODE) | (0b100 << SHIFT_FUNCT3) | (0b0110000 << SHIFT_FUNCT7) | (0b11111 << SHIFT_RS2)) 168 | TEST_ILLEGAL_INSN((0b1110011 << SHIFT_OPCODE) | (0b100 << SHIFT_FUNCT3) | (0b0110010 << SHIFT_FUNCT7) | (0b11111 << SHIFT_RS2)) 169 | TEST_ILLEGAL_INSN((0b1110011 << SHIFT_OPCODE) | (0b100 << SHIFT_FUNCT3) | (0b0110010 << SHIFT_FUNCT7) | (0b11111 << SHIFT_RS2)) 170 | TEST_ILLEGAL_INSN((0b1110011 << SHIFT_OPCODE) | (0b100 << SHIFT_FUNCT3) | (0b0110010 << SHIFT_FUNCT7) | (0b11111 << SHIFT_RS2)) 171 | TEST_ILLEGAL_INSN((0b1110011 << SHIFT_OPCODE) | (0b100 << SHIFT_FUNCT3) | (0b0110100 << SHIFT_FUNCT7) | (0b11111 << SHIFT_RS2)) 172 | TEST_ILLEGAL_INSN((0b1110011 << SHIFT_OPCODE) | (0b100 << SHIFT_FUNCT3) | (0b0110100 << SHIFT_FUNCT7) | (0b11111 << SHIFT_RS2)) 173 | TEST_ILLEGAL_INSN((0b1110011 << SHIFT_OPCODE) | (0b100 << SHIFT_FUNCT3) | (0b0110100 << SHIFT_FUNCT7) | (0b11111 << SHIFT_RS2)) 174 | TEST_ILLEGAL_INSN((0b1110011 << SHIFT_OPCODE) | (0b100 << SHIFT_FUNCT3) | (0b0110110 << SHIFT_FUNCT7) | (0b11111 << SHIFT_RS2)) 175 | 176 | exit_imm(0) 177 | 178 | skip_illegal_insn_trap: 179 | // Expected an illegal instruction exception 180 | csrr gp, mcause 181 | li t6, MCAUSE_ILLEGAL_INSN 182 | bne gp, t6, exit 183 | 184 | // Increment illegal instruction counter 185 | addi t5, t5, 1 186 | 187 | // Resume to next instruction 188 | csrr t6, mepc 189 | addi t6, t6, 4 190 | csrw mepc, t6 191 | mret 192 | 193 | exit_imm(1) 194 | 195 | fail: 196 | exit_imm(1); 197 | 198 | // Exits via HTIF using gp content as the exit code 199 | exit: 200 | // HTIF exits with dev = cmd = 0 and a payload with lsb set. 201 | // the exit code is taken from payload >> 2 202 | slli gp, gp, 16; 203 | srli gp, gp, 15; 204 | ori gp, gp, 1; 205 | 1: 206 | li t0, PMA_HTIF_START_DEF 207 | sd gp, 0(t0); 208 | j 1b; // Should not be necessary 209 | 210 | -------------------------------------------------------------------------------- /src/interrupts.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 tests software interrupts and interrupt delegation 19 | 20 | #include 21 | 22 | // Uses HTIF to exit the emulator with exit code in an immediate 23 | #define exit_imm(imm) \ 24 | li gp, imm; \ 25 | j exit; 26 | 27 | #define SSI_CODE 1 28 | #define MTI_CODE 7 29 | #define SSI_MASK (1<> 2 177 | slli gp, gp, 16; 178 | srli gp, gp, 15; 179 | ori gp, gp, 1; 180 | 1: 181 | li t0, PMA_HTIF_START_DEF 182 | sd gp, 0(t0); 183 | j 1b; // Should not be necessary 184 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /src/shadow_ops.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 programs exercise load/writes in the shadow. 19 | 20 | #include 21 | 22 | // Uses HTIF to exit the emulator with exit code in an immediate 23 | #define exit_imm(imm) \ 24 | li gp, imm; \ 25 | j exit; 26 | 27 | #define expect_trap(cause, code...) \ 28 | li a0, cause; \ 29 | li a1, 1; \ 30 | code \ 31 | bnez a1, fail; 32 | 33 | #define MCAUSE_STORE_AMO_ACCESS_FAULT 0x7 34 | #define MCAUSE_LOAD_ACCESS_FAULT 0x5 35 | #define SHADOWS_PMA_LAST_ENTRY_START (31*16) 36 | #define SHADOWS_PMA_LAST_ENTRY_LENGTH (31*16+8) 37 | #define SHADOWS_PMA_TOTAL_SIZE (32*16) 38 | 39 | // Section with code 40 | .section .text.init 41 | .align 2; 42 | .global _start; 43 | _start: 44 | // Set the exception handler to trap 45 | la t0, fail; 46 | csrw mtvec, t0; 47 | 48 | // We are allowed to read the shadow PMAs 49 | li t0, PMA_SHADOW_PMAS_START_DEF; 50 | ld t1, SHADOWS_PMA_LAST_ENTRY_START(t0); 51 | bnez t1, fail; 52 | ld t1, SHADOWS_PMA_LAST_ENTRY_LENGTH(t0); 53 | bnez t1, fail; 54 | 55 | // Set the exception handler to skip instructions 56 | la t0, skip_insn_trap; 57 | csrw mtvec, t0; 58 | 59 | // Attempt to load a non 8-bytes value from the shadow PMAs 60 | expect_trap(MCAUSE_LOAD_ACCESS_FAULT, 61 | li t0, PMA_SHADOW_PMAS_START_DEF; 62 | lw t1, 0(t0); 63 | ) 64 | 65 | // Attempt to load from a misaligned shadow PMAs offset 66 | expect_trap(MCAUSE_LOAD_ACCESS_FAULT, 67 | li t0, PMA_SHADOW_PMAS_START_DEF; 68 | lb t1, 1(t0); 69 | ) 70 | 71 | // Attempt to load a PMA entry out of bounds from shadow PMAs 72 | expect_trap(MCAUSE_LOAD_ACCESS_FAULT, 73 | li t0, PMA_SHADOW_PMAS_START_DEF; 74 | ld t1, SHADOWS_PMA_TOTAL_SIZE(t0); 75 | ) 76 | 77 | // Attempt to load a value from the shadow state 78 | expect_trap(MCAUSE_LOAD_ACCESS_FAULT, 79 | li t0, PMA_SHADOW_STATE_START_DEF; 80 | ld t1, 8(t0); 81 | ) 82 | 83 | // Attempt to load a value from the shadow TLB 84 | expect_trap(MCAUSE_LOAD_ACCESS_FAULT, 85 | li t0, PMA_SHADOW_TLB_START_DEF; 86 | ld t1, 0(t0); 87 | ) 88 | 89 | // Attempt to store a value in the shadow PMAs 90 | expect_trap(MCAUSE_STORE_AMO_ACCESS_FAULT, 91 | li t0, PMA_SHADOW_PMAS_START_DEF; 92 | sd x0, 0(t0); 93 | ) 94 | 95 | // Attempt to store a value in the shadow state 96 | expect_trap(MCAUSE_STORE_AMO_ACCESS_FAULT, 97 | li t0, PMA_SHADOW_STATE_START_DEF; 98 | sd x0, 8(t0); 99 | ) 100 | 101 | // Attempt to store a value in the shadow TLB 102 | expect_trap(MCAUSE_STORE_AMO_ACCESS_FAULT, 103 | li t0, PMA_SHADOW_TLB_START_DEF; 104 | sd x0, 0(t0); 105 | ) 106 | 107 | exit_imm(0); 108 | 109 | skip_insn_trap: 110 | csrr gp, mcause; 111 | bne gp, a0, exit; 112 | csrr t5, mepc; 113 | addi t5, t5, 4; 114 | csrw mepc, t5; 115 | addi a1, a1, -1; 116 | mret; 117 | 118 | fail: 119 | exit_imm(1); 120 | 121 | // Exits via HTIF using gp content as the exit code 122 | exit: 123 | slli gp, gp, 16; 124 | srli gp, gp, 15; 125 | ori gp, gp, 1; 126 | 1: 127 | li t0, PMA_HTIF_START_DEF 128 | sd gp, 0(t0); 129 | j 1b; 130 | -------------------------------------------------------------------------------- /src/translate_vaddr.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 | #include 20 | 21 | #define PTE_FLAGS (PTE_V | PTE_R | PTE_W | PTE_X | PTE_U) 22 | #define PTE_RESERVED 4 // right shift to the PTE reserved field 23 | #define SATP_MODE_SHIFT 60 24 | 25 | #define MSTATUS_MPP_MASK 0x1800 26 | #define MSTATUS_MPP_S 0x800 27 | 28 | // Uses HTIF to exit the emulator with exit code in an immediate 29 | #define exit_imm(imm) \ 30 | li gp, imm; \ 31 | j exit; 32 | 33 | .section .text.init 34 | .align 2; 35 | .global _start; 36 | _start: 37 | // Set the exception handler 38 | la t0, skip_fetch_page_fault_trap; 39 | csrw mtvec, t0; 40 | 41 | // Enable virtual address translation in user mode 42 | la t0, page_table 43 | srl t0, t0, RISCV_PGSHIFT 44 | li t1, (SATP_MODE_SV39 << SATP_MODE_SHIFT) 45 | or t0, t0, t1 46 | csrw satp, t0 47 | 48 | test1: 49 | //Setting reserved bits in PTE should raise a page fault 50 | li t0, (PTE_RSVD | PTE_V | PTE_R | PTE_W | PTE_X | PTE_U) 51 | la t1, page_table 52 | sd t0, (t1) 53 | li a0, 0 // vaddr pc 54 | auipc a1, 0 // return pc 55 | j enter_user_mode 56 | 57 | test2: 58 | // Svpbmt is not implemented, setting its bits in PTE should raise a page fault 59 | li t0, (PTE_PBMT | PTE_V | PTE_R | PTE_W | PTE_X | PTE_U) 60 | la t1, page_table 61 | sd t0, (t1) 62 | li a0, 0 // vaddr pc 63 | auipc a1, 0 // return pc 64 | j enter_user_mode 65 | 66 | test3: 67 | // Svnapot is not implemented, setting its bits in PTE should raise a page fault 68 | li t0, (PTE_N | PTE_V | PTE_R | PTE_W | PTE_X | PTE_U) 69 | la t1, page_table 70 | sd t0, (t1) 71 | li a0, 0 // vaddr pc 72 | auipc a1, 0 // return pc 73 | j enter_user_mode 74 | 75 | test4: 76 | // PTE with V unset should raise a page fault 77 | li t0, (PTE_R | PTE_W | PTE_X | PTE_U) 78 | la t1, page_table 79 | sd t0, (t1) 80 | li a0, 0 // vaddr pc 81 | auipc a1, 0 // return pc 82 | j enter_user_mode 83 | 84 | test5: // Reserved PTE protection bits (write + execute) are disallowed 85 | li t0, (PTE_V | PTE_W | PTE_X | PTE_U) 86 | la t1, page_table 87 | sd t0, (t1) 88 | li a0, 0 // vaddr pc 89 | auipc a1, 0 // return pc 90 | j enter_user_mode 91 | 92 | test6: // Attempt to execute a read-only page 93 | li t0, (PTE_V | PTE_R | PTE_U) 94 | la t1, page_table 95 | sd t0, (t1) 96 | li a0, 0 // vaddr pc 97 | auipc a1, 0 // return pc 98 | j enter_user_mode 99 | 100 | test7: // U-mode is not allowed to access privileged memory 101 | li t0, (PTE_V | PTE_R | PTE_X) 102 | la t1, page_table 103 | sd t0, (t1) 104 | li a0, 0 // vaddr pc 105 | auipc a1, 0 // return pc 106 | j enter_user_mode 107 | 108 | test8: // PTE with memory out of range 109 | li t0, (PTE_V | PTE_U) 110 | li t1, (1 << 38) 111 | srli t1, t1, 2 112 | or t0, t0, t1 113 | la t1, page_table 114 | sd t0, (t1) 115 | li a0, 0 // vaddr pc 116 | auipc a1, 0 // return pc 117 | j enter_user_mode 118 | 119 | test9: // Recursive PTE should raise a page fault 120 | li t0, PTE_V 121 | la t1, page_table 122 | srli t1, t1, 2 123 | or t0, t0, t1 124 | la t1, page_table 125 | sd t0, (t1) 126 | li a0, 0 // vaddr pc 127 | auipc a1, 0 // return pc 128 | j enter_user_mode 129 | 130 | test10: 131 | // Unused significant bits in virtual address must be 132 | // filled with copies of most significant bit of its VPN, 133 | // otherwise a page fault should be raised 134 | li t0, (PTE_V | PTE_R | PTE_W | PTE_X | PTE_U) 135 | la t1, page_table 136 | sd t0, (t1) 137 | li a0, (1 << 39) // vaddr pc 138 | auipc a1, 0 // return pc 139 | j enter_user_mode 140 | 141 | test13: 142 | // S-mode can never execute instructions from user pages, 143 | // regardless of the state of SUM 144 | 145 | // Enable SUM in mstatus 146 | li t0, MSTATUS_SUM 147 | csrs mstatus, t0 148 | 149 | // Set PTE entry 150 | li t0, (PTE_V | PTE_R | PTE_X | PTE_U) 151 | la t1, page_table 152 | sd t0, (t1) 153 | 154 | // Set vaddr PC and enter U-mode 155 | li a0, 0 // vaddr pc 156 | auipc a1, 0 // return pc 157 | j enter_supervisor_mode 158 | 159 | test11: // We should be able to execute instructions in U-mode using virtual memory 160 | // Set the exception handler 161 | la t0, skip_user_ecall_trap; 162 | csrw mtvec, t0; 163 | 164 | // Set PTE entry 165 | li t0, (PTE_V | PTE_R | PTE_X | PTE_U) 166 | la t1, user_ecall 167 | srli t1, t1, 2 168 | or t0, t0, t1 169 | la t1, page_table 170 | sd t0, (t1) 171 | 172 | // Set vaddr PC and enter U-mode 173 | la t0, user_ecall 174 | li a0, 4095 175 | and a0, a0, t0 // vaddr pc 176 | auipc a1, 0 // return pc 177 | j enter_user_mode 178 | 179 | test12: 180 | // We should be able to read from execute-only pages in less privileged mode 181 | // only when mstatus.MXR is enabled 182 | 183 | // Set PTE entry 184 | li t0, (PTE_V | PTE_X | PTE_U) 185 | la t1, user_read_pc 186 | srli t1, t1, 12 187 | slli t1, t1, 10 188 | or t0, t0, t1 189 | la t1, page_table 190 | sd t0, (t1) 191 | 192 | // Set the exception handler 193 | la t0, skip_load_page_fault_trap; 194 | csrw mtvec, t0; 195 | 196 | // Set vaddr PC and enter U-mode 197 | la t0, user_read_pc 198 | li a0, 4095 199 | and a0, a0, t0 // vaddr pc 200 | auipc a1, 0 // return pc 201 | j enter_user_mode 202 | 203 | // Enable MXR in mstatus 204 | li t0, MSTATUS_MXR 205 | csrs mstatus, t0 206 | 207 | // Set PTE entry 208 | li t0, (PTE_V | PTE_X | PTE_U) 209 | la t1, user_read_pc 210 | srli t1, t1, 12 211 | slli t1, t1, 10 212 | or t0, t0, t1 213 | la t1, page_table 214 | sd t0, (t1) 215 | 216 | // Set the exception handler 217 | la t0, skip_user_ecall_trap; 218 | csrw mtvec, t0; 219 | 220 | // Set vaddr PC and enter U-mode 221 | la t0, user_read_pc 222 | li a0, 4095 223 | and a0, a0, t0 // vaddr pc 224 | auipc a1, 0 // return pc 225 | j enter_user_mode 226 | 227 | success: 228 | exit_imm(0); 229 | 230 | user_ecall: 231 | ecall 232 | exit_imm(1) 233 | 234 | user_read_pc: 235 | auipc t0, 0 236 | lw t0, (t0) 237 | li t1, 0x00000297 // hexcode for "auipc t0, t0" 238 | bne t0, t1, fail 239 | ecall 240 | exit_imm(1) 241 | 242 | enter_user_mode: 243 | csrr t1, mstatus 244 | li t0, ~MSTATUS_MPP 245 | and t1, t0, t1 246 | csrw mstatus, t1 247 | csrw mepc, a0 248 | mret 249 | exit_imm(1) 250 | 251 | enter_supervisor_mode: 252 | li t0, MSTATUS_MPP_MASK 253 | csrc mstatus, t0 254 | li t0, MSTATUS_MPP_S 255 | csrs mstatus, t0 256 | csrw mepc, a0 257 | mret 258 | exit_imm(1) 259 | 260 | skip_user_ecall_trap: 261 | csrr t0, mcause 262 | li t1, CAUSE_USER_ECALL 263 | bne t0, t1, fail 264 | jalr a1, 8 265 | 266 | skip_fetch_page_fault_trap: 267 | csrr t0, mcause 268 | li t1, CAUSE_FETCH_PAGE_FAULT 269 | bne t0, t1, fail 270 | jalr a1, 8 271 | 272 | skip_load_page_fault_trap: 273 | csrr t0, mcause 274 | li t1, CAUSE_LOAD_PAGE_FAULT 275 | bne t0, t1, fail 276 | jalr a1, 8 277 | 278 | fail: 279 | exit_imm(1); 280 | 281 | // Exits via HTIF using gp content as the exit code 282 | exit: 283 | // HTIF exits with dev = cmd = 0 and a payload with lsb set. 284 | // the exit code is taken from payload >> 2 285 | slli gp, gp, 16; 286 | srli gp, gp, 15; 287 | ori gp, gp, 1; 288 | 1: 289 | li t0, PMA_HTIF_START_DEF 290 | sd gp, 0(t0); 291 | j 1b; // Should not be necessary 292 | 293 | .data 294 | .align 12; page_table: .dword 0 295 | -------------------------------------------------------------------------------- /src/uarch/.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | third_party_build/ 3 | 4 | -------------------------------------------------------------------------------- /src/uarch/Makefile: -------------------------------------------------------------------------------- 1 | PREFIX = /opt/cartesi 2 | INSTALLDIR = $(PREFIX)/tests 3 | UARCH_ENV_DIR := $(abspath .) 4 | LIB_DIR := $(abspath ../../lib) 5 | RISCV_PREFIX ?= riscv64-cartesi-linux-gnu- 6 | RISCV_GCC ?= $(RISCV_PREFIX)gcc 7 | RISCV_GCC_OPTS ?= -static -march=rv64i -mabi=lp64 -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles 8 | RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump --disassemble-all --disassemble-zeroes --section=.text --section=.text.startup --section=.text.init --section=.data 9 | RISCV_OBJCOPY ?= $(RISCV_PREFIX)objcopy -S -O binary 10 | 11 | # Tests provided by third party riscv tests 12 | THIRDPARTY_TESTS = \ 13 | add addi addiw addw \ 14 | and andi \ 15 | auipc \ 16 | beq bge bgeu blt bltu bne \ 17 | simple \ 18 | jal jalr \ 19 | lb lbu lh lhu lw lwu ld \ 20 | lui \ 21 | or ori \ 22 | sb sh sw sd \ 23 | sll slli slliw sllw \ 24 | slt slti sltiu sltu \ 25 | sra srai sraiw sraw \ 26 | srl srli srliw srlw \ 27 | sub subw \ 28 | xor xori 29 | 30 | THIRDPARTY_SRC_DIR := $(abspath ../../third-party/riscv-tests/isa/rv64ui) 31 | THIRDPARTY_BUILD_DIR := $(abspath ./third_party_build) 32 | THIRDPARTY_TEST_NAMES = $(addprefix rv64ui-uarch-, $(THIRDPARTY_TESTS)) 33 | THIRDPARTY_TESTS_BIN_NAMES = $(addsuffix .bin, $(THIRDPARTY_TEST_NAMES)) 34 | THIRDPARTY_TESTS_DUMP_NAMES = $(addsuffix .dump, $(THIRDPARTY_TEST_NAMES)) 35 | TARGET_THIRDPARTY_TESTS = $(addprefix $(THIRDPARTY_BUILD_DIR)/, $(THIRDPARTY_TEST_NAMES)) 36 | 37 | # Tests provided by us 38 | TESTS = fence 39 | SRC_DIR = $(abspath .) 40 | BUILD_DIR = $(abspath ./build) 41 | TEST_NAMES = $(addprefix rv64ui-uarch-, $(TESTS)) 42 | TESTS_BIN_NAMES = $(addsuffix .bin, $(TEST_NAMES)) 43 | TESTS_DUMP_NAMES = $(addsuffix .dump, $(TEST_NAMES)) 44 | TARGET_TESTS = $(addprefix $(BUILD_DIR)/, $(TEST_NAMES)) 45 | 46 | TARGET_TEST_BINS = \ 47 | $(addprefix $(THIRDPARTY_BUILD_DIR)/, $(THIRDPARTY_TESTS_BIN_NAMES)) \ 48 | $(addprefix $(BUILD_DIR)/, $(TESTS_BIN_NAMES)) 49 | 50 | TARGET_TEST_DUMPS = \ 51 | $(addprefix $(THIRDPARTY_BUILD_DIR)/, $(THIRDPARTY_TESTS_DUMP_NAMES)) \ 52 | $(addprefix $(BUILD_DIR)/, $(TESTS_DUMP_NAMES)) 53 | 54 | TARGETS = \ 55 | $(TARGET_THIRDPARTY_TESTS) \ 56 | $(TARGET_TESTS) \ 57 | $(TARGET_TEST_BINS) \ 58 | $(TARGET_TEST_DUMPS) 59 | 60 | all: $(TARGETS) 61 | 62 | clean: 63 | rm -rf $(TARGETS) $(BUILD_DIR) $(THIRDPARTY_BUILD_DIR) 64 | 65 | install: 66 | mkdir -p $(INSTALLDIR) 67 | cp -a $(BUILD_DIR)/* $(INSTALLDIR) 68 | cp -a $(THIRDPARTY_BUILD_DIR)/* $(INSTALLDIR) 69 | cp rv64ui-uarch-catalog.json $(INSTALLDIR) 70 | 71 | $(THIRDPARTY_BUILD_DIR)/rv64ui-uarch-%: $(THIRDPARTY_BUILD_DIR) $(THIRDPARTY_SRC_DIR)/%.S 72 | $(RISCV_GCC) $(RISCV_GCC_OPTS) -I$(UARCH_ENV_DIR) \ 73 | -I$(THIRDPARTY_SRC_DIR)/../macros/scalar \ 74 | -I$(LIB_DIR)/machine-emulator-defines \ 75 | -T$(UARCH_ENV_DIR)/link.ld \ 76 | $(THIRDPARTY_SRC_DIR)/$*.S -o $(THIRDPARTY_BUILD_DIR)/rv64ui-uarch-$* 77 | 78 | $(BUILD_DIR)/rv64ui-uarch-%: $(BUILD_DIR) $(SRC_DIR)/%.S 79 | $(RISCV_GCC) $(RISCV_GCC_OPTS) -I$(UARCH_ENV_DIR) \ 80 | -I$(THIRDPARTY_SRC_DIR)/../macros/scalar \ 81 | -I$(LIB_DIR)/machine-emulator-defines \ 82 | -T$(UARCH_ENV_DIR)/link.ld \ 83 | $(SRC_DIR)/$*.S -o $(BUILD_DIR)/rv64ui-uarch-$* 84 | 85 | %.bin: % 86 | $(RISCV_OBJCOPY) $* $*.bin 87 | 88 | %.dump: % 89 | $(RISCV_OBJDUMP) $* > $*.dump 90 | 91 | $(BUILD_DIR) $(THIRDPARTY_BUILD_DIR): 92 | mkdir -p $@ 93 | 94 | -------------------------------------------------------------------------------- /src/uarch/README.md: -------------------------------------------------------------------------------- 1 | # uarch 2 | 3 | Build tests for the Cartesi Machine microarchitecture 4 | -------------------------------------------------------------------------------- /src/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 | -------------------------------------------------------------------------------- /src/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 | -------------------------------------------------------------------------------- /src/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 t0, UARCH_HALT_FLAG_SHADDOW_ADDR_DEF; \ 34 | li t1, UARCH_HALT_FLAG_HALT_VALUE_DEF; \ 35 | sd t1, 0(t0); \ 36 | 37 | //----------------------------------------------------------------------- 38 | // End Macro 39 | //----------------------------------------------------------------------- 40 | 41 | #define TESTNUM gp 42 | #define TEST_SUCEEDED 0xbe1e7aaa 43 | #define TEST_FAILED 0xdeadbeef 44 | 45 | #define RVTEST_CODE_END \ 46 | li ra, TEST_SUCEEDED; \ 47 | RVTEST_HALT 48 | 49 | //----------------------------------------------------------------------- 50 | // Pass/Fail Macro 51 | //----------------------------------------------------------------------- 52 | 53 | #define RVTEST_PASS \ 54 | li ra, TEST_SUCEEDED; \ 55 | li TESTNUM, 1; \ 56 | 57 | #define RVTEST_FAIL \ 58 | li ra, TEST_FAILED; \ 59 | RVTEST_HALT 60 | 61 | //----------------------------------------------------------------------- 62 | // Data Section Macro 63 | //----------------------------------------------------------------------- 64 | 65 | #define EXTRA_DATA \ 66 | ; 67 | 68 | #define RVTEST_DATA_BEGIN \ 69 | ; 70 | 71 | #define RVTEST_DATA_END \ 72 | ; 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /src/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 | ] -------------------------------------------------------------------------------- /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 0xf // 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 | -------------------------------------------------------------------------------- /src/xpie_exceptions.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 machine exception handler to mtrap 31 | la t0, mtrap; 32 | csrw mtvec, t0; 33 | 34 | // Set the supervisor exception handler to strap 35 | la t0, strap; 36 | csrw stvec, t0; 37 | 38 | switch_to_supervisor_mode: 39 | // set supervisor mode start address 40 | la t0, trigger_exception; 41 | csrw mepc, t0; 42 | // Read current mstatus 43 | csrr a0, mstatus; 44 | // Mask out the MPP bits in A0 45 | li a1,~0x1800; 46 | and a0, a0, a1; 47 | // Set the supervisor mode and MPIE bits. 48 | li a1, 0x880; 49 | or a0, a0, a1; 50 | // after this point: 51 | // MPP = supervisor level. 52 | // MPIE = 1 53 | csrw mstatus, a0; 54 | mret; 55 | 56 | trigger_exception: 57 | // Trigger exception with ecall 58 | ecall; 59 | 60 | // fallback if exception was not triggered 61 | exit_imm(1); 62 | 63 | // catch m-mode exception 64 | mtrap: 65 | // Read current mstatus 66 | csrr a0, mstatus; 67 | // Read MPIE bit and compare 68 | li a1, 0x80; 69 | and a2, a0, a1; 70 | bnez a2, switch_to_user_with_supervisor_delegate; 71 | exit_imm(1); 72 | 73 | 74 | switch_to_user_with_supervisor_delegate: 75 | // set delegate MCAUSE_ECALL_BASE + PRV_U 76 | li t0, 0x100; 77 | csrw medeleg, t0; 78 | // set user mode start address 79 | la t0, trigger_exception; 80 | csrw mepc, t0; 81 | // Read current mstatus 82 | csrr a0, mstatus; 83 | // Mask out the MPP bits in A0 84 | li a1,~0x1800; 85 | and a0, a0, a1; 86 | // Set the user mode and SIE bits. 87 | li a1, 0x2; 88 | or a0, a0, a1; 89 | // after this point: 90 | // MPP = user level. 91 | // SIE = 1 92 | csrw mstatus, a0; 93 | mret; 94 | 95 | // catch s-mode exception and exit 96 | strap: 97 | // Read current sstatus (mstatus view) 98 | csrr a0, sstatus; 99 | // Read SPIE bit and compare 100 | li a1, 0x20; 101 | and a2, a0, a1; 102 | seqz gp, a2; 103 | j exit; 104 | 105 | // Exits via HTIF using gp content as the exit code 106 | exit: 107 | // HTIF exits with dev = cmd = 0 and a payload with lsb set. 108 | // the exit code is taken from payload >> 2 109 | slli gp, gp, 16; 110 | srli gp, gp, 15; 111 | ori gp, gp, 1; 112 | 1: 113 | li t0, PMA_HTIF_START_DEF 114 | sd gp, 0(t0); 115 | j 1b; // Should not be necessary 116 | --------------------------------------------------------------------------------