risc0_circuit_rv32im/execute/
syscall.rs

1// Copyright 2025 RISC Zero, Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use anyhow::Result;
16
17use risc0_binfmt::ByteAddr;
18
19/// A host-side implementation of a system call.
20pub trait Syscall {
21    /// Reads from the host.
22    fn host_read(&self, ctx: &mut dyn SyscallContext, fd: u32, buf: &mut [u8]) -> Result<u32>;
23
24    /// Writes to the host.
25    fn host_write(&self, ctx: &mut dyn SyscallContext, fd: u32, buf: &[u8]) -> Result<u32>;
26}
27
28/// Access to memory and machine state for syscalls.
29pub trait SyscallContext {
30    /// Loads the value of the given register, e.g. REG_A0.
31    fn peek_register(&mut self, idx: usize) -> Result<u32>;
32
33    /// Loads an individual word from memory.
34    fn peek_u32(&mut self, addr: ByteAddr) -> Result<u32>;
35
36    /// Loads an individual byte from memory.
37    fn peek_u8(&mut self, addr: ByteAddr) -> Result<u8>;
38
39    /// Loads bytes from the given region of memory.
40    ///
41    /// A region may span multiple pages.
42    fn peek_region(&mut self, addr: ByteAddr, size: usize) -> Result<Vec<u8>>;
43
44    /// Load a page from memory at the specified page index.
45    ///
46    /// This is used by sys_fork in order to build a copy-on-write page cache to
47    /// inherit pages from the parent process.
48    fn peek_page(&mut self, page_idx: u32) -> Result<Vec<u8>>;
49
50    /// Returns the current cycle count.
51    fn get_cycle(&self) -> u64;
52
53    /// Returns the current program counter.
54    fn get_pc(&self) -> u32;
55}