From d447123f042821b45ffdd5aecdebaeaa7fe0518b Mon Sep 17 00:00:00 2001 From: Marcelo Politzer <251334+mpolitzer@users.noreply.github.com> Date: Tue, 23 Jan 2024 14:57:52 -0300 Subject: [PATCH] feat: yield rewrite with libcmt --- sys-utils/Makefile | 2 +- sys-utils/yield/.gitignore | 2 + sys-utils/yield/Makefile | 81 ++++++++++++++++++++ sys-utils/yield/README.md | 41 ++++++++++ sys-utils/yield/yield.c | 150 +++++++++++++++++++++++++++++++++++++ 5 files changed, 275 insertions(+), 1 deletion(-) create mode 100644 sys-utils/yield/.gitignore create mode 100644 sys-utils/yield/Makefile create mode 100644 sys-utils/yield/README.md create mode 100644 sys-utils/yield/yield.c diff --git a/sys-utils/Makefile b/sys-utils/Makefile index ed615246..327a0549 100644 --- a/sys-utils/Makefile +++ b/sys-utils/Makefile @@ -15,7 +15,7 @@ # -UTILITIES := xhalt rollup ioctl-echo-loop +UTILITIES := xhalt yield rollup ioctl-echo-loop UTILITIES_WITH_TOOLCHAIN := $(addsuffix -with-toolchain,$(UTILITIES)) all: $(UTILITIES) diff --git a/sys-utils/yield/.gitignore b/sys-utils/yield/.gitignore new file mode 100644 index 00000000..99593ec3 --- /dev/null +++ b/sys-utils/yield/.gitignore @@ -0,0 +1,2 @@ +extra/halt +halt diff --git a/sys-utils/yield/Makefile b/sys-utils/yield/Makefile new file mode 100644 index 00000000..ba6b44e5 --- /dev/null +++ b/sys-utils/yield/Makefile @@ -0,0 +1,81 @@ +# 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. +# + +UNAME:=$(shell uname) + +TOOLCHAIN_IMAGE ?= cartesi/toolchain +TOOLCHAIN_TAG ?= 0.16.0 +RISCV_ARCH ?= rv64gc +RISCV_ABI ?= lp64d + +TOOLCHAIN_PREFIX ?= riscv64-cartesi-linux-gnu- + +RVCC = $(TOOLCHAIN_PREFIX)gcc +RVCXX = $(TOOLCHAIN_PREFIX)g++ +RVCOPY = $(TOOLCHAIN_PREFIX)objcopy +RVDUMP = $(TOOLCHAIN_PREFIX)objdump +STRIP = $(TOOLCHAIN_PREFIX)strip +CFLAGS :=-Wall -Wextra -pedantic -O2 \ + `PKG_CONFIG_PATH=/usr/riscv64-linux-gnu/lib/pkgconfig pkg-config --cflags libcmt` +LDLIBS := \ + `PKG_CONFIG_PATH=/usr/riscv64-linux-gnu/lib/pkgconfig pkg-config --libs libcmt` + +CONTAINER_MAKE := /usr/bin/make +CONTAINER_BASE := /opt/cartesi/tools +KERNEL_HEADERS_PATH := /opt/riscv/usr/include + +all: yield + +yield.with-toolchain with-toolchain: + $(MAKE) toolchain-exec CONTAINER_COMMAND="$(CONTAINER_MAKE) $@.toolchain" + +extra.ext2.with-toolchain: + $(MAKE) toolchain-exec CONTAINER_COMMAND="$(CONTAINER_MAKE) $@.toolchain" + +yield: yield.c + $(RVCC) $(CFLAGS) -O2 -o yield yield.c $(LDLIBS) + $(STRIP) yield + +extra.ext2: yield + mkdir -m 0755 ./extra + cp ./yield ./extra/yield + xgenext2fs -i 512 -b 8192 -d extra $(basename $@) + rm -rf ./extra + +toolchain-exec: + @docker run --hostname $@ --rm \ + -e USER=$$(id -u -n) \ + -e GROUP=$$(id -g -n) \ + -e UID=$$(id -u) \ + -e GID=$$(id -g) \ + -v `pwd`:$(CONTAINER_BASE) \ + -w $(CONTAINER_BASE) \ + $(TOOLCHAIN_IMAGE):$(TOOLCHAIN_TAG) $(CONTAINER_COMMAND) + +toolchain-env: + @docker run --hostname toolchain-env -it --rm \ + -e USER=$$(id -u -n) \ + -e GROUP=$$(id -g -n) \ + -e UID=$$(id -u) \ + -e GID=$$(id -g) \ + -v `pwd`:$(CONTAINER_BASE) \ + -w $(CONTAINER_BASE) \ + $(TOOLCHAIN_IMAGE):$(TOOLCHAIN_TAG) + +clean: + @rm -rf yield extra.ext2 extra + +.PHONY: toolchain-exec toolchain-env diff --git a/sys-utils/yield/README.md b/sys-utils/yield/README.md new file mode 100644 index 00000000..b656be16 --- /dev/null +++ b/sys-utils/yield/README.md @@ -0,0 +1,41 @@ +## HTIF yield tool + +### Requirements + +- Docker >= 18.x +- GNU Make >= 3.81 + +### Building + +```bash +$ cd linux/htif +$ make +``` + +#### Makefile targets + +The following options are available as `make` targets: + +- **all**: builds the RISC-V yield executable +- **extra.ext2**: builds the extra.ext2 filesystem image with the yield tool inside +- **toolchain-env**: runs the toolchain image with current user UID and GID +- **clean**: clean generated artifacts + +#### Makefile container options + +You can pass the following variables to the make target if you wish to use different docker image tags. + +- TOOLCHAIN\_IMAGE: toolchain image name +- TOOLCHAIN\_TAG: toolchain image tag + +``` +$ make TOOLCHAIN_TAG=mytag +``` + +It's useful when you want to use prebuilt images like `cartesi/toolchain:latest` + +#### Usage + +The purpose of the yield tool please see the emulator documentation. + +The purpose of the `extra.ext2` image is to help the development creating a filesystem that contains the yield tool so it can be used with the emulator. For instructions on how to do that, please see the emulator documentation. diff --git a/sys-utils/yield/yield.c b/sys-utils/yield/yield.c new file mode 100644 index 00000000..165bbf75 --- /dev/null +++ b/sys-utils/yield/yield.c @@ -0,0 +1,150 @@ +/* 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. + */ + + +#include +#include +#include +#include +#include +#include "libcmt/io.h" + +static void help(const char *progname) { + fprintf(stderr, + "Usage: %s []\n" + "Where: \n" + " \"manual\" or \"automatic\"\n" + " \"progress\", \"rx-accepted\", \"rx-rejected\",\n" + " \"tx-voucher\", \"tx-notice\", \"tx-exception\" or\n" + " \"tx-report\"\n" + " 32-bit unsigned integer (decimal, default 0)\n", + progname); + + exit(1); +} + +struct name_value { + const char *name; + uint64_t value; +}; +static int find_value(const struct name_value *pairs, size_t n, const char *s, uint64_t *value) +{ + for (size_t i=0; i UINT32_MAX) { + return 0; + } + return 1; +} + +struct parsed_args { + uint64_t mode; + uint64_t reason; + uint64_t data; +}; + +void parse_args(int argc, char *argv[], struct parsed_args *p) { + int i = 0; + const char *progname = argv[0]; + + memset(p, 0, sizeof(*p)); + + i = 1; + if (i >= argc) { + fprintf(stderr, "Too few arguments.\n\n"); + help(progname); + } + + if (!get_mode(argv[i], &p->mode)) { + fprintf(stderr, "Invalid argument.\n\n"); + help(progname); + } + + i++; + if (i >= argc) { + help(progname); + } + + if (!get_reason(argv[i], &p->reason)) { + fprintf(stderr, "Invalid argument.\n\n"); + help(progname); + } + + i++; + if (i < argc) { + if (get_data(argv[i], &p->data)) { + i++; + } else { + fprintf(stderr, "Invalid argument.\n\n"); + help(progname); + } + } + + if (i != argc) { + fprintf(stderr, "Too many arguments.\n\n"); + help(progname); + } +} + +int main(int argc, char *argv[]) { + struct parsed_args args; + cmt_io_driver_t io[1]; + + parse_args(argc, argv, &args); + cmt_io_yield_t req[1] = {{ + .dev = CMT_IO_DEV, + .cmd = args.mode, + .reason = args.reason, + .data = args.data, + }}; + + int rc = cmt_io_init(io); + if (rc) + return rc; + + return cmt_io_yield(io, req); +}