-
Notifications
You must be signed in to change notification settings - Fork 21
combine interpreter checkpoint #85
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
c9b255c
b750f38
9d5ebcd
1b8f9a8
b7ea28b
d9429ac
fee663e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,2 @@ | ||
| 127e5430d6ca80c65f1943d2b72fe4fd0b970f444376cf6f8663f3ace496f5ff downloads/machine-emulator-tests-data.deb | ||
| 154e2da0e3bb531a8b6e1f9ec64cb90a55cea245aeece2685aa34378d1cf9ea1 downloads/uarch-riscv-tests-json-logs.tar.gz | ||
| fef8844a306d83eef9c30828986645f2b0ff149654490b0f7d47ec2883bcb693 downloads/machine-emulator-tests-data.deb | ||
| bc7a0cc14724167c2826967eaf62feb6a2c902b2b45a73f3c684e1c5ceaa8f69 downloads/uarch-riscv-tests-json-logs.tar.gz |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| // Copyright Cartesi and individual authors (see AUTHORS) | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
| // | ||
|
|
||
| /// @title AdvanceStatus | ||
| /// @notice Return advance status | ||
|
|
||
| pragma solidity ^0.8.0; | ||
|
|
||
| import "./EmulatorCompat.sol"; | ||
| import "./EmulatorConstants.sol"; | ||
|
|
||
| library AdvanceStatus { | ||
| enum Status { | ||
| NOT_YIELDED, | ||
| ACCEPTED, | ||
| REJECTED, | ||
| EXCEPTION | ||
| } | ||
|
|
||
| /* | ||
| typedef struct cmt_io_yield { | ||
| uint8_t dev; | ||
| uint8_t cmd; | ||
| uint16_t reason; | ||
| uint32_t data; | ||
| } cmt_io_yield_t; | ||
| */ | ||
|
|
||
| error InvalidReason(uint16 reason); | ||
|
|
||
| function advanceStatus(AccessLogs.Context memory a) | ||
| internal | ||
| pure | ||
| returns (Status) | ||
| { | ||
| if (!EmulatorCompat.readIflagsY(a)) { | ||
| return Status.NOT_YIELDED; | ||
| } | ||
|
edubart marked this conversation as resolved.
|
||
|
|
||
| // the following two approaches are equivalent: | ||
| // 1. swap the whole struct and then extract the reason | ||
| // 2. extract the reason from the struct and then swap the value | ||
| // EmulatorCompat.readWord already swaps the struct, so we can extract the reason directly | ||
|
|
||
| uint64 tohost = | ||
| EmulatorCompat.readWord(a, EmulatorConstants.HTIF_TOHOST_ADDRESS); | ||
| uint16 reason = uint16(tohost >> 32); | ||
|
edubart marked this conversation as resolved.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This hardcoded |
||
|
|
||
| if (reason == EmulatorConstants.CMIO_YIELD_MANUAL_REASON_RX_ACCEPTED) { | ||
| return Status.ACCEPTED; | ||
| } else if ( | ||
| reason == EmulatorConstants.CMIO_YIELD_MANUAL_REASON_RX_REJECTED | ||
| ) { | ||
| return Status.REJECTED; | ||
| } else if ( | ||
| reason == EmulatorConstants.CMIO_YIELD_MANUAL_REASON_TX_EXCEPTION | ||
| ) { | ||
| return Status.EXCEPTION; | ||
| } else { | ||
| revert InvalidReason(reason); | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,8 +20,28 @@ import "./AccessLogs.sol"; | |
|
|
||
| library EmulatorCompat { | ||
| using AccessLogs for AccessLogs.Context; | ||
| using Buffer for Buffer.Context; | ||
| using Memory for uint64; | ||
|
|
||
| function getCheckpointHash(AccessLogs.Context memory a) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Personally I don't like how both
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think these should be renamed to RevertRootHash to match the emulator.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @stephenctw can we rename this to match the emulator naming convention? I think revert root hash is much more informative than checkpoint hash.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is being renamed by #88 which we will be merged after merging this PR first. |
||
| internal | ||
| pure | ||
| returns (bytes32) | ||
| { | ||
| bytes32 checkpointHash = a.buffer.consumeBytes32(); | ||
| bytes32 hashOfCheckpointHash = a.readLeaf( | ||
| Memory.strideFromLeafAddress( | ||
| EmulatorConstants.REVERT_ROOT_HASH_ADDRESS.toPhysicalAddress() | ||
| ) | ||
| ); | ||
| require( | ||
| keccak256(abi.encodePacked(checkpointHash)) == hashOfCheckpointHash, | ||
| "checkpoint hash mismatch" | ||
| ); | ||
|
|
||
|
mpernambuco marked this conversation as resolved.
|
||
| return checkpointHash; | ||
| } | ||
|
|
||
| function readCycle(AccessLogs.Context memory a) | ||
| internal | ||
| pure | ||
|
|
@@ -35,12 +55,19 @@ library EmulatorCompat { | |
| function readHaltFlag(AccessLogs.Context memory a) | ||
| internal | ||
| pure | ||
| returns (bool) | ||
| returns (uint64) | ||
| { | ||
| return a.readWord( | ||
| EmulatorConstants.UARCH_HALT_FLAG_ADDRESS.toPhysicalAddress() | ||
| ); | ||
| } | ||
|
|
||
| function writeHaltFlag(AccessLogs.Context memory a, uint64 val) | ||
| internal | ||
| pure | ||
| { | ||
| return ( | ||
| a.readWord( | ||
| EmulatorConstants.UARCH_HALT_FLAG_ADDRESS.toPhysicalAddress() | ||
| ) != 0 | ||
| a.writeWord( | ||
| EmulatorConstants.UARCH_HALT_FLAG_ADDRESS.toPhysicalAddress(), val | ||
| ); | ||
| } | ||
|
|
||
|
|
@@ -82,9 +109,15 @@ library EmulatorCompat { | |
| ); | ||
| } | ||
|
|
||
| function setHaltFlag(AccessLogs.Context memory a) internal pure { | ||
| a.writeWord( | ||
| EmulatorConstants.UARCH_HALT_FLAG_ADDRESS.toPhysicalAddress(), 1 | ||
| function setCheckpointHash( | ||
| AccessLogs.Context memory a, | ||
| bytes32 checkpointHash | ||
| ) internal pure { | ||
| a.writeLeaf( | ||
| Memory.strideFromLeafAddress( | ||
| EmulatorConstants.REVERT_ROOT_HASH_ADDRESS.toPhysicalAddress() | ||
| ), | ||
| keccak256(abi.encodePacked(checkpointHash)) | ||
| ); | ||
| } | ||
|
|
||
|
|
@@ -280,7 +313,40 @@ library EmulatorCompat { | |
| revert(text); | ||
| } | ||
|
|
||
| function putChar(AccessLogs.Context memory a, uint8 c) internal pure {} | ||
| function putCharECALL(AccessLogs.Context memory a, uint8 c) internal pure {} | ||
|
|
||
| function markDirtyPageECALL( | ||
| AccessLogs.Context memory a, | ||
| uint64 paddr, | ||
| uint64 pma_index | ||
| ) internal pure {} | ||
|
|
||
| function writeTlbECALL( | ||
| AccessLogs.Context memory a, | ||
| uint64 setIndex, | ||
| uint64 slotIndex, | ||
| uint64 vaddrPage, | ||
| uint64 vpOffset, | ||
| uint64 pmaIndex | ||
| ) internal pure { | ||
|
mpernambuco marked this conversation as resolved.
|
||
| // compute physical address of the TLB slot | ||
| uint64 paddress = EmulatorConstants.AR_SHADOW_TLB_START | ||
| + (setIndex * EmulatorConstants.TLB_SET_LENGTH) | ||
| + (slotIndex * EmulatorConstants.TLB_SLOT_LENGTH); | ||
|
|
||
|
mpernambuco marked this conversation as resolved.
|
||
| // compute stride from physical address (stride = address / leaf_size) | ||
| Memory.Stride writeStride = | ||
| Memory.strideFromLeafAddress(paddress.toPhysicalAddress()); | ||
|
|
||
| // write the 4 words | ||
| a.write4Words( | ||
| writeStride, | ||
| vaddrPage, | ||
| vpOffset, | ||
| pmaIndex, | ||
| 0 // zero_padding_ | ||
| ); | ||
| } | ||
|
|
||
| function uint32Log2(uint32 value) internal pure returns (uint32) { | ||
| require(value > 0, "EmulatorCompat: log2(0) is undefined"); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally I don't like how this
advanceStatuswas introduced in the repository without being used or tests, however I assume Dave is testing it somehow, so we don't need to delay this PR.