From bedec915effe3d7ba8433bf9ee1bd9658560a574 Mon Sep 17 00:00:00 2001 From: Philip Wiese Date: Thu, 12 Feb 2026 19:28:08 +0100 Subject: [PATCH 01/16] Add GAP9 Container Support - Cleanup Docker flow to use a temporary build folder - Install zsh and oh-my-zsh plugin - Adapt GAP9 Docker Flow to support ARM64 - Add GAP9 Docker GitHub Build Flow - Add GAP9 Run script to use real hardware - Update README - Fix missing pre-commit dependency WIP --- .../workflows/docker-build-deeploy-gap9.yml | 155 +++++ .gitignore | 5 + .pre-commit-config.yaml | 1 + Container/.zshrc | 116 ++++ Container/Dockerfile.deeploy | 35 +- Container/Dockerfile.deeploy-gap9 | 121 ++++ Container/Dockerfile.toolchain | 11 +- Container/Makefile | 52 +- Container/gap9-amd64.list | 8 + Container/gap9-amd64.patch | 38 ++ Container/gap9-arm64.patch | 366 ++++++++++++ Container/gap9-sources.list | 46 ++ Makefile | 37 +- README_GAP9.md | 99 ++++ scripts/gap9-build_sdk.sh | 72 +++ scripts/gap9-run.sh | 543 ++++++++++++++++++ 16 files changed, 1674 insertions(+), 31 deletions(-) create mode 100644 .github/workflows/docker-build-deeploy-gap9.yml create mode 100644 Container/.zshrc create mode 100644 Container/Dockerfile.deeploy-gap9 create mode 100644 Container/gap9-amd64.list create mode 100644 Container/gap9-amd64.patch create mode 100644 Container/gap9-arm64.patch create mode 100644 Container/gap9-sources.list create mode 100644 README_GAP9.md create mode 100755 scripts/gap9-build_sdk.sh create mode 100755 scripts/gap9-run.sh diff --git a/.github/workflows/docker-build-deeploy-gap9.yml b/.github/workflows/docker-build-deeploy-gap9.yml new file mode 100644 index 0000000000..e6a9ab7016 --- /dev/null +++ b/.github/workflows/docker-build-deeploy-gap9.yml @@ -0,0 +1,155 @@ +# SPDX-FileCopyrightText: 2025 ETH Zurich and University of Bologna +# +# SPDX-License-Identifier: Apache-2.0 + +--- +name: Docker • Build Deeploy GAP9 Container + +"on": + workflow_dispatch: + inputs: + docker_image_deeploy: + description: "Deeploy Image to use" + required: false + default: "ghcr.io/pulp-platform/deeploy:latest" + +jobs: + prepare: + name: Fetch branch name or tag + runs-on: ubuntu-latest + outputs: + docker_tag: ${{ steps.generate_tag.outputs.docker_tag }} + steps: + - uses: actions/checkout@v4 + + - name: Set up environment variables + run: | + echo "BRANCH_NAME=${GITHUB_REF##*/}" >> $GITHUB_ENV + echo "TAG_NAME=${GITHUB_REF##*/}" >> $GITHUB_ENV + echo "IS_TAG=${GITHUB_REF_TYPE}" >> $GITHUB_ENV + + - name: Set Docker tag + id: generate_tag + run: | + if [[ "${{ env.IS_TAG }}" == "tag" ]]; then + echo "docker_tag=${{ env.TAG_NAME }}" >> $GITHUB_OUTPUT + else + echo "docker_tag=${{ env.BRANCH_NAME }}" >> $GITHUB_OUTPUT + fi + + build-deeploy-gap9: + name: Build Deeploy GAP9 Image + needs: [prepare] + runs-on: ${{ matrix.runner }} + outputs: + digest-amd64: ${{ steps.digest.outputs.digest-amd64 }} + digest-arm64: ${{ steps.digest.outputs.digest-arm64 }} + strategy: + fail-fast: false + matrix: + platform: [amd64, arm64] + include: + - platform: amd64 + runner: ubuntu-latest + - platform: arm64 + runner: ubuntu-22.04-arm + steps: + - uses: actions/checkout@v4 + + - name: Free up disk space + uses: jlumbroso/free-disk-space@v1.3.1 + with: + tool-cache: true + android: true + dotnet: true + haskell: true + large-packages: true + + - uses: docker/setup-buildx-action@v3 + + - name: GHCR Log-in + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build Cache for Docker + id: cache + uses: actions/cache@v4 + with: + path: var-ccache + key: ${{ runner.os }}-${{ matrix.platform }}-build-cache-deeploy-gap9 + + - name: Inject build-cache + uses: reproducible-containers/buildkit-cache-dance@v3.1.0 + with: + cache-map: | + { + "var-ccache": "/ccache" + } + skip-extraction: ${{ steps.cache.outputs.cache-hit }} + + - name: Lower Case Repository Name + run: | + echo "OWNER_LC=${OWNER,,}" >>${GITHUB_ENV} + env: + OWNER: "${{ github.repository_owner }}" + + - name: Build and push final deploy image + id: build + uses: docker/build-push-action@v6 + with: + platforms: linux/${{ matrix.platform }} + context: . + cache-from: type=gha + cache-to: type=gha,mode=min + file: Container/Dockerfile.deeploy-gap9 + push: true + build-args: | + DEEPLOY_IMAGE=${{ github.event.inputs.docker_image_deeploy }} + outputs: type=image,name=ghcr.io/${{ env.OWNER_LC }}/deeploy-gap9,annotation-index=true,name-canonical=true,push=true + + - name: Extract image digest + id: digest + run: echo "digest-${{ matrix.platform }}=${{ steps.build.outputs.digest }}" >> $GITHUB_OUTPUT + + merge-deeploy-gap9-images: + name: Merge Deeploy GAP9 Images + runs-on: ubuntu-latest + needs: [prepare, build-deeploy-gap9] + steps: + - name: GHCR Log-in + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Lower Case Repository Name + run: | + echo "OWNER_LC=${OWNER,,}" >>${GITHUB_ENV} + env: + OWNER: "${{ github.repository_owner }}" + + - name: Merge Deeploy GAP9 Images + uses: Noelware/docker-manifest-action@v1 + with: + inputs: | + ghcr.io/${{ env.OWNER_LC }}/deeploy-gap9@${{ needs.build-deeploy-gap9.outputs.digest-amd64 }}, + ghcr.io/${{ env.OWNER_LC }}/deeploy-gap9@${{ needs.build-deeploy-gap9.outputs.digest-arm64 }} + tags: | + ghcr.io/${{ env.OWNER_LC }}/deeploy-gap9:latest, + ghcr.io/${{ env.OWNER_LC }}/deeploy-gap9:${{ needs.prepare.outputs.docker_tag }} + push: true + + - name: Set package visibility to internal + uses: actions/github-script@v7 + with: + script: | + await github.rest.packages.updatePackageVersionVisibility({ + package_type: 'container', + package_name: 'deeploy-gap9', + visibility: 'internal', + org: context.repo.owner + }); diff --git a/.gitignore b/.gitignore index dc93328e4a..d9e4faace3 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ install/ compile_commands.json toolchain/**/*/ + # Node package.json package-lock.json @@ -52,3 +53,7 @@ DeeployTest/Tests/**/generateTest.py DeeployTest/out.txt CHANGELOG_GEN.md + +# Container Artifacts +.pyusbip/ +.cache/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f1d58d3265..e6f07fbc8d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,6 +13,7 @@ exclude: | | .*TEST_.* | .*TestFiles.* | .*runtime.* + | .*\.patch | .*prebuilt/.* ) diff --git a/Container/.zshrc b/Container/.zshrc new file mode 100644 index 0000000000..c690527643 --- /dev/null +++ b/Container/.zshrc @@ -0,0 +1,116 @@ +# SPDX-FileCopyrightText: 2025 ETH Zurich and University of Bologna +# +# SPDX-License-Identifier: Apache-2.0 + +# If you come from bash you might have to change your $PATH. +# export PATH=$HOME/bin:$HOME/.local/bin:/usr/local/bin:$PATH + +# Path to your Oh My Zsh installation. +export ZSH="$HOME/.oh-my-zsh" + +# Set name of the theme to load --- if set to "random", it will +# load a random theme each time Oh My Zsh is loaded, in which case, +# to know which specific one was loaded, run: echo $RANDOM_THEME +# See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes +ZSH_THEME="cypher" + +# Set list of themes to pick from when loading at random +# Setting this variable when ZSH_THEME=random will cause zsh to load +# a theme from this variable instead of looking in $ZSH/themes/ +# If set to an empty array, this variable will have no effect. +# ZSH_THEME_RANDOM_CANDIDATES=( "robbyrussell" "agnoster" ) + +# Uncomment the following line to use case-sensitive completion. +# CASE_SENSITIVE="true" + +# Uncomment the following line to use hyphen-insensitive completion. +# Case-sensitive completion must be off. _ and - will be interchangeable. +# HYPHEN_INSENSITIVE="true" + +# Uncomment one of the following lines to change the auto-update behavior +# zstyle ':omz:update' mode disabled # disable automatic updates +# zstyle ':omz:update' mode auto # update automatically without asking +# zstyle ':omz:update' mode reminder # just remind me to update when it's time + +# Uncomment the following line to change how often to auto-update (in days). +# zstyle ':omz:update' frequency 13 + +# Uncomment the following line if pasting URLs and other text is messed up. +# DISABLE_MAGIC_FUNCTIONS="true" + +# Uncomment the following line to disable colors in ls. +# DISABLE_LS_COLORS="true" + +# Uncomment the following line to disable auto-setting terminal title. +# DISABLE_AUTO_TITLE="true" + +# Uncomment the following line to enable command auto-correction. +# ENABLE_CORRECTION="true" + +# Uncomment the following line to display red dots whilst waiting for completion. +# You can also set it to another string to have that shown instead of the default red dots. +# e.g. COMPLETION_WAITING_DOTS="%F{yellow}waiting...%f" +# Caution: this setting can cause issues with multiline prompts in zsh < 5.7.1 (see #5765) +# COMPLETION_WAITING_DOTS="true" + +# Uncomment the following line if you want to disable marking untracked files +# under VCS as dirty. This makes repository status check for large repositories +# much, much faster. +# DISABLE_UNTRACKED_FILES_DIRTY="true" + +# Uncomment the following line if you want to change the command execution time +# stamp shown in the history command output. +# You can set one of the optional three formats: +# "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd" +# or set a custom format using the strftime function format specifications, +# see 'man strftime' for details. +# HIST_STAMPS="mm/dd/yyyy" + +# Would you like to use another custom folder than $ZSH/custom? +# ZSH_CUSTOM=/path/to/new-custom-folder + +# Which plugins would you like to load? +# Standard plugins can be found in $ZSH/plugins/ +# Custom plugins may be added to $ZSH_CUSTOM/plugins/ +# Example format: plugins=(rails git textmate ruby lighthouse) +# Add wisely, as too many plugins slow down shell startup. +plugins=(git) + +source $ZSH/oh-my-zsh.sh + +# User configuration + +# export MANPATH="/usr/local/man:$MANPATH" + +# You may need to manually set your language environment +# export LANG=en_US.UTF-8 + +# Preferred editor for local and remote sessions +# if [[ -n $SSH_CONNECTION ]]; then +# export EDITOR='vim' +# else +# export EDITOR='nvim' +# fi + +# Compilation flags +# export ARCHFLAGS="-arch $(uname -m)" + +# Set personal aliases, overriding those provided by Oh My Zsh libs, +# plugins, and themes. Aliases can be placed here, though Oh My Zsh +# users are encouraged to define aliases within a top-level file in +# the $ZSH_CUSTOM folder, with .zsh extension. Examples: +# - $ZSH_CUSTOM/aliases.zsh +# - $ZSH_CUSTOM/macos.zsh +# For a full list of active aliases, run `alias`. +# +# Example aliases +alias zshconfig="nano ~/.zshrc" +# alias ohmyzsh="mate ~/.oh-my-zsh" + +unsetopt HIST_SAVE_BY_COPY +setopt APPEND_HISTORY +setopt SHARE_HISTORY +setopt HIST_IGNORE_ALL_DUPS + +# Make sure the gap command of the GAP9 SDK works +unalias gap diff --git a/Container/Dockerfile.deeploy b/Container/Dockerfile.deeploy index ee5adc5e4f..2b717e49ec 100644 --- a/Container/Dockerfile.deeploy +++ b/Container/Dockerfile.deeploy @@ -14,15 +14,17 @@ ARG TARGETPLATFORM ENV DEBIAN_FRONTEND=noninteractive ENV TZ=Etc/UTC +ENV LANG=C.UTF-8 +ENV LC_ALL=C.UTF-8 ENV PATH="/app/install/bender:${PATH}" +ENV DEEPLOY_INSTALL_DIR=/app/install ENV LLVM_INSTALL_DIR=/app/install/llvm -WORKDIR /app +WORKDIR /app/build # Make sure updates in the repo are reflected in the image COPY toolchain/*.patch toolchain/ COPY Makefile ./ -COPY requirements-dev.txt ./ # Compile emulators # WIESEP: We need to already clean up some space, otherwise the GitHub runners run out of disk space @@ -30,8 +32,8 @@ RUN --mount=type=cache,target=/ccache \ ccache -z && \ make pulp-sdk chimera-sdk qemu mempool banshee xtensor && \ make gvsoc && \ - cp -r /app/toolchain/gvsoc/core/requirements.txt /app/core-requirements.txt && \ - cp -r /app/toolchain/gvsoc/gapy/requirements.txt /app/gapy-requirements.txt && \ + cp -r toolchain/gvsoc/core/requirements.txt /app/core-requirements.txt && \ + cp -r toolchain/gvsoc/gapy/requirements.txt /app/gapy-requirements.txt && \ rm -rf toolchain/pulp-sdk toolchain/qemu toolchain/mempool toolchain/banshee toolchain/xtensor toolchain/xtl toolchain/xsimd toolchain/gvsoc && \ ccache -s @@ -54,13 +56,15 @@ fi # Compile Snitch Runtime ENV CC="gcc" ENV CXX="g++" +ENV PATH=/app/install/bender:${PATH} RUN --mount=type=cache,target=/ccache \ ccache -z && \ make snitch_runtime && \ ccache -s # Remove toolchain to make the container lighter -RUN rm -rf toolchain +WORKDIR /app +RUN rm -rf /app/build ########## Stage 2: Lightweight image with precompiled toolchain and emulators ########## FROM ubuntu:22.04 AS deeploy @@ -68,9 +72,12 @@ FROM ubuntu:22.04 AS deeploy ARG TARGETPLATFORM ARG DEBIAN_FRONTEND=noninteractive ENV TZ=Etc/UTC +ENV LANG=C.UTF-8 +ENV LC_ALL=C.UTF-8 # Export symbols necessary for Deeploy's build flow ENV CMAKE=/usr/bin/cmake +ENV DEEPLOY_INSTALL_DIR=/app/install ENV PULP_SDK_HOME=/app/install/pulp-sdk ENV SNITCH_HOME=/app/install/snitch_cluster ENV CHIMERA_SDK_HOME=/app/install/chimera-sdk @@ -83,7 +90,7 @@ ENV MEMPOOL_HOME=/app/install/mempool ENV BENDER_INSTALL_DIR=/app/install/bender ENV PATH=/app/install/qemu/bin:/app/install/banshee:/app/install/bender:$PATH -WORKDIR /app +WORKDIR /app/build COPY pyproject.toml ./ @@ -99,7 +106,8 @@ RUN apt-get update && \ python-is-python3 \ python3.10-venv \ python3.10-distutils \ - gcc && \ + gcc \ + zsh && \ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && \ python get-pip.py && \ rm get-pip.py && \ @@ -118,10 +126,19 @@ elif [ "$TARGETPLATFORM" = "linux/arm64" ]; then \ ./cmake-3.24.0-linux-aarch64.sh --prefix=/usr --skip-license; \ fi +COPY Container/.zshrc ./ +# # Install Oh My ZSH +RUN sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended && \ + cp .zshrc /root/.zshrc + COPY --from=toolchain /app/core-requirements.txt ./core-requirements.txt COPY --from=toolchain /app/gapy-requirements.txt ./gapy-requirements.txt -COPY --from=toolchain /app/requirements-dev.txt ./ +COPY requirements-dev.txt ./ RUN pip install -r requirements-dev.txt -r core-requirements.txt -r gapy-requirements.txt # Copy pre-built toolchains and emulators -COPY --from=toolchain /app/install ./install +COPY --from=toolchain /app/install /app/install + +# Remove unused files and clean up to reduce image size +WORKDIR /app +RUN rm -rf /app/build diff --git a/Container/Dockerfile.deeploy-gap9 b/Container/Dockerfile.deeploy-gap9 new file mode 100644 index 0000000000..5232636d0c --- /dev/null +++ b/Container/Dockerfile.deeploy-gap9 @@ -0,0 +1,121 @@ +# SPDX-FileCopyrightText: 2026 ETH Zurich and University of Bologna +# +# SPDX-License-Identifier: Apache-2.0 + +ARG DEEPOY_IMAGE=ghcr.io/pulp-platform/deeploy:latest +FROM ${DEEPOY_IMAGE} AS deeploy + +ARG TARGETPLATFORM +ARG DEBIAN_FRONTEND=noninteractive + +ENV GAP_RISCV_GCC_TOOLCHAIN=/app/install/gcc/gap9 +ENV GAP_SDK_HOME=/app/install/gap9-sdk +ENV GAP9_SDK_INSTALL_DIR=/app/install/gap9-sdk +ENV GAP_RISCV_GCC_INSTALL_DIR=/app/install/gcc/gap9 + +WORKDIR /app/build + +# Install SSH keys to access private repositories +RUN mkdir -p -m 0700 ~/.ssh && \ + ssh-keyscan iis-git.ee.ethz.ch >> ~/.ssh/known_hosts && \ + ssh-keyscan github.com >> ~/.ssh/known_hosts + +COPY toolchain/*.patch toolchain/ +COPY Makefile ./ + +RUN apt-get update && \ + apt-get upgrade -y && \ + apt-get install -y \ + git-lfs \ + ccache \ + ninja-build \ + pkg-config \ + ibglib2.0-dev \ + libpixman-1-dev \ + python3 \ + python3-pip \ + python3-dev \ + python-is-python3 \ + python3.10-venv \ + python3.10-distutils \ + curl \ + protobuf-compiler \ + libftdi-dev \ + libftdi1 \ + doxygen \ + libsdl2-dev \ + scons \ + gtkwave \ + libsndfile1-dev \ + rsync \ + autoconf \ + automake \ + texinfo \ + libtool \ + libsdl2-ttf-dev \ + gcc \ + wget \ + clang-format \ + g++ \ + sudo \ + device-tree-compiler \ + zsh \ + nano \ + sudo \ + gdb-multiarch \ + ssh \ + gcc-x86-64-linux-gnu \ + telnet \ + usbutils \ + libftdi-dev \ + libusb-1.0-0-dev && \ + rm -rf /var/lib/apt/lists/* + + +COPY Container/gap9-amd64.list Container/gap9-sources.list ./ +# Install AMD64 libraries on ARM64 for GCC GAP9 compiler support +RUN <traces.new_trace(itf_name, &this->trace, vp::DEBUG); + top->new_master_port("sfu_irq", &this->irq); ++ top->new_master_port("sfu_pdm_out_0", &this->irq); ++ top->new_master_port("sfu_pdm_out_1", &this->irq); ++ top->new_master_port("sfu_pdm_out_2", &this->irq); ++ top->new_master_port("sfu_pdm_out_3", &this->irq); ++ top->new_master_port("sfu_pdm_out_4", &this->irq); ++ top->new_master_port("sfu_pdm_out_5", &this->irq); ++ ++ top->new_master_port("sfu_pdm_in_0", &this->irq); ++ top->new_master_port("sfu_pdm_in_1", &this->irq); ++ top->new_master_port("sfu_pdm_in_2", &this->irq); ++ top->new_master_port("sfu_pdm_in_3", &this->irq); ++ top->new_master_port("sfu_pdm_in_4", &this->irq); ++ top->new_master_port("sfu_pdm_in_5", &this->irq); ++ top->new_master_port("sfu_pdm_in_6", &this->irq); ++ top->new_master_port("sfu_pdm_in_7", &this->irq); ++ top->new_master_port("sfu_pdm_in_8", &this->irq); ++ top->new_master_port("sfu_pdm_in_9", &this->irq); ++ top->new_master_port("sfu_pdm_in_10", &this->irq); ++ top->new_master_port("sfu_pdm_in_11", &this->irq); ++ ++ top->new_master_port("sfu_ws_in_0", &this->irq); ++ top->new_master_port("sfu_ws_in_1", &this->irq); ++ top->new_master_port("sfu_ws_in_2", &this->irq); ++ ++ ++ // top->new_slave_port("sfu_stream_in_ready_0", &this->in); ++ // top->new_slave_port("sfu_stream_in_ready_1", &this->in); ++ // top->new_slave_port("sfu_stream_in_ready_2", &this->in); ++ // top->new_slave_port("sfu_stream_in_ready_3", &this->in); ++ // top->new_slave_port("sfu_stream_in_ready_4", &this->in); ++ // top->new_slave_port("sfu_stream_in_ready_5", &this->in); ++ // top->new_slave_port("sfu_stream_in_ready_6", &this->in); ++ // top->new_slave_port("sfu_stream_in_ready_7", &this->in); ++ // top->new_slave_port("sfu_stream_in_ready_8", &this->in); ++ // top->new_slave_port("sfu_stream_in_ready_9", &this->in); ++ // top->new_slave_port("sfu_stream_in_ready_10", &this->in); ++ // top->new_slave_port("sfu_stream_in_ready_11", &this->in); ++ // top->new_slave_port("sfu_stream_in_ready_12", &this->in); ++ // top->new_slave_port("sfu_stream_in_ready_13", &this->in); ++ // top->new_slave_port("sfu_stream_in_ready_14", &this->in); ++ // top->new_slave_port("sfu_stream_in_ready_15", &this->in); ++ // top->new_slave_port("sfu_stream_out_data_0", &this->in); ++ // top->new_slave_port("sfu_stream_out_data_1", &this->in); ++ // top->new_slave_port("sfu_stream_out_data_2", &this->in); ++ // top->new_slave_port("sfu_stream_out_data_3", &this->in); ++ // top->new_slave_port("sfu_stream_out_data_4", &this->in); ++ // top->new_slave_port("sfu_stream_out_data_5", &this->in); ++ // top->new_slave_port("sfu_stream_out_data_6", &this->in); ++ // top->new_slave_port("sfu_stream_out_data_7", &this->in); ++ // top->new_slave_port("sfu_stream_out_data_8", &this->in); ++ // top->new_slave_port("sfu_stream_out_data_9", &this->in); ++ // top->new_slave_port("sfu_stream_out_data_10", &this->in); ++ // top->new_slave_port("sfu_stream_out_data_11", &this->in); ++ // top->new_slave_port("sfu_stream_out_data_12", &this->in); ++ // top->new_slave_port("sfu_stream_out_data_13", &this->in); ++ // top->new_slave_port("sfu_stream_out_data_14", &this->in); ++ // top->new_slave_port("sfu_stream_out_data_15", &this->in); ++ ++ top->new_master_port("sfu_stream_in_data_0", &this->irq); ++ top->new_master_port("sfu_stream_in_data_1", &this->irq); ++ top->new_master_port("sfu_stream_in_data_2", &this->irq); ++ top->new_master_port("sfu_stream_in_data_3", &this->irq); ++ top->new_master_port("sfu_stream_in_data_4", &this->irq); ++ top->new_master_port("sfu_stream_in_data_5", &this->irq); ++ top->new_master_port("sfu_stream_in_data_6", &this->irq); ++ top->new_master_port("sfu_stream_in_data_7", &this->irq); ++ top->new_master_port("sfu_stream_in_data_8", &this->irq); ++ top->new_master_port("sfu_stream_in_data_9", &this->irq); ++ top->new_master_port("sfu_stream_in_data_10", &this->irq); ++ top->new_master_port("sfu_stream_in_data_11", &this->irq); ++ top->new_master_port("sfu_stream_in_data_12", &this->irq); ++ top->new_master_port("sfu_stream_in_data_13", &this->irq); ++ top->new_master_port("sfu_stream_in_data_14", &this->irq); ++ top->new_master_port("sfu_stream_in_data_15", &this->irq); ++ top->new_master_port("sfu_stream_out_ready_0", &this->irq); ++ top->new_master_port("sfu_stream_out_ready_1", &this->irq); ++ top->new_master_port("sfu_stream_out_ready_2", &this->irq); ++ top->new_master_port("sfu_stream_out_ready_3", &this->irq); ++ top->new_master_port("sfu_stream_out_ready_4", &this->irq); ++ top->new_master_port("sfu_stream_out_ready_5", &this->irq); ++ top->new_master_port("sfu_stream_out_ready_6", &this->irq); ++ top->new_master_port("sfu_stream_out_ready_7", &this->irq); ++ top->new_master_port("sfu_stream_out_ready_8", &this->irq); ++ top->new_master_port("sfu_stream_out_ready_9", &this->irq); ++ top->new_master_port("sfu_stream_out_ready_10", &this->irq); ++ top->new_master_port("sfu_stream_out_ready_11", &this->irq); ++ top->new_master_port("sfu_stream_out_ready_12", &this->irq); ++ top->new_master_port("sfu_stream_out_ready_13", &this->irq); ++ top->new_master_port("sfu_stream_out_ready_14", &this->irq); ++ top->new_master_port("sfu_stream_out_ready_15", &this->irq); + } + + +diff --git a/install_python_deps.sh b/install_python_deps.sh +index 4b0dbb728..8d5610678 100755 +--- a/install_python_deps.sh ++++ b/install_python_deps.sh +@@ -60,7 +60,7 @@ then + pip3 install -r tools/nntool/tests/requirements.txt + fi + +- pip3 install -r tools/audio-framework/requirements.txt ++# pip3 install -r tools/audio-framework/requirements.txt + pip3 install -r utils/gapy_v2/requirements.txt + pip3 install -r doc/requirements.txt + fi +diff --git a/utils/cmake/at.cmake b/utils/cmake/at.cmake +index 476b87c78..ee6449a1d 100644 +--- a/utils/cmake/at.cmake ++++ b/utils/cmake/at.cmake +@@ -909,7 +909,7 @@ macro(_at_model_setup_int) + OUTPUT ${PARAM_MODEL_EXE_PATH} + DEPENDS ${PARAM_MODEL_PATH} ${_MODEL_GEN_SRCS} ${TILER_LIB} + COMMAND ${CMAKE_COMMAND} -E make_directory ${_MODEL_EXE_DIR} +- COMMAND gcc -g -o ${PARAM_MODEL_EXE_PATH} ${_MODEL_GEN_INCS} ${PARAM_MODEL_PATH} ${_MODEL_GEN_SRCS} ${_MODEL_GEN_LIBS} ${SDL2_LDFLAGS} -lm ${PARAM_MODEL_EXTRA_COMPILE_FLAGS} ++ COMMAND x86_64-linux-gnu-gcc -g -o ${PARAM_MODEL_EXE_PATH} ${_MODEL_GEN_INCS} ${PARAM_MODEL_PATH} ${_MODEL_GEN_SRCS} ${_MODEL_GEN_LIBS} ${SDL2_LDFLAGS} -lm ${PARAM_MODEL_EXTRA_COMPILE_FLAGS} + ) + + # global compile model target +diff --git a/utils/gapy_v2/bin/gapylib/chips/gap/gap9_v2/board_runner.py b/utils/gapy_v2/bin/gapylib/chips/gap/gap9_v2/board_runner.py +index a7b191322..b0c5c5e77 100644 +--- a/utils/gapy_v2/bin/gapylib/chips/gap/gap9_v2/board_runner.py ++++ b/utils/gapy_v2/bin/gapylib/chips/gap/gap9_v2/board_runner.py +@@ -159,7 +159,7 @@ class Openocd(): + if self.args.openocd_tools is None: + raise RuntimeError("Argument --openocd-tools is missing") + +- def connect(self, use_existing_port=6666): ++ def connect(self, telnet_port=None, telnet_host='localhost'): + """Connect to target. + + This will launch OpenOCD with the telnet proxy and connect to it so that this class +@@ -169,10 +169,10 @@ class Openocd(): + # To allow the execution of several gapy in parallel, we cannot use a fixed port. + # Iterate until we find an available one. + retry_nb = 0 +- if use_existing_port is not None: ++ if telnet_port is not None: + success = True +- port = use_existing_port +- self.use_existing_port = use_existing_port ++ port = telnet_port ++ self.telnet_port = telnet_port + else: + success = False + while retry_nb < 30: +@@ -208,7 +208,7 @@ class Openocd(): + + # Now that OpenOCD was successfully launched with proxy openocd, launch a telnet. + if success is True: +- self.telnet = pexpect.spawn(f'telnet localhost {port}', encoding='utf-8', echo=False) ++ self.telnet = pexpect.spawn(f'telnet {telnet_host} {port}', encoding='utf-8', echo=False) + match = self.telnet.expect(['Open On-Chip Debugger'], timeout=None) + else: + raise RuntimeError('Failed to connect to openocd after 30 retries') +@@ -472,6 +472,12 @@ class Runner(): + parser.add_argument("--gdb-port", dest="gdb_port", default=3333, type=int, + help="GDB port") + ++ parser.add_argument("--telnet-port", dest="telnet_port", default=None, type=int, ++ help="Telnet port") ++ ++ parser.add_argument("--telnet-host", dest="telnet_host", default='localhost', type=str, ++ help="Telnet host") ++ + parser.add_argument("--wsl", dest = "wsl", type=str, default=None, + help = "Launch command in wsl environment") + +@@ -602,7 +608,7 @@ class Runner(): + + if ocd is None: + ocd = Openocd(args) +- ocd.connect() ++ ocd.connect(args.telnet_port, args.telnet_host) + + self.__flash_image(args, ocd, flash, base_addr, first_index, last) + +diff --git a/utils/openocd_tools/tcl/gap9revb.tcl b/utils/openocd_tools/tcl/gap9revb.tcl +index 4a66dfa27..dea57196b 100644 +--- a/utils/openocd_tools/tcl/gap9revb.tcl ++++ b/utils/openocd_tools/tcl/gap9revb.tcl +@@ -3,7 +3,7 @@ adapter_khz 5000 + + config_reset 0x1 + +-target create $_FC riscv -chain-position $_TAP_RISCV -coreid 0x9 ++target create $_FC riscv -chain-position $_TAP_RISCV -coreid 0x9 + + gdb_report_data_abort enable + gdb_report_register_access_error enable +@@ -23,8 +23,8 @@ proc jtag_init {} { + gap_reset 0 100 + + # wait for jtag ready +- poll_confreg 0x1 +- echo "INIT: confreg polling done" ++ # poll_confreg 0x1 ++ # echo "INIT: confreg polling done" + + $::_FC arp_examine + echo "examine done" +@@ -36,8 +36,8 @@ proc init_reset {mode} { + #targets $::_FC + gap_reset 1 100 + # wait for jtag ready +- poll_confreg 0x1 +- echo "RESET: confreg polling done" ++ # poll_confreg 0x1 ++ # echo "RESET: confreg polling done" + jtag arp_init + } + diff --git a/Container/gap9-sources.list b/Container/gap9-sources.list new file mode 100644 index 0000000000..afd5cb4726 --- /dev/null +++ b/Container/gap9-sources.list @@ -0,0 +1,46 @@ +# SPDX-FileCopyrightText: 2025 ETH Zurich and University of Bologna +# +# SPDX-License-Identifier: Apache-2.0 + +# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to +# newer versions of the distribution. +deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ jammy main restricted +# deb-src http://ports.ubuntu.com/ubuntu-ports/ jammy main restricted + +## Major bug fix updates produced after the final release of the +## distribution. +deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ jammy-updates main restricted +# deb-src http://ports.ubuntu.com/ubuntu-ports/ jammy-updates main restricted + +## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu +## team. Also, please note that software in universe WILL NOT receive any +## review or updates from the Ubuntu security team. +deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ jammy universe +# deb-src http://ports.ubuntu.com/ubuntu-ports/ jammy universe +deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ jammy-updates universe +# deb-src http://ports.ubuntu.com/ubuntu-ports/ jammy-updates universe + +## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu +## team, and may not be under a free licence. Please satisfy yourself as to +## your rights to use the software. Also, please note that software in +## multiverse WILL NOT receive any review or updates from the Ubuntu +## security team. +deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ jammy multiverse +# deb-src http://ports.ubuntu.com/ubuntu-ports/ jammy multiverse +deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ jammy-updates multiverse +# deb-src http://ports.ubuntu.com/ubuntu-ports/ jammy-updates multiverse + +## N.B. software from this repository may not have been tested as +## extensively as that contained in the main release, although it includes +## newer versions of some applications which may provide useful features. +## Also, please note that software in backports WILL NOT receive any review +## or updates from the Ubuntu security team. +deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ jammy-backports main restricted universe multiverse +# deb-src http://ports.ubuntu.com/ubuntu-ports/ jammy-backports main restricted universe multiverse + +deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ jammy-security main restricted +# deb-src http://ports.ubuntu.com/ubuntu-ports/ jammy-security main restricted +deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ jammy-security universe +# deb-src http://ports.ubuntu.com/ubuntu-ports/ jammy-security universe +deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ jammy-security multiverse +# deb-src http://ports.ubuntu.com/ubuntu-ports/ jammy-security multiverse diff --git a/Makefile b/Makefile index d40a49da11..075a716c62 100644 --- a/Makefile +++ b/Makefile @@ -24,6 +24,9 @@ PICOLIBC_RV32IMA_INSTALL_DIR ?= ${LLVM_INSTALL_DIR}/picolibc/riscv/rv32ima PICOLIBC_RV32IMAFD_INSTALL_DIR ?= ${LLVM_INSTALL_DIR}/picolibc/riscv/rv32imafd PICOLIBC_RV32IMF_INSTALL_DIR ?= ${LLVM_INSTALL_DIR}/picolibc/riscv/rv32imf +GCC_INSTALL_DIR ?= ${DEEPLOY_INSTALL_DIR}/gcc +GAP_RISCV_GCC_INSTALL_DIR ?= ${GCC_INSTALL_DIR}/gap9 + CHIMERA_SDK_INSTALL_DIR ?= ${DEEPLOY_INSTALL_DIR}/chimera-sdk PULP_SDK_INSTALL_DIR ?= ${DEEPLOY_INSTALL_DIR}/pulp-sdk SNITCH_INSTALL_DIR ?= ${DEEPLOY_INSTALL_DIR}/snitch_cluster @@ -36,6 +39,7 @@ MINIMALLOC_INSTALL_DIR ?= ${DEEPLOY_INSTALL_DIR}/minimalloc XTL_INSTALL_DIR ?= ${DEEPLOY_INSTALL_DIR}/xtl XSIMD_INSTALL_DIR ?= ${DEEPLOY_INSTALL_DIR}/xsimd XTENSOR_INSTALL_DIR ?= ${DEEPLOY_INSTALL_DIR}/xtensor +GAP9_SDK_INSTALL_DIR ?= ${DEEPLOY_INSTALL_DIR}/gap9-sdk CMAKE ?= cmake @@ -51,6 +55,9 @@ CHIMERA_SDK_COMMIT_HASH ?= b2392f6efcff75c03f4c65eaf3e12104442b22ea XTL_VERSION ?= 0.7.5 XSIMD_VERSION ?= 13.2.0 XTENSOR_VERSION ?= 0.25.0 +GAP9_SDK_COMMIT_HASH ?= 897955d7ab326bd31684429eb16a2e485ab89afb # dev-v5.19.2 +# GAP9_SDK_COMMIT_HASH ?= dfabdddd0e78b9b750a0eb46eee85d5a2c9ae853 # dev-v5.20.4 +GAP_SDK_URL ?= 'git@iis-git.ee.ethz.ch:wiesep/gap9_sdk.git' OS := $(shell uname -s) ARCH:= $(shell uname -m) @@ -77,6 +84,8 @@ echo-bash: @echo "The following symbols need to be exported for Deeploy to work properly:" @echo "export MINIMALLOC_INSTALL_DIR=${MINIMALLOC_INSTALL_DIR}" @echo "export PULP_SDK_HOME=${PULP_SDK_INSTALL_DIR}" + @echo "export GAP_SDK_HOME=${GAP9_SDK_INSTALL_DIR}" + @echo "export GAP_RISCV_GCC_TOOLCHAIN=${GAP_RISCV_GCC_INSTALL_DIR}" @echo "export CHIMERA_SDK_HOME=${CHIMERA_SDK_INSTALL_DIR}" @echo "export SNITCH_HOME=${SNITCH_INSTALL_DIR}" @echo "export GVSOC_INSTALL_DIR=${GVSOC_INSTALL_DIR}" @@ -97,9 +106,11 @@ emulators: snitch_runtime pulp-sdk qemu banshee mempool ${TOOLCHAIN_DIR}/llvm-project: cd ${TOOLCHAIN_DIR} && \ - git clone https://github.com/pulp-platform/llvm-project.git \ - -b main && \ - cd ${TOOLCHAIN_DIR}/llvm-project && git checkout ${LLVM_COMMIT_HASH} && \ + git init llvm-project && \ + cd ${TOOLCHAIN_DIR}/llvm-project && \ + git remote add origin https://github.com/pulp-platform/llvm-project.git && \ + git fetch --depth=1 origin ${LLVM_COMMIT_HASH} && \ + git checkout ${LLVM_COMMIT_HASH} && \ git submodule update --init --recursive ${LLVM_INSTALL_DIR}: ${TOOLCHAIN_DIR}/llvm-project @@ -410,6 +421,26 @@ ${PULP_SDK_INSTALL_DIR}: ${TOOLCHAIN_DIR}/pulp-sdk pulp-sdk: ${PULP_SDK_INSTALL_DIR} +${TOOLCHAIN_DIR}/gap9-toolchain: + cd ${TOOLCHAIN_DIR} && \ + git clone https://github.com/GreenWaves-Technologies/gap_riscv_toolchain_ubuntu.git --depth 1 -b master gap9-toolchain + +${GAP_RISCV_GCC_INSTALL_DIR}: ${TOOLCHAIN_DIR}/gap9-toolchain + cd ${TOOLCHAIN_DIR}/gap9-toolchain && \ + mkdir -p ${GAP_RISCV_GCC_INSTALL_DIR} && \ + ./install.sh ${GAP_RISCV_GCC_INSTALL_DIR} + +gap9-toolchain: ${GAP_RISCV_GCC_INSTALL_DIR} + +.PHONY: gap9-sdk +gap9-sdk: + @echo "Cloning and building GAP9 SDK..." + GAP9_SDK_INSTALL_DIR=${GAP9_SDK_INSTALL_DIR} \ + GAP9_SDK_COMMIT_HASH=${GAP9_SDK_COMMIT_HASH} \ + GAP_SDK_URL=${GAP_SDK_URL} \ + ROOT_DIR=${ROOT_DIR} \ + bash ${ROOT_DIR}/scripts/gap9-build_sdk.sh + ${TOOLCHAIN_DIR}/snitch_cluster: cd ${TOOLCHAIN_DIR} && \ git clone https://github.com/pulp-platform/snitch_cluster.git && \ diff --git a/README_GAP9.md b/README_GAP9.md new file mode 100644 index 0000000000..323465f617 --- /dev/null +++ b/README_GAP9.md @@ -0,0 +1,99 @@ +## Using Deeploy with GAP9 + +> ⚠️ **IMPORTANT NOTE** +> This is a work in progress. The GAP9 support in Deeploy is experimental and may not be fully functional. + +To use Deeploy with GAP9, a custom Docker container is required because the official Deeploy Docker image does yet not include the necessary SDKs and dependencies for GAP9 development, because they are not publicly available. + +### Build The Docker Container + +To use SSH keys for accessing private repositories during the Docker build process, make sure you have an SSH key pair set up on your local machine. By default, the Makefile uses the key located at `~/.ssh/id_ed25519`. If your key is located elsewhere, you can specify its path using the `SSH_PRIVATE_KEY` variable when invoking the make command. + +To build a local version of the Deeploy Docker image with GAP9 support using the upstream toolchain image, run: +```sh +cd Container + +# Build the Deeploy image with the upstream toolchain image +make deeploy-gap9 DEEPOY_GAP9_IMAGE=deeploy-gap9:latest + +# If you want to specify a custom SSH key path, use: +make deeploy-gap9 DEEPOY_GAP9_IMAGE=deeploy-gap9:latest SSH_PRIVATE_KEY=/path/to/your/private/key +``` + +Or, to build the toolchain, Deeploy and GAP9 images locally, use: +```sh +cd Container + +# To build the Deeploy container with the local toolchain image +make deeploy TOOLCHAIN_IMAGE=deeploy-toolchain:gap9 DEEPOY_IMAGE=deeploy:gap9 + +# To build the Deeploy GAP9 container with the local toolchain image +make deeploy-gap9 TOOLCHAIN_IMAGE=deeploy-toolchain:gap9 DEEPOY_IMAGE=deeploy:gap9 DEEPOY_GAP9_IMAGE=deeploy-gap9:latest +``` + +### Use The Docker Container + +Once the image is built, you can create and start the container in interactive mode with: + +```sh +docker run -it --name deeploy_gap9 -v $(pwd):/app/Deeploy deeploy-gap9:latest +``` + +Before running tests, you need to set up the GAP9 environment inside the container: +```sh +source /app/install/gap9-sdk/.gap9-venv/bin/activate +source /app/install/gap9-sdk/configs/gap9_evk_audio.sh +``` +Install Deeploy inside the container in editable mode: + +```sh +cd /app/Deeploy +pip install -e . --extra-index-url=https://pypi.ngc.nvidia.com +``` + +```sh +cd /app/Deeploy/DeeployTest +python deeployRunner_gap9.py -t ./Tests/Kernels/FP32/MatMul +python deeployRunner_tiled_gap9.py -t ./Tests/Kernels/FP32/MatMul +``` + +### Use A Real GAP9 Board (USB/IP via gap9-run.sh) + +For board access, use the orchestration script in [scripts/gap9-run.sh](scripts/gap9-run.sh). It manages: +- host-side USB/IP server (pyusbip) +- usbip device manager container +- GAP9 SDK container with the correct mounts + +#### Prerequisites +- Docker installed and running +- A working SSH key for BuildKit (if you are building the image locally) +- USB/IP host support (the script can set up pyusbip on the host) + + +#### Start the board workflow (recommended) +This launches a tmux session with two panes: one for the host USB/IP server and one for the GAP9 container. + +```sh +./scripts/gap9-run.sh start-tmux +``` + +#### Start manually (two terminals) +Terminal 1 (host USB/IP server): +```sh +./scripts/gap9-run.sh start-usbip-host +``` + +Terminal 2 (containers + attach device): +```sh +./scripts/gap9-run.sh start +``` + +#### Common options and environment variables +- Use a custom image: `-i your-gap9-image:tag` or `GAP9_IMAGE=your-gap9-image:tag` +- Set USB device IDs: `USBIP_VENDOR=15ba USBIP_PRODUCT=002b` +- Change USB/IP host: `USBIP_HOST=host.docker.internal` + +To stop everything: +```sh +./scripts/gap9-run.sh stop +``` diff --git a/scripts/gap9-build_sdk.sh b/scripts/gap9-build_sdk.sh new file mode 100755 index 0000000000..2df7bd3eeb --- /dev/null +++ b/scripts/gap9-build_sdk.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash + +# SPDX-FileCopyrightText: 2026 ETH Zurich and University of Bologna +# +# SPDX-License-Identifier: Apache-2.0 + +# gap9-build_sdk.sh +# Helper script to clone, patch and build the GAP9 SDK. Intended to be +# invoked from the Makefile with environment variables set: +# GAP9_SDK_INSTALL_DIR (required) +# GAP9_SDK_COMMIT_HASH (optional, fallback provided) +# ROOT_DIR (optional, defaults to script dir) + +ROOT_DIR="${ROOT_DIR:-$(cd "$(dirname "$0")" && pwd)}" +GAP9_SDK_INSTALL_DIR="${GAP9_SDK_INSTALL_DIR:?GAP9_SDK_INSTALL_DIR must be set}" +GAP9_SDK_COMMIT_HASH="${GAP9_SDK_COMMIT_HASH:-897955d7ab326bd31684429eb16a2e485ab89afb}" +GAP_SDK_URL="${GAP_SDK_URL:-'git@iis-git.ee.ethz.ch:wiesep/gap9_sdk.git'}" + +echo "Preparing GAP9 SDK in: ${GAP9_SDK_INSTALL_DIR}" + +if [ -d "${GAP9_SDK_INSTALL_DIR}/.git" ]; then + echo "Directory ${GAP9_SDK_INSTALL_DIR} already exists and looks like a git repo. Updating remote URL and fetching latest changes..." + git remote set-url origin "${GAP_SDK_URL}" || true +else + echo "Cloning GAP9 SDK..." + git clone "${GAP_SDK_URL}" "${GAP9_SDK_INSTALL_DIR}" +fi + +cd "${GAP9_SDK_INSTALL_DIR}" +echo "Checking out commit ${GAP9_SDK_COMMIT_HASH} (stash and fetch if necessary)" +git fetch --all --tags || true +git stash || true +git checkout "${GAP9_SDK_COMMIT_HASH}" +git submodule update --init --recursive + +# Platform specific patch +ARCH=$(dpkg --print-architecture 2>/dev/null || true) +if [ -z "$ARCH" ]; then + ARCH=$(uname -m) +fi +case "$ARCH" in +amd64 | x86_64) PATCH=gap9-amd64.patch ;; +arm64 | aarch64) PATCH=gap9-arm64.patch ;; +*) PATCH= ;; +esac + +set -e # Enable strict error handling for the build process +if [ -n "$PATCH" ] && [ -f "${ROOT_DIR}/${PATCH}" ]; then + echo "Applying platform patch: $PATCH" + git apply "${ROOT_DIR}/${PATCH}" +else + echo "No platform-specific patch to apply for architecture '$ARCH' (looked for ${ROOT_DIR}/${PATCH})" +fi +set +e # Disable strict error handling to allow deactivation even if build fails + +echo "Setting up Python virtual environment and installing dependencies" +python -m venv .gap9-venv +. .gap9-venv/bin/activate +pip install "numpy<2.0.0" +echo "Sourcing GAP9 SDK environment" +. configs/gap9_evk_audio.sh || true + +echo "Invoking make install_dependency cmake_sdk.build" +set -e # Enable strict error handling for the build process +make install_dependency cmake_sdk.build openocd.all +set +e # Disable strict error handling to allow deactivation even if build fails + +deactivate + +echo "GAP9 SDK ready at: ${GAP9_SDK_INSTALL_DIR}" + +exit 0 diff --git a/scripts/gap9-run.sh b/scripts/gap9-run.sh new file mode 100755 index 0000000000..912f062819 --- /dev/null +++ b/scripts/gap9-run.sh @@ -0,0 +1,543 @@ +#!/bin/bash + +# SPDX-FileCopyrightText: 2026 ETH Zurich and University of Bologna +# +# SPDX-License-Identifier: Apache-2.0 + +# gap9-run.sh - Docker orchestration script for GAP9 SDK with USB/IP device passthrough +# +# +# This script manages the containerized GAP9 development environment, including: +# - Building the GAP9 Docker image +# - Running the usbip device manager container (for USB device passthrough) +# - Starting the GAP9 SDK container with mounted volumes +# +# Prerequisites: +# - Docker installed and running +# - SSH key configured for BuildKit (if building image) +# - pyusbip server running on host (for USB passthrough) +# + +set -euo pipefail + +######################################################################### +# Configuration & Defaults +######################################################################### + +# Image and container names +GAP9_IMAGE="ghcr.io/pulp-platform/deeploy-gap9" +USBIP_IMAGE="jonathanberi/devmgr" + +DOCKER_PLATFORM="auto" +DOCKER_SHELL="/bin/zsh" + +# USB/IP device settings +USBIP_HOST="host.docker.internal" +USBIP_VENDOR="15ba" +USBIP_PRODUCT="002b" + +# SDK and cache directories +WORK_DIR="." +CACHE_FOLDER=".cache" + +# SSH key gap9 container +SSH_PRIVATE_KEY="~/.ssh/id_ed25519" + +# pyusbip configuration +PYUSBIP_REPO="https://github.com/tumayt/pyusbip" +PYUSBIP_DIR=".pyusbip" + +######################################################################### +# Utility Functions +######################################################################### + +# Print colored output +log_info() { + echo -e "\033[0;36m[INFO ]\033[0m $*" +} + +log_error() { + echo -e "\033[0;31m[ERROR ]\033[0m $*" >&2 +} + +log_warn() { + echo -e "\033[0;33m[WARN ]\033[0m $*" >&2 +} + +log_success() { + echo -e "\033[0;32m[SUCCESS]\033[0m $*" +} + +# Display help message +show_help() { + cat < [options] + +GAP9 Docker Orchestration Script + +Commands: + start Start usbip daemon and GAP9 container + start-tmux Start everything in a tmux session with split panes + stop Stop containers + start-usbip-host Setup and run host-side USB/IP server (in separate terminal) + start-gap9 Start only the GAP9 container + start-usbip-daemon Start only the usbip device manager container + attach-usbip Attach USB device to usbip daemon + detach-usbip Detach USB device from usbip daemon + setup-usbip-host One-time setup for host-side USB/IP server + help Display this help message + +Options: + -i, --image NAME Docker image name (default: $GAP9_IMAGE) + -d, --work-dir PATH Path to working directory (default: $WORK_DIR) + -c, --cache-dir PATH Cache directory (default: $CACHE_FOLDER) + -k, --ssh-key PATH SSH private key (default: $SSH_PRIVATE_KEY) + -h, --host ADDR usbip host address (default: $USBIP_HOST) + -v, --vendor ID USB vendor ID (default: $USBIP_VENDOR) + -p, --product ID USB product ID (default: $USBIP_PRODUCT) + --platform PLATFORM Docker platform (default: $DOCKER_PLATFORM) + --shell SHELL Shell to use in container (default: $DOCKER_SHELL) + +Examples: + # Start everything in tmux (recommended) + $0 start-tmux + + # Start containers with USB device passthrough (manual terminals) + $0 start-usbip-host # In terminal 1 + $0 start # In terminal 2 + + # Custom working directory + $0 -d /path/to/workdir start + + # Stop everything + $0 stop + +EOF +} + +# Parse command-line arguments (collect options first, then run command) +command="" +opts=() +args=("$@") +idx=0 +while [[ $idx -lt ${#args[@]} ]]; do + case "${args[$idx]}" in + -i | --image) + GAP9_IMAGE="${args[$((idx + 1))]}" + opts+=("${args[$idx]}" "${args[$((idx + 1))]}") + idx=$((idx + 2)) + ;; + -d | --work-dir) + WORK_DIR="${args[$((idx + 1))]}" + opts+=("${args[$idx]}" "${args[$((idx + 1))]}") + idx=$((idx + 2)) + ;; + -c | --cache-dir) + CACHE_FOLDER="${args[$((idx + 1))]}" + opts+=("${args[$idx]}" "${args[$((idx + 1))]}") + idx=$((idx + 2)) + ;; + -k | --ssh-key) + SSH_PRIVATE_KEY="${args[$((idx + 1))]}" + opts+=("${args[$idx]}" "${args[$((idx + 1))]}") + idx=$((idx + 2)) + ;; + -h | --host) + USBIP_HOST="${args[$((idx + 1))]}" + opts+=("${args[$idx]}" "${args[$((idx + 1))]}") + idx=$((idx + 2)) + ;; + -v | --vendor) + USBIP_VENDOR="${args[$((idx + 1))]}" + opts+=("${args[$idx]}" "${args[$((idx + 1))]}") + idx=$((idx + 2)) + ;; + -p | --product) + USBIP_PRODUCT="${args[$((idx + 1))]}" + opts+=("${args[$idx]}" "${args[$((idx + 1))]}") + idx=$((idx + 2)) + ;; + --platform) + DOCKER_PLATFORM="${args[$((idx + 1))]}" + opts+=("${args[$idx]}" "${args[$((idx + 1))]}") + idx=$((idx + 2)) + ;; + --shell) + DOCKER_SHELL="${args[$((idx + 1))]}" + opts+=("${args[$idx]}" "${args[$((idx + 1))]}") + idx=$((idx + 2)) + ;; + help | --help) + show_help + exit 0 + ;; + start | start-tmux | stop | start-gap9 | start-usbip-daemon | attach-usbip | detach-usbip | stop-usbip-daemon | start-usbip-host | setup-usbip-host) + if [[ -n "$command" ]]; then + log_error "Multiple commands provided: $command and ${args[$idx]}" + show_help + exit 1 + fi + command="${args[$idx]}" + idx=$((idx + 1)) + ;; + *) + log_error "Unknown option or command: ${args[$idx]}" + show_help + exit 1 + ;; + esac +done + +# Expand path of SSH private key +SSH_PRIVATE_KEY="$(eval echo "$SSH_PRIVATE_KEY")" + +## Print configuration +log_info "Configuration:" +log_info " GAP9 Docker Image: $GAP9_IMAGE" +log_info " Working Directory: $WORK_DIR" +log_info " Cache Directory: $CACHE_FOLDER" +log_info " SSH Private Key: $SSH_PRIVATE_KEY" +log_info " USB/IP Host: $USBIP_HOST" +log_info " USB Vendor ID: $USBIP_VENDOR" +log_info " USB Product ID: $USBIP_PRODUCT" +log_info " Docker Platform: $DOCKER_PLATFORM" +log_info " Docker Shell: $DOCKER_SHELL" + +######################################################################### +# usbip Host Setup Functions +######################################################################### + +cmd_setup_usbip_host() { + log_info "Setting up host-side USB/IP server..." + + # Clone pyusbip if not present + if [ ! -d "$PYUSBIP_DIR" ]; then + log_info "Cloning pyusbip into $PYUSBIP_DIR..." + git clone "$PYUSBIP_REPO" "$PYUSBIP_DIR" + else + log_info "pyusbip directory $PYUSBIP_DIR already exists, skipping clone" + fi + + # Create virtual environment if needed + if [ ! -d "$PYUSBIP_DIR/.venv" ]; then + log_info "Creating Python virtual environment..." + python3 -m venv "$PYUSBIP_DIR/.venv" + + log_info "Installing pyusbip dependencies..." + # shellcheck disable=SC1091 + . "$PYUSBIP_DIR/.venv/bin/activate" + pip install --upgrade pip + pip install libusb1 + else + log_info "Virtual environment already exists, skipping setup" + fi + + log_success "Host-side USB/IP setup complete" +} + +cmd_start_usbip_host() { + cmd_setup_usbip_host + + log_info "Starting host-side USB/IP server (pyusbip)..." + log_info "This process will run in the foreground. Press Ctrl+C to stop." + + cd "$PYUSBIP_DIR" && + # shellcheck disable=SC1091 + . .venv/bin/activate && + python pyusbip.py +} + +######################################################################### +# usbip Daemon Functions +######################################################################### + +# Wait for usbip server to be ready +wait_for_usbip_server() { + local max_retries=20 + local retry_count=0 + local retry_interval=1 + + log_info "Waiting for pyusbip server to be ready..." + + while [ $retry_count -lt $max_retries ]; do + if pgrep -f "python.*pyusbip\.py" >/dev/null; then + log_success "pyusbip server is ready" + return 0 + fi + + retry_count=$((retry_count + 1)) + log_info " Attempt $retry_count/$max_retries: pyusbip not ready yet, retrying in ${retry_interval}s..." + sleep "$retry_interval" + done + + log_error "Timeout waiting for pyusbip server to start (${max_retries}s)" + return 1 +} + +cmd_start_usbip_daemon() { + # Wait for pyusbip server to be ready + if ! wait_for_usbip_server; then + log_error "pyusbip server did not start in time" + log_error "Please run '$0 start-usbip-host' in a separate terminal first" + exit 1 + fi + + # Check if container already running + if [ -n "$(docker ps -q -f name=usbip-devmgr)" ]; then + log_info "usbip-devmgr container already running" + return 0 + fi + + log_info "Starting usbip-devmgr container..." + docker run -d --rm \ + --privileged \ + --pid=host \ + --name usbip-devmgr \ + -e USBIP_HOST="$USBIP_HOST" \ + -e USBIP_VENDOR="$USBIP_VENDOR" \ + -e USBIP_PRODUCT="$USBIP_PRODUCT" \ + "$USBIP_IMAGE" \ + /bin/sh -lc 'nsenter -t1 -m sh -lc "tail -f /dev/null"' + + log_success "usbip-devmgr container started" +} + +cmd_attach_usbip() { + # First detach any existing attachment + cmd_detach_usbip || true + + log_info "Attaching USB device to usbip-devmgr..." + docker exec -it usbip-devmgr /bin/sh -lc 'nsenter -t1 -m sh -lc " + usbip list -r \"$USBIP_HOST\" || { echo \"usbip list failed\"; exit 1; } + BUSID=\$(usbip list -r \"$USBIP_HOST\" \ + | grep \"$USBIP_VENDOR:$USBIP_PRODUCT\" \ + | head -n1 \ + | cut -d\":\" -f1 \ + | xargs) + if [ -z \"\$BUSID\" ]; then + exit 1 + fi + usbip attach -r \"$USBIP_HOST\" -b \"\$BUSID\" + "' + + if [ $? -ne 0 ]; then + log_error "Failed to attach USB device" + else + log_success "USB device attached successfully" + fi +} + +cmd_detach_usbip() { + log_info "Detaching USB device..." + docker run --rm \ + --privileged \ + --pid=host \ + -e USBIP_HOST="$USBIP_HOST" \ + -e USBIP_VENDOR="$USBIP_VENDOR" \ + -e USBIP_PRODUCT="$USBIP_PRODUCT" \ + "$USBIP_IMAGE" \ + /bin/sh -lc 'nsenter -t1 -m sh -lc " + PORT=\$(usbip port \ + | grep \"$USBIP_VENDOR:$USBIP_PRODUCT\" -B 1 \ + | head -n1 \ + | sed -E \"s/^Port ([0-9]+):.*/\1/\" \ + | xargs) + if [ -z \"\$PORT\" ]; then + exit 1 + fi + usbip detach -p \"\$PORT\" + "' >/dev/null 2>&1 + + if [ $? -ne 0 ]; then + log_warn "Failed to detach USB device (it may not have been attached)" + else + log_success "USB device detached (or not attached)" + fi +} + +cmd_stop_usbip_daemon() { + log_info "Stopping usbip-devmgr container..." + + # First detach the device + cmd_detach_usbip || true + + # Stop the container + if [ -n "$(docker ps -q -f name=usbip-devmgr)" ]; then + docker stop usbip-devmgr >/dev/null 2>&1 + log_success "usbip-devmgr container stopped" + else + log_info "usbip-devmgr container not running" + fi +} + +######################################################################### +# GAP9 Container Functions +######################################################################### + +cmd_start_gap9() { + log_info "Starting GAP9 container..." + + # Prepare cache directory + mkdir -p "$CACHE_FOLDER" + touch "$CACHE_FOLDER/.zsh_history" + + # Validate WORK_DIR exists + if [ ! -d "$WORK_DIR" ]; then + log_error "WORK_DIR not found: $WORK_DIR" + log_error "Use -d/--work-dir to set the SDK path" + exit 1 + fi + + log_info "Press Ctrl+D or type 'exit' to exit container" + + # Build docker run command with optional platform argument + local docker_run_args=( + -it --rm + --privileged + -v /dev/bus/usb:/dev/bus/usb + -v "$SSH_PRIVATE_KEY":/root/.ssh/id_ed25519:ro + -v "$WORK_DIR/":/app/work/ + -v "$CACHE_FOLDER/.zsh_history":/root/.zsh_history + -v "$CACHE_FOLDER/ccache":/ccache + -e CCACHE_DIR=/ccache + ) + + # Add platform argument if not 'auto' + if [[ "$DOCKER_PLATFORM" != "auto" ]]; then + docker_run_args+=(--platform "$DOCKER_PLATFORM") + fi + + docker_run_args+=("$GAP9_IMAGE" "$DOCKER_SHELL" -c "cd /app/work && $DOCKER_SHELL") + + docker run "${docker_run_args[@]}" +} + +######################################################################### +# Orchestration Functions +######################################################################### + +cmd_start() { + log_info "Starting GAP9 orchestration (usbip daemon + GAP9 container)..." + cmd_start_usbip_daemon + cmd_attach_usbip + cmd_start_gap9 +} + +cmd_stop() { + log_info "Stopping all containers..." + cmd_stop_usbip_daemon + cmd_stop_tmux + log_success "All containers stopped" +} + +######################################################################### +# Tmux Orchestration +######################################################################### + +cmd_start_tmux() { + local session_name="gap9-dev" + local script_path="$0" + local opts_escaped="" + + for opt in "${opts[@]:-}"; do + if [[ -n "$opt" ]]; then + printf -v opt '%q' "$opt" + opts_escaped+=" $opt" + fi + done + + # Check if tmux is installed + if ! command -v tmux &>/dev/null; then + log_error "tmux is not installed. Please install tmux first." + log_error "On macOS: brew install tmux" + log_error "On Linux: sudo apt-get install tmux" + exit 1 + fi + + # Kill any existing session with the same name + tmux kill-session -t "$session_name" 2>/dev/null || true + + log_info "Creating tmux session: $session_name" + + # Create new session with three panes (usbip-host, usbip-daemon, gap9) + tmux new-session -d -s "$session_name" -x 200 -y 50 + + # First pane: run pyusbip server + + # Second pane: run main orchestration (with delay to let server start) + tmux split-window -t "$session_name:0" -h + tmux split-window -t "$session_name:0" -v + tmux send-keys -t "$session_name:0.1" "alias stop='$script_path$opts_escaped stop'" Enter + tmux send-keys -t "$session_name:0.1" "$script_path$opts_escaped start-usbip-host" Enter + tmux send-keys -t "$session_name:0.2" "alias stop='$script_path$opts_escaped stop'" Enter + tmux send-keys -t "$session_name:0.2" "$script_path$opts_escaped start-usbip-daemon" Enter + tmux send-keys -t "$session_name:0.2" "$script_path$opts_escaped attach-usbip" Enter + tmux send-keys -t "$session_name:0.0" "alias stop='$script_path$opts_escaped stop'" Enter + tmux send-keys -t "$session_name:0.0" "$script_path$opts_escaped start-gap9" Enter + + # Select the first pane + tmux select-pane -t "$session_name:0.0" + + log_success "tmux session created: $session_name" + log_info "Attaching to session..." + log_info "To detach: Ctrl+B then D" + log_info "To kill session: tmux kill-session -t $session_name" + + # Attach to the session + tmux attach-session -t "$session_name" +} + +cmd_stop_tmux() { + local session_name="gap9-dev" + log_info "Stopping tmux session: $session_name" + tmux kill-session -t "$session_name" 2>/dev/null || log_info "tmux session $session_name not running" +} + +######################################################################### +# Main Script Logic +######################################################################### + +# If no command provided, show help +if [[ -z "$command" ]]; then + cmd_start_tmux + exit 0 +fi + +# Execute the command after options are parsed +case "$command" in +start) + cmd_start + ;; +start-tmux) + cmd_start_tmux + ;; +stop) + cmd_stop + ;; +start-gap9) + cmd_start_gap9 + ;; +start-usbip-daemon) + cmd_start_usbip_daemon + ;; +attach-usbip) + cmd_attach_usbip + ;; +detach-usbip) + cmd_detach_usbip + ;; +stop-usbip-daemon) + cmd_stop_usbip_daemon + ;; +start-usbip-host) + cmd_start_usbip_host + ;; +setup-usbip-host) + cmd_setup_usbip_host + ;; +*) + log_error "Unknown command: $command" + show_help + exit 1 + ;; +esac From 97c2d2b6aa89a116de1458ba3d67e908d477a6b2 Mon Sep 17 00:00:00 2001 From: Philip Wiese Date: Wed, 4 Feb 2026 22:30:06 +0100 Subject: [PATCH 02/16] Fix spelling mistakes and remove dependencies from fork --- .github/workflows/docker-build-deeploy-gap9.yml | 2 +- .github/workflows/docker-build-deeploy.yml | 2 +- Container/Makefile | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docker-build-deeploy-gap9.yml b/.github/workflows/docker-build-deeploy-gap9.yml index e6a9ab7016..76e7c6b2fa 100644 --- a/.github/workflows/docker-build-deeploy-gap9.yml +++ b/.github/workflows/docker-build-deeploy-gap9.yml @@ -96,7 +96,7 @@ jobs: env: OWNER: "${{ github.repository_owner }}" - - name: Build and push final deploy image + - name: Build and push final Deeploy image id: build uses: docker/build-push-action@v6 with: diff --git a/.github/workflows/docker-build-deeploy.yml b/.github/workflows/docker-build-deeploy.yml index a4d0221e1f..ff2b507405 100644 --- a/.github/workflows/docker-build-deeploy.yml +++ b/.github/workflows/docker-build-deeploy.yml @@ -109,7 +109,7 @@ jobs: env: OWNER: "${{ github.repository_owner }}" - - name: Build and push final deploy image + - name: Build and push final Deeploy image id: build uses: docker/build-push-action@v6 with: diff --git a/Container/Makefile b/Container/Makefile index b1da56190b..e38d99c519 100644 --- a/Container/Makefile +++ b/Container/Makefile @@ -40,7 +40,7 @@ toolchain: -f Dockerfile.toolchain \ -t $(TOOLCHAIN_IMAGE) .. -# Build the final deploy image using the toolchain image +# Build the final Deeploy image using the toolchain image deeploy: DOCKER_BUILDKIT=1 docker build \ --ssh default \ @@ -48,7 +48,7 @@ deeploy: --build-arg BASE_IMAGE=$(TOOLCHAIN_IMAGE) \ -t $(DEEPOY_IMAGE) .. -# Build the GAP9 deploy image +# Build the GAP9 Deeploy image deeploy-gap9: eval $$(ssh-agent) && \ ssh-add $(SSH_PRIVATE_KEY) && \ From 3423c546f2ca6efff476a2bc94be861a72a546f6 Mon Sep 17 00:00:00 2001 From: Philip Wiese Date: Fri, 6 Feb 2026 17:23:50 +0100 Subject: [PATCH 03/16] Fix Missing Version Link --- docs/conf.py | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/conf.py b/docs/conf.py index 6ca3d33c6f..88b86d601c 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -70,6 +70,7 @@ ["main", "https://pulp-platform.github.io/Deeploy"], ["devel", "https://pulp-platform.github.io/Deeploy/branch/devel"], ["v0.2.0", "https://pulp-platform.github.io/Deeploy/tag/v0.2.0"], + ["v0.2.1", "https://pulp-platform.github.io/Deeploy/tag/v0.2.1"], ], } From d6b6ac962f8dcda79bf3299c35b8a4bc831c9b90 Mon Sep 17 00:00:00 2001 From: Philip Wiese Date: Sun, 8 Feb 2026 22:28:08 +0100 Subject: [PATCH 04/16] Temporarily disable GAP9 on forks --- .github/workflows/ci-platform-gap9-tiled.yml | 1 + .github/workflows/ci-platform-gap9.yml | 1 + .github/workflows/infra-generate-ccache-gap9.yml | 1 + 3 files changed, 3 insertions(+) diff --git a/.github/workflows/ci-platform-gap9-tiled.yml b/.github/workflows/ci-platform-gap9-tiled.yml index 0043f8d3e9..4a3afc717b 100644 --- a/.github/workflows/ci-platform-gap9-tiled.yml +++ b/.github/workflows/ci-platform-gap9-tiled.yml @@ -25,6 +25,7 @@ concurrency: jobs: select-env: + if: github.repository == 'pulp-platform/Deeploy' uses: ./.github/workflows/_select-env.yml with: docker_image_deeploy: ${{ github.event.inputs.docker_image_deeploy || github.repository == 'pulp-platform/Deeploy' && 'ghcr.io/pulp-platform/deeploy-gap9:latest'}} diff --git a/.github/workflows/ci-platform-gap9.yml b/.github/workflows/ci-platform-gap9.yml index 079f13c2a5..e9a59b4927 100644 --- a/.github/workflows/ci-platform-gap9.yml +++ b/.github/workflows/ci-platform-gap9.yml @@ -26,6 +26,7 @@ concurrency: jobs: select-env: + if: github.repository == 'pulp-platform/Deeploy' uses: ./.github/workflows/_select-env.yml with: docker_image_deeploy: ${{ github.event.inputs.docker_image_deeploy || (github.repository == 'pulp-platform/Deeploy' && 'ghcr.io/pulp-platform/deeploy-gap9:latest') }} diff --git a/.github/workflows/infra-generate-ccache-gap9.yml b/.github/workflows/infra-generate-ccache-gap9.yml index b189bfd708..b54f43ce4c 100644 --- a/.github/workflows/infra-generate-ccache-gap9.yml +++ b/.github/workflows/infra-generate-ccache-gap9.yml @@ -18,6 +18,7 @@ name: Infrastructure • Generate CCache GAP9 jobs: generate-ccache-gap9: + if: github.repository == 'pulp-platform/Deeploy' runs-on: ubuntu-latest container: image: ${{ github.event.inputs.docker_image_deeploy || 'ghcr.io/pulp-platform/deeploy-gap9:latest' }} From daf8cdabff148194723ee253a5fde6f9df893557 Mon Sep 17 00:00:00 2001 From: Philip Wiese Date: Thu, 12 Feb 2026 12:33:37 +0100 Subject: [PATCH 05/16] Add Shell Format pre-commit --- .pre-commit-config.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e6f07fbc8d..a8f323faf5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -72,3 +72,7 @@ repos: - id: yamllint name: Lint YAML Files stages: [pre-commit, pre-merge-commit, pre-push, manual] + - repo: https://github.com/scop/pre-commit-shfmt + rev: v3.12.0-2 + hooks: + - id: shfmt From f1c7d5757c127ec506fef9ab9e87c946bb07a38b Mon Sep 17 00:00:00 2001 From: Philip Wiese Date: Thu, 12 Feb 2026 19:07:52 +0100 Subject: [PATCH 06/16] Update to GAP9 SDK `v5.21.1-staging-1` --- Container/Dockerfile.deeploy-gap9 | 4 +- Container/gap9-amd64.patch | 74 ++++--- Container/gap9-arm64.patch | 338 ++++-------------------------- Makefile | 7 +- 4 files changed, 92 insertions(+), 331 deletions(-) diff --git a/Container/Dockerfile.deeploy-gap9 b/Container/Dockerfile.deeploy-gap9 index 5232636d0c..05d3993461 100644 --- a/Container/Dockerfile.deeploy-gap9 +++ b/Container/Dockerfile.deeploy-gap9 @@ -68,7 +68,9 @@ RUN apt-get update && \ telnet \ usbutils \ libftdi-dev \ - libusb-1.0-0-dev && \ + libusb-1.0-0-dev \ + bison \ + flex && \ rm -rf /var/lib/apt/lists/* diff --git a/Container/gap9-amd64.patch b/Container/gap9-amd64.patch index 64c4a2421f..ef90f76938 100644 --- a/Container/gap9-amd64.patch +++ b/Container/gap9-amd64.patch @@ -1,38 +1,62 @@ diff --git a/.gitignore b/.gitignore -index d6c5b54d8..170acc552 100644 +index 6e751e203..d9091f1b1 100644 --- a/.gitignore +++ b/.gitignore -@@ -7,6 +7,7 @@ build - BUILD* - junit-reports/ - reports/ +@@ -57,3 +57,5 @@ gaptest_reports/ + # Release script dry-run output + release_dry_run/ + artifact.txt ++ +.gap9-venv - - - # SDK generated folders diff --git a/install_python_deps.sh b/install_python_deps.sh -index 4b0dbb728..8d5610678 100755 +index cac3e1885..578bb5f71 100755 --- a/install_python_deps.sh +++ b/install_python_deps.sh -@@ -60,7 +60,7 @@ then - pip3 install -r tools/nntool/tests/requirements.txt +@@ -69,7 +69,7 @@ then + python -m pip install -r tools/nntool/tests/requirements.txt fi - -- pip3 install -r tools/audio-framework/requirements.txt -+# pip3 install -r tools/audio-framework/requirements.txt - pip3 install -r utils/gapy_v2/requirements.txt - pip3 install -r doc/requirements.txt - fi + +- python -m pip install -r tools/audio-framework/requirements.txt ++ # python -m pip install -r tools/audio-framework/requirements.txt + python -m pip install -r utils/gapy_v2/requirements.txt + python -m pip install -r doc/requirements.txt + diff --git a/utils/gapy_v2/bin/gapylib/chips/gap/gap9_v2/board_runner.py b/utils/gapy_v2/bin/gapylib/chips/gap/gap9_v2/board_runner.py -index a7b191322..4adaede16 100644 +index 62ee5cac2..d872073f7 100644 --- a/utils/gapy_v2/bin/gapylib/chips/gap/gap9_v2/board_runner.py +++ b/utils/gapy_v2/bin/gapylib/chips/gap/gap9_v2/board_runner.py -@@ -208,7 +208,7 @@ class Openocd(): - - # Now that OpenOCD was successfully launched with proxy openocd, launch a telnet. - if success is True: -- self.telnet = pexpect.spawn(f'telnet localhost {port}', encoding='utf-8', echo=False) -+ self.telnet = pexpect.spawn(f'telnet host.docker.internal {port}', encoding='utf-8', echo=False) - match = self.telnet.expect(['Open On-Chip Debugger'], timeout=None) +@@ -342,7 +342,7 @@ class Openocd(): else: raise RuntimeError('Failed to connect to openocd after 30 retries') + +- self.telnet = pexpect.spawn(f'telnet localhost {port}', encoding='utf-8', echo=False) ++ self.telnet = pexpect.spawn(f'telnet host.docker.internal {port}', encoding='utf-8', echo=False) + match = self.telnet.expect(['Open On-Chip Debugger'], timeout=None) + + def write(self, addr: int, value: int): +diff --git a/utils/openocd_tools/tcl/gap9revb.tcl b/utils/openocd_tools/tcl/gap9revb.tcl +index 9e67f67c7..697483112 100644 +--- a/utils/openocd_tools/tcl/gap9revb.tcl ++++ b/utils/openocd_tools/tcl/gap9revb.tcl +@@ -24,8 +24,8 @@ proc jtag_init {} { + #gap_reset 0 100 + + # wait for jtag ready +- poll_confreg 0x1 +- echo "INIT: confreg polling done" ++ # poll_confreg 0x1 ++ # echo "INIT: confreg polling done" + + #UNCOMMENT IF YOU UNCOMMENT gap_init 1 + #gap_start 1 +@@ -39,8 +39,8 @@ proc init_reset {mode} { + #targets $::_FC + gap_reset 1 100 + # wait for jtag ready +- poll_confreg 0x1 +- echo "RESET: confreg polling done" ++ # poll_confreg 0x1 ++ # echo "RESET: confreg polling done" + jtag arp_init + } + diff --git a/Container/gap9-arm64.patch b/Container/gap9-arm64.patch index 6d2933627c..d5ccc643b1 100644 --- a/Container/gap9-arm64.patch +++ b/Container/gap9-arm64.patch @@ -1,20 +1,18 @@ diff --git a/.gitignore b/.gitignore -index d6c5b54d8..170acc552 100644 +index 6e751e203..d9091f1b1 100644 --- a/.gitignore +++ b/.gitignore -@@ -7,6 +7,7 @@ build - BUILD* - junit-reports/ - reports/ +@@ -57,3 +57,5 @@ gaptest_reports/ + # Release script dry-run output + release_dry_run/ + artifact.txt ++ +.gap9-venv - - - # SDK generated folders diff --git a/Makefile b/Makefile -index b342800d6..54a5d70c5 100644 +index 1dbab3578..60467d1d6 100644 --- a/Makefile +++ b/Makefile -@@ -131,7 +131,7 @@ openocd.checkout: +@@ -119,7 +119,7 @@ openocd.checkout: fi openocd.build: openocd.checkout @@ -24,245 +22,33 @@ index b342800d6..54a5d70c5 100644 openocd.checkout.gap9.5: diff --git a/configs/common.sh b/configs/common.sh -index e594437e3..b7ba06a63 100644 +index bd1f6ffea..e63faefa0 100644 --- a/configs/common.sh +++ b/configs/common.sh -@@ -80,7 +80,7 @@ export PULP_CONFIGS_PATH=$INSTALL_DIR/configs - export GVSOC_MODULES="${GAP_SDK_HOME}/gvsoc/gvsoc/models;${GAP_SDK_HOME}/gvsoc/gvsoc_gap" - export PYTHONPATH="${GAP_SDK_HOME}/gvsoc/gvsoc_gap:$PYTHONPATH" - if [ -d "$GAP_SDK_HOME/gvsoc/gvsoc_libs" ]; then -- export CONFIG_GVSOC_SKIP_UDMA_BUILD=1 -+ export CONFIG_GVSOC_SKIP_UDMA_BUILD=0 +@@ -178,3 +178,5 @@ if [ -n "$GAP_SDK_CI_BUILD" -a -z "$GAP_SDK_CI_DISABLE_GITHUB_ENV" ]; then fi - - # gaptest -diff --git a/gvsoc/gvsoc_gap/gap/gap9/soc.py b/gvsoc/gvsoc_gap/gap/gap9/soc.py -index e2877a2f9..e3fa337f0 100644 ---- a/gvsoc/gvsoc_gap/gap/gap9/soc.py -+++ b/gvsoc/gvsoc_gap/gap/gap9/soc.py -@@ -440,22 +440,22 @@ class Soc(st.Component): - self.bind(udma, 'i2s1_ws_out', udma, 'sfu_ws_in_1') - self.bind(udma, 'i2s2_ws_out', udma, 'sfu_ws_in_2') - -- self.bind(udma, 'sfu_stream_in_ready_0', udma, 'stream_in_ready_0') -- self.bind(udma, 'sfu_stream_in_ready_1', udma, 'stream_in_ready_1') -- self.bind(udma, 'sfu_stream_in_ready_2', udma, 'stream_in_ready_2') -- self.bind(udma, 'sfu_stream_in_ready_3', udma, 'stream_in_ready_3') -- self.bind(udma, 'sfu_stream_in_ready_4', udma, 'stream_in_ready_4') -- self.bind(udma, 'sfu_stream_in_ready_5', udma, 'stream_in_ready_5') -- self.bind(udma, 'sfu_stream_in_ready_6', udma, 'stream_in_ready_6') -- self.bind(udma, 'sfu_stream_in_ready_7', udma, 'stream_in_ready_7') -- self.bind(udma, 'sfu_stream_in_ready_8', udma, 'stream_in_ready_8') -- self.bind(udma, 'sfu_stream_in_ready_9', udma, 'stream_in_ready_9') -- self.bind(udma, 'sfu_stream_in_ready_10', udma, 'stream_in_ready_10') -- self.bind(udma, 'sfu_stream_in_ready_11', udma, 'stream_in_ready_11') -- self.bind(udma, 'sfu_stream_in_ready_12', udma, 'stream_in_ready_12') -- self.bind(udma, 'sfu_stream_in_ready_13', udma, 'stream_in_ready_13') -- self.bind(udma, 'sfu_stream_in_ready_14', udma, 'stream_in_ready_14') -- self.bind(udma, 'sfu_stream_in_ready_15', udma, 'stream_in_ready_15') -+ # self.bind(udma, 'sfu_stream_in_ready_0', udma, 'stream_in_ready_0') -+ # self.bind(udma, 'sfu_stream_in_ready_1', udma, 'stream_in_ready_1') -+ # self.bind(udma, 'sfu_stream_in_ready_2', udma, 'stream_in_ready_2') -+ # self.bind(udma, 'sfu_stream_in_ready_3', udma, 'stream_in_ready_3') -+ # self.bind(udma, 'sfu_stream_in_ready_4', udma, 'stream_in_ready_4') -+ # self.bind(udma, 'sfu_stream_in_ready_5', udma, 'stream_in_ready_5') -+ # self.bind(udma, 'sfu_stream_in_ready_6', udma, 'stream_in_ready_6') -+ # self.bind(udma, 'sfu_stream_in_ready_7', udma, 'stream_in_ready_7') -+ # self.bind(udma, 'sfu_stream_in_ready_8', udma, 'stream_in_ready_8') -+ # self.bind(udma, 'sfu_stream_in_ready_9', udma, 'stream_in_ready_9') -+ # self.bind(udma, 'sfu_stream_in_ready_10', udma, 'stream_in_ready_10') -+ # self.bind(udma, 'sfu_stream_in_ready_11', udma, 'stream_in_ready_11') -+ # self.bind(udma, 'sfu_stream_in_ready_12', udma, 'stream_in_ready_12') -+ # self.bind(udma, 'sfu_stream_in_ready_13', udma, 'stream_in_ready_13') -+ # self.bind(udma, 'sfu_stream_in_ready_14', udma, 'stream_in_ready_14') -+ # self.bind(udma, 'sfu_stream_in_ready_15', udma, 'stream_in_ready_15') - - self.bind(udma, 'stream_in_data_0', udma, 'sfu_stream_in_data_0') - self.bind(udma, 'stream_in_data_1', udma, 'sfu_stream_in_data_1') -@@ -491,22 +491,22 @@ class Soc(st.Component): - self.bind(udma, 'stream_out_ready_14', udma, 'sfu_stream_out_ready_14') - self.bind(udma, 'stream_out_ready_15', udma, 'sfu_stream_out_ready_15') - -- self.bind(udma, 'sfu_stream_out_data_0', udma, 'stream_out_data_0') -- self.bind(udma, 'sfu_stream_out_data_1', udma, 'stream_out_data_1') -- self.bind(udma, 'sfu_stream_out_data_2', udma, 'stream_out_data_2') -- self.bind(udma, 'sfu_stream_out_data_3', udma, 'stream_out_data_3') -- self.bind(udma, 'sfu_stream_out_data_4', udma, 'stream_out_data_4') -- self.bind(udma, 'sfu_stream_out_data_5', udma, 'stream_out_data_5') -- self.bind(udma, 'sfu_stream_out_data_6', udma, 'stream_out_data_6') -- self.bind(udma, 'sfu_stream_out_data_7', udma, 'stream_out_data_7') -- self.bind(udma, 'sfu_stream_out_data_8', udma, 'stream_out_data_8') -- self.bind(udma, 'sfu_stream_out_data_9', udma, 'stream_out_data_9') -- self.bind(udma, 'sfu_stream_out_data_10', udma, 'stream_out_data_10') -- self.bind(udma, 'sfu_stream_out_data_11', udma, 'stream_out_data_11') -- self.bind(udma, 'sfu_stream_out_data_12', udma, 'stream_out_data_12') -- self.bind(udma, 'sfu_stream_out_data_13', udma, 'stream_out_data_13') -- self.bind(udma, 'sfu_stream_out_data_14', udma, 'stream_out_data_14') -- self.bind(udma, 'sfu_stream_out_data_15', udma, 'stream_out_data_15') -+ # self.bind(udma, 'sfu_stream_out_data_0', udma, 'stream_out_data_0') -+ # self.bind(udma, 'sfu_stream_out_data_1', udma, 'stream_out_data_1') -+ # self.bind(udma, 'sfu_stream_out_data_2', udma, 'stream_out_data_2') -+ # self.bind(udma, 'sfu_stream_out_data_3', udma, 'stream_out_data_3') -+ # self.bind(udma, 'sfu_stream_out_data_4', udma, 'stream_out_data_4') -+ # self.bind(udma, 'sfu_stream_out_data_5', udma, 'stream_out_data_5') -+ # self.bind(udma, 'sfu_stream_out_data_6', udma, 'stream_out_data_6') -+ # self.bind(udma, 'sfu_stream_out_data_7', udma, 'stream_out_data_7') -+ # self.bind(udma, 'sfu_stream_out_data_8', udma, 'stream_out_data_8') -+ # self.bind(udma, 'sfu_stream_out_data_9', udma, 'stream_out_data_9') -+ # self.bind(udma, 'sfu_stream_out_data_10', udma, 'stream_out_data_10') -+ # self.bind(udma, 'sfu_stream_out_data_11', udma, 'stream_out_data_11') -+ # self.bind(udma, 'sfu_stream_out_data_12', udma, 'stream_out_data_12') -+ # self.bind(udma, 'sfu_stream_out_data_13', udma, 'stream_out_data_13') -+ # self.bind(udma, 'sfu_stream_out_data_14', udma, 'stream_out_data_14') -+ # self.bind(udma, 'sfu_stream_out_data_15', udma, 'stream_out_data_15') - - # Riscv bus watchpoint - if self.get_property('fc/riscv_fesvr_tohost_addr') is not None: -diff --git a/gvsoc/gvsoc_gap/gap/udma/CMakeLists.txt b/gvsoc/gvsoc_gap/gap/udma/CMakeLists.txt -index 00ea2162a..1abbe5c14 100644 ---- a/gvsoc/gvsoc_gap/gap/udma/CMakeLists.txt -+++ b/gvsoc/gvsoc_gap/gap/udma/CMakeLists.txt -@@ -21,6 +21,7 @@ vp_model(NAME "gap.udma.udma_v4_gap9_v2_impl" - "i2c/v4/udma_i2c_ucode.cpp" - "hyper/udma_hyper_v3.cpp" - "mram/udma_mram_v2.cpp" -+ "sfu/udma_sfu_v1_empty.cpp" - ) - - vp_model_compile_definitions(NAME "gap.udma.udma_v4_gap9_v2_impl" -@@ -34,6 +35,7 @@ vp_model_compile_definitions(NAME "gap.udma.udma_v4_gap9_v2_impl" - -DHAS_I2C - -DHAS_HYPER - -DHAS_MRAM -+ -DHAS_EMPTY_SFU - ) - - vp_model_include_directories(NAME "gap.udma.udma_v4_gap9_v2_impl" -diff --git a/gvsoc/gvsoc_gap/gap/udma/sfu/udma_sfu_v1_empty.cpp b/gvsoc/gvsoc_gap/gap/udma/sfu/udma_sfu_v1_empty.cpp -index 821fd25f8..52dd506e1 100644 ---- a/gvsoc/gvsoc_gap/gap/udma/sfu/udma_sfu_v1_empty.cpp -+++ b/gvsoc/gvsoc_gap/gap/udma/sfu/udma_sfu_v1_empty.cpp -@@ -25,11 +25,101 @@ - - - --Sfu_periph_empty::Sfu_periph_empty(udma *top, int id, int itf_id) : Udma_periph(top, id) -+Sfu_periph_empty::Sfu_periph_empty(udma *top, int id, int itf_id) : Udma_periph(top, "sfu" + std::to_string(itf_id), id) - { - std::string itf_name = "sfu" + std::to_string(itf_id); - top->traces.new_trace(itf_name, &this->trace, vp::DEBUG); - top->new_master_port("sfu_irq", &this->irq); -+ top->new_master_port("sfu_pdm_out_0", &this->irq); -+ top->new_master_port("sfu_pdm_out_1", &this->irq); -+ top->new_master_port("sfu_pdm_out_2", &this->irq); -+ top->new_master_port("sfu_pdm_out_3", &this->irq); -+ top->new_master_port("sfu_pdm_out_4", &this->irq); -+ top->new_master_port("sfu_pdm_out_5", &this->irq); -+ -+ top->new_master_port("sfu_pdm_in_0", &this->irq); -+ top->new_master_port("sfu_pdm_in_1", &this->irq); -+ top->new_master_port("sfu_pdm_in_2", &this->irq); -+ top->new_master_port("sfu_pdm_in_3", &this->irq); -+ top->new_master_port("sfu_pdm_in_4", &this->irq); -+ top->new_master_port("sfu_pdm_in_5", &this->irq); -+ top->new_master_port("sfu_pdm_in_6", &this->irq); -+ top->new_master_port("sfu_pdm_in_7", &this->irq); -+ top->new_master_port("sfu_pdm_in_8", &this->irq); -+ top->new_master_port("sfu_pdm_in_9", &this->irq); -+ top->new_master_port("sfu_pdm_in_10", &this->irq); -+ top->new_master_port("sfu_pdm_in_11", &this->irq); -+ -+ top->new_master_port("sfu_ws_in_0", &this->irq); -+ top->new_master_port("sfu_ws_in_1", &this->irq); -+ top->new_master_port("sfu_ws_in_2", &this->irq); -+ -+ -+ // top->new_slave_port("sfu_stream_in_ready_0", &this->in); -+ // top->new_slave_port("sfu_stream_in_ready_1", &this->in); -+ // top->new_slave_port("sfu_stream_in_ready_2", &this->in); -+ // top->new_slave_port("sfu_stream_in_ready_3", &this->in); -+ // top->new_slave_port("sfu_stream_in_ready_4", &this->in); -+ // top->new_slave_port("sfu_stream_in_ready_5", &this->in); -+ // top->new_slave_port("sfu_stream_in_ready_6", &this->in); -+ // top->new_slave_port("sfu_stream_in_ready_7", &this->in); -+ // top->new_slave_port("sfu_stream_in_ready_8", &this->in); -+ // top->new_slave_port("sfu_stream_in_ready_9", &this->in); -+ // top->new_slave_port("sfu_stream_in_ready_10", &this->in); -+ // top->new_slave_port("sfu_stream_in_ready_11", &this->in); -+ // top->new_slave_port("sfu_stream_in_ready_12", &this->in); -+ // top->new_slave_port("sfu_stream_in_ready_13", &this->in); -+ // top->new_slave_port("sfu_stream_in_ready_14", &this->in); -+ // top->new_slave_port("sfu_stream_in_ready_15", &this->in); -+ // top->new_slave_port("sfu_stream_out_data_0", &this->in); -+ // top->new_slave_port("sfu_stream_out_data_1", &this->in); -+ // top->new_slave_port("sfu_stream_out_data_2", &this->in); -+ // top->new_slave_port("sfu_stream_out_data_3", &this->in); -+ // top->new_slave_port("sfu_stream_out_data_4", &this->in); -+ // top->new_slave_port("sfu_stream_out_data_5", &this->in); -+ // top->new_slave_port("sfu_stream_out_data_6", &this->in); -+ // top->new_slave_port("sfu_stream_out_data_7", &this->in); -+ // top->new_slave_port("sfu_stream_out_data_8", &this->in); -+ // top->new_slave_port("sfu_stream_out_data_9", &this->in); -+ // top->new_slave_port("sfu_stream_out_data_10", &this->in); -+ // top->new_slave_port("sfu_stream_out_data_11", &this->in); -+ // top->new_slave_port("sfu_stream_out_data_12", &this->in); -+ // top->new_slave_port("sfu_stream_out_data_13", &this->in); -+ // top->new_slave_port("sfu_stream_out_data_14", &this->in); -+ // top->new_slave_port("sfu_stream_out_data_15", &this->in); + # There must a newline here since the build version is appended in the release process + export GAP_SDK_VERSION=release-v5.21.1 + -+ top->new_master_port("sfu_stream_in_data_0", &this->irq); -+ top->new_master_port("sfu_stream_in_data_1", &this->irq); -+ top->new_master_port("sfu_stream_in_data_2", &this->irq); -+ top->new_master_port("sfu_stream_in_data_3", &this->irq); -+ top->new_master_port("sfu_stream_in_data_4", &this->irq); -+ top->new_master_port("sfu_stream_in_data_5", &this->irq); -+ top->new_master_port("sfu_stream_in_data_6", &this->irq); -+ top->new_master_port("sfu_stream_in_data_7", &this->irq); -+ top->new_master_port("sfu_stream_in_data_8", &this->irq); -+ top->new_master_port("sfu_stream_in_data_9", &this->irq); -+ top->new_master_port("sfu_stream_in_data_10", &this->irq); -+ top->new_master_port("sfu_stream_in_data_11", &this->irq); -+ top->new_master_port("sfu_stream_in_data_12", &this->irq); -+ top->new_master_port("sfu_stream_in_data_13", &this->irq); -+ top->new_master_port("sfu_stream_in_data_14", &this->irq); -+ top->new_master_port("sfu_stream_in_data_15", &this->irq); -+ top->new_master_port("sfu_stream_out_ready_0", &this->irq); -+ top->new_master_port("sfu_stream_out_ready_1", &this->irq); -+ top->new_master_port("sfu_stream_out_ready_2", &this->irq); -+ top->new_master_port("sfu_stream_out_ready_3", &this->irq); -+ top->new_master_port("sfu_stream_out_ready_4", &this->irq); -+ top->new_master_port("sfu_stream_out_ready_5", &this->irq); -+ top->new_master_port("sfu_stream_out_ready_6", &this->irq); -+ top->new_master_port("sfu_stream_out_ready_7", &this->irq); -+ top->new_master_port("sfu_stream_out_ready_8", &this->irq); -+ top->new_master_port("sfu_stream_out_ready_9", &this->irq); -+ top->new_master_port("sfu_stream_out_ready_10", &this->irq); -+ top->new_master_port("sfu_stream_out_ready_11", &this->irq); -+ top->new_master_port("sfu_stream_out_ready_12", &this->irq); -+ top->new_master_port("sfu_stream_out_ready_13", &this->irq); -+ top->new_master_port("sfu_stream_out_ready_14", &this->irq); -+ top->new_master_port("sfu_stream_out_ready_15", &this->irq); - } - - ++export WITH_EMPTY_SFU=1 diff --git a/install_python_deps.sh b/install_python_deps.sh -index 4b0dbb728..8d5610678 100755 +index cac3e1885..578bb5f71 100755 --- a/install_python_deps.sh +++ b/install_python_deps.sh -@@ -60,7 +60,7 @@ then - pip3 install -r tools/nntool/tests/requirements.txt +@@ -69,7 +69,7 @@ then + python -m pip install -r tools/nntool/tests/requirements.txt fi -- pip3 install -r tools/audio-framework/requirements.txt -+# pip3 install -r tools/audio-framework/requirements.txt - pip3 install -r utils/gapy_v2/requirements.txt - pip3 install -r doc/requirements.txt - fi +- python -m pip install -r tools/audio-framework/requirements.txt ++ # python -m pip install -r tools/audio-framework/requirements.txt + python -m pip install -r utils/gapy_v2/requirements.txt + python -m pip install -r doc/requirements.txt + diff --git a/utils/cmake/at.cmake b/utils/cmake/at.cmake -index 476b87c78..ee6449a1d 100644 +index e03d6b6d5..b7f0104d7 100644 --- a/utils/cmake/at.cmake +++ b/utils/cmake/at.cmake -@@ -909,7 +909,7 @@ macro(_at_model_setup_int) +@@ -919,7 +919,7 @@ macro(_at_model_setup_int) OUTPUT ${PARAM_MODEL_EXE_PATH} DEPENDS ${PARAM_MODEL_PATH} ${_MODEL_GEN_SRCS} ${TILER_LIB} COMMAND ${CMAKE_COMMAND} -E make_directory ${_MODEL_EXE_DIR} @@ -272,78 +58,24 @@ index 476b87c78..ee6449a1d 100644 # global compile model target diff --git a/utils/gapy_v2/bin/gapylib/chips/gap/gap9_v2/board_runner.py b/utils/gapy_v2/bin/gapylib/chips/gap/gap9_v2/board_runner.py -index a7b191322..b0c5c5e77 100644 +index 62ee5cac2..d872073f7 100644 --- a/utils/gapy_v2/bin/gapylib/chips/gap/gap9_v2/board_runner.py +++ b/utils/gapy_v2/bin/gapylib/chips/gap/gap9_v2/board_runner.py -@@ -159,7 +159,7 @@ class Openocd(): - if self.args.openocd_tools is None: - raise RuntimeError("Argument --openocd-tools is missing") - -- def connect(self, use_existing_port=6666): -+ def connect(self, telnet_port=None, telnet_host='localhost'): - """Connect to target. - - This will launch OpenOCD with the telnet proxy and connect to it so that this class -@@ -169,10 +169,10 @@ class Openocd(): - # To allow the execution of several gapy in parallel, we cannot use a fixed port. - # Iterate until we find an available one. - retry_nb = 0 -- if use_existing_port is not None: -+ if telnet_port is not None: - success = True -- port = use_existing_port -- self.use_existing_port = use_existing_port -+ port = telnet_port -+ self.telnet_port = telnet_port - else: - success = False - while retry_nb < 30: -@@ -208,7 +208,7 @@ class Openocd(): - - # Now that OpenOCD was successfully launched with proxy openocd, launch a telnet. - if success is True: -- self.telnet = pexpect.spawn(f'telnet localhost {port}', encoding='utf-8', echo=False) -+ self.telnet = pexpect.spawn(f'telnet {telnet_host} {port}', encoding='utf-8', echo=False) - match = self.telnet.expect(['Open On-Chip Debugger'], timeout=None) +@@ -342,7 +342,7 @@ class Openocd(): else: raise RuntimeError('Failed to connect to openocd after 30 retries') -@@ -472,6 +472,12 @@ class Runner(): - parser.add_argument("--gdb-port", dest="gdb_port", default=3333, type=int, - help="GDB port") -+ parser.add_argument("--telnet-port", dest="telnet_port", default=None, type=int, -+ help="Telnet port") -+ -+ parser.add_argument("--telnet-host", dest="telnet_host", default='localhost', type=str, -+ help="Telnet host") -+ - parser.add_argument("--wsl", dest = "wsl", type=str, default=None, - help = "Launch command in wsl environment") - -@@ -602,7 +608,7 @@ class Runner(): - - if ocd is None: - ocd = Openocd(args) -- ocd.connect() -+ ocd.connect(args.telnet_port, args.telnet_host) - - self.__flash_image(args, ocd, flash, base_addr, first_index, last) +- self.telnet = pexpect.spawn(f'telnet localhost {port}', encoding='utf-8', echo=False) ++ self.telnet = pexpect.spawn(f'telnet host.docker.internal {port}', encoding='utf-8', echo=False) + match = self.telnet.expect(['Open On-Chip Debugger'], timeout=None) + def write(self, addr: int, value: int): diff --git a/utils/openocd_tools/tcl/gap9revb.tcl b/utils/openocd_tools/tcl/gap9revb.tcl -index 4a66dfa27..dea57196b 100644 +index 9e67f67c7..697483112 100644 --- a/utils/openocd_tools/tcl/gap9revb.tcl +++ b/utils/openocd_tools/tcl/gap9revb.tcl -@@ -3,7 +3,7 @@ adapter_khz 5000 - - config_reset 0x1 - --target create $_FC riscv -chain-position $_TAP_RISCV -coreid 0x9 -+target create $_FC riscv -chain-position $_TAP_RISCV -coreid 0x9 - - gdb_report_data_abort enable - gdb_report_register_access_error enable -@@ -23,8 +23,8 @@ proc jtag_init {} { - gap_reset 0 100 +@@ -24,8 +24,8 @@ proc jtag_init {} { + #gap_reset 0 100 # wait for jtag ready - poll_confreg 0x1 @@ -351,9 +83,9 @@ index 4a66dfa27..dea57196b 100644 + # poll_confreg 0x1 + # echo "INIT: confreg polling done" - $::_FC arp_examine - echo "examine done" -@@ -36,8 +36,8 @@ proc init_reset {mode} { + #UNCOMMENT IF YOU UNCOMMENT gap_init 1 + #gap_start 1 +@@ -39,8 +39,8 @@ proc init_reset {mode} { #targets $::_FC gap_reset 1 100 # wait for jtag ready diff --git a/Makefile b/Makefile index 075a716c62..e2d7510348 100644 --- a/Makefile +++ b/Makefile @@ -55,9 +55,12 @@ CHIMERA_SDK_COMMIT_HASH ?= b2392f6efcff75c03f4c65eaf3e12104442b22ea XTL_VERSION ?= 0.7.5 XSIMD_VERSION ?= 13.2.0 XTENSOR_VERSION ?= 0.25.0 -GAP9_SDK_COMMIT_HASH ?= 897955d7ab326bd31684429eb16a2e485ab89afb # dev-v5.19.2 +# GAP9_SDK_COMMIT_HASH ?= 897955d7ab326bd31684429eb16a2e485ab89afb # dev-v5.19.2 # GAP9_SDK_COMMIT_HASH ?= dfabdddd0e78b9b750a0eb46eee85d5a2c9ae853 # dev-v5.20.4 -GAP_SDK_URL ?= 'git@iis-git.ee.ethz.ch:wiesep/gap9_sdk.git' +# GAP_SDK_URL ?= 'git@iis-git.ee.ethz.ch:wiesep/gap9_sdk.git' +# GAP9_SDK_COMMIT_HASH ?= 1796873cec9ca1feb352a6fe980b627df979bdd1 # v5.21.1 +GAP9_SDK_COMMIT_HASH ?= 8c42b65338e554ac73c749f94ecddd23a9ee5490 # v5.21.1-staging-1 +GAP_SDK_URL ?= 'git@github.com:pulp-platform/gap-sdk.git' OS := $(shell uname -s) ARCH:= $(shell uname -m) From 646563dcaa3b41ff4f8157f185f113c0aac06a7b Mon Sep 17 00:00:00 2001 From: Philip Wiese Date: Thu, 12 Feb 2026 21:15:55 +0100 Subject: [PATCH 07/16] Print memory usage by default --- DeeployTest/Platforms/GAP9/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/DeeployTest/Platforms/GAP9/CMakeLists.txt b/DeeployTest/Platforms/GAP9/CMakeLists.txt index 0a7fde9c00..db06a4e38f 100644 --- a/DeeployTest/Platforms/GAP9/CMakeLists.txt +++ b/DeeployTest/Platforms/GAP9/CMakeLists.txt @@ -29,4 +29,7 @@ target_compile_options(network PRIVATE -Wno-error ) +target_link_options(${ProjectId} PRIVATE + -Wl,--print-memory-usage +) link_compile_dump(${TESTNAME}) From b2b43a5c67dc571ca3fd7b9127f6a1d5af10fcfd Mon Sep 17 00:00:00 2001 From: Philip Wiese Date: Fri, 13 Feb 2026 11:30:54 +0100 Subject: [PATCH 08/16] Cleanup Makefile --- Makefile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Makefile b/Makefile index e2d7510348..5f381502bf 100644 --- a/Makefile +++ b/Makefile @@ -55,9 +55,7 @@ CHIMERA_SDK_COMMIT_HASH ?= b2392f6efcff75c03f4c65eaf3e12104442b22ea XTL_VERSION ?= 0.7.5 XSIMD_VERSION ?= 13.2.0 XTENSOR_VERSION ?= 0.25.0 -# GAP9_SDK_COMMIT_HASH ?= 897955d7ab326bd31684429eb16a2e485ab89afb # dev-v5.19.2 -# GAP9_SDK_COMMIT_HASH ?= dfabdddd0e78b9b750a0eb46eee85d5a2c9ae853 # dev-v5.20.4 -# GAP_SDK_URL ?= 'git@iis-git.ee.ethz.ch:wiesep/gap9_sdk.git' + # GAP9_SDK_COMMIT_HASH ?= 1796873cec9ca1feb352a6fe980b627df979bdd1 # v5.21.1 GAP9_SDK_COMMIT_HASH ?= 8c42b65338e554ac73c749f94ecddd23a9ee5490 # v5.21.1-staging-1 GAP_SDK_URL ?= 'git@github.com:pulp-platform/gap-sdk.git' From 1a075d0242c9986fab53cfe63d59a03f8da0ae5c Mon Sep 17 00:00:00 2001 From: Philip Wiese Date: Fri, 13 Feb 2026 16:23:24 +0100 Subject: [PATCH 09/16] Try to fix private GAP9 SDK access issue --- .github/workflows/docker-build-deeploy-gap9.yml | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/.github/workflows/docker-build-deeploy-gap9.yml b/.github/workflows/docker-build-deeploy-gap9.yml index 76e7c6b2fa..e3dac03274 100644 --- a/.github/workflows/docker-build-deeploy-gap9.yml +++ b/.github/workflows/docker-build-deeploy-gap9.yml @@ -96,6 +96,11 @@ jobs: env: OWNER: "${{ github.repository_owner }}" + - name: Load SSH key + uses: webfactory/ssh-agent@v0.9.0 + with: + ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} + - name: Build and push final Deeploy image id: build uses: docker/build-push-action@v6 @@ -108,6 +113,7 @@ jobs: push: true build-args: | DEEPLOY_IMAGE=${{ github.event.inputs.docker_image_deeploy }} + ssh: default outputs: type=image,name=ghcr.io/${{ env.OWNER_LC }}/deeploy-gap9,annotation-index=true,name-canonical=true,push=true - name: Extract image digest @@ -142,14 +148,3 @@ jobs: ghcr.io/${{ env.OWNER_LC }}/deeploy-gap9:latest, ghcr.io/${{ env.OWNER_LC }}/deeploy-gap9:${{ needs.prepare.outputs.docker_tag }} push: true - - - name: Set package visibility to internal - uses: actions/github-script@v7 - with: - script: | - await github.rest.packages.updatePackageVersionVisibility({ - package_type: 'container', - package_name: 'deeploy-gap9', - visibility: 'internal', - org: context.repo.owner - }); From 2bb1bf576f2fbad71d4275d19e1b46e5404072fd Mon Sep 17 00:00:00 2001 From: Philip Wiese Date: Mon, 16 Feb 2026 17:05:33 +0100 Subject: [PATCH 10/16] Use pre-build GAP9 GCC --- .github/workflows/_runner-gap9-tiled.yml | 1 - .github/workflows/_runner-gap9.yml | 1 - .../workflows/infra-generate-ccache-gap9.yml | 1 - Container/Dockerfile.deeploy-gap9 | 27 ----------- Container/gap9-amd64.list | 8 ---- Container/gap9-sources.list | 46 ------------------- Makefile | 35 ++++++-------- README_GAP9.md | 3 +- 8 files changed, 17 insertions(+), 105 deletions(-) delete mode 100644 Container/gap9-amd64.list delete mode 100644 Container/gap9-sources.list diff --git a/.github/workflows/_runner-gap9-tiled.yml b/.github/workflows/_runner-gap9-tiled.yml index d456f9f353..a5c8b3ac98 100644 --- a/.github/workflows/_runner-gap9-tiled.yml +++ b/.github/workflows/_runner-gap9-tiled.yml @@ -45,7 +45,6 @@ jobs: source /app/install/gap9-sdk/.gap9-venv/bin/activate source /app/install/gap9-sdk/configs/gap9_evk_audio.sh || true export GVSOC_INSTALL_DIR=/app/install/gap9-sdk/install/workstation - export GAP_RISCV_GCC_TOOLCHAIN=/app/install/gcc/gap9 cd DeeployTest mkdir -p /app/.ccache export CCACHE_DIR=/app/.ccache diff --git a/.github/workflows/_runner-gap9.yml b/.github/workflows/_runner-gap9.yml index d5d8d8e4c0..e1d6e452a6 100644 --- a/.github/workflows/_runner-gap9.yml +++ b/.github/workflows/_runner-gap9.yml @@ -45,7 +45,6 @@ jobs: source /app/install/gap9-sdk/.gap9-venv/bin/activate source /app/install/gap9-sdk/configs/gap9_evk_audio.sh || true export GVSOC_INSTALL_DIR=/app/install/gap9-sdk/install/workstation - export GAP_RISCV_GCC_TOOLCHAIN=/app/install/gcc/gap9 cd DeeployTest mkdir -p /app/.ccache export CCACHE_DIR=/app/.ccache diff --git a/.github/workflows/infra-generate-ccache-gap9.yml b/.github/workflows/infra-generate-ccache-gap9.yml index b54f43ce4c..038789ce40 100644 --- a/.github/workflows/infra-generate-ccache-gap9.yml +++ b/.github/workflows/infra-generate-ccache-gap9.yml @@ -40,7 +40,6 @@ jobs: source /app/install/gap9-sdk/.gap9-venv/bin/activate source /app/install/gap9-sdk/configs/gap9_evk_audio.sh || true export GVSOC_INSTALL_DIR=/app/install/gap9-sdk/install/workstation - export GAP_RISCV_GCC_TOOLCHAIN=/app/install/gcc/gap9 cd DeeployTest mkdir -p /app/.ccache export CCACHE_DIR=/app/.ccache diff --git a/Container/Dockerfile.deeploy-gap9 b/Container/Dockerfile.deeploy-gap9 index 05d3993461..c8320e0e41 100644 --- a/Container/Dockerfile.deeploy-gap9 +++ b/Container/Dockerfile.deeploy-gap9 @@ -73,33 +73,6 @@ RUN apt-get update && \ flex && \ rm -rf /var/lib/apt/lists/* - -COPY Container/gap9-amd64.list Container/gap9-sources.list ./ -# Install AMD64 libraries on ARM64 for GCC GAP9 compiler support -RUN < Date: Mon, 16 Feb 2026 17:29:43 +0100 Subject: [PATCH 11/16] Fix Typos --- Container/Dockerfile.deeploy-gap9 | 4 ++-- Container/Makefile | 22 +++++++++++----------- README_GAP9.md | 8 ++++---- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Container/Dockerfile.deeploy-gap9 b/Container/Dockerfile.deeploy-gap9 index c8320e0e41..4375b3e2aa 100644 --- a/Container/Dockerfile.deeploy-gap9 +++ b/Container/Dockerfile.deeploy-gap9 @@ -2,8 +2,8 @@ # # SPDX-License-Identifier: Apache-2.0 -ARG DEEPOY_IMAGE=ghcr.io/pulp-platform/deeploy:latest -FROM ${DEEPOY_IMAGE} AS deeploy +ARG DEEPLOY_IMAGE=ghcr.io/pulp-platform/deeploy:latest +FROM ${DEEPLOY_IMAGE} AS deeploy ARG TARGETPLATFORM ARG DEBIAN_FRONTEND=noninteractive diff --git a/Container/Makefile b/Container/Makefile index e38d99c519..78f1bf2532 100644 --- a/Container/Makefile +++ b/Container/Makefile @@ -4,8 +4,8 @@ # Variables TOOLCHAIN_IMAGE ?= ghcr.io/pulp-platform/deeploy-toolchain:latest -DEEPOY_IMAGE ?= ghcr.io/pulp-platform/deeploy:latest -DEEPOY_GAP9_IMAGE ?= ghcr.io/pulp-platform/deeploy-gap9:latest +DEEPLOY_IMAGE ?= ghcr.io/pulp-platform/deeploy:latest +DEEPLOY_GAP9_IMAGE ?= ghcr.io/pulp-platform/deeploy-gap9:latest SSH_PRIVATE_KEY ?= ~/.ssh/id_ed25519 @@ -23,15 +23,15 @@ help: @echo "" @echo "Build Variables:" @echo " TOOLCHAIN_IMAGE # Name of the toolchain image (default: $(TOOLCHAIN_IMAGE))" - @echo " DEEPOY_IMAGE # Name of the deeploy image (default: $(DEEPOY_IMAGE))" - @echo " DEEPOY_GAP9_IMAGE # Name of the GAP9 deeploy image (default: $(DEEPOY_GAP9_IMAGE))" + @echo " DEEPLOY_IMAGE # Name of the deeploy image (default: $(DEEPLOY_IMAGE))" + @echo " DEEPLOY_GAP9_IMAGE # Name of the GAP9 deeploy image (default: $(DEEPLOY_GAP9_IMAGE))" @echo " SSH_PRIVATE_KEY # Path to SSH private key for GAP9 build (default: $(SSH_PRIVATE_KEY))" @echo "" @echo "Example Usage:" @echo " make toolchain TOOLCHAIN_IMAGE=my-toolchain:latest" - @echo " make deeploy DEEPOY_IMAGE=my-deeploy:latest" - @echo " make deeploy-gap9 DEEPOY_GAP9_IMAGE=my-deeploy-gap9:latest" - @echo " make all TOOLCHAIN_IMAGE=my-toolchain:latest DEEPOY_IMAGE=my-deeploy:latest" + @echo " make deeploy DEEPLOY_IMAGE=my-deeploy:latest" + @echo " make deeploy-gap9 DEEPLOY_GAP9_IMAGE=my-deeploy-gap9:latest" + @echo " make all TOOLCHAIN_IMAGE=my-toolchain:latest DEEPLOY_IMAGE=my-deeploy:latest" @echo " make deeploy-gap9 SSH_PRIVATE_KEY=/path/to/key" # Build only the toolchain image @@ -46,7 +46,7 @@ deeploy: --ssh default \ -f Dockerfile.deeploy \ --build-arg BASE_IMAGE=$(TOOLCHAIN_IMAGE) \ - -t $(DEEPOY_IMAGE) .. + -t $(DEEPLOY_IMAGE) .. # Build the GAP9 Deeploy image deeploy-gap9: @@ -55,12 +55,12 @@ deeploy-gap9: DOCKER_BUILDKIT=1 docker build \ --ssh default \ -f Dockerfile.deeploy-gap9 \ - --build-arg DEEPOY_IMAGE=$(DEEPOY_IMAGE) \ - -t $(DEEPOY_GAP9_IMAGE) .. + --build-arg DEEPLOY_IMAGE=$(DEEPLOY_IMAGE) \ + -t $(DEEPLOY_GAP9_IMAGE) .. # Build all images all: toolchain deeploy deeploy-gap9 # Clean all images (optional and dangerous) clean: - docker rmi $(TOOLCHAIN_IMAGE) $(DEEPOY_IMAGE) $(DEEPOY_GAP9_IMAGE) || true + docker rmi $(TOOLCHAIN_IMAGE) $(DEELPOY_IMAGE) $(DEELPOY_GAP9_IMAGE) || true diff --git a/README_GAP9.md b/README_GAP9.md index 68773aa845..8b561574aa 100644 --- a/README_GAP9.md +++ b/README_GAP9.md @@ -14,10 +14,10 @@ To build a local version of the Deeploy Docker image with GAP9 support using the cd Container # Build the Deeploy image with the upstream toolchain image -make deeploy-gap9 DEEPOY_GAP9_IMAGE=deeploy-gap9:latest +make deeploy-gap9 DEEPLOY_GAP9_IMAGE=deeploy-gap9:latest # If you want to specify a custom SSH key path, use: -make deeploy-gap9 DEEPOY_GAP9_IMAGE=deeploy-gap9:latest SSH_PRIVATE_KEY=/path/to/your/private/key +make deeploy-gap9 DEEPLOY_GAP9_IMAGE=deeploy-gap9:latest SSH_PRIVATE_KEY=/path/to/your/private/key ``` Or, to build the toolchain, Deeploy and GAP9 images locally, use: @@ -25,10 +25,10 @@ Or, to build the toolchain, Deeploy and GAP9 images locally, use: cd Container # To build the Deeploy container with the local toolchain image -make deeploy TOOLCHAIN_IMAGE=deeploy-toolchain:gap9 DEEPOY_IMAGE=deeploy:gap9 +make deeploy TOOLCHAIN_IMAGE=deeploy-toolchain:gap9 DEEPLOY_IMAGE=deeploy:gap9 # To build the Deeploy GAP9 container with the local toolchain image -make deeploy-gap9 TOOLCHAIN_IMAGE=deeploy-toolchain:gap9 DEEPOY_IMAGE=deeploy:gap9 DEEPOY_GAP9_IMAGE=deeploy-gap9:latest +make deeploy-gap9 TOOLCHAIN_IMAGE=deeploy-toolchain:gap9 DEEPLOY_IMAGE=deeploy:gap9 DEEPLOY_GAP9_IMAGE=deeploy-gap9:latest ``` ### Use The Docker Container From c6bc2c6458111f08b24283ff2240d52ce767a6bf Mon Sep 17 00:00:00 2001 From: Philip Wiese Date: Mon, 16 Feb 2026 17:44:10 +0100 Subject: [PATCH 12/16] Partially revert a16c1c757928ed37f89d2744609fd97bb3ddd702 We still need x86 compilation for Autotiler --- Container/Dockerfile.deeploy-gap9 | 27 ++++++++++++++++++ Container/gap9-amd64.list | 8 ++++++ Container/gap9-sources.list | 46 +++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100644 Container/gap9-amd64.list create mode 100644 Container/gap9-sources.list diff --git a/Container/Dockerfile.deeploy-gap9 b/Container/Dockerfile.deeploy-gap9 index 4375b3e2aa..6d6f7a2db3 100644 --- a/Container/Dockerfile.deeploy-gap9 +++ b/Container/Dockerfile.deeploy-gap9 @@ -73,6 +73,33 @@ RUN apt-get update && \ flex && \ rm -rf /var/lib/apt/lists/* + +COPY Container/gap9-amd64.list Container/gap9-sources.list ./ +# Install AMD64 libraries on ARM64 for GCC GAP9 compiler support +RUN < Date: Mon, 16 Feb 2026 18:17:39 +0100 Subject: [PATCH 13/16] Build AutoTiler --- Container/Dockerfile.deeploy-gap9 | 32 +-------------------- Container/gap9-amd64.list | 8 ------ Container/gap9-arm64.patch | 13 --------- Container/gap9-sources.list | 46 ------------------------------- scripts/gap9-build_sdk.sh | 3 +- 5 files changed, 3 insertions(+), 99 deletions(-) delete mode 100644 Container/gap9-amd64.list delete mode 100644 Container/gap9-sources.list diff --git a/Container/Dockerfile.deeploy-gap9 b/Container/Dockerfile.deeploy-gap9 index 6d6f7a2db3..734674945a 100644 --- a/Container/Dockerfile.deeploy-gap9 +++ b/Container/Dockerfile.deeploy-gap9 @@ -73,33 +73,6 @@ RUN apt-get update && \ flex && \ rm -rf /var/lib/apt/lists/* - -COPY Container/gap9-amd64.list Container/gap9-sources.list ./ -# Install AMD64 libraries on ARM64 for GCC GAP9 compiler support -RUN < Date: Mon, 16 Feb 2026 19:32:21 +0100 Subject: [PATCH 14/16] CodeAIRabbit Feedback --- Container/Makefile | 2 +- README_GAP9.md | 22 +++++++++++++++++++++- scripts/gap9-build_sdk.sh | 2 +- scripts/gap9-run.sh | 2 -- 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/Container/Makefile b/Container/Makefile index 78f1bf2532..e2ba85a65d 100644 --- a/Container/Makefile +++ b/Container/Makefile @@ -63,4 +63,4 @@ all: toolchain deeploy deeploy-gap9 # Clean all images (optional and dangerous) clean: - docker rmi $(TOOLCHAIN_IMAGE) $(DEELPOY_IMAGE) $(DEELPOY_GAP9_IMAGE) || true + docker rmi $(TOOLCHAIN_IMAGE) $(DEEPLOY_IMAGE) $(DEEPLOY_GAP9_IMAGE) || true diff --git a/README_GAP9.md b/README_GAP9.md index 8b561574aa..08aab49c51 100644 --- a/README_GAP9.md +++ b/README_GAP9.md @@ -3,7 +3,7 @@ > ⚠️ **IMPORTANT NOTE** > This is a work in progress. The GAP9 support in Deeploy is experimental and may not be fully functional. -To use Deeploy with GAP9, a custom Docker container is required because the official Deeploy Docker image does yet not include the necessary SDKs and dependencies for GAP9 development, because they are not publicly available. +To use Deeploy with GAP9, a custom Docker container is required because the official Deeploy Docker image does not yet include the necessary SDKs and dependencies for GAP9 development, because they are not publicly available. ### Build The Docker Container @@ -94,6 +94,26 @@ Terminal 2 (containers + attach device): - Set USB device IDs: `USBIP_VENDOR=15ba USBIP_PRODUCT=002b` - Change USB/IP host: `USBIP_HOST=host.docker.internal` +#### Linux note: host.docker.internal workaround +The GAP9 workflow spawns telnet using `host.docker.internal`. This hostname is provided by Docker Desktop only (macOS/Windows). On Linux, you must either add the host-gateway alias when starting Docker or override the host in the script, otherwise telnet connections will fail. + +Option 1 (Docker 20.10+): start Docker with the host-gateway alias so `host.docker.internal` resolves: +```sh +dockerd --add-host=host.docker.internal:host-gateway +``` + +Option 2 (recommended for Linux): run the script with a USB/IP host override: +```sh +USBIP_HOST=localhost ./scripts/gap9-run.sh start +``` + +Or use the script flag to set the host explicitly: +```sh +./scripts/gap9-run.sh -h localhost start +``` + +If you are on Linux and not using Docker Desktop, prefer the USBIP_HOST override (or `-h`) unless you already manage `dockerd` with the host-gateway alias. + To stop everything: ```sh ./scripts/gap9-run.sh stop diff --git a/scripts/gap9-build_sdk.sh b/scripts/gap9-build_sdk.sh index 819f1680a2..3d044b9b90 100755 --- a/scripts/gap9-build_sdk.sh +++ b/scripts/gap9-build_sdk.sh @@ -14,7 +14,7 @@ ROOT_DIR="${ROOT_DIR:-$(cd "$(dirname "$0")" && pwd)}" GAP9_SDK_INSTALL_DIR="${GAP9_SDK_INSTALL_DIR:?GAP9_SDK_INSTALL_DIR must be set}" GAP9_SDK_COMMIT_HASH="${GAP9_SDK_COMMIT_HASH:-897955d7ab326bd31684429eb16a2e485ab89afb}" -GAP_SDK_URL="${GAP_SDK_URL:-'git@iis-git.ee.ethz.ch:wiesep/gap9_sdk.git'}" +GAP_SDK_URL="${GAP_SDK_URL:-git@iis-git.ee.ethz.ch:wiesep/gap9_sdk.git}" echo "Preparing GAP9 SDK in: ${GAP9_SDK_INSTALL_DIR}" diff --git a/scripts/gap9-run.sh b/scripts/gap9-run.sh index 912f062819..8c38c551f9 100755 --- a/scripts/gap9-run.sh +++ b/scripts/gap9-run.sh @@ -224,7 +224,6 @@ cmd_setup_usbip_host() { python3 -m venv "$PYUSBIP_DIR/.venv" log_info "Installing pyusbip dependencies..." - # shellcheck disable=SC1091 . "$PYUSBIP_DIR/.venv/bin/activate" pip install --upgrade pip pip install libusb1 @@ -242,7 +241,6 @@ cmd_start_usbip_host() { log_info "This process will run in the foreground. Press Ctrl+C to stop." cd "$PYUSBIP_DIR" && - # shellcheck disable=SC1091 . .venv/bin/activate && python pyusbip.py } From 6d1c8c305b95db714ed112a2695d9c598dbc641b Mon Sep 17 00:00:00 2001 From: Philip Wiese Date: Tue, 17 Feb 2026 11:02:39 +0100 Subject: [PATCH 15/16] Update Changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f4e08ba71..a277d2361d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ This file contains the changelog for the Deeploy project. The changelog is divid ### List of Pull Requests +- Add GAP9 Container Support [#163](https://github.com/pulp-platform/Deeploy/pull/163) - Extend Codeowners [#164](https://github.com/pulp-platform/Deeploy/pull/164) - Support for MaxPool1D and RQSConv1D for PULPOpen [#146](https://github.com/pulp-platform/Deeploy/pull/146) - Use Pre-Commit in CI [#159](https://github.com/pulp-platform/Deeploy/pull/159) @@ -12,10 +13,14 @@ This file contains the changelog for the Deeploy project. The changelog is divid - Update CLI interface Across Project, Fix Tutorial, and Remove Legacy Test [#157](https://github.com/pulp-platform/Deeploy/pull/157) ### Added +- GAP9 Container Support with ARM64 architecture support +- `zsh` and `oh-my-zsh` plugin installation in containers +- Shell Format pre-commit hook - Add integer MaxPool1D for Generic platform and RQSConv1D support for PULPOpen, with corresponding kernel tests. - Added GAP9 Platform Support: Deployer, Bindings, Templates, Tiler, DMA (L3Dma/MchanDma), target library, CI workflows ### Changed +- Cleaned up Docker flow to use a temporary build folder - Switch CI to use pre-commit for linting - Update `pulp-nnx` and `pulp-nn-mixed` submodules to their latest versions - PULP-NN moved to TargetLibraries third-party folder From 6db1c52b376d0473621afba8b2dc2ed898d90e5e Mon Sep 17 00:00:00 2001 From: Philip Wiese Date: Tue, 17 Feb 2026 11:17:56 +0100 Subject: [PATCH 16/16] CodeAIRabbit Feedback --- Container/Dockerfile.deeploy-gap9 | 66 +++++++++++++++---------------- Makefile | 2 +- README_GAP9.md | 34 +--------------- scripts/gap9-build_sdk.sh | 4 +- scripts/gap9-run.sh | 3 +- 5 files changed, 38 insertions(+), 71 deletions(-) diff --git a/Container/Dockerfile.deeploy-gap9 b/Container/Dockerfile.deeploy-gap9 index 734674945a..21724019b4 100644 --- a/Container/Dockerfile.deeploy-gap9 +++ b/Container/Dockerfile.deeploy-gap9 @@ -26,51 +26,49 @@ COPY Makefile ./ RUN apt-get update && \ apt-get upgrade -y && \ apt-get install -y \ - git-lfs \ + autoconf \ + automake \ + bison \ ccache \ - ninja-build \ - pkg-config \ - ibglib2.0-dev \ - libpixman-1-dev \ - python3 \ - python3-pip \ - python3-dev \ - python-is-python3 \ - python3.10-venv \ - python3.10-distutils \ + clang-format \ curl \ - protobuf-compiler \ + device-tree-compiler \ + doxygen \ + flex \ + g++ \ + gcc \ + gcc-x86-64-linux-gnu \ + gdb-multiarch \ + git-lfs \ + gtkwave \ + ibglib2.0-dev \ libftdi-dev \ libftdi1 \ - doxygen \ + libpixman-1-dev \ libsdl2-dev \ - scons \ - gtkwave \ + libsdl2-ttf-dev \ libsndfile1-dev \ - rsync \ - autoconf \ - automake \ - texinfo \ libtool \ - libsdl2-ttf-dev \ - gcc \ - wget \ - clang-format \ - g++ \ - sudo \ - device-tree-compiler \ - zsh \ + libusb-1.0-0-dev \ nano \ - sudo \ - gdb-multiarch \ + ninja-build \ + pkg-config \ + protobuf-compiler \ + python-is-python3 \ + python3 \ + python3-dev \ + python3-pip \ + python3.10-distutils \ + python3.10-venv \ + rsync \ + scons \ ssh \ - gcc-x86-64-linux-gnu \ + sudo \ telnet \ + texinfo \ usbutils \ - libftdi-dev \ - libusb-1.0-0-dev \ - bison \ - flex && \ + wget \ + zsh && \ rm -rf /var/lib/apt/lists/* RUN --mount=type=cache,target=/ccache \ diff --git a/Makefile b/Makefile index 88512e5966..44a74542ff 100644 --- a/Makefile +++ b/Makefile @@ -59,7 +59,7 @@ XTENSOR_VERSION ?= 0.25.0 GAP_RISCV_GCC_COMMIT_HASH ?= fbb9fa450d01c1c170f94af817490f41c5ef7971 # GAP9_SDK_COMMIT_HASH ?= 1796873cec9ca1feb352a6fe980b627df979bdd1 # v5.21.1 GAP9_SDK_COMMIT_HASH ?= 8c42b65338e554ac73c749f94ecddd23a9ee5490 # v5.21.1-staging-1 -GAP_SDK_URL ?= 'git@github.com:pulp-platform/gap-sdk.git' +GAP_SDK_URL ?= git@github.com:pulp-platform/gap-sdk.git OS := $(shell uname -s) ARCH:= $(shell uname -m) diff --git a/README_GAP9.md b/README_GAP9.md index 08aab49c51..d649fbb6e9 100644 --- a/README_GAP9.md +++ b/README_GAP9.md @@ -72,7 +72,7 @@ For board access, use the orchestration script in [scripts/gap9-run.sh](scripts/ #### Start the board workflow (recommended) -This launches a tmux session with two panes: one for the host USB/IP server and one for the GAP9 container. +This launches a tmux session with three panes: one for the host USB/IP server, one for the GAP9 container and one terminal on the host to manage the USB/IP devices. ```sh ./scripts/gap9-run.sh start-tmux @@ -87,34 +87,4 @@ Terminal 1 (host USB/IP server): Terminal 2 (containers + attach device): ```sh ./scripts/gap9-run.sh start -``` - -#### Common options and environment variables -- Use a custom image: `-i your-gap9-image:tag` or `GAP9_IMAGE=your-gap9-image:tag` -- Set USB device IDs: `USBIP_VENDOR=15ba USBIP_PRODUCT=002b` -- Change USB/IP host: `USBIP_HOST=host.docker.internal` - -#### Linux note: host.docker.internal workaround -The GAP9 workflow spawns telnet using `host.docker.internal`. This hostname is provided by Docker Desktop only (macOS/Windows). On Linux, you must either add the host-gateway alias when starting Docker or override the host in the script, otherwise telnet connections will fail. - -Option 1 (Docker 20.10+): start Docker with the host-gateway alias so `host.docker.internal` resolves: -```sh -dockerd --add-host=host.docker.internal:host-gateway -``` - -Option 2 (recommended for Linux): run the script with a USB/IP host override: -```sh -USBIP_HOST=localhost ./scripts/gap9-run.sh start -``` - -Or use the script flag to set the host explicitly: -```sh -./scripts/gap9-run.sh -h localhost start -``` - -If you are on Linux and not using Docker Desktop, prefer the USBIP_HOST override (or `-h`) unless you already manage `dockerd` with the host-gateway alias. - -To stop everything: -```sh -./scripts/gap9-run.sh stop -``` +``` \ No newline at end of file diff --git a/scripts/gap9-build_sdk.sh b/scripts/gap9-build_sdk.sh index 3d044b9b90..21c832927e 100755 --- a/scripts/gap9-build_sdk.sh +++ b/scripts/gap9-build_sdk.sh @@ -20,14 +20,14 @@ echo "Preparing GAP9 SDK in: ${GAP9_SDK_INSTALL_DIR}" if [ -d "${GAP9_SDK_INSTALL_DIR}/.git" ]; then echo "Directory ${GAP9_SDK_INSTALL_DIR} already exists and looks like a git repo. Updating remote URL and fetching latest changes..." - cd "${GAP9_SDK_INSTALL_DIR}" + cd "${GAP9_SDK_INSTALL_DIR}" || exit 1 git remote set-url origin "${GAP_SDK_URL}" || true else echo "Cloning GAP9 SDK..." git clone "${GAP_SDK_URL}" "${GAP9_SDK_INSTALL_DIR}" fi -cd "${GAP9_SDK_INSTALL_DIR}" +cd "${GAP9_SDK_INSTALL_DIR}" || exit 1 echo "Checking out commit ${GAP9_SDK_COMMIT_HASH} (stash and fetch if necessary)" git fetch --all --tags || true git stash || true diff --git a/scripts/gap9-run.sh b/scripts/gap9-run.sh index 8c38c551f9..fa01424df1 100755 --- a/scripts/gap9-run.sh +++ b/scripts/gap9-run.sh @@ -437,7 +437,7 @@ cmd_start_tmux() { local script_path="$0" local opts_escaped="" - for opt in "${opts[@]:-}"; do + for opt in ${opts[@]+"${opts[@]}"}; do if [[ -n "$opt" ]]; then printf -v opt '%q' "$opt" opts_escaped+=" $opt" @@ -495,7 +495,6 @@ cmd_stop_tmux() { # Main Script Logic ######################################################################### -# If no command provided, show help if [[ -z "$command" ]]; then cmd_start_tmux exit 0